diff options
Diffstat (limited to 'drivers/spi/spi-pl022.c')
-rw-r--r-- | drivers/spi/spi-pl022.c | 75 |
1 files changed, 23 insertions, 52 deletions
diff --git a/drivers/spi/spi-pl022.c b/drivers/spi/spi-pl022.c index 3c5b90559bec..51d99779682f 100644 --- a/drivers/spi/spi-pl022.c +++ b/drivers/spi/spi-pl022.c | |||
@@ -2108,8 +2108,6 @@ static int pl022_probe(struct amba_device *adev, const struct amba_id *id) | |||
2108 | pl022->chipselects = devm_kzalloc(dev, num_cs * sizeof(int), | 2108 | pl022->chipselects = devm_kzalloc(dev, num_cs * sizeof(int), |
2109 | GFP_KERNEL); | 2109 | GFP_KERNEL); |
2110 | 2110 | ||
2111 | pinctrl_pm_select_default_state(dev); | ||
2112 | |||
2113 | /* | 2111 | /* |
2114 | * Bus Number Which has been Assigned to this SSP controller | 2112 | * Bus Number Which has been Assigned to this SSP controller |
2115 | * on this board | 2113 | * on this board |
@@ -2182,13 +2180,7 @@ static int pl022_probe(struct amba_device *adev, const struct amba_id *id) | |||
2182 | goto err_no_clk; | 2180 | goto err_no_clk; |
2183 | } | 2181 | } |
2184 | 2182 | ||
2185 | status = clk_prepare(pl022->clk); | 2183 | status = clk_prepare_enable(pl022->clk); |
2186 | if (status) { | ||
2187 | dev_err(&adev->dev, "could not prepare SSP/SPI bus clock\n"); | ||
2188 | goto err_clk_prep; | ||
2189 | } | ||
2190 | |||
2191 | status = clk_enable(pl022->clk); | ||
2192 | if (status) { | 2184 | if (status) { |
2193 | dev_err(&adev->dev, "could not enable SSP/SPI bus clock\n"); | 2185 | dev_err(&adev->dev, "could not enable SSP/SPI bus clock\n"); |
2194 | goto err_no_clk_en; | 2186 | goto err_no_clk_en; |
@@ -2249,10 +2241,8 @@ static int pl022_probe(struct amba_device *adev, const struct amba_id *id) | |||
2249 | if (platform_info->enable_dma) | 2241 | if (platform_info->enable_dma) |
2250 | pl022_dma_remove(pl022); | 2242 | pl022_dma_remove(pl022); |
2251 | err_no_irq: | 2243 | err_no_irq: |
2252 | clk_disable(pl022->clk); | 2244 | clk_disable_unprepare(pl022->clk); |
2253 | err_no_clk_en: | 2245 | err_no_clk_en: |
2254 | clk_unprepare(pl022->clk); | ||
2255 | err_clk_prep: | ||
2256 | err_no_clk: | 2246 | err_no_clk: |
2257 | err_no_ioremap: | 2247 | err_no_ioremap: |
2258 | amba_release_regions(adev); | 2248 | amba_release_regions(adev); |
@@ -2280,42 +2270,13 @@ pl022_remove(struct amba_device *adev) | |||
2280 | if (pl022->master_info->enable_dma) | 2270 | if (pl022->master_info->enable_dma) |
2281 | pl022_dma_remove(pl022); | 2271 | pl022_dma_remove(pl022); |
2282 | 2272 | ||
2283 | clk_disable(pl022->clk); | 2273 | clk_disable_unprepare(pl022->clk); |
2284 | clk_unprepare(pl022->clk); | ||
2285 | amba_release_regions(adev); | 2274 | amba_release_regions(adev); |
2286 | tasklet_disable(&pl022->pump_transfers); | 2275 | tasklet_disable(&pl022->pump_transfers); |
2287 | return 0; | 2276 | return 0; |
2288 | } | 2277 | } |
2289 | 2278 | ||
2290 | #if defined(CONFIG_SUSPEND) || defined(CONFIG_PM_RUNTIME) | 2279 | #ifdef CONFIG_PM_SLEEP |
2291 | /* | ||
2292 | * These two functions are used from both suspend/resume and | ||
2293 | * the runtime counterparts to handle external resources like | ||
2294 | * clocks, pins and regulators when going to sleep. | ||
2295 | */ | ||
2296 | static void pl022_suspend_resources(struct pl022 *pl022, bool runtime) | ||
2297 | { | ||
2298 | clk_disable(pl022->clk); | ||
2299 | |||
2300 | if (runtime) | ||
2301 | pinctrl_pm_select_idle_state(&pl022->adev->dev); | ||
2302 | else | ||
2303 | pinctrl_pm_select_sleep_state(&pl022->adev->dev); | ||
2304 | } | ||
2305 | |||
2306 | static void pl022_resume_resources(struct pl022 *pl022, bool runtime) | ||
2307 | { | ||
2308 | /* First go to the default state */ | ||
2309 | pinctrl_pm_select_default_state(&pl022->adev->dev); | ||
2310 | if (!runtime) | ||
2311 | /* Then let's idle the pins until the next transfer happens */ | ||
2312 | pinctrl_pm_select_idle_state(&pl022->adev->dev); | ||
2313 | |||
2314 | clk_enable(pl022->clk); | ||
2315 | } | ||
2316 | #endif | ||
2317 | |||
2318 | #ifdef CONFIG_SUSPEND | ||
2319 | static int pl022_suspend(struct device *dev) | 2280 | static int pl022_suspend(struct device *dev) |
2320 | { | 2281 | { |
2321 | struct pl022 *pl022 = dev_get_drvdata(dev); | 2282 | struct pl022 *pl022 = dev_get_drvdata(dev); |
@@ -2327,8 +2288,13 @@ static int pl022_suspend(struct device *dev) | |||
2327 | return ret; | 2288 | return ret; |
2328 | } | 2289 | } |
2329 | 2290 | ||
2330 | pm_runtime_get_sync(dev); | 2291 | ret = pm_runtime_force_suspend(dev); |
2331 | pl022_suspend_resources(pl022, false); | 2292 | if (ret) { |
2293 | spi_master_resume(pl022->master); | ||
2294 | return ret; | ||
2295 | } | ||
2296 | |||
2297 | pinctrl_pm_select_sleep_state(dev); | ||
2332 | 2298 | ||
2333 | dev_dbg(dev, "suspended\n"); | 2299 | dev_dbg(dev, "suspended\n"); |
2334 | return 0; | 2300 | return 0; |
@@ -2339,8 +2305,9 @@ static int pl022_resume(struct device *dev) | |||
2339 | struct pl022 *pl022 = dev_get_drvdata(dev); | 2305 | struct pl022 *pl022 = dev_get_drvdata(dev); |
2340 | int ret; | 2306 | int ret; |
2341 | 2307 | ||
2342 | pl022_resume_resources(pl022, false); | 2308 | ret = pm_runtime_force_resume(dev); |
2343 | pm_runtime_put(dev); | 2309 | if (ret) |
2310 | dev_err(dev, "problem resuming\n"); | ||
2344 | 2311 | ||
2345 | /* Start the queue running */ | 2312 | /* Start the queue running */ |
2346 | ret = spi_master_resume(pl022->master); | 2313 | ret = spi_master_resume(pl022->master); |
@@ -2351,14 +2318,16 @@ static int pl022_resume(struct device *dev) | |||
2351 | 2318 | ||
2352 | return ret; | 2319 | return ret; |
2353 | } | 2320 | } |
2354 | #endif /* CONFIG_PM */ | 2321 | #endif |
2355 | 2322 | ||
2356 | #ifdef CONFIG_PM_RUNTIME | 2323 | #ifdef CONFIG_PM |
2357 | static int pl022_runtime_suspend(struct device *dev) | 2324 | static int pl022_runtime_suspend(struct device *dev) |
2358 | { | 2325 | { |
2359 | struct pl022 *pl022 = dev_get_drvdata(dev); | 2326 | struct pl022 *pl022 = dev_get_drvdata(dev); |
2360 | 2327 | ||
2361 | pl022_suspend_resources(pl022, true); | 2328 | clk_disable_unprepare(pl022->clk); |
2329 | pinctrl_pm_select_idle_state(dev); | ||
2330 | |||
2362 | return 0; | 2331 | return 0; |
2363 | } | 2332 | } |
2364 | 2333 | ||
@@ -2366,14 +2335,16 @@ static int pl022_runtime_resume(struct device *dev) | |||
2366 | { | 2335 | { |
2367 | struct pl022 *pl022 = dev_get_drvdata(dev); | 2336 | struct pl022 *pl022 = dev_get_drvdata(dev); |
2368 | 2337 | ||
2369 | pl022_resume_resources(pl022, true); | 2338 | pinctrl_pm_select_default_state(dev); |
2339 | clk_prepare_enable(pl022->clk); | ||
2340 | |||
2370 | return 0; | 2341 | return 0; |
2371 | } | 2342 | } |
2372 | #endif | 2343 | #endif |
2373 | 2344 | ||
2374 | static const struct dev_pm_ops pl022_dev_pm_ops = { | 2345 | static const struct dev_pm_ops pl022_dev_pm_ops = { |
2375 | SET_SYSTEM_SLEEP_PM_OPS(pl022_suspend, pl022_resume) | 2346 | SET_SYSTEM_SLEEP_PM_OPS(pl022_suspend, pl022_resume) |
2376 | SET_RUNTIME_PM_OPS(pl022_runtime_suspend, pl022_runtime_resume, NULL) | 2347 | SET_PM_RUNTIME_PM_OPS(pl022_runtime_suspend, pl022_runtime_resume, NULL) |
2377 | }; | 2348 | }; |
2378 | 2349 | ||
2379 | static struct vendor_data vendor_arm = { | 2350 | static struct vendor_data vendor_arm = { |