[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