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

dmaengine: cv1800b-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: db7d07b5add4 ("dmaengine: add driver for Sophgo CV18XX/SG200X dmamux")
Cc: stable@vger.kernel.org # 6.17
Cc: Inochi Amaoto <inochiama@gmail.com>
Signed-off-by: Johan Hovold <johan@kernel.org>
Link: https://patch.msgid.link/20251117161258.10679-5-johan@kernel.org
Signed-off-by: Vinod Koul <vkoul@kernel.org>

authored by

Johan Hovold and committed by
Vinod Koul
7bb7d696 7c3a46eb

+10 -7
+10 -7
drivers/dma/cv1800b-dmamux.c
··· 102 102 struct llist_node *node; 103 103 unsigned long flags; 104 104 unsigned int chid, devid, cpuid; 105 - int ret; 105 + int ret = -EINVAL; 106 106 107 107 if (dma_spec->args_count != DMAMUX_NCELLS) { 108 108 dev_err(&pdev->dev, "invalid number of dma mux args\n"); 109 - return ERR_PTR(-EINVAL); 109 + goto err_put_pdev; 110 110 } 111 111 112 112 devid = dma_spec->args[0]; ··· 115 115 116 116 if (devid > MAX_DMA_MAPPING_ID) { 117 117 dev_err(&pdev->dev, "invalid device id: %u\n", devid); 118 - return ERR_PTR(-EINVAL); 118 + goto err_put_pdev; 119 119 } 120 120 121 121 if (cpuid > MAX_DMA_CPU_ID) { 122 122 dev_err(&pdev->dev, "invalid cpu id: %u\n", cpuid); 123 - return ERR_PTR(-EINVAL); 123 + goto err_put_pdev; 124 124 } 125 125 126 126 dma_spec->np = of_parse_phandle(ofdma->of_node, "dma-masters", 0); 127 127 if (!dma_spec->np) { 128 128 dev_err(&pdev->dev, "can't get dma master\n"); 129 - return ERR_PTR(-EINVAL); 129 + goto err_put_pdev; 130 130 } 131 131 132 132 spin_lock_irqsave(&dmamux->lock, flags); ··· 136 136 if (map->peripheral == devid && map->cpu == cpuid) 137 137 goto found; 138 138 } 139 - 140 - ret = -EINVAL; 141 139 goto failed; 142 140 } else { 143 141 node = llist_del_first(&dmamux->free_maps); ··· 169 171 dev_dbg(&pdev->dev, "register channel %u for req %u (cpu %u)\n", 170 172 chid, devid, cpuid); 171 173 174 + put_device(&pdev->dev); 175 + 172 176 return map; 173 177 174 178 failed: 175 179 spin_unlock_irqrestore(&dmamux->lock, flags); 176 180 of_node_put(dma_spec->np); 177 181 dev_err(&pdev->dev, "errno %d\n", ret); 182 + err_put_pdev: 183 + put_device(&pdev->dev); 184 + 178 185 return ERR_PTR(ret); 179 186 } 180 187