aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/dma/stm32-dma.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/dma/stm32-dma.c')
-rw-r--r--drivers/dma/stm32-dma.c71
1 files changed, 59 insertions, 12 deletions
diff --git a/drivers/dma/stm32-dma.c b/drivers/dma/stm32-dma.c
index 4903a408fc14..ba239b529fa9 100644
--- a/drivers/dma/stm32-dma.c
+++ b/drivers/dma/stm32-dma.c
@@ -23,6 +23,7 @@
23#include <linux/of_device.h> 23#include <linux/of_device.h>
24#include <linux/of_dma.h> 24#include <linux/of_dma.h>
25#include <linux/platform_device.h> 25#include <linux/platform_device.h>
26#include <linux/pm_runtime.h>
26#include <linux/reset.h> 27#include <linux/reset.h>
27#include <linux/sched.h> 28#include <linux/sched.h>
28#include <linux/slab.h> 29#include <linux/slab.h>
@@ -641,12 +642,13 @@ static irqreturn_t stm32_dma_chan_irq(int irq, void *devid)
641{ 642{
642 struct stm32_dma_chan *chan = devid; 643 struct stm32_dma_chan *chan = devid;
643 struct stm32_dma_device *dmadev = stm32_dma_get_dev(chan); 644 struct stm32_dma_device *dmadev = stm32_dma_get_dev(chan);
644 u32 status, scr; 645 u32 status, scr, sfcr;
645 646
646 spin_lock(&chan->vchan.lock); 647 spin_lock(&chan->vchan.lock);
647 648
648 status = stm32_dma_irq_status(chan); 649 status = stm32_dma_irq_status(chan);
649 scr = stm32_dma_read(dmadev, STM32_DMA_SCR(chan->id)); 650 scr = stm32_dma_read(dmadev, STM32_DMA_SCR(chan->id));
651 sfcr = stm32_dma_read(dmadev, STM32_DMA_SFCR(chan->id));
650 652
651 if (status & STM32_DMA_TCI) { 653 if (status & STM32_DMA_TCI) {
652 stm32_dma_irq_clear(chan, STM32_DMA_TCI); 654 stm32_dma_irq_clear(chan, STM32_DMA_TCI);
@@ -661,10 +663,12 @@ static irqreturn_t stm32_dma_chan_irq(int irq, void *devid)
661 if (status & STM32_DMA_FEI) { 663 if (status & STM32_DMA_FEI) {
662 stm32_dma_irq_clear(chan, STM32_DMA_FEI); 664 stm32_dma_irq_clear(chan, STM32_DMA_FEI);
663 status &= ~STM32_DMA_FEI; 665 status &= ~STM32_DMA_FEI;
664 if (!(scr & STM32_DMA_SCR_EN)) 666 if (sfcr & STM32_DMA_SFCR_FEIE) {
665 dev_err(chan2dev(chan), "FIFO Error\n"); 667 if (!(scr & STM32_DMA_SCR_EN))
666 else 668 dev_err(chan2dev(chan), "FIFO Error\n");
667 dev_dbg(chan2dev(chan), "FIFO over/underrun\n"); 669 else
670 dev_dbg(chan2dev(chan), "FIFO over/underrun\n");
671 }
668 } 672 }
669 if (status) { 673 if (status) {
670 stm32_dma_irq_clear(chan, status); 674 stm32_dma_irq_clear(chan, status);
@@ -1112,15 +1116,14 @@ static int stm32_dma_alloc_chan_resources(struct dma_chan *c)
1112 int ret; 1116 int ret;
1113 1117
1114 chan->config_init = false; 1118 chan->config_init = false;
1115 ret = clk_prepare_enable(dmadev->clk); 1119
1116 if (ret < 0) { 1120 ret = pm_runtime_get_sync(dmadev->ddev.dev);
1117 dev_err(chan2dev(chan), "clk_prepare_enable failed: %d\n", ret); 1121 if (ret < 0)
1118 return ret; 1122 return ret;
1119 }
1120 1123
1121 ret = stm32_dma_disable_chan(chan); 1124 ret = stm32_dma_disable_chan(chan);
1122 if (ret < 0) 1125 if (ret < 0)
1123 clk_disable_unprepare(dmadev->clk); 1126 pm_runtime_put(dmadev->ddev.dev);
1124 1127
1125 return ret; 1128 return ret;
1126} 1129}
@@ -1140,7 +1143,7 @@ static void stm32_dma_free_chan_resources(struct dma_chan *c)
1140 spin_unlock_irqrestore(&chan->vchan.lock, flags); 1143 spin_unlock_irqrestore(&chan->vchan.lock, flags);
1141 } 1144 }
1142 1145
1143 clk_disable_unprepare(dmadev->clk); 1146 pm_runtime_put(dmadev->ddev.dev);
1144 1147
1145 vchan_free_chan_resources(to_virt_chan(c)); 1148 vchan_free_chan_resources(to_virt_chan(c));
1146} 1149}
@@ -1240,6 +1243,12 @@ static int stm32_dma_probe(struct platform_device *pdev)
1240 return PTR_ERR(dmadev->clk); 1243 return PTR_ERR(dmadev->clk);
1241 } 1244 }
1242 1245
1246 ret = clk_prepare_enable(dmadev->clk);
1247 if (ret < 0) {
1248 dev_err(&pdev->dev, "clk_prep_enable error: %d\n", ret);
1249 return ret;
1250 }
1251
1243 dmadev->mem2mem = of_property_read_bool(pdev->dev.of_node, 1252 dmadev->mem2mem = of_property_read_bool(pdev->dev.of_node,
1244 "st,mem2mem"); 1253 "st,mem2mem");
1245 1254
@@ -1289,7 +1298,7 @@ static int stm32_dma_probe(struct platform_device *pdev)
1289 1298
1290 ret = dma_async_device_register(dd); 1299 ret = dma_async_device_register(dd);
1291 if (ret) 1300 if (ret)
1292 return ret; 1301 goto clk_free;
1293 1302
1294 for (i = 0; i < STM32_DMA_MAX_CHANNELS; i++) { 1303 for (i = 0; i < STM32_DMA_MAX_CHANNELS; i++) {
1295 chan = &dmadev->chan[i]; 1304 chan = &dmadev->chan[i];
@@ -1321,20 +1330,58 @@ static int stm32_dma_probe(struct platform_device *pdev)
1321 1330
1322 platform_set_drvdata(pdev, dmadev); 1331 platform_set_drvdata(pdev, dmadev);
1323 1332
1333 pm_runtime_set_active(&pdev->dev);
1334 pm_runtime_enable(&pdev->dev);
1335 pm_runtime_get_noresume(&pdev->dev);
1336 pm_runtime_put(&pdev->dev);
1337
1324 dev_info(&pdev->dev, "STM32 DMA driver registered\n"); 1338 dev_info(&pdev->dev, "STM32 DMA driver registered\n");
1325 1339
1326 return 0; 1340 return 0;
1327 1341
1328err_unregister: 1342err_unregister:
1329 dma_async_device_unregister(dd); 1343 dma_async_device_unregister(dd);
1344clk_free:
1345 clk_disable_unprepare(dmadev->clk);
1330 1346
1331 return ret; 1347 return ret;
1332} 1348}
1333 1349
1350#ifdef CONFIG_PM
1351static int stm32_dma_runtime_suspend(struct device *dev)
1352{
1353 struct stm32_dma_device *dmadev = dev_get_drvdata(dev);
1354
1355 clk_disable_unprepare(dmadev->clk);
1356
1357 return 0;
1358}
1359
1360static int stm32_dma_runtime_resume(struct device *dev)
1361{
1362 struct stm32_dma_device *dmadev = dev_get_drvdata(dev);
1363 int ret;
1364
1365 ret = clk_prepare_enable(dmadev->clk);
1366 if (ret) {
1367 dev_err(dev, "failed to prepare_enable clock\n");
1368 return ret;
1369 }
1370
1371 return 0;
1372}
1373#endif
1374
1375static const struct dev_pm_ops stm32_dma_pm_ops = {
1376 SET_RUNTIME_PM_OPS(stm32_dma_runtime_suspend,
1377 stm32_dma_runtime_resume, NULL)
1378};
1379
1334static struct platform_driver stm32_dma_driver = { 1380static struct platform_driver stm32_dma_driver = {
1335 .driver = { 1381 .driver = {
1336 .name = "stm32-dma", 1382 .name = "stm32-dma",
1337 .of_match_table = stm32_dma_of_match, 1383 .of_match_table = stm32_dma_of_match,
1384 .pm = &stm32_dma_pm_ops,
1338 }, 1385 },
1339}; 1386};
1340 1387