diff options
author | Addy Ke <addy.ke@rockchip.com> | 2014-07-11 10:08:24 +0800 |
---|---|---|
committer | Mark Brown <broonie@linaro.org> | 2014-07-11 13:59:57 +0100 |
commit | 2df08e7890231c44c3b57ece8b95a5797cd82388 (patch) | |
tree | 54255af64f8c5184e9d2b2108b6069a1029bfd74 /drivers/spi/spi-rockchip.c | |
parent | 5dcc44ed911cadc7eb3db46e874a447848f3b340 (diff) |
spi/rockchip: call wait_for_idle() for the transfer to complete
Suggested-by: Mark Brown <broonie@kernel.org>
Signed-off-by: Addy Ke <addy.ke@rockchip.com>
Signed-off-by: Mark Brown <broonie@linaro.org>
Diffstat (limited to 'drivers/spi/spi-rockchip.c')
-rw-r--r-- | drivers/spi/spi-rockchip.c | 24 |
1 files changed, 19 insertions, 5 deletions
diff --git a/drivers/spi/spi-rockchip.c b/drivers/spi/spi-rockchip.c index 8c247086e520..09c690c65956 100644 --- a/drivers/spi/spi-rockchip.c +++ b/drivers/spi/spi-rockchip.c @@ -214,6 +214,18 @@ static inline void flush_fifo(struct rockchip_spi *rs) readl_relaxed(rs->regs + ROCKCHIP_SPI_RXDR); } +static inline void wait_for_idle(struct rockchip_spi *rs) +{ + unsigned long timeout = jiffies + msecs_to_jiffies(5); + + do { + if (!(readl_relaxed(rs->regs + ROCKCHIP_SPI_SR) & SR_BUSY)) + return; + } while (time_before(jiffies, timeout)); + + dev_warn(rs->dev, "spi controller is in busy state!\n"); +} + static u32 get_fifo_len(struct rockchip_spi *rs) { u32 fifo; @@ -371,6 +383,10 @@ static int rockchip_spi_pio_transfer(struct rockchip_spi *rs) cpu_relax(); } while (remain); + /* If tx, wait until the FIFO data completely. */ + if (rs->tx) + wait_for_idle(rs); + return 0; } @@ -393,6 +409,9 @@ static void rockchip_spi_dma_txcb(void *data) unsigned long flags; struct rockchip_spi *rs = data; + /* Wait until the FIFO data completely. */ + wait_for_idle(rs); + spin_lock_irqsave(&rs->lock, flags); rs->state &= ~TXBUSY; @@ -536,11 +555,6 @@ static int rockchip_spi_transfer_one( rs->tx_sg = xfer->tx_sg; rs->rx_sg = xfer->rx_sg; - /* Delay until the FIFO data completely */ - if (xfer->tx_buf) - xfer->delay_usecs - = rs->fifo_len * rs->bpw * 1000000 / rs->speed; - if (rs->tx && rs->rx) rs->tmode = CR0_XFM_TR; else if (rs->tx) |