diff options
author | Shawn Lin <shawn.lin@rock-chips.com> | 2016-03-09 03:11:15 -0500 |
---|---|---|
committer | Mark Brown <broonie@kernel.org> | 2016-03-09 04:10:18 -0500 |
commit | ea98491133439773b69345eb9a314fc5f15e07a4 (patch) | |
tree | 17a8d78602a10a7bc664eaf7bc20dee6a3cbadb1 /drivers/spi/spi-rockchip.c | |
parent | 0277e01aebc8895198a4717ccaf7e4fcf39ada78 (diff) |
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>
Diffstat (limited to 'drivers/spi/spi-rockchip.c')
-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) | |||
436 | spin_unlock_irqrestore(&rs->lock, flags); | 436 | spin_unlock_irqrestore(&rs->lock, flags); |
437 | } | 437 | } |
438 | 438 | ||
439 | static void rockchip_spi_prepare_dma(struct rockchip_spi *rs) | 439 | static int rockchip_spi_prepare_dma(struct rockchip_spi *rs) |
440 | { | 440 | { |
441 | unsigned long flags; | 441 | unsigned long flags; |
442 | struct dma_slave_config rxconf, txconf; | 442 | struct dma_slave_config rxconf, txconf; |
@@ -459,6 +459,8 @@ static void rockchip_spi_prepare_dma(struct rockchip_spi *rs) | |||
459 | rs->dma_rx.ch, | 459 | rs->dma_rx.ch, |
460 | rs->rx_sg.sgl, rs->rx_sg.nents, | 460 | rs->rx_sg.sgl, rs->rx_sg.nents, |
461 | rs->dma_rx.direction, DMA_PREP_INTERRUPT); | 461 | rs->dma_rx.direction, DMA_PREP_INTERRUPT); |
462 | if (!rxdesc) | ||
463 | return -EINVAL; | ||
462 | 464 | ||
463 | rxdesc->callback = rockchip_spi_dma_rxcb; | 465 | rxdesc->callback = rockchip_spi_dma_rxcb; |
464 | rxdesc->callback_param = rs; | 466 | rxdesc->callback_param = rs; |
@@ -476,6 +478,11 @@ static void rockchip_spi_prepare_dma(struct rockchip_spi *rs) | |||
476 | rs->dma_tx.ch, | 478 | rs->dma_tx.ch, |
477 | rs->tx_sg.sgl, rs->tx_sg.nents, | 479 | rs->tx_sg.sgl, rs->tx_sg.nents, |
478 | rs->dma_tx.direction, DMA_PREP_INTERRUPT); | 480 | rs->dma_tx.direction, DMA_PREP_INTERRUPT); |
481 | if (!txdesc) { | ||
482 | if (rxdesc) | ||
483 | dmaengine_terminate_sync(rs->dma_rx.ch); | ||
484 | return -EINVAL; | ||
485 | } | ||
479 | 486 | ||
480 | txdesc->callback = rockchip_spi_dma_txcb; | 487 | txdesc->callback = rockchip_spi_dma_txcb; |
481 | txdesc->callback_param = rs; | 488 | txdesc->callback_param = rs; |
@@ -497,6 +504,8 @@ static void rockchip_spi_prepare_dma(struct rockchip_spi *rs) | |||
497 | dmaengine_submit(txdesc); | 504 | dmaengine_submit(txdesc); |
498 | dma_async_issue_pending(rs->dma_tx.ch); | 505 | dma_async_issue_pending(rs->dma_tx.ch); |
499 | } | 506 | } |
507 | |||
508 | return 0; | ||
500 | } | 509 | } |
501 | 510 | ||
502 | static void rockchip_spi_config(struct rockchip_spi *rs) | 511 | static void rockchip_spi_config(struct rockchip_spi *rs) |
@@ -610,12 +619,12 @@ static int rockchip_spi_transfer_one( | |||
610 | if (rs->use_dma) { | 619 | if (rs->use_dma) { |
611 | if (rs->tmode == CR0_XFM_RO) { | 620 | if (rs->tmode == CR0_XFM_RO) { |
612 | /* rx: dma must be prepared first */ | 621 | /* rx: dma must be prepared first */ |
613 | rockchip_spi_prepare_dma(rs); | 622 | ret = rockchip_spi_prepare_dma(rs); |
614 | spi_enable_chip(rs, 1); | 623 | spi_enable_chip(rs, 1); |
615 | } else { | 624 | } else { |
616 | /* tx or tr: spi must be enabled first */ | 625 | /* tx or tr: spi must be enabled first */ |
617 | spi_enable_chip(rs, 1); | 626 | spi_enable_chip(rs, 1); |
618 | rockchip_spi_prepare_dma(rs); | 627 | ret = rockchip_spi_prepare_dma(rs); |
619 | } | 628 | } |
620 | } else { | 629 | } else { |
621 | spi_enable_chip(rs, 1); | 630 | spi_enable_chip(rs, 1); |