diff options
author | Rafael J. Wysocki <rjw@sisk.pl> | 2012-08-13 08:00:16 -0400 |
---|---|---|
committer | Rafael J. Wysocki <rjw@sisk.pl> | 2012-09-03 19:36:05 -0400 |
commit | 3cb6f10a4d925ec21f414bc30a8aded2830963e5 (patch) | |
tree | b283b2ab8fed7b3b50ce5fa9acd61b635da62416 /drivers/clocksource/sh_mtu2.c | |
parent | bad813831e291cf34a007e6f03c37cf95037c868 (diff) |
sh: MTU2: Basic runtime PM support
Modify the SH MTU2 clock event device driver to support runtime PM at
a basic level (i.e. device clocks can be disabled and enabled, but
domain power must be on, because the device has to be marked as
"irq safe").
Signed-off-by: Rafael J. Wysocki <rjw@sisk.pl>
Acked-by: Magnus Damm <damm@opensource.se>
Diffstat (limited to 'drivers/clocksource/sh_mtu2.c')
-rw-r--r-- | drivers/clocksource/sh_mtu2.c | 29 |
1 files changed, 23 insertions, 6 deletions
diff --git a/drivers/clocksource/sh_mtu2.c b/drivers/clocksource/sh_mtu2.c index 1a95cad96819..c5eea858054a 100644 --- a/drivers/clocksource/sh_mtu2.c +++ b/drivers/clocksource/sh_mtu2.c | |||
@@ -32,6 +32,7 @@ | |||
32 | #include <linux/slab.h> | 32 | #include <linux/slab.h> |
33 | #include <linux/module.h> | 33 | #include <linux/module.h> |
34 | #include <linux/pm_domain.h> | 34 | #include <linux/pm_domain.h> |
35 | #include <linux/pm_runtime.h> | ||
35 | 36 | ||
36 | struct sh_mtu2_priv { | 37 | struct sh_mtu2_priv { |
37 | void __iomem *mapbase; | 38 | void __iomem *mapbase; |
@@ -123,6 +124,9 @@ static int sh_mtu2_enable(struct sh_mtu2_priv *p) | |||
123 | { | 124 | { |
124 | int ret; | 125 | int ret; |
125 | 126 | ||
127 | pm_runtime_get_sync(&p->pdev->dev); | ||
128 | dev_pm_syscore_device(&p->pdev->dev, true); | ||
129 | |||
126 | /* enable clock */ | 130 | /* enable clock */ |
127 | ret = clk_enable(p->clk); | 131 | ret = clk_enable(p->clk); |
128 | if (ret) { | 132 | if (ret) { |
@@ -157,6 +161,9 @@ static void sh_mtu2_disable(struct sh_mtu2_priv *p) | |||
157 | 161 | ||
158 | /* stop clock */ | 162 | /* stop clock */ |
159 | clk_disable(p->clk); | 163 | clk_disable(p->clk); |
164 | |||
165 | dev_pm_syscore_device(&p->pdev->dev, false); | ||
166 | pm_runtime_put(&p->pdev->dev); | ||
160 | } | 167 | } |
161 | 168 | ||
162 | static irqreturn_t sh_mtu2_interrupt(int irq, void *dev_id) | 169 | static irqreturn_t sh_mtu2_interrupt(int irq, void *dev_id) |
@@ -317,18 +324,17 @@ static int sh_mtu2_setup(struct sh_mtu2_priv *p, struct platform_device *pdev) | |||
317 | static int __devinit sh_mtu2_probe(struct platform_device *pdev) | 324 | static int __devinit sh_mtu2_probe(struct platform_device *pdev) |
318 | { | 325 | { |
319 | struct sh_mtu2_priv *p = platform_get_drvdata(pdev); | 326 | struct sh_mtu2_priv *p = platform_get_drvdata(pdev); |
327 | struct sh_timer_config *cfg = pdev->dev.platform_data; | ||
320 | int ret; | 328 | int ret; |
321 | 329 | ||
322 | if (!is_early_platform_device(pdev)) { | 330 | if (!is_early_platform_device(pdev)) { |
323 | struct sh_timer_config *cfg = pdev->dev.platform_data; | 331 | pm_runtime_set_active(&pdev->dev); |
324 | 332 | pm_runtime_enable(&pdev->dev); | |
325 | if (cfg->clockevent_rating) | ||
326 | dev_pm_syscore_device(&pdev->dev, true); | ||
327 | } | 333 | } |
328 | 334 | ||
329 | if (p) { | 335 | if (p) { |
330 | dev_info(&pdev->dev, "kept as earlytimer\n"); | 336 | dev_info(&pdev->dev, "kept as earlytimer\n"); |
331 | return 0; | 337 | goto out; |
332 | } | 338 | } |
333 | 339 | ||
334 | p = kmalloc(sizeof(*p), GFP_KERNEL); | 340 | p = kmalloc(sizeof(*p), GFP_KERNEL); |
@@ -341,8 +347,19 @@ static int __devinit sh_mtu2_probe(struct platform_device *pdev) | |||
341 | if (ret) { | 347 | if (ret) { |
342 | kfree(p); | 348 | kfree(p); |
343 | platform_set_drvdata(pdev, NULL); | 349 | platform_set_drvdata(pdev, NULL); |
350 | pm_runtime_idle(&pdev->dev); | ||
351 | return ret; | ||
344 | } | 352 | } |
345 | return ret; | 353 | if (is_early_platform_device(pdev)) |
354 | return 0; | ||
355 | |||
356 | out: | ||
357 | if (cfg->clockevent_rating) | ||
358 | pm_runtime_irq_safe(&pdev->dev); | ||
359 | else | ||
360 | pm_runtime_idle(&pdev->dev); | ||
361 | |||
362 | return 0; | ||
346 | } | 363 | } |
347 | 364 | ||
348 | static int __devexit sh_mtu2_remove(struct platform_device *pdev) | 365 | static int __devexit sh_mtu2_remove(struct platform_device *pdev) |