Patch "dmaengine: fsl-edma: disable clks on all error paths" has been added to the 4.14-stable tree
Subsystems (3)
This is a note to let you know that I've just added the patch titled
dmaengine: fsl-edma: disable clks on all error paths
to the 4.14-stable tree which can be found at:
http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=summary
The filename of the patch is:
dmaengine-fsl-edma-disable-clks-on-all-error-paths.patch
and it can be found in the queue-4.14 subdirectory.
If you, or anyone else, feels it should not be added to the stable tree, please let <[email protected]> know about it.
Quoted 1 line
From foo@baz Wed Feb 28 16:23:28 CET 2018
From: Andreas Platschek <[email protected]>
Date: Thu, 14 Dec 2017 12:50:51 +0100
Subject: dmaengine: fsl-edma: disable clks on all error paths
From: Andreas Platschek <[email protected]>
[ Upstream commit 2610acf46b9ed528ec2cacd717bc9d354e452b73 ]
Previously enabled clks are only disabled if clk_prepare_enable() fails. However, there are other error paths were the previously enabled clocks are not disabled.
To fix the problem, fsl_disable_clocks() now takes the number of clocks that shall be disabled + unprepared. For existing calls were all clocks were already successfully prepared + enabled, DMAMUX_NR is passed to disable + unprepare all clocks.
In error paths were only some clocks were successfully prepared + enabled the loop counter is passed, in order to disable + unprepare all successfully prepared + enabled clocks.
Found by Linux Driver Verification project (linuxtesting.org).
--- drivers/dma/fsl-edma.c | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-)
drivers/dma/fsl-edma.c +14 -14
@@ -863,11 +863,11 @@ static void fsl_edma_irq_exit( } } -static void fsl_disable_clocks (struct fsl_edma_engine *fsl_edma) +static void fsl_disable_clocks (struct fsl_edma_engine *fsl_edma,int nr_clocks) {int i; -for (i =0 ; i <DMAMUX_NR ; i++) +for (i =0 ; i < nr_clocks; i++)clk_disable_unprepare (fsl_edma->muxclk[i]); }
@@ -904,25 +904,25 @@ static int fsl_edma_probe(struct platfor res =platform_get_resource (pdev,IORESOURCE_MEM ,1 + i); fsl_edma->muxbase[i] =devm_ioremap_resource (&pdev->dev, res); -if (IS_ERR (fsl_edma->muxbase[i])) +if (IS_ERR (fsl_edma->muxbase[i])) { +/* on error: disable all previously enabled clks */ +fsl_disable_clocks (fsl_edma, i);return PTR_ERR (fsl_edma->muxbase[i]); + }sprintf (clkname,"dmamux%d" , i); fsl_edma->muxclk[i] =devm_clk_get (&pdev->dev, clkname);if (IS_ERR (fsl_edma->muxclk[i])) {dev_err (&pdev->dev,"Missing DMAMUX block clock.\n" ); +/* on error: disable all previously enabled clks */ +fsl_disable_clocks (fsl_edma, i);return PTR_ERR (fsl_edma->muxclk[i]); } ret =clk_prepare_enable (fsl_edma->muxclk[i]); -if (ret) { -/* disable only clks which were enabled on error */ -for (; i >=0 ; i--) -clk_disable_unprepare (fsl_edma->muxclk[i]); - -dev_err (&pdev->dev,"DMAMUX clk block failed.\n" ); -return ret; - } +if (ret) +/* on error: disable all previously enabled clks */ +fsl_disable_clocks (fsl_edma, i); }
@@ -976,7 +976,7 @@ static int fsl_edma_probe(struct platforif (ret) {dev_err (&pdev->dev,"Can't register Freescale eDMA engine. (%d)\n" , ret); -fsl_disable_clocks (fsl_edma); +fsl_disable_clocks (fsl_edma,DMAMUX_NR );return ret; }
@@ -985,7 +985,7 @@ static int fsl_edma_probe(struct platfordev_err (&pdev->dev,"Can't register Freescale eDMA of_dma. (%d)\n" , ret);dma_async_device_unregister (&fsl_edma->dma_dev); -fsl_disable_clocks (fsl_edma); +fsl_disable_clocks (fsl_edma,DMAMUX_NR );return ret; }
@@ -1015,7 +1015,7 @@ static int fsl_edma_remove(struct platfofsl_edma_cleanup_vchan (&fsl_edma->dma_dev);of_dma_controller_free (np);dma_async_device_unregister (&fsl_edma->dma_dev); -fsl_disable_clocks (fsl_edma); +fsl_disable_clocks (fsl_edma,DMAMUX_NR );return 0 ; }
Patches currently in stable-queue which might be from [email protected] are
queue-4.14/dmaengine-fsl-edma-disable-clks-on-all-error-paths.patch