aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/spi/spi-pl022.c
diff options
context:
space:
mode:
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