aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/spi/spi-pl022.c
diff options
context:
space:
mode:
authorUlf Hansson <ulf.hansson@linaro.org>2014-03-01 05:56:07 -0500
committerMark Brown <broonie@linaro.org>2014-03-05 23:44:48 -0500
commit84a5dc41f64faadb79cde600b130c8cbd7e21977 (patch)
tree281812efcb7a1c3fd46ec0b658062cfee366cf52 /drivers/spi/spi-pl022.c
parent736198b0486c8d5032456de0813515d954df978a (diff)
spi: pl022: Don't ignore power domain and amba bus at system suspend
Previously only the resources controlled by the driver were put into low power state at system suspend. Both the amba bus and a potential power domain were ignored. Moreover, while putting the device into low power state we first brought it back to full power, but for no particular reason. To handle both issues above, use pm_runtime_force_suspend|resume() from the system suspend|resume callbacks. Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org> Signed-off-by: Mark Brown <broonie@linaro.org>
Diffstat (limited to 'drivers/spi/spi-pl022.c')
-rw-r--r--drivers/spi/spi-pl022.c54
1 files changed, 18 insertions, 36 deletions
diff --git a/drivers/spi/spi-pl022.c b/drivers/spi/spi-pl022.c
index 6dfcabf74728..d37e840944d6 100644
--- a/drivers/spi/spi-pl022.c
+++ b/drivers/spi/spi-pl022.c
@@ -2277,35 +2277,7 @@ pl022_remove(struct amba_device *adev)
2277 return 0; 2277 return 0;
2278} 2278}
2279 2279
2280#ifdef CONFIG_PM 2280#ifdef CONFIG_PM_SLEEP
2281/*
2282 * These two functions are used from both suspend/resume and
2283 * the runtime counterparts to handle external resources like
2284 * clocks, pins and regulators when going to sleep.
2285 */
2286static void pl022_suspend_resources(struct pl022 *pl022, bool runtime)
2287{
2288 clk_disable_unprepare(pl022->clk);
2289
2290 if (runtime)
2291 pinctrl_pm_select_idle_state(&pl022->adev->dev);
2292 else
2293 pinctrl_pm_select_sleep_state(&pl022->adev->dev);
2294}
2295
2296static void pl022_resume_resources(struct pl022 *pl022, bool runtime)
2297{
2298 /* First go to the default state */
2299 pinctrl_pm_select_default_state(&pl022->adev->dev);
2300 if (!runtime)
2301 /* Then let's idle the pins until the next transfer happens */
2302 pinctrl_pm_select_idle_state(&pl022->adev->dev);
2303
2304 clk_prepare_enable(pl022->clk);
2305}
2306#endif
2307
2308#ifdef CONFIG_SUSPEND
2309static int pl022_suspend(struct device *dev) 2281static int pl022_suspend(struct device *dev)
2310{ 2282{
2311 struct pl022 *pl022 = dev_get_drvdata(dev); 2283 struct pl022 *pl022 = dev_get_drvdata(dev);
@@ -2317,8 +2289,13 @@ static int pl022_suspend(struct device *dev)
2317 return ret; 2289 return ret;
2318 } 2290 }
2319 2291
2320 pm_runtime_get_sync(dev); 2292 ret = pm_runtime_force_suspend(dev);
2321 pl022_suspend_resources(pl022, false); 2293 if (ret) {
2294 spi_master_resume(pl022->master);
2295 return ret;
2296 }
2297
2298 pinctrl_pm_select_sleep_state(dev);
2322 2299
2323 dev_dbg(dev, "suspended\n"); 2300 dev_dbg(dev, "suspended\n");
2324 return 0; 2301 return 0;
@@ -2329,8 +2306,9 @@ static int pl022_resume(struct device *dev)
2329 struct pl022 *pl022 = dev_get_drvdata(dev); 2306 struct pl022 *pl022 = dev_get_drvdata(dev);
2330 int ret; 2307 int ret;
2331 2308
2332 pl022_resume_resources(pl022, false); 2309 ret = pm_runtime_force_resume(dev);
2333 pm_runtime_put(dev); 2310 if (ret)
2311 dev_err(dev, "problem resuming\n");
2334 2312
2335 /* Start the queue running */ 2313 /* Start the queue running */
2336 ret = spi_master_resume(pl022->master); 2314 ret = spi_master_resume(pl022->master);
@@ -2341,14 +2319,16 @@ static int pl022_resume(struct device *dev)
2341 2319
2342 return ret; 2320 return ret;
2343} 2321}
2344#endif /* CONFIG_PM */ 2322#endif
2345 2323
2346#ifdef CONFIG_PM 2324#ifdef CONFIG_PM
2347static int pl022_runtime_suspend(struct device *dev) 2325static int pl022_runtime_suspend(struct device *dev)
2348{ 2326{
2349 struct pl022 *pl022 = dev_get_drvdata(dev); 2327 struct pl022 *pl022 = dev_get_drvdata(dev);
2350 2328
2351 pl022_suspend_resources(pl022, true); 2329 clk_disable_unprepare(pl022->clk);
2330 pinctrl_pm_select_idle_state(dev);
2331
2352 return 0; 2332 return 0;
2353} 2333}
2354 2334
@@ -2356,7 +2336,9 @@ static int pl022_runtime_resume(struct device *dev)
2356{ 2336{
2357 struct pl022 *pl022 = dev_get_drvdata(dev); 2337 struct pl022 *pl022 = dev_get_drvdata(dev);
2358 2338
2359 pl022_resume_resources(pl022, true); 2339 pinctrl_pm_select_default_state(dev);
2340 clk_prepare_enable(pl022->clk);
2341
2360 return 0; 2342 return 0;
2361} 2343}
2362#endif 2344#endif