Hi Andrew, On 5/20/22 15:40, Andrew Lunn wrote: > On Thu, May 19, 2022 at 11:40:17PM +0300, Pavel Skripkin wrote: >> Accidentally noticed, that this driver is the only user of >> while (timer_after(jiffies...)). >> >> It looks like typo, because likely this while loop will finish after 1st >> iteration, because time_after() returns true when 1st argument _is after_ >> 2nd one. >> >> Fix it by negating time_after return value inside while loops statement > > A better fix would be to use one of the helpers in linux/iopoll.h. > > There is a second bug in the current code: > > static int ocelot_fdma_wait_chan_safe(struct ocelot *ocelot, int chan) > { > unsigned long timeout; > u32 safe; > > timeout = jiffies + usecs_to_jiffies(OCELOT_FDMA_CH_SAFE_TIMEOUT_US); > do { > safe = ocelot_fdma_readl(ocelot, MSCC_FDMA_CH_SAFE); > if (safe & BIT(chan)) > return 0; > } while (time_after(jiffies, timeout)); > > return -ETIMEDOUT; > } > > The scheduler could put the thread to sleep, and it does not get woken > up for OCELOT_FDMA_CH_SAFE_TIMEOUT_US. During that time, the hardware > has done its thing, but you exit the while loop and return -ETIMEDOUT. > > linux/iopoll.h handles this correctly by testing the state one more > time after the timeout has expired. > I wasn't aware about these macros. Thanks for pointing out to that header! Will send v2 soon, With regards, Pavel Skripkin