summaryrefslogtreecommitdiff
path: root/drivers/spi/spi-rockchip.c
diff options
context:
space:
mode:
authorShawn Lin <shawn.lin@rock-chips.com>2016-03-09 16:11:15 +0800
committerHuang, Tao <huangtao@rock-chips.com>2016-06-16 20:46:30 +0800
commitd6c1d4eadd00e7ab0b626244655d181cfe37c4bc (patch)
tree5665abcea4e1de565043a31be6e083554750a8be /drivers/spi/spi-rockchip.c
parent9c66d0fd42c8c4169ef80f1c49c3e8215232d682 (diff)
UPSTREAM: 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. Change-Id: I2cc468563d630169f314e353d835ad33091c0d3c Signed-off-by: Shawn Lin <shawn.lin@rock-chips.com> Signed-off-by: Mark Brown <broonie@kernel.org> Signed-off-by: Caesar Wang <wxt@rock-chips.com> (cherry picked from git.kernel.org next/linux-next.git master commit ea98491133439773b69345eb9a314fc5f15e07a4)
Diffstat (limited to 'drivers/spi/spi-rockchip.c')
-rw-r--r--drivers/spi/spi-rockchip.c15
1 files changed, 12 insertions, 3 deletions
diff --git a/drivers/spi/spi-rockchip.c b/drivers/spi/spi-rockchip.c
index 7f121e679a33..b8a462b0ae56 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);