Skip to content

Commit 675c496

Browse files
xdarklightbebarino
authored andcommitted
clk: composite: Also consider .determine_rate for rate + mux composites
Commit 69a00fb ("clk: divider: Implement and wire up .determine_rate by default") switches clk_divider_ops to implement .determine_rate by default. This breaks composite clocks with multiple parents because clk-composite.c does not use the special handling for mux + divider combinations anymore (that was restricted to rate clocks which only implement .round_rate, but not .determine_rate). Alex reports: This breaks lot of clocks for Rockchip which intensively uses composites, i.e. those clocks will always stay at the initial parent, which in some cases is the XTAL clock and I strongly guess it is the same for other platforms, which use composite clocks having more than one parent (e.g. mediatek, ti ...) Example (RK3399) clk_sdio is set (initialized) with XTAL (24 MHz) as parent in u-boot. It will always stay at this parent, even if the mmc driver sets a rate of 200 MHz (fails, as the nature of things), which should switch it to any of its possible parent PLLs defined in mux_pll_src_cpll_gpll_npll_ppll_upll_24m_p (see clk-rk3399.c) - which never happens. Restore the original behavior by changing the priority of the conditions inside clk-composite.c. Now the special rate + mux case (with rate_ops having a .round_rate - which is still the case for the default clk_divider_ops) is preferred over rate_ops which have .determine_rate defined (and not further considering the mux). Fixes: 69a00fb ("clk: divider: Implement and wire up .determine_rate by default") Reported-by: Alex Bee <[email protected]> Signed-off-by: Martin Blumenstingl <[email protected]> Link: https://lore.kernel.org/r/[email protected] Tested-by: Alex Bee <[email protected]> Tested-by: Chen-Yu Tsai <[email protected]> Signed-off-by: Stephen Boyd <[email protected]>
1 parent 6880fa6 commit 675c496

File tree

1 file changed

+5
-5
lines changed

1 file changed

+5
-5
lines changed

drivers/clk/clk-composite.c

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -58,11 +58,8 @@ static int clk_composite_determine_rate(struct clk_hw *hw,
5858
long rate;
5959
int i;
6060

61-
if (rate_hw && rate_ops && rate_ops->determine_rate) {
62-
__clk_hw_set_clk(rate_hw, hw);
63-
return rate_ops->determine_rate(rate_hw, req);
64-
} else if (rate_hw && rate_ops && rate_ops->round_rate &&
65-
mux_hw && mux_ops && mux_ops->set_parent) {
61+
if (rate_hw && rate_ops && rate_ops->round_rate &&
62+
mux_hw && mux_ops && mux_ops->set_parent) {
6663
req->best_parent_hw = NULL;
6764

6865
if (clk_hw_get_flags(hw) & CLK_SET_RATE_NO_REPARENT) {
@@ -107,6 +104,9 @@ static int clk_composite_determine_rate(struct clk_hw *hw,
107104

108105
req->rate = best_rate;
109106
return 0;
107+
} else if (rate_hw && rate_ops && rate_ops->determine_rate) {
108+
__clk_hw_set_clk(rate_hw, hw);
109+
return rate_ops->determine_rate(rate_hw, req);
110110
} else if (mux_hw && mux_ops && mux_ops->determine_rate) {
111111
__clk_hw_set_clk(mux_hw, hw);
112112
return mux_ops->determine_rate(mux_hw, req);

0 commit comments

Comments
 (0)