On 32-bit platforms, "usb start" aborted with
"### ERROR ### Please RESET the board ###". If the clock driver
does not implement the "ref" clock, clk_get_rate() returns
-ENOENT, which dwc3_ref_clk_period() treated as a valid rate.
period became 0 and the fladj calculation divided by zero; the
software 64-bit division on 32-bit ARM calls the
division-by-zero handler __div0() and hangs (64-bit platforms
survive silently since UDIV returns 0).
Skip REFCLKPER/GFLADJ programming when clk_get_rate() returns an
error code, as is already done for rate == 0.
Fixes: 6bae0eb5b8bd ("usb: dwc3: Calculate REFCLKPER based on reference clock")
Signed-off-by: Frank Wang <[email protected]>
---
drivers/usb/dwc3/core.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/usb/dwc3/core.c b/drivers/usb/dwc3/core.c
index be198041f08..9a84ec6a60e 100644
--- a/drivers/usb/dwc3/core.c
+++ b/drivers/usb/dwc3/core.c
@@ -151,7 +151,7 @@ static void dwc3_ref_clk_period(struct dwc3 *dwc)
if (dwc->ref_clk) {
rate = clk_get_rate(dwc->ref_clk);
- if (!rate)
+ if (!rate || IS_ERR_VALUE(rate))
return;
period = NSEC_PER_SEC / rate;
} else {
--
2.17.1