Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

dmaengine: lpc18xx-dmamux: fix device leak on route allocation

Make sure to drop the reference taken when looking up the DMA mux
platform device during route allocation.

Note that holding a reference to a device does not prevent its driver
data from going away so there is no point in keeping the reference.

Fixes: e5f4ae84be74 ("dmaengine: add driver for lpc18xx dmamux")
Cc: stable@vger.kernel.org # 4.3
Signed-off-by: Johan Hovold <johan@kernel.org>
Reviewed-by: Vladimir Zapolskiy <vz@mleia.com>
Link: https://patch.msgid.link/20251117161258.10679-8-johan@kernel.org
Signed-off-by: Vinod Koul <vkoul@kernel.org>

authored by

Johan Hovold and committed by
Vinod Koul
d4d63059 799900f0

+14 -5
+14 -5
drivers/dma/lpc18xx-dmamux.c
··· 57 57 struct lpc18xx_dmamux_data *dmamux = platform_get_drvdata(pdev); 58 58 unsigned long flags; 59 59 unsigned mux; 60 + int ret = -EINVAL; 60 61 61 62 if (dma_spec->args_count != 3) { 62 63 dev_err(&pdev->dev, "invalid number of dma mux args\n"); 63 - return ERR_PTR(-EINVAL); 64 + goto err_put_pdev; 64 65 } 65 66 66 67 mux = dma_spec->args[0]; 67 68 if (mux >= dmamux->dma_master_requests) { 68 69 dev_err(&pdev->dev, "invalid mux number: %d\n", 69 70 dma_spec->args[0]); 70 - return ERR_PTR(-EINVAL); 71 + goto err_put_pdev; 71 72 } 72 73 73 74 if (dma_spec->args[1] > LPC18XX_DMAMUX_MAX_VAL) { 74 75 dev_err(&pdev->dev, "invalid dma mux value: %d\n", 75 76 dma_spec->args[1]); 76 - return ERR_PTR(-EINVAL); 77 + goto err_put_pdev; 77 78 } 78 79 79 80 /* The of_node_put() will be done in the core for the node */ 80 81 dma_spec->np = of_parse_phandle(ofdma->of_node, "dma-masters", 0); 81 82 if (!dma_spec->np) { 82 83 dev_err(&pdev->dev, "can't get dma master\n"); 83 - return ERR_PTR(-EINVAL); 84 + goto err_put_pdev; 84 85 } 85 86 86 87 spin_lock_irqsave(&dmamux->lock, flags); ··· 90 89 dev_err(&pdev->dev, "dma request %u busy with %u.%u\n", 91 90 mux, mux, dmamux->muxes[mux].value); 92 91 of_node_put(dma_spec->np); 93 - return ERR_PTR(-EBUSY); 92 + ret = -EBUSY; 93 + goto err_put_pdev; 94 94 } 95 95 96 96 dmamux->muxes[mux].busy = true; ··· 108 106 dev_dbg(&pdev->dev, "mapping dmamux %u.%u to dma request %u\n", mux, 109 107 dmamux->muxes[mux].value, mux); 110 108 109 + put_device(&pdev->dev); 110 + 111 111 return &dmamux->muxes[mux]; 112 + 113 + err_put_pdev: 114 + put_device(&pdev->dev); 115 + 116 + return ERR_PTR(ret); 112 117 } 113 118 114 119 static int lpc18xx_dmamux_probe(struct platform_device *pdev)