aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/amba/bus.c57
-rw-r--r--drivers/spi/spi-pl022.c80
2 files changed, 102 insertions, 35 deletions
diff --git a/drivers/amba/bus.c b/drivers/amba/bus.c
index d74926e0939e..84bdaace56c8 100644
--- a/drivers/amba/bus.c
+++ b/drivers/amba/bus.c
@@ -365,6 +365,40 @@ static int amba_pm_restore_noirq(struct device *dev)
365 365
366#endif /* !CONFIG_HIBERNATE_CALLBACKS */ 366#endif /* !CONFIG_HIBERNATE_CALLBACKS */
367 367
368#ifdef CONFIG_PM_RUNTIME
369/*
370 * Hooks to provide runtime PM of the pclk (bus clock). It is safe to
371 * enable/disable the bus clock at runtime PM suspend/resume as this
372 * does not result in loss of context. However, disabling vcore power
373 * would do, so we leave that to the driver.
374 */
375static int amba_pm_runtime_suspend(struct device *dev)
376{
377 struct amba_device *pcdev = to_amba_device(dev);
378 int ret = pm_generic_runtime_suspend(dev);
379
380 if (ret == 0 && dev->driver)
381 clk_disable(pcdev->pclk);
382
383 return ret;
384}
385
386static int amba_pm_runtime_resume(struct device *dev)
387{
388 struct amba_device *pcdev = to_amba_device(dev);
389 int ret;
390
391 if (dev->driver) {
392 ret = clk_enable(pcdev->pclk);
393 /* Failure is probably fatal to the system, but... */
394 if (ret)
395 return ret;
396 }
397
398 return pm_generic_runtime_resume(dev);
399}
400#endif
401
368#ifdef CONFIG_PM 402#ifdef CONFIG_PM
369 403
370static const struct dev_pm_ops amba_pm = { 404static const struct dev_pm_ops amba_pm = {
@@ -383,8 +417,8 @@ static const struct dev_pm_ops amba_pm = {
383 .poweroff_noirq = amba_pm_poweroff_noirq, 417 .poweroff_noirq = amba_pm_poweroff_noirq,
384 .restore_noirq = amba_pm_restore_noirq, 418 .restore_noirq = amba_pm_restore_noirq,
385 SET_RUNTIME_PM_OPS( 419 SET_RUNTIME_PM_OPS(
386 pm_generic_runtime_suspend, 420 amba_pm_runtime_suspend,
387 pm_generic_runtime_resume, 421 amba_pm_runtime_resume,
388 pm_generic_runtime_idle 422 pm_generic_runtime_idle
389 ) 423 )
390}; 424};
@@ -494,10 +528,18 @@ static int amba_probe(struct device *dev)
494 if (ret) 528 if (ret)
495 break; 529 break;
496 530
531 pm_runtime_get_noresume(dev);
532 pm_runtime_set_active(dev);
533 pm_runtime_enable(dev);
534
497 ret = pcdrv->probe(pcdev, id); 535 ret = pcdrv->probe(pcdev, id);
498 if (ret == 0) 536 if (ret == 0)
499 break; 537 break;
500 538
539 pm_runtime_disable(dev);
540 pm_runtime_set_suspended(dev);
541 pm_runtime_put_noidle(dev);
542
501 amba_put_disable_pclk(pcdev); 543 amba_put_disable_pclk(pcdev);
502 amba_put_disable_vcore(pcdev); 544 amba_put_disable_vcore(pcdev);
503 } while (0); 545 } while (0);
@@ -509,7 +551,16 @@ static int amba_remove(struct device *dev)
509{ 551{
510 struct amba_device *pcdev = to_amba_device(dev); 552 struct amba_device *pcdev = to_amba_device(dev);
511 struct amba_driver *drv = to_amba_driver(dev->driver); 553 struct amba_driver *drv = to_amba_driver(dev->driver);
512 int ret = drv->remove(pcdev); 554 int ret;
555
556 pm_runtime_get_sync(dev);
557 ret = drv->remove(pcdev);
558 pm_runtime_put_noidle(dev);
559
560 /* Undo the runtime PM settings in amba_probe() */
561 pm_runtime_disable(dev);
562 pm_runtime_set_suspended(dev);
563 pm_runtime_put_noidle(dev);
513 564
514 amba_put_disable_pclk(pcdev); 565 amba_put_disable_pclk(pcdev);
515 amba_put_disable_vcore(pcdev); 566 amba_put_disable_vcore(pcdev);
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
2292static int pl022_suspend(struct amba_device *adev, pm_message_t state) 2285static 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
2312static int pl022_resume(struct amba_device *adev) 2305static 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
2322static 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
2332static 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
2343static 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
2331static struct vendor_data vendor_arm = { 2348static 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[] = {
2407static struct amba_driver pl022_driver = { 2424static 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