>From 2367a5e238f0d26ae38510fb0fa2eb33a43cc046 Mon Sep 17 00:00:00 2001 From: Brian Masney Date: Fri, 16 Jan 2026 11:21:21 -0500 Subject: [PATCH] clk: test: introduce test to test the rollback of consumer's rate boundaries Content-type: text/plain Add a kunit test to ensure that when a second consumer requests an invalid rate range that the aggregated range is rolled back correctly, and the first consumer is not impacted. Signed-off-by: Brian Masney --- drivers/clk/clk_test.c | 53 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 53 insertions(+) diff --git a/drivers/clk/clk_test.c b/drivers/clk/clk_test.c index a268d7b5d4cb..afffa182559f 100644 --- a/drivers/clk/clk_test.c +++ b/drivers/clk/clk_test.c @@ -1500,6 +1500,58 @@ static void clk_range_test_multiple_disjoints_range(struct kunit *test) clk_put(user1); } +static void clk_range_test_consumer_boundaries_rollback(struct kunit *test) +{ + struct clk_dummy_context *ctx = test->priv; + struct clk_hw *hw = &ctx->hw; + unsigned long rate, min, max; + struct clk *user1, *user2; + int ret; + + user1 = clk_hw_get_clk(hw, NULL); + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, user1); + + user2 = clk_hw_get_clk(hw, NULL); + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, user2); + + /* user1 sets a range */ + ret = clk_set_rate_range(user1, 1000, 2000); + KUNIT_ASSERT_EQ(test, ret, 0); + + clk_hw_get_rate_range(hw, &min, &max); + KUNIT_ASSERT_EQ(test, min, 1000); + KUNIT_ASSERT_EQ(test, max, 2000); + + /* Verify user1 can set a rate within its range */ + ret = clk_set_rate(user1, 1500); + KUNIT_ASSERT_EQ(test, ret, 0); + rate = clk_get_rate(user1); + KUNIT_EXPECT_EQ(test, rate, 1500); + + /* user2 attempts to set a disjoint range [3000, 4000] - should fail */ + ret = clk_set_rate_range(user2, 3000, 4000); + KUNIT_EXPECT_EQ(test, ret, -EINVAL); + + /* + * After the failed call, user1 should still be able to set rates + * within its original range. This verifies that user2's boundaries + * were correctly rolled back and didn't corrupt the aggregated + * boundaries. + */ + + clk_hw_get_rate_range(hw, &min, &max); + KUNIT_EXPECT_EQ(test, min, 1000); + KUNIT_EXPECT_EQ(test, max, 2000); + + ret = clk_set_rate(user1, 1800); + KUNIT_EXPECT_EQ(test, ret, 0); + rate = clk_get_rate(user1); + KUNIT_EXPECT_EQ(test, rate, 1800); + + clk_put(user2); + clk_put(user1); +} + /* * Test that if our clock has some boundaries and we try to round a rate * lower than the minimum, the returned rate will be within range. @@ -1738,6 +1790,7 @@ static struct kunit_case clk_range_test_cases[] = { KUNIT_CASE(clk_range_test_set_range), KUNIT_CASE(clk_range_test_set_range_invalid), KUNIT_CASE(clk_range_test_multiple_disjoints_range), + KUNIT_CASE(clk_range_test_consumer_boundaries_rollback), KUNIT_CASE(clk_range_test_set_range_round_rate_lower), KUNIT_CASE(clk_range_test_set_range_set_rate_lower), KUNIT_CASE(clk_range_test_set_range_set_round_rate_consistent_lower), -- 2.52.0