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

dmaengine: lpc32xx-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: 5d318b595982 ("dmaengine: Add dma router for pl08x in LPC32XX SoC")
Cc: stable@vger.kernel.org # 6.12
Cc: Piotr Wojtaszczyk <piotr.wojtaszczyk@timesys.com>
Signed-off-by: Johan Hovold <johan@kernel.org>
Reviewed-by: Vladimir Zapolskiy <vz@mleia.com>
Link: https://patch.msgid.link/20251117161258.10679-9-johan@kernel.org
Signed-off-by: Vinod Koul <vkoul@kernel.org>

authored by

Johan Hovold and committed by
Vinod Koul
d9847e6d d4d63059

+14 -5
+14 -5
drivers/dma/lpc32xx-dmamux.c
··· 95 95 struct lpc32xx_dmamux_data *dmamux = platform_get_drvdata(pdev); 96 96 unsigned long flags; 97 97 struct lpc32xx_dmamux *mux = NULL; 98 + int ret = -EINVAL; 98 99 int i; 99 100 100 101 if (dma_spec->args_count != 3) { 101 102 dev_err(&pdev->dev, "invalid number of dma mux args\n"); 102 - return ERR_PTR(-EINVAL); 103 + goto err_put_pdev; 103 104 } 104 105 105 106 for (i = 0; i < ARRAY_SIZE(lpc32xx_muxes); i++) { ··· 112 111 if (!mux) { 113 112 dev_err(&pdev->dev, "invalid mux request number: %d\n", 114 113 dma_spec->args[0]); 115 - return ERR_PTR(-EINVAL); 114 + goto err_put_pdev; 116 115 } 117 116 118 117 if (dma_spec->args[2] > 1) { 119 118 dev_err(&pdev->dev, "invalid dma mux value: %d\n", 120 119 dma_spec->args[1]); 121 - return ERR_PTR(-EINVAL); 120 + goto err_put_pdev; 122 121 } 123 122 124 123 /* The of_node_put() will be done in the core for the node */ 125 124 dma_spec->np = of_parse_phandle(ofdma->of_node, "dma-masters", 0); 126 125 if (!dma_spec->np) { 127 126 dev_err(&pdev->dev, "can't get dma master\n"); 128 - return ERR_PTR(-EINVAL); 127 + goto err_put_pdev; 129 128 } 130 129 131 130 spin_lock_irqsave(&dmamux->lock, flags); ··· 134 133 dev_err(dev, "dma request signal %d busy, routed to %s\n", 135 134 mux->signal, mux->muxval ? mux->name_sel1 : mux->name_sel1); 136 135 of_node_put(dma_spec->np); 137 - return ERR_PTR(-EBUSY); 136 + ret = -EBUSY; 137 + goto err_put_pdev; 138 138 } 139 139 140 140 mux->busy = true; ··· 150 148 dev_dbg(dev, "dma request signal %d routed to %s\n", 151 149 mux->signal, mux->muxval ? mux->name_sel1 : mux->name_sel1); 152 150 151 + put_device(&pdev->dev); 152 + 153 153 return mux; 154 + 155 + err_put_pdev: 156 + put_device(&pdev->dev); 157 + 158 + return ERR_PTR(ret); 154 159 } 155 160 156 161 static int lpc32xx_dmamux_probe(struct platform_device *pdev)