diff options
author | Addy Ke <addy.ke@rockchip.com> | 2014-07-10 22:08:24 -0400 |
---|---|---|
committer | Mark Brown <broonie@linaro.org> | 2014-07-11 08:59:57 -0400 |
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) | |||
214 | readl_relaxed(rs->regs + ROCKCHIP_SPI_RXDR); | 214 | readl_relaxed(rs->regs + ROCKCHIP_SPI_RXDR); |
215 | } | 215 | } |
216 | 216 | ||
217 | static inline void wait_for_idle(struct rockchip_spi *rs) | ||
218 | { | ||
219 | unsigned long timeout = jiffies + msecs_to_jiffies(5); | ||
220 | |||
221 | do { | ||
222 | if (!(readl_relaxed(rs->regs + ROCKCHIP_SPI_SR) & SR_BUSY)) | ||
223 | return; | ||
224 | } while (time_before(jiffies, timeout)); | ||
225 | |||
226 | dev_warn(rs->dev, "spi controller is in busy state!\n"); | ||
227 | } | ||
228 | |||
217 | static u32 get_fifo_len(struct rockchip_spi *rs) | 229 | static u32 get_fifo_len(struct rockchip_spi *rs) |
218 | { | 230 | { |
219 | u32 fifo; | 231 | u32 fifo; |
@@ -371,6 +383,10 @@ static int rockchip_spi_pio_transfer(struct rockchip_spi *rs) | |||
371 | cpu_relax(); | 383 | cpu_relax(); |
372 | } while (remain); | 384 | } while (remain); |
373 | 385 | ||
386 | /* If tx, wait until the FIFO data completely. */ | ||
387 | if (rs->tx) | ||
388 | wait_for_idle(rs); | ||
389 | |||
374 | return 0; | 390 | return 0; |
375 | } | 391 | } |
376 | 392 | ||
@@ -393,6 +409,9 @@ static void rockchip_spi_dma_txcb(void *data) | |||
393 | unsigned long flags; | 409 | unsigned long flags; |
394 | struct rockchip_spi *rs = data; | 410 | struct rockchip_spi *rs = data; |
395 | 411 | ||
412 | /* Wait until the FIFO data completely. */ | ||
413 | wait_for_idle(rs); | ||
414 | |||
396 | spin_lock_irqsave(&rs->lock, flags); | 415 | spin_lock_irqsave(&rs->lock, flags); |
397 | 416 | ||
398 | rs->state &= ~TXBUSY; | 417 | rs->state &= ~TXBUSY; |
@@ -536,11 +555,6 @@ static int rockchip_spi_transfer_one( | |||
536 | rs->tx_sg = xfer->tx_sg; | 555 | rs->tx_sg = xfer->tx_sg; |
537 | rs->rx_sg = xfer->rx_sg; | 556 | rs->rx_sg = xfer->rx_sg; |
538 | 557 | ||
539 | /* Delay until the FIFO data completely */ | ||
540 | if (xfer->tx_buf) | ||
541 | xfer->delay_usecs | ||
542 | = rs->fifo_len * rs->bpw * 1000000 / rs->speed; | ||
543 | |||
544 | if (rs->tx && rs->rx) | 558 | if (rs->tx && rs->rx) |
545 | rs->tmode = CR0_XFM_TR; | 559 | rs->tmode = CR0_XFM_TR; |
546 | else if (rs->tx) | 560 | else if (rs->tx) |