summaryrefslogtreecommitdiffstats
path: root/drivers/spi/spi_bfin5xx.c
diff options
context:
space:
mode:
authorBryan Wu <bryan.wu@analog.com>2007-06-11 17:34:17 +0800
committerBryan Wu <bryan.wu@analog.com>2007-06-11 17:34:17 +0800
commitd6fe89b0630080e2bd6ece20ff7b1b5c2647ed62 (patch)
treeebccbeacb2e2fa2c5ee5319e60465cdcb7194999 /drivers/spi/spi_bfin5xx.c
parent27bb9e79bcfedc1888d23c3c212c189fa8534fe7 (diff)
downloadlinux-d6fe89b0630080e2bd6ece20ff7b1b5c2647ed62.tar.gz
linux-d6fe89b0630080e2bd6ece20ff7b1b5c2647ed62.tar.bz2
linux-d6fe89b0630080e2bd6ece20ff7b1b5c2647ed62.zip
Blackfin SPI driver: fix bug SPI DMA incomplete transmission
SPI writes intermittently drop bytes at end of DMA transfer http://blackfin.uclinux.org/gf/project/uclinux-dist/tracker/?action=TrackerItemEdit&tracker_item_id=3205 http://blackfin.uclinux.org/gf/project/uclinux-dist/tracker/?action=TrackerItemEdit&tracker_item_id=2892 Signed-off-by: Mike Frysinger <michael.frysinger@analog.com> Signed-off-by: Bryan Wu <bryan.wu@analog.com>
Diffstat (limited to 'drivers/spi/spi_bfin5xx.c')
-rw-r--r--drivers/spi/spi_bfin5xx.c15
1 files changed, 10 insertions, 5 deletions
diff --git a/drivers/spi/spi_bfin5xx.c b/drivers/spi/spi_bfin5xx.c
index a2d4884752ef..48587c27050d 100644
--- a/drivers/spi/spi_bfin5xx.c
+++ b/drivers/spi/spi_bfin5xx.c
@@ -582,14 +582,19 @@ static irqreturn_t dma_irq_handler(int irq, void *dev_id)
dev_dbg(&drv_data->pdev->dev, "in dma_irq_handler\n");
clear_dma_irqstat(CH_SPI);
+ /* Wait for DMA to complete */
+ while (get_dma_curr_irqstat(CH_SPI) & DMA_RUN)
+ continue;
+
/*
- * wait for the last transaction shifted out. yes, these two
- * while loops are supposed to be the same (see the HRM).
+ * wait for the last transaction shifted out. HRM states:
+ * at this point there may still be data in the SPI DMA FIFO waiting
+ * to be transmitted ... software needs to poll TXS in the SPI_STAT
+ * register until it goes low for 2 successive reads
*/
if (drv_data->tx != NULL) {
- while (bfin_read_SPI_STAT() & TXS)
- continue;
- while (bfin_read_SPI_STAT() & TXS)
+ while ((bfin_read_SPI_STAT() & TXS) ||
+ (bfin_read_SPI_STAT() & TXS))
continue;
}