| From a24e70c0ac146f8bcae3cdb7f514950d5b32219e Mon Sep 17 00:00:00 2001 |
| From: Addy Ke <addy.ke@rock-chips.com> |
| Date: Thu, 25 Sep 2014 14:59:41 +0800 |
| Subject: spi/rockchip: fix bug that cause the failure to read data in DMA mode |
| |
| From: Addy Ke <addy.ke@rock-chips.com> |
| |
| commit a24e70c0ac146f8bcae3cdb7f514950d5b32219e upstream. |
| |
| In my test on RK3288-pinky board, if spi is enabled, it will begin to |
| read data from slave regardless of whether the DMA is ready. So we |
| need prepare DMA before spi is enable. |
| |
| Signed-off-by: Addy Ke <addy.ke@rock-chips.com> |
| Signed-off-by: Mark Brown <broonie@kernel.org> |
| Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> |
| |
| --- |
| drivers/spi/spi-rockchip.c | 15 +++++++-------- |
| 1 file changed, 7 insertions(+), 8 deletions(-) |
| |
| --- a/drivers/spi/spi-rockchip.c |
| +++ b/drivers/spi/spi-rockchip.c |
| @@ -415,7 +415,7 @@ static void rockchip_spi_dma_txcb(void * |
| spin_unlock_irqrestore(&rs->lock, flags); |
| } |
| |
| -static int rockchip_spi_dma_transfer(struct rockchip_spi *rs) |
| +static void rockchip_spi_prepare_dma(struct rockchip_spi *rs) |
| { |
| unsigned long flags; |
| struct dma_slave_config rxconf, txconf; |
| @@ -474,8 +474,6 @@ static int rockchip_spi_dma_transfer(str |
| dmaengine_submit(txdesc); |
| dma_async_issue_pending(rs->dma_tx.ch); |
| } |
| - |
| - return 1; |
| } |
| |
| static void rockchip_spi_config(struct rockchip_spi *rs) |
| @@ -557,16 +555,17 @@ static int rockchip_spi_transfer_one( |
| else if (rs->rx) |
| rs->tmode = CR0_XFM_RO; |
| |
| - if (master->can_dma && master->can_dma(master, spi, xfer)) |
| + /* we need prepare dma before spi was enabled */ |
| + if (master->can_dma && master->can_dma(master, spi, xfer)) { |
| rs->use_dma = 1; |
| - else |
| + rockchip_spi_prepare_dma(rs); |
| + } else { |
| rs->use_dma = 0; |
| + } |
| |
| rockchip_spi_config(rs); |
| |
| - if (rs->use_dma) |
| - ret = rockchip_spi_dma_transfer(rs); |
| - else |
| + if (!rs->use_dma) |
| ret = rockchip_spi_pio_transfer(rs); |
| |
| return ret; |