On Mon, Jun 17, 2019 at 02:14:34AM +0000, Robin Gong wrote: > 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; I think the "stat &= ~1;" can be removed completely. This bit should never be set, now that the interrupt for channel 0 is disabled. Michael -- Pengutronix e.K. | | Industrial Linux Solutions | http://www.pengutronix.de/ | Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0 | Amtsgericht Hildesheim, HRA 2686 | Fax: +49-5121-206917-5555 |