From: Chuhong Yuan hslester96@gmail.com
mainline inclusion from mainline-v5.6-rc1 commit 2a03c1314506557277829562dd2ec5c11a6ea914 category: bugfix bugzilla: https://gitee.com/src-openeuler/kernel/issues/I9E2MP CVE: NA
Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?i...
--------------------------------
The driver forgets to call pm_runtime_disable and pm_runtime_put_sync in probe failure and remove. Add the calls and modify probe failure handling to fix it.
To simplify the fix, the patch adjusts the calling order and merges checks for devm_kcalloc.
Fixes: 2b6b3b742019 ("ARM/dmaengine: edma: Merge the two drivers under drivers/dma/") Signed-off-by: Chuhong Yuan hslester96@gmail.com Acked-by: Peter Ujfalusi peter.ujfalusi@ti.com Link: https://lore.kernel.org/r/20191124052855.6472-1-hslester96@gmail.com Signed-off-by: Vinod Koul vkoul@kernel.org Conflicts: drivers/dma/ti/edma.c Signed-off-by: GUO Zihua guozihua@huawei.com --- drivers/dma/ti/edma.c | 35 ++++++++++++++++++++--------------- 1 file changed, 20 insertions(+), 15 deletions(-)
diff --git a/drivers/dma/ti/edma.c b/drivers/dma/ti/edma.c index 44158fa85973..800271647574 100644 --- a/drivers/dma/ti/edma.c +++ b/drivers/dma/ti/edma.c @@ -2218,13 +2218,6 @@ static int edma_probe(struct platform_device *pdev) if (!info) return -ENODEV;
- pm_runtime_enable(dev); - ret = pm_runtime_get_sync(dev); - if (ret < 0) { - dev_err(dev, "pm_runtime_get_sync() failed\n"); - return ret; - } - ret = dma_set_mask_and_coherent(dev, DMA_BIT_MASK(32)); if (ret) return ret; @@ -2255,21 +2248,27 @@ static int edma_probe(struct platform_device *pdev)
platform_set_drvdata(pdev, ecc);
+ pm_runtime_enable(dev); + ret = pm_runtime_get_sync(dev); + if (ret < 0) { + dev_err(dev, "pm_runtime_get_sync() failed\n"); + pm_runtime_disable(dev); + return ret; + } + /* Get eDMA3 configuration from IP */ ret = edma_setup_from_hw(dev, info, ecc); if (ret) - return ret; + goto err_disable_pm;
/* Allocate memory based on the information we got from the IP */ ecc->slave_chans = devm_kcalloc(dev, ecc->num_channels, sizeof(*ecc->slave_chans), GFP_KERNEL); - if (!ecc->slave_chans) - return -ENOMEM;
ecc->slot_inuse = devm_kcalloc(dev, BITS_TO_LONGS(ecc->num_slots), sizeof(unsigned long), GFP_KERNEL); - if (!ecc->slot_inuse) - return -ENOMEM; + if (!ecc->slave_chans || !ecc->slot_inuse) + goto err_disable_pm;
ecc->default_queue = info->default_queue;
@@ -2310,7 +2309,7 @@ static int edma_probe(struct platform_device *pdev) ecc); if (ret) { dev_err(dev, "CCINT (%d) failed --> %d\n", irq, ret); - return ret; + goto err_disable_pm; } ecc->ccint = irq; } @@ -2326,7 +2325,7 @@ static int edma_probe(struct platform_device *pdev) ecc); if (ret) { dev_err(dev, "CCERRINT (%d) failed --> %d\n", irq, ret); - return ret; + goto err_disable_pm; } ecc->ccerrint = irq; } @@ -2334,7 +2333,8 @@ static int edma_probe(struct platform_device *pdev) ecc->dummy_slot = edma_alloc_slot(ecc, EDMA_SLOT_ANY); if (ecc->dummy_slot < 0) { dev_err(dev, "Can't allocate PaRAM dummy slot\n"); - return ecc->dummy_slot; + ret = ecc->dummy_slot; + goto err_disable_pm; }
queue_priority_mapping = info->queue_priority_mapping; @@ -2418,6 +2418,9 @@ static int edma_probe(struct platform_device *pdev)
err_reg1: edma_free_slot(ecc, ecc->dummy_slot); +err_disable_pm: + pm_runtime_put_sync(dev); + pm_runtime_disable(dev); return ret; }
@@ -2448,6 +2451,8 @@ static int edma_remove(struct platform_device *pdev) if (ecc->dma_memcpy) dma_async_device_unregister(ecc->dma_memcpy); edma_free_slot(ecc, ecc->dummy_slot); + pm_runtime_put_sync(dev); + pm_runtime_disable(dev);
return 0; }