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>
This commit is contained in:
@@ -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)
|
|||||||
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)
|
|||||||
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)
|
|||||||
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
|
||||||
|
Reference in New Issue
Block a user