diff options
| -rw-r--r-- | drivers/spi/spi-pl022.c | 66 |
1 files changed, 44 insertions, 22 deletions
diff --git a/drivers/spi/spi-pl022.c b/drivers/spi/spi-pl022.c index 15737bcee9fb..919464102d33 100644 --- a/drivers/spi/spi-pl022.c +++ b/drivers/spi/spi-pl022.c | |||
| @@ -2300,6 +2300,45 @@ pl022_remove(struct amba_device *adev) | |||
| 2300 | return 0; | 2300 | return 0; |
| 2301 | } | 2301 | } |
| 2302 | 2302 | ||
| 2303 | #if defined(CONFIG_SUSPEND) || defined(CONFIG_PM_RUNTIME) | ||
| 2304 | /* | ||
| 2305 | * These two functions are used from both suspend/resume and | ||
| 2306 | * the runtime counterparts to handle external resources like | ||
| 2307 | * clocks, pins and regulators when going to sleep. | ||
| 2308 | */ | ||
| 2309 | static void pl022_suspend_resources(struct pl022 *pl022) | ||
| 2310 | { | ||
| 2311 | int ret; | ||
| 2312 | |||
| 2313 | clk_disable(pl022->clk); | ||
| 2314 | |||
| 2315 | /* Optionally let pins go into sleep states */ | ||
| 2316 | if (!IS_ERR(pl022->pins_sleep)) { | ||
| 2317 | ret = pinctrl_select_state(pl022->pinctrl, | ||
| 2318 | pl022->pins_sleep); | ||
| 2319 | if (ret) | ||
| 2320 | dev_err(&pl022->adev->dev, | ||
| 2321 | "could not set pins to sleep state\n"); | ||
| 2322 | } | ||
| 2323 | } | ||
| 2324 | |||
| 2325 | static void pl022_resume_resources(struct pl022 *pl022) | ||
| 2326 | { | ||
| 2327 | int ret; | ||
| 2328 | |||
| 2329 | /* Optionaly enable pins to be muxed in and configured */ | ||
| 2330 | if (!IS_ERR(pl022->pins_default)) { | ||
| 2331 | ret = pinctrl_select_state(pl022->pinctrl, | ||
| 2332 | pl022->pins_default); | ||
| 2333 | if (ret) | ||
| 2334 | dev_err(&pl022->adev->dev, | ||
| 2335 | "could not set default pins\n"); | ||
| 2336 | } | ||
| 2337 | |||
| 2338 | clk_enable(pl022->clk); | ||
| 2339 | } | ||
| 2340 | #endif | ||
| 2341 | |||
| 2303 | #ifdef CONFIG_SUSPEND | 2342 | #ifdef CONFIG_SUSPEND |
| 2304 | static int pl022_suspend(struct device *dev) | 2343 | static int pl022_suspend(struct device *dev) |
| 2305 | { | 2344 | { |
| @@ -2311,6 +2350,7 @@ static int pl022_suspend(struct device *dev) | |||
| 2311 | dev_warn(dev, "cannot suspend master\n"); | 2350 | dev_warn(dev, "cannot suspend master\n"); |
| 2312 | return ret; | 2351 | return ret; |
| 2313 | } | 2352 | } |
| 2353 | pl022_suspend_resources(pl022); | ||
| 2314 | 2354 | ||
| 2315 | dev_dbg(dev, "suspended\n"); | 2355 | dev_dbg(dev, "suspended\n"); |
| 2316 | return 0; | 2356 | return 0; |
| @@ -2321,6 +2361,8 @@ static int pl022_resume(struct device *dev) | |||
| 2321 | struct pl022 *pl022 = dev_get_drvdata(dev); | 2361 | struct pl022 *pl022 = dev_get_drvdata(dev); |
| 2322 | int ret; | 2362 | int ret; |
| 2323 | 2363 | ||
| 2364 | pl022_resume_resources(pl022); | ||
| 2365 | |||
| 2324 | /* Start the queue running */ | 2366 | /* Start the queue running */ |
| 2325 | ret = spi_master_resume(pl022->master); | 2367 | ret = spi_master_resume(pl022->master); |
| 2326 | if (ret) | 2368 | if (ret) |
| @@ -2336,36 +2378,16 @@ static int pl022_resume(struct device *dev) | |||
| 2336 | static int pl022_runtime_suspend(struct device *dev) | 2378 | static int pl022_runtime_suspend(struct device *dev) |
| 2337 | { | 2379 | { |
| 2338 | struct pl022 *pl022 = dev_get_drvdata(dev); | 2380 | struct pl022 *pl022 = dev_get_drvdata(dev); |
| 2339 | int status = 0; | ||
| 2340 | |||
| 2341 | clk_disable(pl022->clk); | ||
| 2342 | |||
| 2343 | /* Optionally let pins go into sleep states */ | ||
| 2344 | if (!IS_ERR(pl022->pins_sleep)) { | ||
| 2345 | status = pinctrl_select_state(pl022->pinctrl, | ||
| 2346 | pl022->pins_sleep); | ||
| 2347 | if (status) | ||
| 2348 | dev_err(dev, "could not set pins to sleep state\n"); | ||
| 2349 | } | ||
| 2350 | 2381 | ||
| 2382 | pl022_suspend_resources(pl022); | ||
| 2351 | return 0; | 2383 | return 0; |
| 2352 | } | 2384 | } |
| 2353 | 2385 | ||
| 2354 | static int pl022_runtime_resume(struct device *dev) | 2386 | static int pl022_runtime_resume(struct device *dev) |
| 2355 | { | 2387 | { |
| 2356 | struct pl022 *pl022 = dev_get_drvdata(dev); | 2388 | struct pl022 *pl022 = dev_get_drvdata(dev); |
| 2357 | int status = 0; | ||
| 2358 | |||
| 2359 | /* Optionaly enable pins to be muxed in and configured */ | ||
| 2360 | if (!IS_ERR(pl022->pins_default)) { | ||
| 2361 | status = pinctrl_select_state(pl022->pinctrl, | ||
| 2362 | pl022->pins_default); | ||
| 2363 | if (status) | ||
| 2364 | dev_err(dev, "could not set default pins\n"); | ||
| 2365 | } | ||
| 2366 | |||
| 2367 | clk_enable(pl022->clk); | ||
| 2368 | 2389 | ||
| 2390 | pl022_resume_resources(pl022); | ||
| 2369 | return 0; | 2391 | return 0; |
| 2370 | } | 2392 | } |
| 2371 | #endif | 2393 | #endif |
