aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/spi/amba-pl022.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/spi/amba-pl022.c')
-rw-r--r--drivers/spi/amba-pl022.c18
1 files changed, 12 insertions, 6 deletions
diff --git a/drivers/spi/amba-pl022.c b/drivers/spi/amba-pl022.c
index ff5bbb9c43c9..9aeb68113100 100644
--- a/drivers/spi/amba-pl022.c
+++ b/drivers/spi/amba-pl022.c
@@ -363,6 +363,7 @@ struct pl022 {
363 void *rx_end; 363 void *rx_end;
364 enum ssp_reading read; 364 enum ssp_reading read;
365 enum ssp_writing write; 365 enum ssp_writing write;
366 u32 exp_fifo_level;
366}; 367};
367 368
368/** 369/**
@@ -501,6 +502,9 @@ static int flush(struct pl022 *pl022)
501 while (readw(SSP_SR(pl022->virtbase)) & SSP_SR_MASK_RNE) 502 while (readw(SSP_SR(pl022->virtbase)) & SSP_SR_MASK_RNE)
502 readw(SSP_DR(pl022->virtbase)); 503 readw(SSP_DR(pl022->virtbase));
503 } while ((readw(SSP_SR(pl022->virtbase)) & SSP_SR_MASK_BSY) && limit--); 504 } while ((readw(SSP_SR(pl022->virtbase)) & SSP_SR_MASK_BSY) && limit--);
505
506 pl022->exp_fifo_level = 0;
507
504 return limit; 508 return limit;
505} 509}
506 510
@@ -583,10 +587,9 @@ static void readwriter(struct pl022 *pl022)
583 * errons in 8bit wide transfers on ARM variants (just 8 words 587 * errons in 8bit wide transfers on ARM variants (just 8 words
584 * FIFO, means only 8x8 = 64 bits in FIFO) at least. 588 * FIFO, means only 8x8 = 64 bits in FIFO) at least.
585 * 589 *
586 * FIXME: currently we have no logic to account for this. 590 * To prevent this issue, the TX FIFO is only filled to the
587 * perhaps there is even something broken in HW regarding 591 * unused RX FIFO fill length, regardless of what the TX
588 * 8bit transfers (it doesn't fail on 16bit) so this needs 592 * FIFO status flag indicates.
589 * more investigation...
590 */ 593 */
591 dev_dbg(&pl022->adev->dev, 594 dev_dbg(&pl022->adev->dev,
592 "%s, rx: %p, rxend: %p, tx: %p, txend: %p\n", 595 "%s, rx: %p, rxend: %p, tx: %p, txend: %p\n",
@@ -613,11 +616,12 @@ static void readwriter(struct pl022 *pl022)
613 break; 616 break;
614 } 617 }
615 pl022->rx += (pl022->cur_chip->n_bytes); 618 pl022->rx += (pl022->cur_chip->n_bytes);
619 pl022->exp_fifo_level--;
616 } 620 }
617 /* 621 /*
618 * Write as much as you can, while keeping an eye on the RX FIFO! 622 * Write as much as possible up to the RX FIFO size
619 */ 623 */
620 while ((readw(SSP_SR(pl022->virtbase)) & SSP_SR_MASK_TNF) 624 while ((pl022->exp_fifo_level < pl022->vendor->fifodepth)
621 && (pl022->tx < pl022->tx_end)) { 625 && (pl022->tx < pl022->tx_end)) {
622 switch (pl022->write) { 626 switch (pl022->write) {
623 case WRITING_NULL: 627 case WRITING_NULL:
@@ -634,6 +638,7 @@ static void readwriter(struct pl022 *pl022)
634 break; 638 break;
635 } 639 }
636 pl022->tx += (pl022->cur_chip->n_bytes); 640 pl022->tx += (pl022->cur_chip->n_bytes);
641 pl022->exp_fifo_level++;
637 /* 642 /*
638 * This inner reader takes care of things appearing in the RX 643 * This inner reader takes care of things appearing in the RX
639 * FIFO as we're transmitting. This will happen a lot since the 644 * FIFO as we're transmitting. This will happen a lot since the
@@ -660,6 +665,7 @@ static void readwriter(struct pl022 *pl022)
660 break; 665 break;
661 } 666 }
662 pl022->rx += (pl022->cur_chip->n_bytes); 667 pl022->rx += (pl022->cur_chip->n_bytes);
668 pl022->exp_fifo_level--;
663 } 669 }
664 } 670 }
665 /* 671 /*