bcm27xx: add support for linux v5.15
[openwrt/staging/chunkeey.git] / target / linux / bcm27xx / patches-5.15 / 950-0846-clk-Set-req_rate-on-reparenting.patch
1 From 36595ef49aac284d386e1f9e8ac0910451ef40d6 Mon Sep 17 00:00:00 2001
2 From: Maxime Ripard <maxime@cerno.tech>
3 Date: Fri, 1 Apr 2022 15:26:46 +0200
4 Subject: [PATCH] clk: Set req_rate on reparenting
5
6 If a non-rate clock started by default with a parent that never
7 registered, core->req_rate will be 0. The expectation is that whenever
8 the parent will be registered, req_rate will be updated with the new
9 value that has just been computed.
10
11 However, if that clock is a mux, clk_set_parent() can also make that
12 clock no longer orphan. In this case however, we never update req_rate.
13 Let's make sure it's the case for the newly unorphan clock and all its
14 children.
15
16 Tested-by: Alexander Stein <alexander.stein@ew.tq-group.com> # imx8mp
17 Tested-by: Marek Szyprowski <m.szyprowski@samsung.com> # exynos4210, meson g12b
18 Signed-off-by: Maxime Ripard <maxime@cerno.tech>
19 ---
20 drivers/clk/clk.c | 18 ++++
21 drivers/clk/clk_test.c | 231 +++++++++++++++++++++++++++++++++++++++++
22 2 files changed, 249 insertions(+)
23
24 --- a/drivers/clk/clk.c
25 +++ b/drivers/clk/clk.c
26 @@ -1758,6 +1758,23 @@ static void clk_core_update_orphan_statu
27 clk_core_update_orphan_status(child, is_orphan);
28 }
29
30 +/*
31 + * Update the orphan rate and req_rate of @core and all its children.
32 + */
33 +static void clk_core_update_orphan_child_rates(struct clk_core *core)
34 +{
35 + struct clk_core *child;
36 + unsigned long parent_rate = 0;
37 +
38 + if (core->parent)
39 + parent_rate = core->parent->rate;
40 +
41 + core->rate = core->req_rate = clk_recalc(core, parent_rate);
42 +
43 + hlist_for_each_entry(child, &core->children, child_node)
44 + clk_core_update_orphan_child_rates(child);
45 +}
46 +
47 static void clk_reparent(struct clk_core *core, struct clk_core *new_parent)
48 {
49 bool was_orphan = core->orphan;
50 @@ -1782,6 +1799,7 @@ static void clk_reparent(struct clk_core
51 }
52
53 core->parent = new_parent;
54 + clk_core_update_orphan_child_rates(core);
55 }
56
57 static struct clk_core *__clk_set_parent_before(struct clk_core *core,
58 --- a/drivers/clk/clk_test.c
59 +++ b/drivers/clk/clk_test.c
60 @@ -577,6 +577,39 @@ clk_test_orphan_transparent_multiple_par
61
62 /*
63 * Test that, for a mux that started orphan but got switched to a valid
64 + * parent, calling clk_drop_range() on the mux won't affect the parent
65 + * rate.
66 + */
67 +static void
68 +clk_test_orphan_transparent_multiple_parent_mux_set_parent_drop_range(struct kunit *test)
69 +{
70 + struct clk_multiple_parent_ctx *ctx = test->priv;
71 + struct clk_hw *hw = &ctx->hw;
72 + struct clk *clk = hw->clk, *parent;
73 + unsigned long parent_rate, new_parent_rate;
74 + int ret;
75 +
76 + parent = clk_hw_get_clk(&ctx->parents_ctx[1].hw, NULL);
77 + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, parent);
78 +
79 + parent_rate = clk_get_rate(parent);
80 + KUNIT_ASSERT_GT(test, parent_rate, 0);
81 +
82 + ret = clk_set_parent(clk, parent);
83 + KUNIT_ASSERT_EQ(test, ret, 0);
84 +
85 + ret = clk_drop_range(clk);
86 + KUNIT_ASSERT_EQ(test, ret, 0);
87 +
88 + new_parent_rate = clk_get_rate(clk);
89 + KUNIT_ASSERT_GT(test, new_parent_rate, 0);
90 + KUNIT_EXPECT_EQ(test, parent_rate, new_parent_rate);
91 +
92 + clk_put(parent);
93 +}
94 +
95 +/*
96 + * Test that, for a mux that started orphan but got switched to a valid
97 * parent, the rate of the mux and its new parent are consistent.
98 */
99 static void
100 @@ -605,6 +638,39 @@ clk_test_orphan_transparent_multiple_par
101
102 /*
103 * Test that, for a mux that started orphan but got switched to a valid
104 + * parent, calling clk_put() on the mux won't affect the parent rate.
105 + */
106 +static void
107 +clk_test_orphan_transparent_multiple_parent_mux_set_parent_put(struct kunit *test)
108 +{
109 + struct clk_multiple_parent_ctx *ctx = test->priv;
110 + struct clk *clk, *parent;
111 + unsigned long parent_rate, new_parent_rate;
112 + int ret;
113 +
114 + parent = clk_hw_get_clk(&ctx->parents_ctx[1].hw, NULL);
115 + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, parent);
116 +
117 + clk = clk_hw_get_clk(&ctx->hw, NULL);
118 + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, clk);
119 +
120 + parent_rate = clk_get_rate(parent);
121 + KUNIT_ASSERT_GT(test, parent_rate, 0);
122 +
123 + ret = clk_set_parent(clk, parent);
124 + KUNIT_ASSERT_EQ(test, ret, 0);
125 +
126 + clk_put(clk);
127 +
128 + new_parent_rate = clk_get_rate(parent);
129 + KUNIT_ASSERT_GT(test, new_parent_rate, 0);
130 + KUNIT_EXPECT_EQ(test, parent_rate, new_parent_rate);
131 +
132 + clk_put(parent);
133 +}
134 +
135 +/*
136 + * Test that, for a mux that started orphan but got switched to a valid
137 * parent, calling clk_set_rate_range() will affect the parent state if
138 * its rate is out of range.
139 */
140 @@ -635,6 +701,41 @@ clk_test_orphan_transparent_multiple_par
141 }
142
143 /*
144 + * Test that, for a mux that started orphan but got switched to a valid
145 + * parent, calling clk_set_rate_range() won't affect the parent state if
146 + * its rate is within range.
147 + */
148 +static void
149 +clk_test_orphan_transparent_multiple_parent_mux_set_parent_set_range_untouched(struct kunit *test)
150 +{
151 + struct clk_multiple_parent_ctx *ctx = test->priv;
152 + struct clk_hw *hw = &ctx->hw;
153 + struct clk *clk = hw->clk, *parent;
154 + unsigned long parent_rate, new_parent_rate;
155 + int ret;
156 +
157 + parent = clk_hw_get_clk(&ctx->parents_ctx[1].hw, NULL);
158 + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, parent);
159 +
160 + parent_rate = clk_get_rate(parent);
161 + KUNIT_ASSERT_GT(test, parent_rate, 0);
162 +
163 + ret = clk_set_parent(clk, parent);
164 + KUNIT_ASSERT_EQ(test, ret, 0);
165 +
166 + ret = clk_set_rate_range(clk,
167 + DUMMY_CLOCK_INIT_RATE - 1000,
168 + DUMMY_CLOCK_INIT_RATE + 1000);
169 + KUNIT_ASSERT_EQ(test, ret, 0);
170 +
171 + new_parent_rate = clk_get_rate(parent);
172 + KUNIT_ASSERT_GT(test, new_parent_rate, 0);
173 + KUNIT_EXPECT_EQ(test, parent_rate, new_parent_rate);
174 +
175 + clk_put(parent);
176 +}
177 +
178 +/*
179 * Test that, for a mux whose current parent hasn't been registered yet,
180 * calling clk_set_rate_range() will succeed, and will be taken into
181 * account when rounding a rate.
182 @@ -660,8 +761,11 @@ clk_test_orphan_transparent_multiple_par
183 static struct kunit_case clk_orphan_transparent_multiple_parent_mux_test_cases[] = {
184 KUNIT_CASE(clk_test_orphan_transparent_multiple_parent_mux_get_parent),
185 KUNIT_CASE(clk_test_orphan_transparent_multiple_parent_mux_set_parent),
186 + KUNIT_CASE(clk_test_orphan_transparent_multiple_parent_mux_set_parent_drop_range),
187 KUNIT_CASE(clk_test_orphan_transparent_multiple_parent_mux_set_parent_get_rate),
188 + KUNIT_CASE(clk_test_orphan_transparent_multiple_parent_mux_set_parent_put),
189 KUNIT_CASE(clk_test_orphan_transparent_multiple_parent_mux_set_parent_set_range_modified),
190 + KUNIT_CASE(clk_test_orphan_transparent_multiple_parent_mux_set_parent_set_range_untouched),
191 KUNIT_CASE(clk_test_orphan_transparent_multiple_parent_mux_set_range_round_rate),
192 {}
193 };
194 @@ -946,6 +1050,132 @@ static struct kunit_suite clk_orphan_tra
195 .test_cases = clk_orphan_transparent_single_parent_mux_test_cases,
196 };
197
198 +struct clk_single_parent_two_lvl_ctx {
199 + struct clk_dummy_context parent_parent_ctx;
200 + struct clk_dummy_context parent_ctx;
201 + struct clk_hw hw;
202 +};
203 +
204 +static int
205 +clk_orphan_two_level_root_last_test_init(struct kunit *test)
206 +{
207 + struct clk_single_parent_two_lvl_ctx *ctx;
208 + int ret;
209 +
210 + ctx = kunit_kzalloc(test, sizeof(*ctx), GFP_KERNEL);
211 + if (!ctx)
212 + return -ENOMEM;
213 + test->priv = ctx;
214 +
215 + ctx->parent_ctx.hw.init =
216 + CLK_HW_INIT("intermediate-parent",
217 + "root-parent",
218 + &clk_dummy_single_parent_ops,
219 + CLK_SET_RATE_PARENT);
220 + ret = clk_hw_register(NULL, &ctx->parent_ctx.hw);
221 + if (ret)
222 + return ret;
223 +
224 + ctx->hw.init =
225 + CLK_HW_INIT("test-clk", "intermediate-parent",
226 + &clk_dummy_single_parent_ops,
227 + CLK_SET_RATE_PARENT);
228 + ret = clk_hw_register(NULL, &ctx->hw);
229 + if (ret)
230 + return ret;
231 +
232 + ctx->parent_parent_ctx.rate = DUMMY_CLOCK_INIT_RATE;
233 + ctx->parent_parent_ctx.hw.init =
234 + CLK_HW_INIT_NO_PARENT("root-parent",
235 + &clk_dummy_rate_ops,
236 + 0);
237 + ret = clk_hw_register(NULL, &ctx->parent_parent_ctx.hw);
238 + if (ret)
239 + return ret;
240 +
241 + return 0;
242 +}
243 +
244 +static void
245 +clk_orphan_two_level_root_last_test_exit(struct kunit *test)
246 +{
247 + struct clk_single_parent_two_lvl_ctx *ctx = test->priv;
248 +
249 + clk_hw_unregister(&ctx->hw);
250 + clk_hw_unregister(&ctx->parent_ctx.hw);
251 + clk_hw_unregister(&ctx->parent_parent_ctx.hw);
252 +}
253 +
254 +/*
255 + * Test that, for a clock whose parent used to be orphan, clk_get_rate()
256 + * will return the proper rate.
257 + */
258 +static void
259 +clk_orphan_two_level_root_last_test_get_rate(struct kunit *test)
260 +{
261 + struct clk_single_parent_two_lvl_ctx *ctx = test->priv;
262 + struct clk_hw *hw = &ctx->hw;
263 + struct clk *clk = hw->clk;
264 + unsigned long rate;
265 +
266 + rate = clk_get_rate(clk);
267 + KUNIT_EXPECT_EQ(test, rate, DUMMY_CLOCK_INIT_RATE);
268 +}
269 +
270 +/*
271 + * Test that, for a clock whose parent used to be orphan,
272 + * clk_set_rate_range() won't affect its rate if it is already within
273 + * range.
274 + *
275 + * See (for Exynos 4210):
276 + * https://lore.kernel.org/linux-clk/366a0232-bb4a-c357-6aa8-636e398e05eb@samsung.com/
277 + */
278 +static void
279 +clk_orphan_two_level_root_last_test_set_range(struct kunit *test)
280 +{
281 + struct clk_single_parent_two_lvl_ctx *ctx = test->priv;
282 + struct clk_hw *hw = &ctx->hw;
283 + struct clk *clk = hw->clk;
284 + unsigned long rate;
285 + int ret;
286 +
287 + ret = clk_set_rate_range(clk,
288 + DUMMY_CLOCK_INIT_RATE - 1000,
289 + DUMMY_CLOCK_INIT_RATE + 1000);
290 + KUNIT_ASSERT_EQ(test, ret, 0);
291 +
292 + rate = clk_get_rate(clk);
293 + KUNIT_ASSERT_GT(test, rate, 0);
294 + KUNIT_EXPECT_EQ(test, rate, DUMMY_CLOCK_INIT_RATE);
295 +}
296 +
297 +static struct kunit_case
298 +clk_orphan_two_level_root_last_test_cases[] = {
299 + KUNIT_CASE(clk_orphan_two_level_root_last_test_get_rate),
300 + KUNIT_CASE(clk_orphan_two_level_root_last_test_set_range),
301 + {}
302 +};
303 +
304 +/*
305 + * Test suite for a basic, transparent, clock with a parent that is also
306 + * such a clock. The parent's parent is registered last, while the
307 + * parent and its child are registered in that order. The intermediate
308 + * and leaf clocks will thus be orphan when registered, but the leaf
309 + * clock itself will always have its parent and will never be
310 + * reparented. Indeed, it's only orphan because its parent is.
311 + *
312 + * These tests are supposed to exercise the behaviour of the consumer
313 + * API when dealing with an orphan clock, and how we deal with the
314 + * transition to a valid parent.
315 + */
316 +static struct kunit_suite
317 +clk_orphan_two_level_root_last_test_suite = {
318 + .name = "clk-orphan-two-level-root-last-test",
319 + .init = clk_orphan_two_level_root_last_test_init,
320 + .exit = clk_orphan_two_level_root_last_test_exit,
321 + .test_cases = clk_orphan_two_level_root_last_test_cases,
322 +};
323 +
324 /*
325 * Test that clk_set_rate_range won't return an error for a valid range
326 * and that it will make sure the rate of the clock is within the
327 @@ -1629,6 +1859,7 @@ kunit_test_suites(
328 &clk_multiple_parents_mux_test_suite,
329 &clk_orphan_transparent_multiple_parent_mux_test_suite,
330 &clk_orphan_transparent_single_parent_test_suite,
331 + &clk_orphan_two_level_root_last_test_suite,
332 &clk_range_test_suite,
333 &clk_range_maximize_test_suite,
334 &clk_range_minimize_test_suite,