summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVaradarajan Narayanan <quic_varada@quicinc.com>2025-01-15 11:50:44 +0530
committerMarek Vasut <marex@denx.de>2025-05-25 15:44:13 +0200
commit068f83499c2f8299c6172c511ec875eef2b26a6f (patch)
tree5ad1fd5b1d6c911fb1e4f3bbff924c1828fd9fd4
parentdf2ed552f0b05591090369a7fe7ddc92439dea5c (diff)
usb: dwc3: core: Fix timeout check
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. Use poll API instead to resolve this. Signed-off-by: Varadarajan Narayanan <quic_varada@quicinc.com> Reviewed-by: Mattijs Korpershoek <mkorpershoek@baylibre.com> Reviewed-by: Caleb Connolly <caleb.connolly@linaro.org>
-rw-r--r--drivers/usb/dwc3/core.c14
1 files changed, 5 insertions, 9 deletions
diff --git a/drivers/usb/dwc3/core.c b/drivers/usb/dwc3/core.c
index a35b8c2f646..847fa1f82c3 100644
--- a/drivers/usb/dwc3/core.c
+++ b/drivers/usb/dwc3/core.c
@@ -23,6 +23,7 @@
#include <linux/delay.h>
#include <linux/dma-mapping.h>
#include <linux/err.h>
+#include <linux/iopoll.h>
#include <linux/ioport.h>
#include <dm.h>
#include <generic-phy.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,15 +610,11 @@ 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;