[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <6f5cd1d796fb7c666348cc611b2f8178c009e2e4.1677749625.git.quic_varada@quicinc.com>
Date: Thu, 2 Mar 2023 15:25:08 +0530
From: Varadarajan Narayanan <quic_varada@...cinc.com>
To: Thinh Nguyen <Thinh.Nguyen@...opsys.com>,
Greg Kroah-Hartman <gregkh@...uxfoundation.org>
CC: Varadarajan Narayanan <quic_varada@...cinc.com>,
<linux-usb@...r.kernel.org>, <linux-kernel@...r.kernel.org>
Subject: [PATCH 1/8] usb: dwc3: core: Handle fladj becoming zero
In dwc3_ref_clk_period, the computation
fladj = div64_u64(125000ULL * NSEC_PER_SEC, (u64)rate * period);
fladj -= 125000;
could turn out to be zero. If fladj is zero, the following
FIELD_PREP clears out that field and the user overridden value
set in the DTS using "snps,quirk-frame-length-adjustment" is
lost. Ensure to retain the user overridden value if the above
evaluates to 0.
Signed-off-by: Varadarajan Narayanan <quic_varada@...cinc.com>
---
drivers/usb/dwc3/core.c | 27 +++++++++++++++++++++++++++
1 file changed, 27 insertions(+)
diff --git a/drivers/usb/dwc3/core.c b/drivers/usb/dwc3/core.c
index 476b636..63af83b 100644
--- a/drivers/usb/dwc3/core.c
+++ b/drivers/usb/dwc3/core.c
@@ -401,6 +401,33 @@ static void dwc3_ref_clk_period(struct dwc3 *dwc)
fladj -= 125000;
/*
+ * Since rate = NSEC_PER_SEC / period and period = NSEC_PER_SEC / rate
+ * above calculation could turn out to be zero.
+ *
+ * if (dwc->ref_clk)
+ * 125000 * NSEC_PER_SEC 125000 * NSEC_PER_SEC
+ * --------------------- => ---------------------
+ * rate * period rate * NSEC_PER_SEC
+ * ------------
+ * rate
+ * else
+ * 125000 * NSEC_PER_SEC 125000 * NSEC_PER_SEC
+ * --------------------- => ---------------------
+ * rate * period NSEC_PER_SEC * period
+ * ------------
+ * period
+ * Hence, the calculation
+ * div64_u64(125000ULL * NSEC_PER_SEC, (u64)rate * period)
+ * returns 125000ULL and fladj -= 125000 sets fladj to zero.
+ * If fladj is zero, the following FIELD_PREP clears out that
+ * field and the user overridden value set in the DTS using
+ * "snps,quirk-frame-length-adjustment" is lost. Ensure to retain
+ * the user overridden value if the above calculation evaluates to 0.
+ */
+ if (fladj == 0)
+ fladj = FIELD_GET(DWC3_GFLADJ_REFCLK_FLADJ_MASK, dwc->fladj);
+
+ /*
* The documented 240MHz constant is scaled by 2 to get PLS1 as well.
*/
decr = 480000000 / rate;
--
2.7.4
Powered by blists - more mailing lists