summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRobin Gong <yibin.gong@nxp.com>2019-06-21 16:23:06 +0800
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2019-07-10 09:53:48 +0200
commitf37de75cb8ebfcb5aa048824e7dc706ecebad4ca (patch)
treeacf05747293cd46822be00f92af1f819755712bd
parent018c968de710af1372d456ededc0a575ee038b92 (diff)
downloadlinux-stable-f37de75cb8ebfcb5aa048824e7dc706ecebad4ca.tar.gz
linux-stable-f37de75cb8ebfcb5aa048824e7dc706ecebad4ca.tar.bz2
linux-stable-f37de75cb8ebfcb5aa048824e7dc706ecebad4ca.zip
dmaengine: imx-sdma: remove BD_INTR for channel0
commit 3f93a4f297961c12bb17aa16cb3a4d1291823cae upstream. It is possible for an irq triggered by channel0 to be received later after clks are disabled once firmware loaded during sdma probe. If that happens then clearing them by writing to SDMA_H_INTR won't work and the kernel will hang processing infinite interrupts. Actually, don't need interrupt triggered on channel0 since it's pollling SDMA_H_STATSTOP to know channel0 done rather than interrupt in current code, just clear BD_INTR to disable channel0 interrupt to avoid the above case. This issue was brought by commit 1d069bfa3c78 ("dmaengine: imx-sdma: ack channel 0 IRQ in the interrupt handler") which didn't take care the above case. Fixes: 1d069bfa3c78 ("dmaengine: imx-sdma: ack channel 0 IRQ in the interrupt handler") Cc: stable@vger.kernel.org #5.0+ Signed-off-by: Robin Gong <yibin.gong@nxp.com> Reported-by: Sven Van Asbroeck <thesven73@gmail.com> Tested-by: Sven Van Asbroeck <thesven73@gmail.com> Reviewed-by: Michael Olbrich <m.olbrich@pengutronix.de> Signed-off-by: Vinod Koul <vkoul@kernel.org> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
-rw-r--r--drivers/dma/imx-sdma.c4
1 files changed, 2 insertions, 2 deletions
diff --git a/drivers/dma/imx-sdma.c b/drivers/dma/imx-sdma.c
index cb1b44d78a1f..1c658ec3cbf4 100644
--- a/drivers/dma/imx-sdma.c
+++ b/drivers/dma/imx-sdma.c
@@ -681,7 +681,7 @@ static int sdma_load_script(struct sdma_engine *sdma, void *buf, int size,
spin_lock_irqsave(&sdma->channel_0_lock, flags);
bd0->mode.command = C0_SETPM;
- bd0->mode.status = BD_DONE | BD_INTR | BD_WRAP | BD_EXTD;
+ bd0->mode.status = BD_DONE | BD_WRAP | BD_EXTD;
bd0->mode.count = size / 2;
bd0->buffer_addr = buf_phys;
bd0->ext_buffer_addr = address;
@@ -1000,7 +1000,7 @@ static int sdma_load_context(struct sdma_channel *sdmac)
context->gReg[7] = sdmac->watermark_level;
bd0->mode.command = C0_SETDM;
- bd0->mode.status = BD_DONE | BD_INTR | BD_WRAP | BD_EXTD;
+ bd0->mode.status = BD_DONE | BD_WRAP | BD_EXTD;
bd0->mode.count = sizeof(*context) / 4;
bd0->buffer_addr = sdma->context_phys;
bd0->ext_buffer_addr = 2048 + (sizeof(*context) / 4) * channel;