aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/dma
diff options
context:
space:
mode:
authorJon Hunter <jonathanh@nvidia.com>2015-11-13 11:39:38 -0500
committerVinod Koul <vinod.koul@intel.com>2015-12-05 05:43:08 -0500
commitedd3bdbe9db1415f744bb5da0752675ddbd9eee0 (patch)
tree58551c86b816e5ecb5555c6936c8930d6a1d4086 /drivers/dma
parent8005c49d9aea74d382f474ce11afbbc7d7130bec (diff)
dmaengine: tegra-apb: Correct runtime-pm usage
The tegra-apb DMA driver enables runtime-pm but never calls pm_runtime_get/put and hence the runtime-pm callbacks are never invoked. The driver manages the clocks by directly calling clk_prepare_enable() and clk_unprepare_disable(). Fix this by replacing the clk_prepare_enable() and clk_disable_unprepare() with pm_runtime_get_sync() and pm_runtime_put(), respectively. Note that the consequence of this is that if runtime-pm is disabled, then the clocks will remain on the entire time the driver is loaded. However, if runtime-pm is disabled, then power is not most likely not a concern. Signed-off-by: Jon Hunter <jonathanh@nvidia.com> Signed-off-by: Vinod Koul <vinod.koul@intel.com>
Diffstat (limited to 'drivers/dma')
-rw-r--r--drivers/dma/tegra20-apb-dma.c43
1 files changed, 18 insertions, 25 deletions
diff --git a/drivers/dma/tegra20-apb-dma.c b/drivers/dma/tegra20-apb-dma.c
index c8f79dcaaee8..f68bccf55a24 100644
--- a/drivers/dma/tegra20-apb-dma.c
+++ b/drivers/dma/tegra20-apb-dma.c
@@ -1186,10 +1186,12 @@ static int tegra_dma_alloc_chan_resources(struct dma_chan *dc)
1186 1186
1187 dma_cookie_init(&tdc->dma_chan); 1187 dma_cookie_init(&tdc->dma_chan);
1188 tdc->config_init = false; 1188 tdc->config_init = false;
1189 ret = clk_prepare_enable(tdma->dma_clk); 1189
1190 ret = pm_runtime_get_sync(tdma->dev);
1190 if (ret < 0) 1191 if (ret < 0)
1191 dev_err(tdc2dev(tdc), "clk_prepare_enable failed: %d\n", ret); 1192 return ret;
1192 return ret; 1193
1194 return 0;
1193} 1195}
1194 1196
1195static void tegra_dma_free_chan_resources(struct dma_chan *dc) 1197static void tegra_dma_free_chan_resources(struct dma_chan *dc)
@@ -1232,7 +1234,7 @@ static void tegra_dma_free_chan_resources(struct dma_chan *dc)
1232 list_del(&sg_req->node); 1234 list_del(&sg_req->node);
1233 kfree(sg_req); 1235 kfree(sg_req);
1234 } 1236 }
1235 clk_disable_unprepare(tdma->dma_clk); 1237 pm_runtime_put(tdma->dev);
1236 1238
1237 tdc->slave_id = 0; 1239 tdc->slave_id = 0;
1238} 1240}
@@ -1356,20 +1358,14 @@ static int tegra_dma_probe(struct platform_device *pdev)
1356 spin_lock_init(&tdma->global_lock); 1358 spin_lock_init(&tdma->global_lock);
1357 1359
1358 pm_runtime_enable(&pdev->dev); 1360 pm_runtime_enable(&pdev->dev);
1359 if (!pm_runtime_enabled(&pdev->dev)) { 1361 if (!pm_runtime_enabled(&pdev->dev))
1360 ret = tegra_dma_runtime_resume(&pdev->dev); 1362 ret = tegra_dma_runtime_resume(&pdev->dev);
1361 if (ret) { 1363 else
1362 dev_err(&pdev->dev, "dma_runtime_resume failed %d\n", 1364 ret = pm_runtime_get_sync(&pdev->dev);
1363 ret);
1364 goto err_pm_disable;
1365 }
1366 }
1367 1365
1368 /* Enable clock before accessing registers */
1369 ret = clk_prepare_enable(tdma->dma_clk);
1370 if (ret < 0) { 1366 if (ret < 0) {
1371 dev_err(&pdev->dev, "clk_prepare_enable failed: %d\n", ret); 1367 pm_runtime_disable(&pdev->dev);
1372 goto err_pm_disable; 1368 return ret;
1373 } 1369 }
1374 1370
1375 /* Reset DMA controller */ 1371 /* Reset DMA controller */
@@ -1382,7 +1378,7 @@ static int tegra_dma_probe(struct platform_device *pdev)
1382 tdma_write(tdma, TEGRA_APBDMA_CONTROL, 0); 1378 tdma_write(tdma, TEGRA_APBDMA_CONTROL, 0);
1383 tdma_write(tdma, TEGRA_APBDMA_IRQ_MASK_SET, 0xFFFFFFFFul); 1379 tdma_write(tdma, TEGRA_APBDMA_IRQ_MASK_SET, 0xFFFFFFFFul);
1384 1380
1385 clk_disable_unprepare(tdma->dma_clk); 1381 pm_runtime_put(&pdev->dev);
1386 1382
1387 INIT_LIST_HEAD(&tdma->dma_dev.channels); 1383 INIT_LIST_HEAD(&tdma->dma_dev.channels);
1388 for (i = 0; i < cdata->nr_channels; i++) { 1384 for (i = 0; i < cdata->nr_channels; i++) {
@@ -1485,7 +1481,6 @@ err_irq:
1485 tasklet_kill(&tdc->tasklet); 1481 tasklet_kill(&tdc->tasklet);
1486 } 1482 }
1487 1483
1488err_pm_disable:
1489 pm_runtime_disable(&pdev->dev); 1484 pm_runtime_disable(&pdev->dev);
1490 if (!pm_runtime_status_suspended(&pdev->dev)) 1485 if (!pm_runtime_status_suspended(&pdev->dev))
1491 tegra_dma_runtime_suspend(&pdev->dev); 1486 tegra_dma_runtime_suspend(&pdev->dev);
@@ -1543,7 +1538,7 @@ static int tegra_dma_pm_suspend(struct device *dev)
1543 int ret; 1538 int ret;
1544 1539
1545 /* Enable clock before accessing register */ 1540 /* Enable clock before accessing register */
1546 ret = tegra_dma_runtime_resume(dev); 1541 ret = pm_runtime_get_sync(dev);
1547 if (ret < 0) 1542 if (ret < 0)
1548 return ret; 1543 return ret;
1549 1544
@@ -1560,7 +1555,7 @@ static int tegra_dma_pm_suspend(struct device *dev)
1560 } 1555 }
1561 1556
1562 /* Disable clock */ 1557 /* Disable clock */
1563 tegra_dma_runtime_suspend(dev); 1558 pm_runtime_put(dev);
1564 return 0; 1559 return 0;
1565} 1560}
1566 1561
@@ -1571,7 +1566,7 @@ static int tegra_dma_pm_resume(struct device *dev)
1571 int ret; 1566 int ret;
1572 1567
1573 /* Enable clock before accessing register */ 1568 /* Enable clock before accessing register */
1574 ret = tegra_dma_runtime_resume(dev); 1569 ret = pm_runtime_get_sync(dev);
1575 if (ret < 0) 1570 if (ret < 0)
1576 return ret; 1571 return ret;
1577 1572
@@ -1592,16 +1587,14 @@ static int tegra_dma_pm_resume(struct device *dev)
1592 } 1587 }
1593 1588
1594 /* Disable clock */ 1589 /* Disable clock */
1595 tegra_dma_runtime_suspend(dev); 1590 pm_runtime_put(dev);
1596 return 0; 1591 return 0;
1597} 1592}
1598#endif 1593#endif
1599 1594
1600static const struct dev_pm_ops tegra_dma_dev_pm_ops = { 1595static const struct dev_pm_ops tegra_dma_dev_pm_ops = {
1601#ifdef CONFIG_PM 1596 SET_RUNTIME_PM_OPS(tegra_dma_runtime_suspend, tegra_dma_runtime_resume,
1602 .runtime_suspend = tegra_dma_runtime_suspend, 1597 NULL)
1603 .runtime_resume = tegra_dma_runtime_resume,
1604#endif
1605 SET_SYSTEM_SLEEP_PM_OPS(tegra_dma_pm_suspend, tegra_dma_pm_resume) 1598 SET_SYSTEM_SLEEP_PM_OPS(tegra_dma_pm_suspend, tegra_dma_pm_resume)
1606}; 1599};
1607 1600