Commit abd9ccc8 authored by Huang Shijie's avatar Huang Shijie Committed by Vinod Koul

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: default avatarHuang Shijie <b32955@freescale.com>
Signed-off-by: default avatarVinod Koul <vinod.koul@linux.intel.com>
parent d3f797d9
...@@ -271,6 +271,7 @@ struct sdma_channel { ...@@ -271,6 +271,7 @@ struct sdma_channel {
enum dma_status status; enum dma_status status;
unsigned int chn_count; unsigned int chn_count;
unsigned int chn_real_count; unsigned int chn_real_count;
struct tasklet_struct tasklet;
}; };
#define IMX_DMA_SG_LOOP BIT(0) #define IMX_DMA_SG_LOOP BIT(0)
...@@ -534,8 +535,10 @@ static void mxc_sdma_handle_channel_normal(struct sdma_channel *sdmac) ...@@ -534,8 +535,10 @@ static void mxc_sdma_handle_channel_normal(struct sdma_channel *sdmac)
sdmac->desc.callback(sdmac->desc.callback_param); 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); complete(&sdmac->done);
/* not interested in channel 0 interrupts */ /* not interested in channel 0 interrupts */
...@@ -560,7 +563,7 @@ static irqreturn_t sdma_int_handler(int irq, void *dev_id) ...@@ -560,7 +563,7 @@ static irqreturn_t sdma_int_handler(int irq, void *dev_id)
int channel = fls(stat) - 1; int channel = fls(stat) - 1;
struct sdma_channel *sdmac = &sdma->channel[channel]; struct sdma_channel *sdmac = &sdma->channel[channel];
mxc_sdma_handle_channel(sdmac); tasklet_schedule(&sdmac->tasklet);
__clear_bit(channel, &stat); __clear_bit(channel, &stat);
} }
...@@ -1359,6 +1362,8 @@ static int __init sdma_probe(struct platform_device *pdev) ...@@ -1359,6 +1362,8 @@ static int __init sdma_probe(struct platform_device *pdev)
dma_cookie_init(&sdmac->chan); dma_cookie_init(&sdmac->chan);
sdmac->channel = i; 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 * 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 * because we need it internally in the SDMA driver. This also means
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment