]> Pileus Git - ~andy/linux/commitdiff
dma: imx-sdma: keep the callbacks invoked in the tasklet
authorHuang Shijie <b32955@freescale.com>
Sat, 28 Apr 2012 10:15:42 +0000 (18:15 +0800)
committerVinod Koul <vinod.koul@linux.intel.com>
Fri, 11 May 2012 05:38:10 +0000 (11:08 +0530)
The current code keeps the callbacks invoked from interrupt context, this
does not conform to the Documentation/dmaengine.txt.

So add tasklet support to fix this issue.

Signed-off-by: Huang Shijie <b32955@freescale.com>
Signed-off-by: Vinod Koul <vinod.koul@linux.intel.com>
drivers/dma/imx-sdma.c

index d3e38e28bb6b19a480eb1b05b732a0dc2f40eb7f..5a457777f5c016991fafa91127948bf8130539f7 100644 (file)
@@ -271,6 +271,7 @@ struct sdma_channel {
        enum dma_status                 status;
        unsigned int                    chn_count;
        unsigned int                    chn_real_count;
+       struct tasklet_struct           tasklet;
 };
 
 #define IMX_DMA_SG_LOOP                BIT(0)
@@ -534,8 +535,10 @@ static void mxc_sdma_handle_channel_normal(struct sdma_channel *sdmac)
                sdmac->desc.callback(sdmac->desc.callback_param);
 }
 
-static void mxc_sdma_handle_channel(struct sdma_channel *sdmac)
+static void sdma_tasklet(unsigned long data)
 {
+       struct sdma_channel *sdmac = (struct sdma_channel *) data;
+
        complete(&sdmac->done);
 
        /* not interested in channel 0 interrupts */
@@ -560,7 +563,7 @@ static irqreturn_t sdma_int_handler(int irq, void *dev_id)
                int channel = fls(stat) - 1;
                struct sdma_channel *sdmac = &sdma->channel[channel];
 
-               mxc_sdma_handle_channel(sdmac);
+               tasklet_schedule(&sdmac->tasklet);
 
                __clear_bit(channel, &stat);
        }
@@ -1359,6 +1362,8 @@ static int __init sdma_probe(struct platform_device *pdev)
                dma_cookie_init(&sdmac->chan);
                sdmac->channel = i;
 
+               tasklet_init(&sdmac->tasklet, sdma_tasklet,
+                            (unsigned long) sdmac);
                /*
                 * Add the channel to the DMAC list. Do not add channel 0 though
                 * because we need it internally in the SDMA driver. This also means