aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/hwtracing
diff options
context:
space:
mode:
authorLinus Walleij <linus.walleij@linaro.org>2015-05-19 12:55:12 -0400
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2015-05-24 14:12:08 -0400
commite2d08f96d48dcca844ec1d50188c7a975bed1ded (patch)
treed32b4abc0444b1eeed6342983dadb950be5aa736 /drivers/hwtracing
parent1b19f59dca70d802cee8a7d324c2340fdf0bd258 (diff)
coresight: funnel: let runtime PM handle core clock
This uses runtime PM to manage the PCLK ("amba_pclk") instead of screwing around with the framework by going in and taking a copy from the amba device. The amba bus core will unprepare and disable the clock when the device is unused when CONFIG_PM is selected, else the clock will be always on. Prior to this patch, as the AMBA primecell bus code enables the PCLK, it would be left on after probe as clk_disable_unprepare() was not called. Now the runtime PM callbacks will make sure the PCLK is properly disabled after probe. Reviewed-by: Ulf Hansson <ulf.hansson@linaro.org> Signed-off-by: Linus Walleij <linus.walleij@linaro.org> Signed-off-by: Mathieu Poirier <mathieu.poirier@linaro.org> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers/hwtracing')
-rw-r--r--drivers/hwtracing/coresight/coresight-funnel.c24
1 files changed, 7 insertions, 17 deletions
diff --git a/drivers/hwtracing/coresight/coresight-funnel.c b/drivers/hwtracing/coresight/coresight-funnel.c
index 3db36f70b666..330de2c88759 100644
--- a/drivers/hwtracing/coresight/coresight-funnel.c
+++ b/drivers/hwtracing/coresight/coresight-funnel.c
@@ -18,7 +18,7 @@
18#include <linux/err.h> 18#include <linux/err.h>
19#include <linux/fs.h> 19#include <linux/fs.h>
20#include <linux/slab.h> 20#include <linux/slab.h>
21#include <linux/clk.h> 21#include <linux/pm_runtime.h>
22#include <linux/coresight.h> 22#include <linux/coresight.h>
23#include <linux/amba/bus.h> 23#include <linux/amba/bus.h>
24 24
@@ -36,14 +36,12 @@
36 * @base: memory mapped base address for this component. 36 * @base: memory mapped base address for this component.
37 * @dev: the device entity associated to this component. 37 * @dev: the device entity associated to this component.
38 * @csdev: component vitals needed by the framework. 38 * @csdev: component vitals needed by the framework.
39 * @clk: the clock this component is associated to.
40 * @priority: port selection order. 39 * @priority: port selection order.
41 */ 40 */
42struct funnel_drvdata { 41struct funnel_drvdata {
43 void __iomem *base; 42 void __iomem *base;
44 struct device *dev; 43 struct device *dev;
45 struct coresight_device *csdev; 44 struct coresight_device *csdev;
46 struct clk *clk;
47 unsigned long priority; 45 unsigned long priority;
48}; 46};
49 47
@@ -67,12 +65,8 @@ static int funnel_enable(struct coresight_device *csdev, int inport,
67 int outport) 65 int outport)
68{ 66{
69 struct funnel_drvdata *drvdata = dev_get_drvdata(csdev->dev.parent); 67 struct funnel_drvdata *drvdata = dev_get_drvdata(csdev->dev.parent);
70 int ret;
71
72 ret = clk_prepare_enable(drvdata->clk);
73 if (ret)
74 return ret;
75 68
69 pm_runtime_get_sync(drvdata->dev);
76 funnel_enable_hw(drvdata, inport); 70 funnel_enable_hw(drvdata, inport);
77 71
78 dev_info(drvdata->dev, "FUNNEL inport %d enabled\n", inport); 72 dev_info(drvdata->dev, "FUNNEL inport %d enabled\n", inport);
@@ -98,8 +92,7 @@ static void funnel_disable(struct coresight_device *csdev, int inport,
98 struct funnel_drvdata *drvdata = dev_get_drvdata(csdev->dev.parent); 92 struct funnel_drvdata *drvdata = dev_get_drvdata(csdev->dev.parent);
99 93
100 funnel_disable_hw(drvdata, inport); 94 funnel_disable_hw(drvdata, inport);
101 95 pm_runtime_put(drvdata->dev);
102 clk_disable_unprepare(drvdata->clk);
103 96
104 dev_info(drvdata->dev, "FUNNEL inport %d disabled\n", inport); 97 dev_info(drvdata->dev, "FUNNEL inport %d disabled\n", inport);
105} 98}
@@ -153,16 +146,14 @@ static u32 get_funnel_ctrl_hw(struct funnel_drvdata *drvdata)
153static ssize_t funnel_ctrl_show(struct device *dev, 146static ssize_t funnel_ctrl_show(struct device *dev,
154 struct device_attribute *attr, char *buf) 147 struct device_attribute *attr, char *buf)
155{ 148{
156 int ret;
157 u32 val; 149 u32 val;
158 struct funnel_drvdata *drvdata = dev_get_drvdata(dev->parent); 150 struct funnel_drvdata *drvdata = dev_get_drvdata(dev->parent);
159 151
160 ret = clk_prepare_enable(drvdata->clk); 152 pm_runtime_get_sync(drvdata->dev);
161 if (ret)
162 return ret;
163 153
164 val = get_funnel_ctrl_hw(drvdata); 154 val = get_funnel_ctrl_hw(drvdata);
165 clk_disable_unprepare(drvdata->clk); 155
156 pm_runtime_put(drvdata->dev);
166 157
167 return sprintf(buf, "%#x\n", val); 158 return sprintf(buf, "%#x\n", val);
168} 159}
@@ -205,8 +196,7 @@ static int funnel_probe(struct amba_device *adev, const struct amba_id *id)
205 return PTR_ERR(base); 196 return PTR_ERR(base);
206 197
207 drvdata->base = base; 198 drvdata->base = base;
208 199 pm_runtime_put(&adev->dev);
209 drvdata->clk = adev->pclk;
210 200
211 desc = devm_kzalloc(dev, sizeof(*desc), GFP_KERNEL); 201 desc = devm_kzalloc(dev, sizeof(*desc), GFP_KERNEL);
212 if (!desc) 202 if (!desc)