]> www.pilppa.org Git - linux-2.6-omap-h63xx.git/blobdiff - drivers/spi/spi_bfin5xx.c
Blackfin SPI Driver: get dma working for SPI flashes
[linux-2.6-omap-h63xx.git] / drivers / spi / spi_bfin5xx.c
index b797ece0b10c655b8282f9378b7967ae2c313e8b..88dee87fc420fa81dc310d3ad18e68a46ef31ca8 100644 (file)
@@ -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 */