diff options
Diffstat (limited to 'drivers/spi')
-rw-r--r-- | drivers/spi/spi-pl022.c | 80 |
1 files changed, 48 insertions, 32 deletions
diff --git a/drivers/spi/spi-pl022.c b/drivers/spi/spi-pl022.c index 730b4a37b823..078338f59481 100644 --- a/drivers/spi/spi-pl022.c +++ b/drivers/spi/spi-pl022.c | |||
@@ -515,9 +515,6 @@ static void giveback(struct pl022 *pl022) | |||
515 | if (msg->complete) | 515 | if (msg->complete) |
516 | msg->complete(msg->context); | 516 | msg->complete(msg->context); |
517 | /* This message is completed, so let's turn off the clocks & power */ | 517 | /* This message is completed, so let's turn off the clocks & power */ |
518 | clk_disable(pl022->clk); | ||
519 | amba_pclk_disable(pl022->adev); | ||
520 | amba_vcore_disable(pl022->adev); | ||
521 | pm_runtime_put(&pl022->adev->dev); | 518 | pm_runtime_put(&pl022->adev->dev); |
522 | } | 519 | } |
523 | 520 | ||
@@ -1545,9 +1542,6 @@ static void pump_messages(struct work_struct *work) | |||
1545 | * (poll/interrupt/DMA) | 1542 | * (poll/interrupt/DMA) |
1546 | */ | 1543 | */ |
1547 | pm_runtime_get_sync(&pl022->adev->dev); | 1544 | pm_runtime_get_sync(&pl022->adev->dev); |
1548 | amba_vcore_enable(pl022->adev); | ||
1549 | amba_pclk_enable(pl022->adev); | ||
1550 | clk_enable(pl022->clk); | ||
1551 | restore_state(pl022); | 1545 | restore_state(pl022); |
1552 | flush(pl022); | 1546 | flush(pl022); |
1553 | 1547 | ||
@@ -2186,8 +2180,6 @@ pl022_probe(struct amba_device *adev, const struct amba_id *id) | |||
2186 | } | 2180 | } |
2187 | printk(KERN_INFO "pl022: mapped registers from 0x%08x to %p\n", | 2181 | printk(KERN_INFO "pl022: mapped registers from 0x%08x to %p\n", |
2188 | adev->res.start, pl022->virtbase); | 2182 | adev->res.start, pl022->virtbase); |
2189 | pm_runtime_enable(dev); | ||
2190 | pm_runtime_resume(dev); | ||
2191 | 2183 | ||
2192 | pl022->clk = clk_get(&adev->dev, NULL); | 2184 | pl022->clk = clk_get(&adev->dev, NULL); |
2193 | if (IS_ERR(pl022->clk)) { | 2185 | if (IS_ERR(pl022->clk)) { |
@@ -2195,7 +2187,6 @@ pl022_probe(struct amba_device *adev, const struct amba_id *id) | |||
2195 | dev_err(&adev->dev, "could not retrieve SSP/SPI bus clock\n"); | 2187 | dev_err(&adev->dev, "could not retrieve SSP/SPI bus clock\n"); |
2196 | goto err_no_clk; | 2188 | goto err_no_clk; |
2197 | } | 2189 | } |
2198 | |||
2199 | /* Disable SSP */ | 2190 | /* Disable SSP */ |
2200 | writew((readw(SSP_CR1(pl022->virtbase)) & (~SSP_CR1_MASK_SSE)), | 2191 | writew((readw(SSP_CR1(pl022->virtbase)) & (~SSP_CR1_MASK_SSE)), |
2201 | SSP_CR1(pl022->virtbase)); | 2192 | SSP_CR1(pl022->virtbase)); |
@@ -2235,12 +2226,9 @@ pl022_probe(struct amba_device *adev, const struct amba_id *id) | |||
2235 | goto err_spi_register; | 2226 | goto err_spi_register; |
2236 | } | 2227 | } |
2237 | dev_dbg(dev, "probe succeeded\n"); | 2228 | dev_dbg(dev, "probe succeeded\n"); |
2238 | /* | 2229 | |
2239 | * Disable the silicon block pclk and any voltage domain and just | 2230 | /* let runtime pm put suspend */ |
2240 | * power it up and clock it when it's needed | 2231 | pm_runtime_put(dev); |
2241 | */ | ||
2242 | amba_pclk_disable(adev); | ||
2243 | amba_vcore_disable(adev); | ||
2244 | return 0; | 2232 | return 0; |
2245 | 2233 | ||
2246 | err_spi_register: | 2234 | err_spi_register: |
@@ -2249,7 +2237,6 @@ pl022_probe(struct amba_device *adev, const struct amba_id *id) | |||
2249 | destroy_queue(pl022); | 2237 | destroy_queue(pl022); |
2250 | pl022_dma_remove(pl022); | 2238 | pl022_dma_remove(pl022); |
2251 | free_irq(adev->irq[0], pl022); | 2239 | free_irq(adev->irq[0], pl022); |
2252 | pm_runtime_disable(&adev->dev); | ||
2253 | err_no_irq: | 2240 | err_no_irq: |
2254 | clk_put(pl022->clk); | 2241 | clk_put(pl022->clk); |
2255 | err_no_clk: | 2242 | err_no_clk: |
@@ -2271,6 +2258,12 @@ pl022_remove(struct amba_device *adev) | |||
2271 | if (!pl022) | 2258 | if (!pl022) |
2272 | return 0; | 2259 | return 0; |
2273 | 2260 | ||
2261 | /* | ||
2262 | * undo pm_runtime_put() in probe. I assume that we're not | ||
2263 | * accessing the primecell here. | ||
2264 | */ | ||
2265 | pm_runtime_get_noresume(&adev->dev); | ||
2266 | |||
2274 | /* Remove the queue */ | 2267 | /* Remove the queue */ |
2275 | if (destroy_queue(pl022) != 0) | 2268 | if (destroy_queue(pl022) != 0) |
2276 | dev_err(&adev->dev, "queue remove failed\n"); | 2269 | dev_err(&adev->dev, "queue remove failed\n"); |
@@ -2288,10 +2281,10 @@ pl022_remove(struct amba_device *adev) | |||
2288 | return 0; | 2281 | return 0; |
2289 | } | 2282 | } |
2290 | 2283 | ||
2291 | #ifdef CONFIG_PM | 2284 | #ifdef CONFIG_SUSPEND |
2292 | static int pl022_suspend(struct amba_device *adev, pm_message_t state) | 2285 | static int pl011_suspend(struct device *dev) |
2293 | { | 2286 | { |
2294 | struct pl022 *pl022 = amba_get_drvdata(adev); | 2287 | struct pl022 *pl022 = dev_get_drvdata(dev); |
2295 | int status = 0; | 2288 | int status = 0; |
2296 | 2289 | ||
2297 | status = stop_queue(pl022); | 2290 | status = stop_queue(pl022); |
@@ -2300,34 +2293,58 @@ static int pl022_suspend(struct amba_device *adev, pm_message_t state) | |||
2300 | return status; | 2293 | return status; |
2301 | } | 2294 | } |
2302 | 2295 | ||
2303 | amba_vcore_enable(adev); | 2296 | amba_vcore_enable(pl022->adev); |
2304 | amba_pclk_enable(adev); | 2297 | amba_pclk_enable(pl022->adev); |
2305 | load_ssp_default_config(pl022); | 2298 | load_ssp_default_config(pl022); |
2306 | amba_pclk_disable(adev); | 2299 | amba_pclk_disable(pl022->adev); |
2307 | amba_vcore_disable(adev); | 2300 | amba_vcore_disable(pl022->adev); |
2308 | dev_dbg(&adev->dev, "suspended\n"); | 2301 | dev_dbg(&adev->dev, "suspended\n"); |
2309 | return 0; | 2302 | return 0; |
2310 | } | 2303 | } |
2311 | 2304 | ||
2312 | static int pl022_resume(struct amba_device *adev) | 2305 | static int pl022_resume(struct device *dev) |
2313 | { | 2306 | { |
2314 | struct pl022 *pl022 = amba_get_drvdata(adev); | 2307 | struct pl022 *pl022 = dev_get_drvdata(dev); |
2315 | int status = 0; | 2308 | int status = 0; |
2316 | 2309 | ||
2317 | /* Start the queue running */ | 2310 | /* Start the queue running */ |
2318 | status = start_queue(pl022); | 2311 | status = start_queue(pl022); |
2319 | if (status) | 2312 | if (status) |
2320 | dev_err(&adev->dev, "problem starting queue (%d)\n", status); | 2313 | dev_err(dev, "problem starting queue (%d)\n", status); |
2321 | else | 2314 | else |
2322 | dev_dbg(&adev->dev, "resumed\n"); | 2315 | dev_dbg(dev, "resumed\n"); |
2323 | 2316 | ||
2324 | return status; | 2317 | return status; |
2325 | } | 2318 | } |
2326 | #else | ||
2327 | #define pl022_suspend NULL | ||
2328 | #define pl022_resume NULL | ||
2329 | #endif /* CONFIG_PM */ | 2319 | #endif /* CONFIG_PM */ |
2330 | 2320 | ||
2321 | #ifdef CONFIG_PM_RUNTIME | ||
2322 | static int pl022_runtime_suspend(struct device *dev) | ||
2323 | { | ||
2324 | struct pl022 *pl022 = dev_get_drvdata(dev); | ||
2325 | |||
2326 | clk_disable(pl022->clk); | ||
2327 | amba_vcore_disable(pl022->adev); | ||
2328 | |||
2329 | return 0; | ||
2330 | } | ||
2331 | |||
2332 | static int pl022_runtime_resume(struct device *dev) | ||
2333 | { | ||
2334 | struct pl022 *pl022 = dev_get_drvdata(dev); | ||
2335 | |||
2336 | amba_vcore_enable(pl022->adev); | ||
2337 | clk_enable(pl022->clk); | ||
2338 | |||
2339 | return 0; | ||
2340 | } | ||
2341 | #endif | ||
2342 | |||
2343 | static const struct dev_pm_ops pl022_dev_pm_ops = { | ||
2344 | SET_SYSTEM_SLEEP_PM_OPS(pl022_suspend, pl022_resume) | ||
2345 | SET_RUNTIME_PM_OPS(pl022_runtime_suspend, pl022_runtime_resume, NULL) | ||
2346 | }; | ||
2347 | |||
2331 | static struct vendor_data vendor_arm = { | 2348 | static struct vendor_data vendor_arm = { |
2332 | .fifodepth = 8, | 2349 | .fifodepth = 8, |
2333 | .max_bpw = 16, | 2350 | .max_bpw = 16, |
@@ -2407,12 +2424,11 @@ static struct amba_id pl022_ids[] = { | |||
2407 | static struct amba_driver pl022_driver = { | 2424 | static struct amba_driver pl022_driver = { |
2408 | .drv = { | 2425 | .drv = { |
2409 | .name = "ssp-pl022", | 2426 | .name = "ssp-pl022", |
2427 | .pm = &pl022_dev_pm_ops, | ||
2410 | }, | 2428 | }, |
2411 | .id_table = pl022_ids, | 2429 | .id_table = pl022_ids, |
2412 | .probe = pl022_probe, | 2430 | .probe = pl022_probe, |
2413 | .remove = __devexit_p(pl022_remove), | 2431 | .remove = __devexit_p(pl022_remove), |
2414 | .suspend = pl022_suspend, | ||
2415 | .resume = pl022_resume, | ||
2416 | }; | 2432 | }; |
2417 | 2433 | ||
2418 | 2434 | ||