1 From ca0a8c7c024409a0c83afdab7e436348d1a7390f Mon Sep 17 00:00:00 2001
2 From: Maxime Ripard <maxime@cerno.tech>
3 Date: Thu, 7 Apr 2022 14:11:37 +0200
4 Subject: [PATCH] clk: Introduce clk_core_has_parent()
6 We will need to know if a clk_core pointer has a given parent in other
7 functions, so let's create a clk_core_has_parent() function that
8 clk_has_parent() will call into.
10 For good measure, let's add some unit tests as well to make sure it
13 Tested-by: Alexander Stein <alexander.stein@ew.tq-group.com> # imx8mp
14 Tested-by: Marek Szyprowski <m.szyprowski@samsung.com> # exynos4210, meson g12b
15 Signed-off-by: Maxime Ripard <maxime@cerno.tech>
17 drivers/clk/clk.c | 36 +++++++++++++++++++++---------------
18 drivers/clk/clk_test.c | 32 ++++++++++++++++++++++++++++++++
19 2 files changed, 53 insertions(+), 15 deletions(-)
21 --- a/drivers/clk/clk.c
22 +++ b/drivers/clk/clk.c
23 @@ -545,6 +545,26 @@ static bool mux_is_better_rate(unsigned
24 static int clk_core_round_rate_nolock(struct clk_core *core,
25 struct clk_rate_request *req);
27 +static bool clk_core_has_parent(struct clk_core *core, struct clk_core *parent)
31 + /* Optimize for the case where the parent is already the parent. */
35 + for (i = 0; i < core->num_parents; i++) {
36 + struct clk_core *tmp = clk_core_get_parent_by_index(core, i);
47 int clk_mux_determine_rate_flags(struct clk_hw *hw,
48 struct clk_rate_request *req,
50 @@ -2568,25 +2588,11 @@ void clk_hw_reparent(struct clk_hw *hw,
52 bool clk_has_parent(struct clk *clk, struct clk *parent)
54 - struct clk_core *core, *parent_core;
57 /* NULL clocks should be nops, so return success if either is NULL. */
62 - parent_core = parent->core;
64 - /* Optimize for the case where the parent is already the parent. */
65 - if (core->parent == parent_core)
68 - for (i = 0; i < core->num_parents; i++)
69 - if (!strcmp(core->parents[i].name, parent_core->name))
73 + return clk_core_has_parent(clk->core, parent->core);
75 EXPORT_SYMBOL_GPL(clk_has_parent);
77 --- a/drivers/clk/clk_test.c
78 +++ b/drivers/clk/clk_test.c
79 @@ -473,8 +473,24 @@ clk_test_multiple_parents_mux_get_parent
80 KUNIT_EXPECT_TRUE(test, clk_is_match(parent, ctx->parents_ctx[0].hw.clk));
84 + * Test that for a clock with a multiple parents, clk_has_parent()
85 + * actually reports all of them as parents.
88 +clk_test_multiple_parents_mux_has_parent(struct kunit *test)
90 + struct clk_multiple_parent_ctx *ctx = test->priv;
91 + struct clk_hw *hw = &ctx->hw;
92 + struct clk *clk = hw->clk;
94 + KUNIT_EXPECT_TRUE(test, clk_has_parent(clk, ctx->parents_ctx[0].hw.clk));
95 + KUNIT_EXPECT_TRUE(test, clk_has_parent(clk, ctx->parents_ctx[1].hw.clk));
98 static struct kunit_case clk_multiple_parents_mux_test_cases[] = {
99 KUNIT_CASE(clk_test_multiple_parents_mux_get_parent),
100 + KUNIT_CASE(clk_test_multiple_parents_mux_has_parent),
104 @@ -907,6 +923,21 @@ clk_test_single_parent_mux_get_parent(st
108 + * Test that for a clock with a single parent, clk_has_parent() actually
109 + * reports it as a parent.
112 +clk_test_single_parent_mux_has_parent(struct kunit *test)
114 + struct clk_single_parent_ctx *ctx = test->priv;
115 + struct clk_hw *hw = &ctx->hw;
116 + struct clk *clk = hw->clk;
117 + struct clk *parent = ctx->parent_ctx.hw.clk;
119 + KUNIT_EXPECT_TRUE(test, clk_has_parent(clk, parent));
123 * Test that for a clock that can't modify its rate and with a single
124 * parent, if we set disjoints range on the parent and then the child,
125 * the second will return an error.
126 @@ -1004,6 +1035,7 @@ clk_test_single_parent_mux_set_range_rou
128 static struct kunit_case clk_single_parent_mux_test_cases[] = {
129 KUNIT_CASE(clk_test_single_parent_mux_get_parent),
130 + KUNIT_CASE(clk_test_single_parent_mux_has_parent),
131 KUNIT_CASE(clk_test_single_parent_mux_set_range_disjoint_child_last),
132 KUNIT_CASE(clk_test_single_parent_mux_set_range_disjoint_parent_last),
133 KUNIT_CASE(clk_test_single_parent_mux_set_range_round_rate_child_smaller),