From: Carlos Song <carlos.song@nxp.com>
The LPI2C driver currently requests DMA channels using dma_request_chan(),
but only releases them when the request fails. DMA channels are not
released during driver remove or shutdown, resulting in resource leaks.
Switch to devm_dma_request_chan() to let the device core manage DMA
channel lifetime automatically, ensuring proper cleanup on all exit
paths.
Fixes: a09c8b3f9047 ("i2c: imx-lpi2c: add eDMA mode support for LPI2C")
Cc: stable@vger.kernel.org
Signed-off-by: Carlos Song <carlos.song@nxp.com>
---
drivers/i2c/busses/i2c-imx-lpi2c.c | 25 ++++---------------------
1 file changed, 4 insertions(+), 21 deletions(-)
diff --git a/drivers/i2c/busses/i2c-imx-lpi2c.c b/drivers/i2c/busses/i2c-imx-lpi2c.c
index 96f6dc23232e..fb52db5b4062 100644
--- a/drivers/i2c/busses/i2c-imx-lpi2c.c
+++ b/drivers/i2c/busses/i2c-imx-lpi2c.c
@@ -1383,17 +1383,6 @@ static int lpi2c_imx_init_recovery_info(struct lpi2c_imx_struct *lpi2c_imx,
return 0;
}
-static void dma_exit(struct device *dev, struct lpi2c_imx_dma *dma)
-{
- if (dma->chan_rx)
- dma_release_channel(dma->chan_rx);
-
- if (dma->chan_tx)
- dma_release_channel(dma->chan_tx);
-
- devm_kfree(dev, dma);
-}
-
static int lpi2c_dma_init(struct device *dev, dma_addr_t phy_addr)
{
struct lpi2c_imx_struct *lpi2c_imx = dev_get_drvdata(dev);
@@ -1407,32 +1396,26 @@ static int lpi2c_dma_init(struct device *dev, dma_addr_t phy_addr)
dma->phy_addr = phy_addr;
/* Prepare for TX DMA: */
- dma->chan_tx = dma_request_chan(dev, "tx");
+ dma->chan_tx = devm_dma_request_chan(dev, "tx");
if (IS_ERR(dma->chan_tx)) {
ret = PTR_ERR(dma->chan_tx);
if (ret != -ENODEV && ret != -EPROBE_DEFER)
dev_err(dev, "can't request DMA tx channel (%d)\n", ret);
- dma->chan_tx = NULL;
- goto dma_exit;
+ return ret;
}
/* Prepare for RX DMA: */
- dma->chan_rx = dma_request_chan(dev, "rx");
+ dma->chan_rx = devm_dma_request_chan(dev, "rx");
if (IS_ERR(dma->chan_rx)) {
ret = PTR_ERR(dma->chan_rx);
if (ret != -ENODEV && ret != -EPROBE_DEFER)
dev_err(dev, "can't request DMA rx channel (%d)\n", ret);
- dma->chan_rx = NULL;
- goto dma_exit;
+ return ret;
}
lpi2c_imx->can_use_dma = true;
lpi2c_imx->dma = dma;
return 0;
-
-dma_exit:
- dma_exit(dev, dma);
- return ret;
}
static u32 lpi2c_imx_func(struct i2c_adapter *adapter)
--
2.43.0