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

Reply via email to