diff options
author | Andrea Bastoni <bastoni@cs.unc.edu> | 2010-05-30 19:16:45 -0400 |
---|---|---|
committer | Andrea Bastoni <bastoni@cs.unc.edu> | 2010-05-30 19:16:45 -0400 |
commit | ada47b5fe13d89735805b566185f4885f5a3f750 (patch) | |
tree | 644b88f8a71896307d71438e9b3af49126ffb22b /drivers/spi/amba-pl022.c | |
parent | 43e98717ad40a4ae64545b5ba047c7b86aa44f4f (diff) | |
parent | 3280f21d43ee541f97f8cda5792150d2dbec20d5 (diff) |
Merge branch 'wip-2.6.34' into old-private-masterarchived-private-master
Diffstat (limited to 'drivers/spi/amba-pl022.c')
-rw-r--r-- | drivers/spi/amba-pl022.c | 19 |
1 files changed, 13 insertions, 6 deletions
diff --git a/drivers/spi/amba-pl022.c b/drivers/spi/amba-pl022.c index ff5bbb9c43c9..e9aeee16d922 100644 --- a/drivers/spi/amba-pl022.c +++ b/drivers/spi/amba-pl022.c | |||
@@ -44,6 +44,7 @@ | |||
44 | #include <linux/amba/bus.h> | 44 | #include <linux/amba/bus.h> |
45 | #include <linux/amba/pl022.h> | 45 | #include <linux/amba/pl022.h> |
46 | #include <linux/io.h> | 46 | #include <linux/io.h> |
47 | #include <linux/slab.h> | ||
47 | 48 | ||
48 | /* | 49 | /* |
49 | * This macro is used to define some register default values. | 50 | * This macro is used to define some register default values. |
@@ -363,6 +364,7 @@ struct pl022 { | |||
363 | void *rx_end; | 364 | void *rx_end; |
364 | enum ssp_reading read; | 365 | enum ssp_reading read; |
365 | enum ssp_writing write; | 366 | enum ssp_writing write; |
367 | u32 exp_fifo_level; | ||
366 | }; | 368 | }; |
367 | 369 | ||
368 | /** | 370 | /** |
@@ -501,6 +503,9 @@ static int flush(struct pl022 *pl022) | |||
501 | while (readw(SSP_SR(pl022->virtbase)) & SSP_SR_MASK_RNE) | 503 | while (readw(SSP_SR(pl022->virtbase)) & SSP_SR_MASK_RNE) |
502 | readw(SSP_DR(pl022->virtbase)); | 504 | readw(SSP_DR(pl022->virtbase)); |
503 | } while ((readw(SSP_SR(pl022->virtbase)) & SSP_SR_MASK_BSY) && limit--); | 505 | } while ((readw(SSP_SR(pl022->virtbase)) & SSP_SR_MASK_BSY) && limit--); |
506 | |||
507 | pl022->exp_fifo_level = 0; | ||
508 | |||
504 | return limit; | 509 | return limit; |
505 | } | 510 | } |
506 | 511 | ||
@@ -583,10 +588,9 @@ static void readwriter(struct pl022 *pl022) | |||
583 | * errons in 8bit wide transfers on ARM variants (just 8 words | 588 | * errons in 8bit wide transfers on ARM variants (just 8 words |
584 | * FIFO, means only 8x8 = 64 bits in FIFO) at least. | 589 | * FIFO, means only 8x8 = 64 bits in FIFO) at least. |
585 | * | 590 | * |
586 | * FIXME: currently we have no logic to account for this. | 591 | * To prevent this issue, the TX FIFO is only filled to the |
587 | * perhaps there is even something broken in HW regarding | 592 | * unused RX FIFO fill length, regardless of what the TX |
588 | * 8bit transfers (it doesn't fail on 16bit) so this needs | 593 | * FIFO status flag indicates. |
589 | * more investigation... | ||
590 | */ | 594 | */ |
591 | dev_dbg(&pl022->adev->dev, | 595 | dev_dbg(&pl022->adev->dev, |
592 | "%s, rx: %p, rxend: %p, tx: %p, txend: %p\n", | 596 | "%s, rx: %p, rxend: %p, tx: %p, txend: %p\n", |
@@ -613,11 +617,12 @@ static void readwriter(struct pl022 *pl022) | |||
613 | break; | 617 | break; |
614 | } | 618 | } |
615 | pl022->rx += (pl022->cur_chip->n_bytes); | 619 | pl022->rx += (pl022->cur_chip->n_bytes); |
620 | pl022->exp_fifo_level--; | ||
616 | } | 621 | } |
617 | /* | 622 | /* |
618 | * Write as much as you can, while keeping an eye on the RX FIFO! | 623 | * Write as much as possible up to the RX FIFO size |
619 | */ | 624 | */ |
620 | while ((readw(SSP_SR(pl022->virtbase)) & SSP_SR_MASK_TNF) | 625 | while ((pl022->exp_fifo_level < pl022->vendor->fifodepth) |
621 | && (pl022->tx < pl022->tx_end)) { | 626 | && (pl022->tx < pl022->tx_end)) { |
622 | switch (pl022->write) { | 627 | switch (pl022->write) { |
623 | case WRITING_NULL: | 628 | case WRITING_NULL: |
@@ -634,6 +639,7 @@ static void readwriter(struct pl022 *pl022) | |||
634 | break; | 639 | break; |
635 | } | 640 | } |
636 | pl022->tx += (pl022->cur_chip->n_bytes); | 641 | pl022->tx += (pl022->cur_chip->n_bytes); |
642 | pl022->exp_fifo_level++; | ||
637 | /* | 643 | /* |
638 | * This inner reader takes care of things appearing in the RX | 644 | * This inner reader takes care of things appearing in the RX |
639 | * FIFO as we're transmitting. This will happen a lot since the | 645 | * FIFO as we're transmitting. This will happen a lot since the |
@@ -660,6 +666,7 @@ static void readwriter(struct pl022 *pl022) | |||
660 | break; | 666 | break; |
661 | } | 667 | } |
662 | pl022->rx += (pl022->cur_chip->n_bytes); | 668 | pl022->rx += (pl022->cur_chip->n_bytes); |
669 | pl022->exp_fifo_level--; | ||
663 | } | 670 | } |
664 | } | 671 | } |
665 | /* | 672 | /* |