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 | |
| 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>
| -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) |
