clk: qcom: clk-rcg2: Fix clock rate overflow for high parent frequencies
authorDevi Priya <quic_devipriy@quicinc.com>
Fri, 1 Sep 2023 07:36:40 +0000 (13:06 +0530)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Mon, 20 Nov 2023 10:59:04 +0000 (11:59 +0100)
[ Upstream commit f7b7d30158cff246667273bd2a62fc93ee0725d2 ]

If the parent clock rate is greater than unsigned long max/2 then
integer overflow happens when calculating the clock rate on 32-bit systems.
As RCG2 uses half integer dividers, the clock rate is first being
multiplied by 2 which will overflow the unsigned long max value.
Hence, replace the common pattern of doing 64-bit multiplication
and then a do_div() call with simpler mult_frac call.

Fixes: bcd61c0f535a ("clk: qcom: Add support for root clock generators (RCGs)")
Signed-off-by: Devi Priya <quic_devipriy@quicinc.com>
Reviewed-by: Marijn Suijten <marijn.suijten@somainline.org>
Link: https://lore.kernel.org/r/20230901073640.4973-1-quic_devipriy@quicinc.com
[bjorn: Also drop unnecessary {} around single statements]
Signed-off-by: Bjorn Andersson <andersson@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
drivers/clk/qcom/clk-rcg2.c

index e22baf3..5183c74 100644 (file)
@@ -158,17 +158,11 @@ static int clk_rcg2_set_parent(struct clk_hw *hw, u8 index)
 static unsigned long
 calc_rate(unsigned long rate, u32 m, u32 n, u32 mode, u32 hid_div)
 {
-       if (hid_div) {
-               rate *= 2;
-               rate /= hid_div + 1;
-       }
+       if (hid_div)
+               rate = mult_frac(rate, 2, hid_div + 1);
 
-       if (mode) {
-               u64 tmp = rate;
-               tmp *= m;
-               do_div(tmp, n);
-               rate = tmp;
-       }
+       if (mode)
+               rate = mult_frac(rate, m, n);
 
        return rate;
 }