aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/spi/spi-rockchip.c
diff options
context:
space:
mode:
authorAddy Ke <addy.ke@rock-chips.com>2014-10-15 07:26:18 -0400
committerMark Brown <broonie@kernel.org>2014-10-15 09:05:38 -0400
commitc28be31b11f56b3bb62490dfe5304eaa2724afc2 (patch)
treea6d6abddeb38faee5fcebe670e949b2220264e51 /drivers/spi/spi-rockchip.c
parentf9cfd52262d36a55b39d41e2b0faae632ad57e4c (diff)
spi/rockchip: fix bug that cause spi transfer timed out in DMA duplex mode
In rx mode, dma must be prepared before spi is enabled. But in tx and tr mode, spi must be enabled first. Signed-off-by: Addy Ke <addy.ke@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.c34
1 files changed, 23 insertions, 11 deletions
diff --git a/drivers/spi/spi-rockchip.c b/drivers/spi/spi-rockchip.c
index 3044c6c27332..153269b60564 100644
--- a/drivers/spi/spi-rockchip.c
+++ b/drivers/spi/spi-rockchip.c
@@ -328,6 +328,8 @@ static int rockchip_spi_unprepare_message(struct spi_master *master,
328 328
329 spin_unlock_irqrestore(&rs->lock, flags); 329 spin_unlock_irqrestore(&rs->lock, flags);
330 330
331 spi_enable_chip(rs, 0);
332
331 return 0; 333 return 0;
332} 334}
333 335
@@ -384,6 +386,8 @@ static int rockchip_spi_pio_transfer(struct rockchip_spi *rs)
384 if (rs->tx) 386 if (rs->tx)
385 wait_for_idle(rs); 387 wait_for_idle(rs);
386 388
389 spi_enable_chip(rs, 0);
390
387 return 0; 391 return 0;
388} 392}
389 393
@@ -395,8 +399,10 @@ static void rockchip_spi_dma_rxcb(void *data)
395 spin_lock_irqsave(&rs->lock, flags); 399 spin_lock_irqsave(&rs->lock, flags);
396 400
397 rs->state &= ~RXBUSY; 401 rs->state &= ~RXBUSY;
398 if (!(rs->state & TXBUSY)) 402 if (!(rs->state & TXBUSY)) {
403 spi_enable_chip(rs, 0);
399 spi_finalize_current_transfer(rs->master); 404 spi_finalize_current_transfer(rs->master);
405 }
400 406
401 spin_unlock_irqrestore(&rs->lock, flags); 407 spin_unlock_irqrestore(&rs->lock, flags);
402} 408}
@@ -512,8 +518,6 @@ static void rockchip_spi_config(struct rockchip_spi *rs)
512 div = max_t(u32, rs->max_freq / rs->speed, 1); 518 div = max_t(u32, rs->max_freq / rs->speed, 1);
513 div = (div + 1) & 0xfffe; 519 div = (div + 1) & 0xfffe;
514 520
515 spi_enable_chip(rs, 0);
516
517 writel_relaxed(cr0, rs->regs + ROCKCHIP_SPI_CTRLR0); 521 writel_relaxed(cr0, rs->regs + ROCKCHIP_SPI_CTRLR0);
518 522
519 writel_relaxed(rs->len - 1, rs->regs + ROCKCHIP_SPI_CTRLR1); 523 writel_relaxed(rs->len - 1, rs->regs + ROCKCHIP_SPI_CTRLR1);
@@ -527,8 +531,6 @@ static void rockchip_spi_config(struct rockchip_spi *rs)
527 spi_set_clk(rs, div); 531 spi_set_clk(rs, div);
528 532
529 dev_dbg(rs->dev, "cr0 0x%x, div %d\n", cr0, div); 533 dev_dbg(rs->dev, "cr0 0x%x, div %d\n", cr0, div);
530
531 spi_enable_chip(rs, 1);
532} 534}
533 535
534static int rockchip_spi_transfer_one( 536static int rockchip_spi_transfer_one(
@@ -536,7 +538,7 @@ static int rockchip_spi_transfer_one(
536 struct spi_device *spi, 538 struct spi_device *spi,
537 struct spi_transfer *xfer) 539 struct spi_transfer *xfer)
538{ 540{
539 int ret = 0; 541 int ret = 1;
540 struct rockchip_spi *rs = spi_master_get_devdata(master); 542 struct rockchip_spi *rs = spi_master_get_devdata(master);
541 543
542 WARN_ON(readl_relaxed(rs->regs + ROCKCHIP_SPI_SSIENR) && 544 WARN_ON(readl_relaxed(rs->regs + ROCKCHIP_SPI_SSIENR) &&
@@ -568,17 +570,27 @@ static int rockchip_spi_transfer_one(
568 rs->tmode = CR0_XFM_RO; 570 rs->tmode = CR0_XFM_RO;
569 571
570 /* we need prepare dma before spi was enabled */ 572 /* we need prepare dma before spi was enabled */
571 if (master->can_dma && master->can_dma(master, spi, xfer)) { 573 if (master->can_dma && master->can_dma(master, spi, xfer))
572 rs->use_dma = 1; 574 rs->use_dma = 1;
573 rockchip_spi_prepare_dma(rs); 575 else
574 } else {
575 rs->use_dma = 0; 576 rs->use_dma = 0;
576 }
577 577
578 rockchip_spi_config(rs); 578 rockchip_spi_config(rs);
579 579
580 if (!rs->use_dma) 580 if (rs->use_dma) {
581 if (rs->tmode == CR0_XFM_RO) {
582 /* rx: dma must be prepared first */
583 rockchip_spi_prepare_dma(rs);
584 spi_enable_chip(rs, 1);
585 } else {
586 /* tx or tr: spi must be enabled first */
587 spi_enable_chip(rs, 1);
588 rockchip_spi_prepare_dma(rs);
589 }
590 } else {
591 spi_enable_chip(rs, 1);
581 ret = rockchip_spi_pio_transfer(rs); 592 ret = rockchip_spi_pio_transfer(rs);
593 }
582 594
583 return ret; 595 return ret;
584} 596}