|
@@ -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 */
|