clk: tests: Add Kunit testing for nexus nodes

Add a nexus node with a child requesting a mapped clock in the fake DT
overlay to verify that the parsing is also correctly working.

Create an of_find_node_by_name() like kunit helper to garbage collect the
node automatically in case of failed assertion.

Suggested-by: Stephen Boyd <sboyd@kernel.org>
Signed-off-by: Miquel Raynal (Schneider Electric) <miquel.raynal@bootlin.com>
Reviewed-by: Frank Li <Frank.Li@nxp.com>
Signed-off-by: Brian Masney <bmasney@redhat.com>
This commit is contained in:
Miquel Raynal (Schneider Electric) 2026-08-07 17:24:08 +02:00 committed by Brian Masney
parent aacc54c678
commit 91b1b8d437
4 changed files with 58 additions and 0 deletions

View File

@ -233,5 +233,36 @@ int of_clk_add_hw_provider_kunit(struct kunit *test, struct device_node *np,
}
EXPORT_SYMBOL_GPL(of_clk_add_hw_provider_kunit);
KUNIT_DEFINE_ACTION_WRAPPER(of_node_put_wrapper, of_node_put, struct device_node *);
/**
* clk_of_find_node_by_name_kunit() - Test managed of_find_node_by_name()
* @test: The test context
* @from: Parent device node to start searching from, or NULL to search from root
* @name: The name string to match against
*
* Just like of_find_node_by_name(), except the device_node is managed by
* the test case and is automatically put after the test case concludes.
*
* Return: the device_node on success, NULL if not found, or an error pointer on failure.
*/
struct device_node *clk_of_find_node_by_name_kunit(struct kunit *test, struct device_node *from,
const char *name)
{
struct device_node *np;
int ret;
np = of_find_node_by_name(from, name);
if (!np)
return NULL;
ret = kunit_add_action_or_reset(test, of_node_put_wrapper, np);
if (ret)
return ERR_PTR(ret);
return np;
}
EXPORT_SYMBOL_GPL(clk_of_find_node_by_name_kunit);
MODULE_LICENSE("GPL");
MODULE_DESCRIPTION("KUnit helpers for clk providers and consumers");

View File

@ -3847,10 +3847,25 @@ static void of_clk_get_parent_name_gets_parent_name(struct kunit *test)
of_clk_get_parent_name(ctx->cons_np, 0));
}
static void of_clk_get_hw_maps_thru_nexus(struct kunit *test)
{
struct clk_parse_clkspec_ctx *ctx = test->priv;
struct clk_hw *expected;
struct device_node *np;
np = clk_of_find_node_by_name_kunit(test, NULL, "kunit-clock-nexus-child");
KUNIT_ASSERT_NOT_ERR_OR_NULL(test, np);
expected = of_clk_get_hw(ctx->cons_np, 1, NULL);
KUNIT_ASSERT_NOT_ERR_OR_NULL(test, expected);
KUNIT_EXPECT_PTR_EQ(test, expected, of_clk_get_hw(np, 0, NULL));
}
static struct kunit_case clk_parse_clkspec_test_cases[] = {
KUNIT_CASE(clk_parse_clkspec_with_correct_index_and_name),
KUNIT_CASE(clk_parse_clkspec_with_incorrect_index_and_name),
KUNIT_CASE(of_clk_get_parent_name_gets_parent_name),
KUNIT_CASE(of_clk_get_hw_maps_thru_nexus),
{}
};

View File

@ -18,4 +18,14 @@ kunit-clock-consumer {
clocks = <&kunit_clock_provider1 0>, <&kunit_clock_provider2 0>;
clock-names = "first_clock", "second_clock";
};
kunit_clock_nexus: kunit-clock-nexus {
clocks = <&kunit_clock_provider2 0>;
clock-map = <&kunit_clock_provider2 0>;
#clock-cells = <0>;
kunit-clock-nexus-child {
clocks = <&kunit_clock_nexus>;
};
};
};

View File

@ -29,5 +29,7 @@ int of_clk_hw_register_kunit(struct kunit *test, struct device_node *node,
int of_clk_add_hw_provider_kunit(struct kunit *test, struct device_node *np,
struct clk_hw *(*get)(struct of_phandle_args *clkspec, void *data),
void *data);
struct device_node *clk_of_find_node_by_name_kunit(struct kunit *test, struct device_node *from,
const char *name);
#endif