]> Pileus Git - ~andy/linux/blobdiff - drivers/dma/ioat_dma.c
spi: au1550_spi full duplex dma fix
[~andy/linux] / drivers / dma / ioat_dma.c
index 43b8cefad2c6ddfb57276e53a6ce19710677ea5a..ecd743f7cc617b9921b7d08e553da0264d8c401c 100644 (file)
@@ -33,6 +33,7 @@
 #include <linux/delay.h>
 #include <linux/dma-mapping.h>
 #include <linux/workqueue.h>
+#include <linux/i7300_idle.h>
 #include "ioatdma.h"
 #include "ioatdma_registers.h"
 #include "ioatdma_hw.h"
@@ -171,8 +172,10 @@ static int ioat_dma_enumerate_channels(struct ioatdma_device *device)
        xfercap_scale = readb(device->reg_base + IOAT_XFERCAP_OFFSET);
        xfercap = (xfercap_scale == 0 ? -1 : (1UL << xfercap_scale));
 
-#if CONFIG_I7300_IDLE_IOAT_CHANNEL
-       device->common.chancnt--;
+#ifdef  CONFIG_I7300_IDLE_IOAT_CHANNEL
+       if (i7300_idle_platform_probe(NULL, NULL) == 0) {
+               device->common.chancnt--;
+       }
 #endif
        for (i = 0; i < device->common.chancnt; i++) {
                ioat_chan = kzalloc(sizeof(*ioat_chan), GFP_KERNEL);
@@ -522,7 +525,7 @@ static dma_cookie_t ioat1_tx_submit(struct dma_async_tx_descriptor *tx)
        }
 
        hw->ctl = IOAT_DMA_DESCRIPTOR_CTL_CP_STS;
-       if (new->async_tx.callback) {
+       if (first->async_tx.callback) {
                hw->ctl |= IOAT_DMA_DESCRIPTOR_CTL_INT_GN;
                if (first != new) {
                        /* move callback into to last desc */
@@ -614,7 +617,7 @@ static dma_cookie_t ioat2_tx_submit(struct dma_async_tx_descriptor *tx)
        }
 
        hw->ctl |= IOAT_DMA_DESCRIPTOR_CTL_CP_STS;
-       if (new->async_tx.callback) {
+       if (first->async_tx.callback) {
                hw->ctl |= IOAT_DMA_DESCRIPTOR_CTL_INT_GN;
                if (first != new) {
                        /* move callback into to last desc */
@@ -804,6 +807,12 @@ static void ioat_dma_free_chan_resources(struct dma_chan *chan)
        struct ioat_desc_sw *desc, *_desc;
        int in_use_descs = 0;
 
+       /* Before freeing channel resources first check
+        * if they have been previously allocated for this channel.
+        */
+       if (ioat_chan->desccount == 0)
+               return;
+
        tasklet_disable(&ioat_chan->cleanup_task);
        ioat_dma_memcpy_cleanup(ioat_chan);
 
@@ -866,6 +875,7 @@ static void ioat_dma_free_chan_resources(struct dma_chan *chan)
        ioat_chan->last_completion = ioat_chan->completion_addr = 0;
        ioat_chan->pending = 0;
        ioat_chan->dmacount = 0;
+       ioat_chan->desccount = 0;
        ioat_chan->watchdog_completion = 0;
        ioat_chan->last_compl_desc_addr_hw = 0;
        ioat_chan->watchdog_tcp_cookie =