X-Git-Url: https://git.wh0rd.org/?p=patches.git;a=blobdiff_plain;f=spi-flash-dma.patch;fp=spi-flash-dma.patch;h=492f37ab1a8f6215cb52140eed36810eeac29f08;hp=0000000000000000000000000000000000000000;hb=b77ff2bc4309cd456bbee6a5eb08dc2426619f56;hpb=5e993f12c1f493f3b518b651ebb3861e2a67673d diff --git a/spi-flash-dma.patch b/spi-flash-dma.patch new file mode 100644 index 0000000..492f37a --- /dev/null +++ b/spi-flash-dma.patch @@ -0,0 +1,57 @@ +--- spi_bfin5xx.c (revision 5493) ++++ spi_bfin5xx.c (working copy) +@@ -619,6 +619,7 @@ static void pump_transfers(unsigned long + struct spi_transfer *transfer = NULL; + struct spi_transfer *previous = NULL; + struct chip_data *chip = NULL; ++ unsigned long flags; + u8 width; + u16 cr, dma_width, dma_config; + u32 tranf_success = 1; +@@ -766,7 +767,6 @@ static void pump_transfers(unsigned long + + 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"); +@@ -797,8 +797,7 @@ static void pump_transfers(unsigned long + 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 +@@ -840,14 +839,22 @@ static void pump_transfers(unsigned long + } 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 */