[PATCH v5 3/3] clk: nuvoton: ma35d1: fix ma35d1_clk_pll_determine_rate logic

Joey Lu <[email protected]>
Newsgroups org.kernel.vger.linux-clk,org.infradead.lists.linux-arm-kernel,org.kernel.vger.linux-kernel
Message-ID <[email protected]>
ma35d1_clk_pll_determine_rate() called ma35d1_pll_find_closest()
unconditionally before the switch statement, and then every case
branch overwrote pll_freq by reading the current hardware registers.
For CAPLL and DDRPLL this means find_closest() ran unnecessarily
(and incorrectly, since those PLLs are read-only) and its result
was silently discarded.

Fix by moving the find_closest() call inside the APLL/EPLL/VPLL
branch where it belongs.  Split CAPLL and DDRPLL into separate case
labels mirroring ma35d1_clk_pll_recalc_rate(), with a shared
req->rate = pll_freq tail after the switch and an explicit default
label for unknown PLL IDs.

Fixes: 691521a367cf ("clk: nuvoton: Add clock driver for ma35d1 clock controller")
Signed-off-by: Joey Lu <[email protected]>
Reviewed-by: Alexandre Mergnat <[email protected]>
---
 drivers/clk/nuvoton/clk-ma35d1-pll.c | 31 ++++++++++++++--------------
 1 file changed, 16 insertions(+), 15 deletions(-)

diff --git a/drivers/clk/nuvoton/clk-ma35d1-pll.c b/drivers/clk/nuvoton/clk-ma35d1-pll.c
index eb9d69d2077b..878b23bb5918 100644
--- a/drivers/clk/nuvoton/clk-ma35d1-pll.c
+++ b/drivers/clk/nuvoton/clk-ma35d1-pll.c
@@ -255,32 +255,33 @@ static int ma35d1_clk_pll_determine_rate(struct clk_hw *hw,
 	if (req->best_parent_rate < PLL_FREF_MIN_FREQ || req->best_parent_rate > PLL_FREF_MAX_FREQ)
 		return -EINVAL;
 
-	ret = ma35d1_pll_find_closest(pll, req->rate, req->best_parent_rate,
-				      reg_ctl, &pll_freq);
-	if (ret < 0)
-		return ret;
-
 	switch (pll->id) {
 	case CAPLL:
+		/* SMIC design: single control register */
 		reg_ctl[0] = readl_relaxed(pll->ctl0_base);
 		pll_freq = ma35d1_calc_smic_pll_freq(reg_ctl[0], req->best_parent_rate);
-		req->rate = pll_freq;
-
-		return 0;
+		break;
 	case DDRPLL:
-	case APLL:
-	case EPLL:
-	case VPLL:
+		/* Standard design: read current rate, not configurable */
 		reg_ctl[0] = readl_relaxed(pll->ctl0_base);
 		reg_ctl[1] = readl_relaxed(pll->ctl1_base);
 		pll_freq = ma35d1_calc_pll_freq(pll->mode, reg_ctl, req->best_parent_rate);
-		req->rate = pll_freq;
-
+		break;
+	case APLL:
+	case EPLL:
+	case VPLL:
+		/* Configurable PLLs: find closest achievable rate */
+		ret = ma35d1_pll_find_closest(pll, req->rate, req->best_parent_rate,
+					      reg_ctl, &pll_freq);
+		if (ret < 0)
+			return ret;
+		break;
+	default:
+		req->rate = 0;
 		return 0;
 	}
 
-	req->rate = 0;
-
+	req->rate = pll_freq;
 	return 0;
 }
 
-- 
2.43.0
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.