diff options
author | Huang Shijie <b32955@freescale.com> | 2012-04-28 18:15:42 +0800 |
---|---|---|
committer | Vinod Koul <vinod.koul@linux.intel.com> | 2012-05-11 11:08:10 +0530 |
commit | abd9ccc84c35cf1e296335a7b655bba40c92386c (patch) | |
tree | 22c39af6cc57d6371cf4d74e76c04c60f979e9b5 /drivers/dma | |
parent | d3f797d93e593aa891f5b04a404b4ab45fd0e66a (diff) | |
download | op-kernel-dev-abd9ccc84c35cf1e296335a7b655bba40c92386c.zip op-kernel-dev-abd9ccc84c35cf1e296335a7b655bba40c92386c.tar.gz |
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.c | 9 |
1 files changed, 7 insertions, 2 deletions
diff --git a/drivers/dma/imx-sdma.c b/drivers/dma/imx-sdma.c index d3e38e2..5a45777 100644 --- a/drivers/dma/imx-sdma.c +++ b/drivers/dma/imx-sdma.c @@ -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 |