aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/dma
diff options
context:
space:
mode:
authorHuang Shijie <b32955@freescale.com>2012-04-28 06:15:42 -0400
committerVinod Koul <vinod.koul@linux.intel.com>2012-05-11 01:38:10 -0400
commitabd9ccc84c35cf1e296335a7b655bba40c92386c (patch)
tree22c39af6cc57d6371cf4d74e76c04c60f979e9b5 /drivers/dma
parentd3f797d93e593aa891f5b04a404b4ab45fd0e66a (diff)
dma: imx-sdma: keep the callbacks invoked in the tasklet
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>
Diffstat (limited to 'drivers/dma')
-rw-r--r--drivers/dma/imx-sdma.c9
1 files changed, 7 insertions, 2 deletions
diff --git a/drivers/dma/imx-sdma.c b/drivers/dma/imx-sdma.c
index d3e38e28bb6..5a457777f5c 100644
--- a/drivers/dma/imx-sdma.c
+++ b/drivers/dma/imx-sdma.c
@@ -271,6 +271,7 @@ struct sdma_channel {
271 enum dma_status status; 271 enum dma_status status;
272 unsigned int chn_count; 272 unsigned int chn_count;
273 unsigned int chn_real_count; 273 unsigned int chn_real_count;
274 struct tasklet_struct tasklet;
274}; 275};
275 276
276#define IMX_DMA_SG_LOOP BIT(0) 277#define IMX_DMA_SG_LOOP BIT(0)
@@ -534,8 +535,10 @@ static void mxc_sdma_handle_channel_normal(struct sdma_channel *sdmac)
534 sdmac->desc.callback(sdmac->desc.callback_param); 535 sdmac->desc.callback(sdmac->desc.callback_param);
535} 536}
536 537
537static void mxc_sdma_handle_channel(struct sdma_channel *sdmac) 538static void sdma_tasklet(unsigned long data)
538{ 539{
540 struct sdma_channel *sdmac = (struct sdma_channel *) data;
541
539 complete(&sdmac->done); 542 complete(&sdmac->done);
540 543
541 /* not interested in channel 0 interrupts */ 544 /* not interested in channel 0 interrupts */
@@ -560,7 +563,7 @@ static irqreturn_t sdma_int_handler(int irq, void *dev_id)
560 int channel = fls(stat) - 1; 563 int channel = fls(stat) - 1;
561 struct sdma_channel *sdmac = &sdma->channel[channel]; 564 struct sdma_channel *sdmac = &sdma->channel[channel];
562 565
563 mxc_sdma_handle_channel(sdmac); 566 tasklet_schedule(&sdmac->tasklet);
564 567
565 __clear_bit(channel, &stat); 568 __clear_bit(channel, &stat);
566 } 569 }
@@ -1359,6 +1362,8 @@ static int __init sdma_probe(struct platform_device *pdev)
1359 dma_cookie_init(&sdmac->chan); 1362 dma_cookie_init(&sdmac->chan);
1360 sdmac->channel = i; 1363 sdmac->channel = i;
1361 1364
1365 tasklet_init(&sdmac->tasklet, sdma_tasklet,
1366 (unsigned long) sdmac);
1362 /* 1367 /*
1363 * Add the channel to the DMAC list. Do not add channel 0 though 1368 * Add the channel to the DMAC list. Do not add channel 0 though
1364 * because we need it internally in the SDMA driver. This also means 1369 * because we need it internally in the SDMA driver. This also means