diff options
| -rw-r--r-- | drivers/spi/amba-pl022.c | 18 |
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 | /* |
