diff options
author | Gao Pan <pandy.gao@nxp.com> | 2016-01-18 15:44:01 +0800 |
---|---|---|
committer | Mark Brown <broonie@kernel.org> | 2016-02-19 00:12:52 +0000 |
commit | ba4a3550e93415f4ff300810b8d0659949fea193 (patch) | |
tree | c00efada7dfe0fc50c1e4d1f6a348245baf18f3a /drivers/spi | |
parent | 390f0ffe92aea878b763c7fd8afd1dff62e0d20b (diff) | |
download | linux-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.c | 8 |
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)); |