On Sun, Jan 12, 2025 at 09:48:41PM +0100, Marek Vasut wrote: > On 1/10/25 8:43 AM, Varadarajan Narayanan wrote: > > dwc3_core_init loops 'timeout' times to check if the IP block is out > > of reset using 'while (timeout--)'. If there is some issue and > > the block doesn't come out of reset, the loop will run till > > 'timeout' becomes zero and the post decrement operator would set > > timeout to 0xffffffff. Though the IP block is not out reset, the > > subsequent if check 'if !timeout' would fail as timeout is not > > equal to zero and the function proceeds with the initialization. > > > > Make this a pre decrement to address this. > > > > Signed-off-by: Varadarajan Narayanan <quic_var...@quicinc.com> > Does the following patch work too ? It removes all the fragile open-coded > polling > > diff --git a/drivers/usb/dwc3/core.c b/drivers/usb/dwc3/core.c > index a35b8c2f646..7e7017d4be7 100644 > --- a/drivers/usb/dwc3/core.c > +++ b/drivers/usb/dwc3/core.c > @@ -29,6 +29,7 @@ > #include <linux/usb/ch9.h> > #include <linux/usb/gadget.h> > #include <linux/bitfield.h> > +#include <linux/iopoll.h> > #include <linux/math64.h> > #include <linux/time.h> > > @@ -587,7 +588,6 @@ static void dwc3_set_incr_burst_type(struct dwc3 *dwc) > */ > static int dwc3_core_init(struct dwc3 *dwc) > { > - unsigned long timeout; > u32 hwparams4 = dwc->hwparams.hwparams4; > u32 reg; > int ret; > @@ -610,17 +610,12 @@ static int dwc3_core_init(struct dwc3 *dwc) > } > > /* issue device SoftReset too */ > - timeout = 5000; > dwc3_writel(dwc->regs, DWC3_DCTL, DWC3_DCTL_CSFTRST); > - while (timeout--) { > - reg = dwc3_readl(dwc->regs, DWC3_DCTL); > - if (!(reg & DWC3_DCTL_CSFTRST)) > - break; > - }; > - > - if (!timeout) { > + ret = read_poll_timeout(dwc3_readl, reg, > + !(reg & DWC3_DCTL_CSFTRST), > + 1, 5000, dwc->regs, DWC3_DCTL); > + if (ret) { > dev_err(dwc->dev, "Reset Timed Out\n"); > - ret = -ETIMEDOUT; > goto err0; > }
This worked too. Tested-By: Varadarajan Narayanan <quic_var...@quicinc.com> Thanks Varada