diff options
author | Shawn Lin <shawn.lin@rock-chips.com> | 2016-03-09 09:11:15 +0100 |
---|---|---|
committer | Mark Brown <broonie@kernel.org> | 2016-03-09 10:10:18 +0100 |
commit | ea98491133439773b69345eb9a314fc5f15e07a4 (patch) | |
tree | 17a8d78602a10a7bc664eaf7bc20dee6a3cbadb1 | |
parent | spi/rockchip: fix endian mode for 16-bit transfers (diff) | |
download | linux-ea98491133439773b69345eb9a314fc5f15e07a4.tar.xz linux-ea98491133439773b69345eb9a314fc5f15e07a4.zip |
spi: rockchip: check return value of dmaengine_prep_slave_sg
We should check return value of dmaengine_prep_slave_sg, otherwise
we take risk of null pointer.
Signed-off-by: Shawn Lin <shawn.lin@rock-chips.com>
Signed-off-by: Mark Brown <broonie@kernel.org>
-rw-r--r-- | drivers/spi/spi-rockchip.c | 15 |
1 files changed, 12 insertions, 3 deletions
diff --git a/drivers/spi/spi-rockchip.c b/drivers/spi/spi-rockchip.c index 9a5c51764833..aa8528e9840c 100644 --- a/drivers/spi/spi-rockchip.c +++ b/drivers/spi/spi-rockchip.c @@ -436,7 +436,7 @@ static void rockchip_spi_dma_txcb(void *data) spin_unlock_irqrestore(&rs->lock, flags); } -static void rockchip_spi_prepare_dma(struct rockchip_spi *rs) +static int rockchip_spi_prepare_dma(struct rockchip_spi *rs) { unsigned long flags; struct dma_slave_config rxconf, txconf; @@ -459,6 +459,8 @@ static void rockchip_spi_prepare_dma(struct rockchip_spi *rs) rs->dma_rx.ch, rs->rx_sg.sgl, rs->rx_sg.nents, rs->dma_rx.direction, DMA_PREP_INTERRUPT); + if (!rxdesc) + return -EINVAL; rxdesc->callback = rockchip_spi_dma_rxcb; rxdesc->callback_param = rs; @@ -476,6 +478,11 @@ static void rockchip_spi_prepare_dma(struct rockchip_spi *rs) rs->dma_tx.ch, rs->tx_sg.sgl, rs->tx_sg.nents, rs->dma_tx.direction, DMA_PREP_INTERRUPT); + if (!txdesc) { + if (rxdesc) + dmaengine_terminate_sync(rs->dma_rx.ch); + return -EINVAL; + } txdesc->callback = rockchip_spi_dma_txcb; txdesc->callback_param = rs; @@ -497,6 +504,8 @@ static void rockchip_spi_prepare_dma(struct rockchip_spi *rs) dmaengine_submit(txdesc); dma_async_issue_pending(rs->dma_tx.ch); } + + return 0; } static void rockchip_spi_config(struct rockchip_spi *rs) @@ -610,12 +619,12 @@ static int rockchip_spi_transfer_one( if (rs->use_dma) { if (rs->tmode == CR0_XFM_RO) { /* rx: dma must be prepared first */ - rockchip_spi_prepare_dma(rs); + ret = rockchip_spi_prepare_dma(rs); spi_enable_chip(rs, 1); } else { /* tx or tr: spi must be enabled first */ spi_enable_chip(rs, 1); - rockchip_spi_prepare_dma(rs); + ret = rockchip_spi_prepare_dma(rs); } } else { spi_enable_chip(rs, 1); |