summaryrefslogtreecommitdiffstats
path: root/drivers/spi/spi_bfin5xx.c
diff options
context:
space:
mode:
authorMike Frysinger <vapier.adi@gmail.com>2009-04-07 04:00:41 +0200
committerLinus Torvalds <torvalds@linux-foundation.org>2009-04-07 17:31:05 +0200
commit11d6f5995137ba4dc49e9337185ac0a8753f8f69 (patch)
tree36f45d8415d190db572be32dd12ec24424c98ad5 /drivers/spi/spi_bfin5xx.c
parentBlackfin SPI Driver: SPI slave select code cleanup (diff)
downloadlinux-11d6f5995137ba4dc49e9337185ac0a8753f8f69.tar.xz
linux-11d6f5995137ba4dc49e9337185ac0a8753f8f69.zip
Blackfin SPI Driver: get dma working for SPI flashes
When using a BF533-STAMP here with a W25X10 SPI flash. It works fine when enable_dma is disabled, but doesn't work at all when turning DMA on. We get just 0xff bytes back when trying to read the device. Change the code around so that it programs the SPI first and then enables DMA, it seems to work a lot better ... Signed-off-by: Mike Frysinger <vapier.adi@gmail.com> Signed-off-by: Bryan Wu <cooloney@kernel.org> Acked-by: David Brownell <dbrownell@users.sourceforge.net> Cc: David Brownell <david-b@pacbell.net> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'drivers/spi/spi_bfin5xx.c')
-rw-r--r--drivers/spi/spi_bfin5xx.c26
1 files changed, 16 insertions, 10 deletions
diff --git a/drivers/spi/spi_bfin5xx.c b/drivers/spi/spi_bfin5xx.c
index b797ece0b10c..88dee87fc420 100644
--- a/drivers/spi/spi_bfin5xx.c
+++ b/drivers/spi/spi_bfin5xx.c
@@ -761,11 +761,10 @@ static void pump_transfers(unsigned long data)
if (!full_duplex && drv_data->cur_chip->enable_dma
&& drv_data->len > 6) {
- unsigned long dma_start_addr;
+ unsigned long dma_start_addr, flags;
disable_dma(drv_data->dma_channel);
clear_dma_irqstat(drv_data->dma_channel);
- bfin_spi_disable(drv_data);
/* config dma channel */
dev_dbg(&drv_data->pdev->dev, "doing dma transfer\n");
@@ -796,8 +795,7 @@ static void pump_transfers(unsigned long data)
enable_dma(drv_data->dma_channel);
/* start SPI transfer */
- write_CTRL(drv_data,
- (cr | BIT_CTL_TIMOD_DMA_TX | BIT_CTL_ENABLE));
+ write_CTRL(drv_data, cr | BIT_CTL_TIMOD_DMA_TX);
/* just return here, there can only be one transfer
* in this mode
@@ -842,14 +840,22 @@ static void pump_transfers(unsigned long data)
} else
BUG();
- /* start dma */
- dma_enable_irq(drv_data->dma_channel);
- set_dma_config(drv_data->dma_channel, dma_config);
+ /* oh man, here there be monsters ... and i dont mean the
+ * fluffy cute ones from pixar, i mean the kind that'll eat
+ * your data, kick your dog, and love it all. do *not* try
+ * and change these lines unless you (1) heavily test DMA
+ * with SPI flashes on a loaded system (e.g. ping floods),
+ * (2) know just how broken the DMA engine interaction with
+ * the SPI peripheral is, and (3) have someone else to blame
+ * when you screw it all up anyways.
+ */
set_dma_start_addr(drv_data->dma_channel, dma_start_addr);
+ set_dma_config(drv_data->dma_channel, dma_config);
+ local_irq_save(flags);
enable_dma(drv_data->dma_channel);
-
- /* start SPI transfer */
- write_CTRL(drv_data, (cr | BIT_CTL_ENABLE));
+ write_CTRL(drv_data, cr);
+ dma_enable_irq(drv_data->dma_channel);
+ local_irq_restore(flags);
} else {
/* IO mode write then read */