On 2019-06-14 at 18:09 +0000, Michael Olbrich wrote: > On Fri, Jun 14, 2019 at 09:25:51AM -0400, Sven Van Asbroeck wrote: > > > > On Fri, Jun 14, 2019 at 6:49 AM Fabio Estevam <festevam@xxxxxxxxx> > > wrote: > > > > > > > > > According to the original report from Sven the issue started to > > > happen > > > on 5.0, so it would be good to add a Fixes tag and Cc stable so > > > that > > > this fix could be backported to 5.0/5.1 stable trees. > > Good catch ! > > > > However, the issue is highly timing-dependent. It will come and go > > depending > > on the kernel version, devicetree and defconfig. If it works for me > > on > > 4.19, that > > doesn't mean the bug is gone on 4.19. > > > > Looking at the commit history, I think the commit below possibly > > introduced the > > issue. Until this commit, sdma_run_channel() would wait on the > > interrupt > > before proceeding. It has been there since 4.8: > > > > Fixes: 1d069bfa3c78 ("dmaengine: imx-sdma: ack channel 0 IRQ in the > > interrupt handler") > I think this is correct. Starting with this commit, the interrupt > status fr > channel 0 is no longer cleared in sdma_run_channel0() and > sdma_int_handler() is always called for channel 0. > During firmware loading the interrupts are enabled again just before > the > clocks are disabled. The interrupt is pending at this moment so on a > single > core system I think this will always work as expected. If the > firmware > loading and the interrupt handler run on different cores then this is > racy. > Maybe something else changed to make this more likely? > > With this new change sdma_int_handler() is no longer called for > channel 0 > right, so you should also remove the special handling there. What's 'special handling' should be removed here? Do you mean put below pieces of your patch back? static int sdma_load_script(struct sdma_engine *sdma, void *buf, int size, @@ -727,9 +720,9 @@ static irqreturn_t sdma_int_handler(int irq, void *dev_id) unsigned long stat; stat = readl_relaxed(sdma->regs + SDMA_H_INTR); - /* not interested in channel 0 interrupts */ - stat &= ~1; writel_relaxed(stat, sdma->regs + SDMA_H_INTR); + /* channel 0 is special and not handled here, see run_channel0() */ + stat &= ~1; > > Michael >