Skip to content

Commit 6594988

Browse files
xdarklightbebarino
authored andcommitted
clk: composite: Use rate_ops.determine_rate when also a mux is available
Update clk_composite_determine_rate() to use rate_ops.determine_rate when available in combination with a mux. So far clk_divider_ops provide both, .round_rate and .determine_rate. Removing the former would make clk-composite fail silently for example on Rockchip platforms (which heavily use composite clocks). Add support for using rate_ops.determine_rate when either rate_ops.round_rate is not available or both (.round_rate and .determine_rate) are provided. Suggested-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 675c496 commit 6594988

File tree

1 file changed

+48
-20
lines changed

1 file changed

+48
-20
lines changed

drivers/clk/clk-composite.c

Lines changed: 48 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,29 @@ static unsigned long clk_composite_recalc_rate(struct clk_hw *hw,
4242
return rate_ops->recalc_rate(rate_hw, parent_rate);
4343
}
4444

45+
static int clk_composite_determine_rate_for_parent(struct clk_hw *rate_hw,
46+
struct clk_rate_request *req,
47+
struct clk_hw *parent_hw,
48+
const struct clk_ops *rate_ops)
49+
{
50+
long rate;
51+
52+
req->best_parent_hw = parent_hw;
53+
req->best_parent_rate = clk_hw_get_rate(parent_hw);
54+
55+
if (rate_ops->determine_rate)
56+
return rate_ops->determine_rate(rate_hw, req);
57+
58+
rate = rate_ops->round_rate(rate_hw, req->rate,
59+
&req->best_parent_rate);
60+
if (rate < 0)
61+
return rate;
62+
63+
req->rate = rate;
64+
65+
return 0;
66+
}
67+
4568
static int clk_composite_determine_rate(struct clk_hw *hw,
4669
struct clk_rate_request *req)
4770
{
@@ -51,51 +74,56 @@ static int clk_composite_determine_rate(struct clk_hw *hw,
5174
struct clk_hw *rate_hw = composite->rate_hw;
5275
struct clk_hw *mux_hw = composite->mux_hw;
5376
struct clk_hw *parent;
54-
unsigned long parent_rate;
55-
long tmp_rate, best_rate = 0;
5677
unsigned long rate_diff;
5778
unsigned long best_rate_diff = ULONG_MAX;
58-
long rate;
59-
int i;
79+
unsigned long best_rate = 0;
80+
int i, ret;
6081

61-
if (rate_hw && rate_ops && rate_ops->round_rate &&
82+
if (rate_hw && rate_ops &&
83+
(rate_ops->determine_rate || rate_ops->round_rate) &&
6284
mux_hw && mux_ops && mux_ops->set_parent) {
6385
req->best_parent_hw = NULL;
6486

6587
if (clk_hw_get_flags(hw) & CLK_SET_RATE_NO_REPARENT) {
88+
struct clk_rate_request tmp_req = *req;
89+
6690
parent = clk_hw_get_parent(mux_hw);
67-
req->best_parent_hw = parent;
68-
req->best_parent_rate = clk_hw_get_rate(parent);
6991

70-
rate = rate_ops->round_rate(rate_hw, req->rate,
71-
&req->best_parent_rate);
72-
if (rate < 0)
73-
return rate;
92+
ret = clk_composite_determine_rate_for_parent(rate_hw,
93+
&tmp_req,
94+
parent,
95+
rate_ops);
96+
if (ret)
97+
return ret;
98+
99+
req->rate = tmp_req.rate;
100+
req->best_parent_rate = tmp_req.best_parent_rate;
74101

75-
req->rate = rate;
76102
return 0;
77103
}
78104

79105
for (i = 0; i < clk_hw_get_num_parents(mux_hw); i++) {
106+
struct clk_rate_request tmp_req = *req;
107+
80108
parent = clk_hw_get_parent_by_index(mux_hw, i);
81109
if (!parent)
82110
continue;
83111

84-
parent_rate = clk_hw_get_rate(parent);
85-
86-
tmp_rate = rate_ops->round_rate(rate_hw, req->rate,
87-
&parent_rate);
88-
if (tmp_rate < 0)
112+
ret = clk_composite_determine_rate_for_parent(rate_hw,
113+
&tmp_req,
114+
parent,
115+
rate_ops);
116+
if (ret)
89117
continue;
90118

91-
rate_diff = abs(req->rate - tmp_rate);
119+
rate_diff = abs(req->rate - tmp_req.rate);
92120

93121
if (!rate_diff || !req->best_parent_hw
94122
|| best_rate_diff > rate_diff) {
95123
req->best_parent_hw = parent;
96-
req->best_parent_rate = parent_rate;
124+
req->best_parent_rate = tmp_req.best_parent_rate;
97125
best_rate_diff = rate_diff;
98-
best_rate = tmp_rate;
126+
best_rate = tmp_req.rate;
99127
}
100128

101129
if (!rate_diff)

0 commit comments

Comments
 (0)