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.c52
1 files changed, 36 insertions, 16 deletions
diff --git a/drivers/spi/spi-pl022.c b/drivers/spi/spi-pl022.c
index a1db91a99b89..1361868fced7 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))
@@ -2246,10 +2252,9 @@ pl022_probe(struct amba_device *adev, const struct amba_id *id)
2246 pm_runtime_set_autosuspend_delay(dev, 2252 pm_runtime_set_autosuspend_delay(dev,
2247 platform_info->autosuspend_delay); 2253 platform_info->autosuspend_delay);
2248 pm_runtime_use_autosuspend(dev); 2254 pm_runtime_use_autosuspend(dev);
2249 pm_runtime_put_autosuspend(dev);
2250 } else {
2251 pm_runtime_put(dev);
2252 } 2255 }
2256 pm_runtime_put(dev);
2257
2253 return 0; 2258 return 0;
2254 2259
2255 err_spi_register: 2260 err_spi_register:
@@ -2303,35 +2308,47 @@ pl022_remove(struct amba_device *adev)
2303 * the runtime counterparts to handle external resources like 2308 * the runtime counterparts to handle external resources like
2304 * clocks, pins and regulators when going to sleep. 2309 * clocks, pins and regulators when going to sleep.
2305 */ 2310 */
2306static void pl022_suspend_resources(struct pl022 *pl022) 2311static void pl022_suspend_resources(struct pl022 *pl022, bool runtime)
2307{ 2312{
2308 int ret; 2313 int ret;
2314 struct pinctrl_state *pins_state;
2309 2315
2310 clk_disable(pl022->clk); 2316 clk_disable(pl022->clk);
2311 2317
2318 pins_state = runtime ? pl022->pins_idle : pl022->pins_sleep;
2312 /* Optionally let pins go into sleep states */ 2319 /* Optionally let pins go into sleep states */
2313 if (!IS_ERR(pl022->pins_sleep)) { 2320 if (!IS_ERR(pins_state)) {
2314 ret = pinctrl_select_state(pl022->pinctrl, 2321 ret = pinctrl_select_state(pl022->pinctrl, pins_state);
2315 pl022->pins_sleep);
2316 if (ret) 2322 if (ret)
2317 dev_err(&pl022->adev->dev, 2323 dev_err(&pl022->adev->dev, "could not set %s pins\n",
2318 "could not set pins to sleep state\n"); 2324 runtime ? "idle" : "sleep");
2319 } 2325 }
2320} 2326}
2321 2327
2322static void pl022_resume_resources(struct pl022 *pl022) 2328static void pl022_resume_resources(struct pl022 *pl022, bool runtime)
2323{ 2329{
2324 int ret; 2330 int ret;
2325 2331
2326 /* Optionaly enable pins to be muxed in and configured */ 2332 /* Optionaly enable pins to be muxed in and configured */
2333 /* First go to the default state */
2327 if (!IS_ERR(pl022->pins_default)) { 2334 if (!IS_ERR(pl022->pins_default)) {
2328 ret = pinctrl_select_state(pl022->pinctrl, 2335 ret = pinctrl_select_state(pl022->pinctrl, pl022->pins_default);
2329 pl022->pins_default);
2330 if (ret) 2336 if (ret)
2331 dev_err(&pl022->adev->dev, 2337 dev_err(&pl022->adev->dev,
2332 "could not set default pins\n"); 2338 "could not set default pins\n");
2333 } 2339 }
2334 2340
2341 if (!runtime) {
2342 /* Then let's idle the pins until the next transfer happens */
2343 if (!IS_ERR(pl022->pins_idle)) {
2344 ret = pinctrl_select_state(pl022->pinctrl,
2345 pl022->pins_idle);
2346 if (ret)
2347 dev_err(&pl022->adev->dev,
2348 "could not set idle pins\n");
2349 }
2350 }
2351
2335 clk_enable(pl022->clk); 2352 clk_enable(pl022->clk);
2336} 2353}
2337#endif 2354#endif
@@ -2347,7 +2364,9 @@ static int pl022_suspend(struct device *dev)
2347 dev_warn(dev, "cannot suspend master\n"); 2364 dev_warn(dev, "cannot suspend master\n");
2348 return ret; 2365 return ret;
2349 } 2366 }
2350 pl022_suspend_resources(pl022); 2367
2368 pm_runtime_get_sync(dev);
2369 pl022_suspend_resources(pl022, false);
2351 2370
2352 dev_dbg(dev, "suspended\n"); 2371 dev_dbg(dev, "suspended\n");
2353 return 0; 2372 return 0;
@@ -2358,7 +2377,8 @@ static int pl022_resume(struct device *dev)
2358 struct pl022 *pl022 = dev_get_drvdata(dev); 2377 struct pl022 *pl022 = dev_get_drvdata(dev);
2359 int ret; 2378 int ret;
2360 2379
2361 pl022_resume_resources(pl022); 2380 pl022_resume_resources(pl022, false);
2381 pm_runtime_put(dev);
2362 2382
2363 /* Start the queue running */ 2383 /* Start the queue running */
2364 ret = spi_master_resume(pl022->master); 2384 ret = spi_master_resume(pl022->master);
@@ -2376,7 +2396,7 @@ static int pl022_runtime_suspend(struct device *dev)
2376{ 2396{
2377 struct pl022 *pl022 = dev_get_drvdata(dev); 2397 struct pl022 *pl022 = dev_get_drvdata(dev);
2378 2398
2379 pl022_suspend_resources(pl022); 2399 pl022_suspend_resources(pl022, true);
2380 return 0; 2400 return 0;
2381} 2401}
2382 2402
@@ -2384,7 +2404,7 @@ static int pl022_runtime_resume(struct device *dev)
2384{ 2404{
2385 struct pl022 *pl022 = dev_get_drvdata(dev); 2405 struct pl022 *pl022 = dev_get_drvdata(dev);
2386 2406
2387 pl022_resume_resources(pl022); 2407 pl022_resume_resources(pl022, true);
2388 return 0; 2408 return 0;
2389} 2409}
2390#endif 2410#endif