[PATCH v1] usb: dwc3: core: Fix timeout check
Marek Vasut
marex at denx.de
Sun Jan 12 21:48:41 CET 2025
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_varada at 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;
}
More information about the U-Boot
mailing list