Commit d4d63059 authored by Johan Hovold's avatar Johan Hovold Committed by Vinod Koul
Browse files

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: e5f4ae84 ("dmaengine: add driver for lpc18xx dmamux")
Cc: stable@vger.kernel.org	# 4.3
Signed-off-by: default avatarJohan Hovold <johan@kernel.org>
Reviewed-by: default avatarVladimir Zapolskiy <vz@mleia.com>
Link: https://patch.msgid.link/20251117161258.10679-8-johan@kernel.org


Signed-off-by: default avatarVinod Koul <vkoul@kernel.org>
parent 799900f0
Loading
Loading
Loading
Loading
+14 −5
Original line number Diff line number Diff line
@@ -57,30 +57,31 @@ static void *lpc18xx_dmamux_reserve(struct of_phandle_args *dma_spec,
	struct lpc18xx_dmamux_data *dmamux = platform_get_drvdata(pdev);
	unsigned long flags;
	unsigned mux;
	int ret = -EINVAL;

	if (dma_spec->args_count != 3) {
		dev_err(&pdev->dev, "invalid number of dma mux args\n");
		return ERR_PTR(-EINVAL);
		goto err_put_pdev;
	}

	mux = dma_spec->args[0];
	if (mux >= dmamux->dma_master_requests) {
		dev_err(&pdev->dev, "invalid mux number: %d\n",
			dma_spec->args[0]);
		return ERR_PTR(-EINVAL);
		goto err_put_pdev;
	}

	if (dma_spec->args[1] > LPC18XX_DMAMUX_MAX_VAL) {
		dev_err(&pdev->dev, "invalid dma mux value: %d\n",
			dma_spec->args[1]);
		return ERR_PTR(-EINVAL);
		goto err_put_pdev;
	}

	/* The of_node_put() will be done in the core for the node */
	dma_spec->np = of_parse_phandle(ofdma->of_node, "dma-masters", 0);
	if (!dma_spec->np) {
		dev_err(&pdev->dev, "can't get dma master\n");
		return ERR_PTR(-EINVAL);
		goto err_put_pdev;
	}

	spin_lock_irqsave(&dmamux->lock, flags);
@@ -89,7 +90,8 @@ static void *lpc18xx_dmamux_reserve(struct of_phandle_args *dma_spec,
		dev_err(&pdev->dev, "dma request %u busy with %u.%u\n",
			mux, mux, dmamux->muxes[mux].value);
		of_node_put(dma_spec->np);
		return ERR_PTR(-EBUSY);
		ret = -EBUSY;
		goto err_put_pdev;
	}

	dmamux->muxes[mux].busy = true;
@@ -106,7 +108,14 @@ static void *lpc18xx_dmamux_reserve(struct of_phandle_args *dma_spec,
	dev_dbg(&pdev->dev, "mapping dmamux %u.%u to dma request %u\n", mux,
		dmamux->muxes[mux].value, mux);

	put_device(&pdev->dev);

	return &dmamux->muxes[mux];

err_put_pdev:
	put_device(&pdev->dev);

	return ERR_PTR(ret);
}

static int lpc18xx_dmamux_probe(struct platform_device *pdev)