aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/spi
diff options
context:
space:
mode:
authorPatrice Chotard <patrice.chotard@stericsson.com>2012-10-17 08:27:24 -0400
committerMark Brown <broonie@opensource.wolfsonmicro.com>2012-10-17 09:14:25 -0400
commitd8f18420c552de6d38e5464074133e0e9730abcd (patch)
tree2fa18925654779319b0ca85cbdda36ecba6fc1bc /drivers/spi
parent4964a26df72c4a82e56c6b40818648d54bde93cc (diff)
spi/pl022: add IDLE state pin management
This commit allow to put pins in IDLE state in runtime_suspend and in SLEEP state in suspend, corresponding to defined semantics in <linux/pinctrl/pinctrl-state.h>. To do this, just add a boolean parameter runtime to pl022_resume_resources/pl022_suspend_resources which indicates if it's called from PM_RUNTIME callbacks or not. Signed-off-by: Patrice Chotard <patrice.chotard@stericsson.com> Signed-off-by: Linus Walleij <linus.walleij@linaro.org> Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
Diffstat (limited to 'drivers/spi')
-rw-r--r--drivers/spi/spi-pl022.c44
1 files changed, 31 insertions, 13 deletions
diff --git a/drivers/spi/spi-pl022.c b/drivers/spi/spi-pl022.c
index c220c2346276..7e3c4166e8f8 100644
--- a/drivers/spi/spi-pl022.c
+++ b/drivers/spi/spi-pl022.c
@@ -371,6 +371,7 @@ struct pl022 {
371 /* Two optional pin states - default & sleep */ 371 /* Two optional pin states - default & sleep */
372 struct pinctrl *pinctrl; 372 struct pinctrl *pinctrl;
373 struct pinctrl_state *pins_default; 373 struct pinctrl_state *pins_default;
374 struct pinctrl_state *pins_idle;
374 struct pinctrl_state *pins_sleep; 375 struct pinctrl_state *pins_sleep;
375 struct spi_master *master; 376 struct spi_master *master;
376 struct pl022_ssp_controller *master_info; 377 struct pl022_ssp_controller *master_info;
@@ -2116,6 +2117,11 @@ pl022_probe(struct amba_device *adev, const struct amba_id *id)
2116 } else 2117 } else
2117 dev_err(dev, "could not get default pinstate\n"); 2118 dev_err(dev, "could not get default pinstate\n");
2118 2119
2120 pl022->pins_idle = pinctrl_lookup_state(pl022->pinctrl,
2121 PINCTRL_STATE_IDLE);
2122 if (IS_ERR(pl022->pins_idle))
2123 dev_dbg(dev, "could not get idle pinstate\n");
2124
2119 pl022->pins_sleep = pinctrl_lookup_state(pl022->pinctrl, 2125 pl022->pins_sleep = pinctrl_lookup_state(pl022->pinctrl,
2120 PINCTRL_STATE_SLEEP); 2126 PINCTRL_STATE_SLEEP);
2121 if (IS_ERR(pl022->pins_sleep)) 2127 if (IS_ERR(pl022->pins_sleep))
@@ -2305,35 +2311,47 @@ pl022_remove(struct amba_device *adev)
2305 * the runtime counterparts to handle external resources like 2311 * the runtime counterparts to handle external resources like
2306 * clocks, pins and regulators when going to sleep. 2312 * clocks, pins and regulators when going to sleep.
2307 */ 2313 */
2308static void pl022_suspend_resources(struct pl022 *pl022) 2314static void pl022_suspend_resources(struct pl022 *pl022, bool runtime)
2309{ 2315{
2310 int ret; 2316 int ret;
2317 struct pinctrl_state *pins_state;
2311 2318
2312 clk_disable(pl022->clk); 2319 clk_disable(pl022->clk);
2313 2320
2321 pins_state = runtime ? pl022->pins_idle : pl022->pins_sleep;
2314 /* Optionally let pins go into sleep states */ 2322 /* Optionally let pins go into sleep states */
2315 if (!IS_ERR(pl022->pins_sleep)) { 2323 if (!IS_ERR(pins_state)) {
2316 ret = pinctrl_select_state(pl022->pinctrl, 2324 ret = pinctrl_select_state(pl022->pinctrl, pins_state);
2317 pl022->pins_sleep);
2318 if (ret) 2325 if (ret)
2319 dev_err(&pl022->adev->dev, 2326 dev_err(&pl022->adev->dev, "could not set %s pins\n",
2320 "could not set pins to sleep state\n"); 2327 runtime ? "idle" : "sleep");
2321 } 2328 }
2322} 2329}
2323 2330
2324static void pl022_resume_resources(struct pl022 *pl022) 2331static void pl022_resume_resources(struct pl022 *pl022, bool runtime)
2325{ 2332{
2326 int ret; 2333 int ret;
2327 2334
2328 /* Optionaly enable pins to be muxed in and configured */ 2335 /* Optionaly enable pins to be muxed in and configured */
2336 /* First go to the default state */
2329 if (!IS_ERR(pl022->pins_default)) { 2337 if (!IS_ERR(pl022->pins_default)) {
2330 ret = pinctrl_select_state(pl022->pinctrl, 2338 ret = pinctrl_select_state(pl022->pinctrl, pl022->pins_default);
2331 pl022->pins_default);
2332 if (ret) 2339 if (ret)
2333 dev_err(&pl022->adev->dev, 2340 dev_err(&pl022->adev->dev,
2334 "could not set default pins\n"); 2341 "could not set default pins\n");
2335 } 2342 }
2336 2343
2344 if (!runtime) {
2345 /* Then let's idle the pins until the next transfer happens */
2346 if (!IS_ERR(pl022->pins_idle)) {
2347 ret = pinctrl_select_state(pl022->pinctrl,
2348 pl022->pins_idle);
2349 if (ret)
2350 dev_err(&pl022->adev->dev,
2351 "could not set idle pins\n");
2352 }
2353 }
2354
2337 clk_enable(pl022->clk); 2355 clk_enable(pl022->clk);
2338} 2356}
2339#endif 2357#endif
@@ -2351,7 +2369,7 @@ static int pl022_suspend(struct device *dev)
2351 } 2369 }
2352 2370
2353 pm_runtime_get_sync(dev); 2371 pm_runtime_get_sync(dev);
2354 pl022_suspend_resources(pl022); 2372 pl022_suspend_resources(pl022, false);
2355 2373
2356 dev_dbg(dev, "suspended\n"); 2374 dev_dbg(dev, "suspended\n");
2357 return 0; 2375 return 0;
@@ -2362,7 +2380,7 @@ static int pl022_resume(struct device *dev)
2362 struct pl022 *pl022 = dev_get_drvdata(dev); 2380 struct pl022 *pl022 = dev_get_drvdata(dev);
2363 int ret; 2381 int ret;
2364 2382
2365 pl022_resume_resources(pl022); 2383 pl022_resume_resources(pl022, false);
2366 pm_runtime_put(dev); 2384 pm_runtime_put(dev);
2367 2385
2368 /* Start the queue running */ 2386 /* Start the queue running */
@@ -2381,7 +2399,7 @@ static int pl022_runtime_suspend(struct device *dev)
2381{ 2399{
2382 struct pl022 *pl022 = dev_get_drvdata(dev); 2400 struct pl022 *pl022 = dev_get_drvdata(dev);
2383 2401
2384 pl022_suspend_resources(pl022); 2402 pl022_suspend_resources(pl022, true);
2385 return 0; 2403 return 0;
2386} 2404}
2387 2405
@@ -2389,7 +2407,7 @@ static int pl022_runtime_resume(struct device *dev)
2389{ 2407{
2390 struct pl022 *pl022 = dev_get_drvdata(dev); 2408 struct pl022 *pl022 = dev_get_drvdata(dev);
2391 2409
2392 pl022_resume_resources(pl022); 2410 pl022_resume_resources(pl022, true);
2393 return 0; 2411 return 0;
2394} 2412}
2395#endif 2413#endif