summaryrefslogtreecommitdiffstats
path: root/drivers/spi
diff options
context:
space:
mode:
authorGao Pan <pandy.gao@nxp.com>2016-01-18 15:44:01 +0800
committerMark Brown <broonie@kernel.org>2016-02-19 00:12:52 +0000
commitba4a3550e93415f4ff300810b8d0659949fea193 (patch)
treec00efada7dfe0fc50c1e4d1f6a348245baf18f3a /drivers/spi
parent390f0ffe92aea878b763c7fd8afd1dff62e0d20b (diff)
downloadlinux-ba4a3550e93415f4ff300810b8d0659949fea193.tar.gz
linux-ba4a3550e93415f4ff300810b8d0659949fea193.tar.bz2
linux-ba4a3550e93415f4ff300810b8d0659949fea193.zip
spi: imx: fix spi resource leak with dma transfer
In spi_imx_dma_transfer(), when desc_rx = dmaengine_prep_slave_sg() fails, the context goes to label no_dma and then return. However, the memory allocated for desc_tx has not been freed yet, which leads to resource leak. Signed-off-by: Gao Pan <pandy.gao@nxp.com> Reviewed-by: Fugang Duan <B38611@freescale.com> Signed-off-by: Mark Brown <broonie@kernel.org>
Diffstat (limited to 'drivers/spi')
-rw-r--r--drivers/spi/spi-imx.c8
1 files changed, 5 insertions, 3 deletions
diff --git a/drivers/spi/spi-imx.c b/drivers/spi/spi-imx.c
index 08492d6faa0d..c688efa95e29 100644
--- a/drivers/spi/spi-imx.c
+++ b/drivers/spi/spi-imx.c
@@ -927,7 +927,7 @@ static int spi_imx_dma_transfer(struct spi_imx_data *spi_imx,
tx->sgl, tx->nents, DMA_MEM_TO_DEV,
DMA_PREP_INTERRUPT | DMA_CTRL_ACK);
if (!desc_tx)
- goto no_dma;
+ goto tx_nodma;
desc_tx->callback = spi_imx_dma_tx_callback;
desc_tx->callback_param = (void *)spi_imx;
@@ -939,7 +939,7 @@ static int spi_imx_dma_transfer(struct spi_imx_data *spi_imx,
rx->sgl, rx->nents, DMA_DEV_TO_MEM,
DMA_PREP_INTERRUPT | DMA_CTRL_ACK);
if (!desc_rx)
- goto no_dma;
+ goto rx_nodma;
desc_rx->callback = spi_imx_dma_rx_callback;
desc_rx->callback_param = (void *)spi_imx;
@@ -995,7 +995,9 @@ static int spi_imx_dma_transfer(struct spi_imx_data *spi_imx,
return ret;
-no_dma:
+rx_nodma:
+ dmaengine_terminate_all(master->dma_tx);
+tx_nodma:
pr_warn_once("%s %s: DMA not available, falling back to PIO\n",
dev_driver_string(&master->dev),
dev_name(&master->dev));