aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/amba
diff options
context:
space:
mode:
authorKrzysztof Kozlowski <k.kozlowski@samsung.com>2014-11-14 03:48:27 -0500
committerRussell King <rmk+kernel@arm.linux.org.uk>2014-11-17 15:23:36 -0500
commit5670c2a52f60418f67dd589e20d30600804fcfde (patch)
treebd5866f69b59b72adfe7eebadd078ee507fd2987 /drivers/amba
parentf560e3229564a673603541ebfb36118d7cd98038 (diff)
ARM: 8201/1: amba: Don't unprepare the clocks if device driver wants IRQ safe runtime PM v12
The AMBA bus driver defines runtime Power Management functions which disable and unprepare AMBA bus clock. This is problematic for runtime PM because unpreparing a clock might sleep so it is not interrupt safe. However some drivers may want to implement runtime PM functions in interrupt-safe way (see pm_runtime_irq_safe()). In such case the AMBA bus driver should only disable/enable the clock in runtime suspend and resume callbacks. Signed-off-by: Krzysztof Kozlowski <k.kozlowski@samsung.com> Reviewed-by: Ulf Hansson <ulf.hansson@linaro.org> Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
Diffstat (limited to 'drivers/amba')
-rw-r--r--drivers/amba/bus.c15
1 files changed, 11 insertions, 4 deletions
diff --git a/drivers/amba/bus.c b/drivers/amba/bus.c
index 47bbdc1b5be3..f8e3bb44938e 100644
--- a/drivers/amba/bus.c
+++ b/drivers/amba/bus.c
@@ -95,8 +95,12 @@ static int amba_pm_runtime_suspend(struct device *dev)
95 struct amba_device *pcdev = to_amba_device(dev); 95 struct amba_device *pcdev = to_amba_device(dev);
96 int ret = pm_generic_runtime_suspend(dev); 96 int ret = pm_generic_runtime_suspend(dev);
97 97
98 if (ret == 0 && dev->driver) 98 if (ret == 0 && dev->driver) {
99 clk_disable_unprepare(pcdev->pclk); 99 if (pm_runtime_is_irq_safe(dev))
100 clk_disable(pcdev->pclk);
101 else
102 clk_disable_unprepare(pcdev->pclk);
103 }
100 104
101 return ret; 105 return ret;
102} 106}
@@ -107,7 +111,10 @@ static int amba_pm_runtime_resume(struct device *dev)
107 int ret; 111 int ret;
108 112
109 if (dev->driver) { 113 if (dev->driver) {
110 ret = clk_prepare_enable(pcdev->pclk); 114 if (pm_runtime_is_irq_safe(dev))
115 ret = clk_enable(pcdev->pclk);
116 else
117 ret = clk_prepare_enable(pcdev->pclk);
111 /* Failure is probably fatal to the system, but... */ 118 /* Failure is probably fatal to the system, but... */
112 if (ret) 119 if (ret)
113 return ret; 120 return ret;
@@ -115,7 +122,7 @@ static int amba_pm_runtime_resume(struct device *dev)
115 122
116 return pm_generic_runtime_resume(dev); 123 return pm_generic_runtime_resume(dev);
117} 124}
118#endif 125#endif /* CONFIG_PM */
119 126
120static const struct dev_pm_ops amba_pm = { 127static const struct dev_pm_ops amba_pm = {
121 .suspend = pm_generic_suspend, 128 .suspend = pm_generic_suspend,