imx-sdma: fix pagefault when channel is disabled during interrupt
Quoted 12 lines · Thierry Bultel
Add a spinlock and a 'enabled' boolean on channel descriptor, to avoid using buffer descriptors in the interrupt context,
sdma_disable_channelis called meanwhile.--- drivers/dma/imx-sdma.c | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+)drivers/dma/imx-sdma.c +0
-0
drivers/dma/imx-sdma.c struct sdma_channel { · line 333
Quoted 4 lines
drivers/dma/imx-sdma.c +1
-0@@ -330,6 +330,7 @@ struct sdma_channel {unsigned int chn_real_count;struct tasklet_struct tasklet;struct imx_dma_data data; +unsigned int enabled;
description says bool but this is int?
drivers/dma/imx-sdma.c static int sdma_config_ownership(struct sdma_channel *sdmac, · line 593
Quoted 9 lines
drivers/dma/imx-sdma.c +2
-0};#define IMX_DMA_SG_LOOP BIT(0)@@ -588,7 +589,13 @@ static int sdma_config_ownership(struct sdma_channel *sdmac,static void sdma_enable_channel (struct sdma_engine *sdma,int channel) { +unsigned long flags; +struct sdma_channel *sdmac = &sdma->channel[channel];
Empty line here please
Quoted 9 lines
drivers/dma/imx-sdma.c +4
-0writel (BIT (channel), sdma->regs +SDMA_H_START ); + +spin_lock_irqsave (&sdmac->lock, flags); + sdmac->enabled =1 ; +spin_unlock_irqrestore (&sdmac->lock, flags); }/*
drivers/dma/imx-sdma.c static void sdma_update_channel_loop(struct sdma_channel *sdmac) · line 688
Quoted 5 lines
drivers/dma/imx-sdma.c +2
-0@@ -677,6 +684,15 @@ static void sdma_update_channel_loop(struct sdma_channel *sdmac)struct sdma_buffer_descriptor *bd;int error =0 ;enum dma_status old_status = sdmac->status; +unsigned long flags; +
this empty line is bogus
drivers/dma/imx-sdma.c static void sdma_update_channel_loop(struct sdma_channel *sdmac) · line 689
Quoted 1 line
drivers/dma/imx-sdma.c +1
-0+int enabled;
and is required here. Empty line needs to be added to a fn after defining variables and before code statements
Quoted 32 lines
drivers/dma/imx-sdma.c +11
-0+spin_lock_irqsave (&sdmac->lock, flags); + enabled = sdmac->enabled; +spin_unlock_irqrestore (&sdmac->lock, flags); + +if (!enabled) +return ;/* * loop mode. Iterate over descriptors, re-setup them and @@ -930,10 +946,15 @@ static int sdma_disable_channel(struct dma_chan *chan)struct sdma_channel *sdmac =to_sdma_chan (chan);struct sdma_engine *sdma = sdmac->sdma;int channel = sdmac->channel; +unsigned long flags;writel_relaxed (BIT (channel), sdma->regs +SDMA_H_STATSTOP ); sdmac->status =DMA_ERROR ; +spin_lock_irqsave (&sdmac->lock, flags); + sdmac->enabled =0 ; +spin_unlock_irqrestore (&sdmac->lock, flags); +return 0 ; }Signature · 6 lines
2.7.4 -- To unsubscribe from this list: send the line "unsubscribe dmaengine" in the body of a message to [email protected] More majordomo info at http://vger.kernel.org/majordomo-info.html