aboutsummaryrefslogtreecommitdiff
path: root/drivers/spi
diff options
context:
space:
mode:
authorLinus Torvalds2010-03-01 09:15:15 -0800
committerLinus Torvalds2010-03-01 09:15:15 -0800
commitac0f6f927db539e03e1f3f61bcd4ed57d5cde7a9 (patch)
tree816e5ac643b15c2050c64a7075f0f7e13d86ea09 /drivers/spi
parentb1bf9368407ae7e89d8a005bb40beb70a41df539 (diff)
parent9f33be2c3a80bdc2cc08342dd77fac87652e0548 (diff)
Merge branch 'for-linus' of master.kernel.org:/home/rmk/linux-2.6-arm
* 'for-linus' of master.kernel.org:/home/rmk/linux-2.6-arm: (100 commits) ARM: Eliminate decompressor -Dstatic= PIC hack ARM: 5958/1: ARM: U300: fix inverted clk round rate ARM: 5956/1: misplaced parentheses ARM: 5955/1: ep93xx: move timer defines into core.c and document ARM: 5954/1: ep93xx: move gpio interrupt support to gpio.c ARM: 5953/1: ep93xx: fix broken build of clock.c ARM: 5952/1: ARM: MM: Add ARM_L1_CACHE_SHIFT_6 for handle inside each ARCH Kconfig ARM: 5949/1: NUC900 add gpio virtual memory map ARM: 5948/1: Enable timer0 to time4 clock support for nuc910 ARM: 5940/2: ARM: MMCI: remove custom DBG macro and printk ARM: make_coherent(): fix problems with highpte, part 2 MM: Pass a PTE pointer to update_mmu_cache() rather than the PTE itself ARM: 5945/1: ep93xx: include correct irq.h in core.c ARM: 5933/1: amba-pl011: support hardware flow control ARM: 5930/1: Add PKMAP area description to memory.txt. ARM: 5929/1: Add checks to detect overlap of memory regions. ARM: 5928/1: Change type of VMALLOC_END to unsigned long. ARM: 5927/1: Make delimiters of DMA area globally visibly. ARM: 5926/1: Add "Virtual kernel memory..." printout. ARM: 5920/1: OMAP4: Enable L2 Cache ... Fix up trivial conflict in arch/arm/mach-mx25/clock.c
Diffstat (limited to 'drivers/spi')
-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 {
void *rx_end;
enum ssp_reading read;
enum ssp_writing write;
+ u32 exp_fifo_level;
};
/**
@@ -501,6 +502,9 @@ static int flush(struct pl022 *pl022)
while (readw(SSP_SR(pl022->virtbase)) & SSP_SR_MASK_RNE)
readw(SSP_DR(pl022->virtbase));
} while ((readw(SSP_SR(pl022->virtbase)) & SSP_SR_MASK_BSY) && limit--);
+
+ pl022->exp_fifo_level = 0;
+
return limit;
}
@@ -583,10 +587,9 @@ static void readwriter(struct pl022 *pl022)
* errons in 8bit wide transfers on ARM variants (just 8 words
* FIFO, means only 8x8 = 64 bits in FIFO) at least.
*
- * FIXME: currently we have no logic to account for this.
- * perhaps there is even something broken in HW regarding
- * 8bit transfers (it doesn't fail on 16bit) so this needs
- * more investigation...
+ * To prevent this issue, the TX FIFO is only filled to the
+ * unused RX FIFO fill length, regardless of what the TX
+ * FIFO status flag indicates.
*/
dev_dbg(&pl022->adev->dev,
"%s, rx: %p, rxend: %p, tx: %p, txend: %p\n",
@@ -613,11 +616,12 @@ static void readwriter(struct pl022 *pl022)
break;
}
pl022->rx += (pl022->cur_chip->n_bytes);
+ pl022->exp_fifo_level--;
}
/*
- * Write as much as you can, while keeping an eye on the RX FIFO!
+ * Write as much as possible up to the RX FIFO size
*/
- while ((readw(SSP_SR(pl022->virtbase)) & SSP_SR_MASK_TNF)
+ while ((pl022->exp_fifo_level < pl022->vendor->fifodepth)
&& (pl022->tx < pl022->tx_end)) {
switch (pl022->write) {
case WRITING_NULL:
@@ -634,6 +638,7 @@ static void readwriter(struct pl022 *pl022)
break;
}
pl022->tx += (pl022->cur_chip->n_bytes);
+ pl022->exp_fifo_level++;
/*
* This inner reader takes care of things appearing in the RX
* FIFO as we're transmitting. This will happen a lot since the
@@ -660,6 +665,7 @@ static void readwriter(struct pl022 *pl022)
break;
}
pl022->rx += (pl022->cur_chip->n_bytes);
+ pl022->exp_fifo_level--;
}
}
/*