diff options
Diffstat (limited to 'kernel/drivers/hwtracing/coresight/coresight-funnel.c')
-rw-r--r-- | kernel/drivers/hwtracing/coresight/coresight-funnel.c | 61 |
1 files changed, 44 insertions, 17 deletions
diff --git a/kernel/drivers/hwtracing/coresight/coresight-funnel.c b/kernel/drivers/hwtracing/coresight/coresight-funnel.c index 3db36f70b..2e36bde7f 100644 --- a/kernel/drivers/hwtracing/coresight/coresight-funnel.c +++ b/kernel/drivers/hwtracing/coresight/coresight-funnel.c @@ -18,9 +18,10 @@ #include <linux/err.h> #include <linux/fs.h> #include <linux/slab.h> -#include <linux/clk.h> +#include <linux/pm_runtime.h> #include <linux/coresight.h> #include <linux/amba/bus.h> +#include <linux/clk.h> #include "coresight-priv.h" @@ -35,15 +36,15 @@ * struct funnel_drvdata - specifics associated to a funnel component * @base: memory mapped base address for this component. * @dev: the device entity associated to this component. + * @atclk: optional clock for the core parts of the funnel. * @csdev: component vitals needed by the framework. - * @clk: the clock this component is associated to. * @priority: port selection order. */ struct funnel_drvdata { void __iomem *base; struct device *dev; + struct clk *atclk; struct coresight_device *csdev; - struct clk *clk; unsigned long priority; }; @@ -67,12 +68,8 @@ static int funnel_enable(struct coresight_device *csdev, int inport, int outport) { struct funnel_drvdata *drvdata = dev_get_drvdata(csdev->dev.parent); - int ret; - - ret = clk_prepare_enable(drvdata->clk); - if (ret) - return ret; + pm_runtime_get_sync(drvdata->dev); funnel_enable_hw(drvdata, inport); dev_info(drvdata->dev, "FUNNEL inport %d enabled\n", inport); @@ -98,8 +95,7 @@ static void funnel_disable(struct coresight_device *csdev, int inport, struct funnel_drvdata *drvdata = dev_get_drvdata(csdev->dev.parent); funnel_disable_hw(drvdata, inport); - - clk_disable_unprepare(drvdata->clk); + pm_runtime_put(drvdata->dev); dev_info(drvdata->dev, "FUNNEL inport %d disabled\n", inport); } @@ -153,16 +149,14 @@ static u32 get_funnel_ctrl_hw(struct funnel_drvdata *drvdata) static ssize_t funnel_ctrl_show(struct device *dev, struct device_attribute *attr, char *buf) { - int ret; u32 val; struct funnel_drvdata *drvdata = dev_get_drvdata(dev->parent); - ret = clk_prepare_enable(drvdata->clk); - if (ret) - return ret; + pm_runtime_get_sync(drvdata->dev); val = get_funnel_ctrl_hw(drvdata); - clk_disable_unprepare(drvdata->clk); + + pm_runtime_put(drvdata->dev); return sprintf(buf, "%#x\n", val); } @@ -177,6 +171,7 @@ ATTRIBUTE_GROUPS(coresight_funnel); static int funnel_probe(struct amba_device *adev, const struct amba_id *id) { + int ret; void __iomem *base; struct device *dev = &adev->dev; struct coresight_platform_data *pdata = NULL; @@ -197,6 +192,12 @@ static int funnel_probe(struct amba_device *adev, const struct amba_id *id) return -ENOMEM; drvdata->dev = &adev->dev; + drvdata->atclk = devm_clk_get(&adev->dev, "atclk"); /* optional */ + if (!IS_ERR(drvdata->atclk)) { + ret = clk_prepare_enable(drvdata->atclk); + if (ret) + return ret; + } dev_set_drvdata(dev, drvdata); /* Validity for the resource is already checked by the AMBA core */ @@ -205,8 +206,7 @@ static int funnel_probe(struct amba_device *adev, const struct amba_id *id) return PTR_ERR(base); drvdata->base = base; - - drvdata->clk = adev->pclk; + pm_runtime_put(&adev->dev); desc = devm_kzalloc(dev, sizeof(*desc), GFP_KERNEL); if (!desc) @@ -234,6 +234,32 @@ static int funnel_remove(struct amba_device *adev) return 0; } +#ifdef CONFIG_PM +static int funnel_runtime_suspend(struct device *dev) +{ + struct funnel_drvdata *drvdata = dev_get_drvdata(dev); + + if (drvdata && !IS_ERR(drvdata->atclk)) + clk_disable_unprepare(drvdata->atclk); + + return 0; +} + +static int funnel_runtime_resume(struct device *dev) +{ + struct funnel_drvdata *drvdata = dev_get_drvdata(dev); + + if (drvdata && !IS_ERR(drvdata->atclk)) + clk_prepare_enable(drvdata->atclk); + + return 0; +} +#endif + +static const struct dev_pm_ops funnel_dev_pm_ops = { + SET_RUNTIME_PM_OPS(funnel_runtime_suspend, funnel_runtime_resume, NULL) +}; + static struct amba_id funnel_ids[] = { { .id = 0x0003b908, @@ -246,6 +272,7 @@ static struct amba_driver funnel_driver = { .drv = { .name = "coresight-funnel", .owner = THIS_MODULE, + .pm = &funnel_dev_pm_ops, }, .probe = funnel_probe, .remove = funnel_remove, |