| From 3f05998db340f3ce49dc46957aedd5bbebb198de Mon Sep 17 00:00:00 2001 |
| From: Sasha Levin <sashal@kernel.org> |
| Date: Wed, 12 Feb 2025 21:01:35 +0100 |
| Subject: clk: qcom: clk-alpha-pll: Do not use random stack value for recalc |
| rate |
| |
| From: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org> |
| |
| [ Upstream commit 7a243e1b814a02ab40793026ef64223155d86395 ] |
| |
| If regmap_read() fails, random stack value was used in calculating new |
| frequency in recalc_rate() callbacks. Such failure is really not |
| expected as these are all MMIO reads, however code should be here |
| correct and bail out. This also avoids possible warning on |
| uninitialized value. |
| |
| Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org> |
| Link: https://lore.kernel.org/r/20250212-b4-clk-qcom-clean-v3-1-499f37444f5d@linaro.org |
| Signed-off-by: Bjorn Andersson <andersson@kernel.org> |
| Signed-off-by: Sasha Levin <sashal@kernel.org> |
| --- |
| drivers/clk/qcom/clk-alpha-pll.c | 52 ++++++++++++++++++++++---------- |
| 1 file changed, 36 insertions(+), 16 deletions(-) |
| |
| diff --git a/drivers/clk/qcom/clk-alpha-pll.c b/drivers/clk/qcom/clk-alpha-pll.c |
| index 9a65d14acf71c..cec0afea8e446 100644 |
| --- a/drivers/clk/qcom/clk-alpha-pll.c |
| +++ b/drivers/clk/qcom/clk-alpha-pll.c |
| @@ -709,14 +709,19 @@ clk_alpha_pll_recalc_rate(struct clk_hw *hw, unsigned long parent_rate) |
| struct clk_alpha_pll *pll = to_clk_alpha_pll(hw); |
| u32 alpha_width = pll_alpha_width(pll); |
| |
| - regmap_read(pll->clkr.regmap, PLL_L_VAL(pll), &l); |
| + if (regmap_read(pll->clkr.regmap, PLL_L_VAL(pll), &l)) |
| + return 0; |
| + |
| + if (regmap_read(pll->clkr.regmap, PLL_USER_CTL(pll), &ctl)) |
| + return 0; |
| |
| - regmap_read(pll->clkr.regmap, PLL_USER_CTL(pll), &ctl); |
| if (ctl & PLL_ALPHA_EN) { |
| - regmap_read(pll->clkr.regmap, PLL_ALPHA_VAL(pll), &low); |
| + if (regmap_read(pll->clkr.regmap, PLL_ALPHA_VAL(pll), &low)) |
| + return 0; |
| if (alpha_width > 32) { |
| - regmap_read(pll->clkr.regmap, PLL_ALPHA_VAL_U(pll), |
| - &high); |
| + if (regmap_read(pll->clkr.regmap, PLL_ALPHA_VAL_U(pll), |
| + &high)) |
| + return 0; |
| a = (u64)high << 32 | low; |
| } else { |
| a = low & GENMASK(alpha_width - 1, 0); |
| @@ -942,8 +947,11 @@ alpha_pll_huayra_recalc_rate(struct clk_hw *hw, unsigned long parent_rate) |
| struct clk_alpha_pll *pll = to_clk_alpha_pll(hw); |
| u32 l, alpha = 0, ctl, alpha_m, alpha_n; |
| |
| - regmap_read(pll->clkr.regmap, PLL_L_VAL(pll), &l); |
| - regmap_read(pll->clkr.regmap, PLL_USER_CTL(pll), &ctl); |
| + if (regmap_read(pll->clkr.regmap, PLL_L_VAL(pll), &l)) |
| + return 0; |
| + |
| + if (regmap_read(pll->clkr.regmap, PLL_USER_CTL(pll), &ctl)) |
| + return 0; |
| |
| if (ctl & PLL_ALPHA_EN) { |
| regmap_read(pll->clkr.regmap, PLL_ALPHA_VAL(pll), &alpha); |
| @@ -1137,8 +1145,11 @@ clk_trion_pll_recalc_rate(struct clk_hw *hw, unsigned long parent_rate) |
| struct clk_alpha_pll *pll = to_clk_alpha_pll(hw); |
| u32 l, frac, alpha_width = pll_alpha_width(pll); |
| |
| - regmap_read(pll->clkr.regmap, PLL_L_VAL(pll), &l); |
| - regmap_read(pll->clkr.regmap, PLL_ALPHA_VAL(pll), &frac); |
| + if (regmap_read(pll->clkr.regmap, PLL_L_VAL(pll), &l)) |
| + return 0; |
| + |
| + if (regmap_read(pll->clkr.regmap, PLL_ALPHA_VAL(pll), &frac)) |
| + return 0; |
| |
| return alpha_pll_calc_rate(parent_rate, l, frac, alpha_width); |
| } |
| @@ -1196,7 +1207,8 @@ clk_alpha_pll_postdiv_recalc_rate(struct clk_hw *hw, unsigned long parent_rate) |
| struct clk_alpha_pll_postdiv *pll = to_clk_alpha_pll_postdiv(hw); |
| u32 ctl; |
| |
| - regmap_read(pll->clkr.regmap, PLL_USER_CTL(pll), &ctl); |
| + if (regmap_read(pll->clkr.regmap, PLL_USER_CTL(pll), &ctl)) |
| + return 0; |
| |
| ctl >>= PLL_POST_DIV_SHIFT; |
| ctl &= PLL_POST_DIV_MASK(pll); |
| @@ -1412,8 +1424,11 @@ static unsigned long alpha_pll_fabia_recalc_rate(struct clk_hw *hw, |
| struct clk_alpha_pll *pll = to_clk_alpha_pll(hw); |
| u32 l, frac, alpha_width = pll_alpha_width(pll); |
| |
| - regmap_read(pll->clkr.regmap, PLL_L_VAL(pll), &l); |
| - regmap_read(pll->clkr.regmap, PLL_FRAC(pll), &frac); |
| + if (regmap_read(pll->clkr.regmap, PLL_L_VAL(pll), &l)) |
| + return 0; |
| + |
| + if (regmap_read(pll->clkr.regmap, PLL_FRAC(pll), &frac)) |
| + return 0; |
| |
| return alpha_pll_calc_rate(parent_rate, l, frac, alpha_width); |
| } |
| @@ -1563,7 +1578,8 @@ clk_trion_pll_postdiv_recalc_rate(struct clk_hw *hw, unsigned long parent_rate) |
| struct regmap *regmap = pll->clkr.regmap; |
| u32 i, div = 1, val; |
| |
| - regmap_read(regmap, PLL_USER_CTL(pll), &val); |
| + if (regmap_read(regmap, PLL_USER_CTL(pll), &val)) |
| + return 0; |
| |
| val >>= pll->post_div_shift; |
| val &= PLL_POST_DIV_MASK(pll); |
| @@ -2484,9 +2500,12 @@ static unsigned long alpha_pll_lucid_evo_recalc_rate(struct clk_hw *hw, |
| struct regmap *regmap = pll->clkr.regmap; |
| u32 l, frac; |
| |
| - regmap_read(regmap, PLL_L_VAL(pll), &l); |
| + if (regmap_read(regmap, PLL_L_VAL(pll), &l)) |
| + return 0; |
| l &= LUCID_EVO_PLL_L_VAL_MASK; |
| - regmap_read(regmap, PLL_ALPHA_VAL(pll), &frac); |
| + |
| + if (regmap_read(regmap, PLL_ALPHA_VAL(pll), &frac)) |
| + return 0; |
| |
| return alpha_pll_calc_rate(parent_rate, l, frac, pll_alpha_width(pll)); |
| } |
| @@ -2699,7 +2718,8 @@ static unsigned long clk_rivian_evo_pll_recalc_rate(struct clk_hw *hw, |
| struct clk_alpha_pll *pll = to_clk_alpha_pll(hw); |
| u32 l; |
| |
| - regmap_read(pll->clkr.regmap, PLL_L_VAL(pll), &l); |
| + if (regmap_read(pll->clkr.regmap, PLL_L_VAL(pll), &l)) |
| + return 0; |
| |
| return parent_rate * l; |
| } |
| -- |
| 2.39.5 |
| |