Skip to content

Commit 7dabfa2

Browse files
mripardbebarino
authored andcommitted
clk: Drop the rate range on clk_put()
When clk_put() is called we don't make another clk_set_rate() call to re-evaluate the rate boundaries. This is unlike clk_set_rate_range() that evaluates the rate again each time it is called. However, clk_put() is essentially equivalent to clk_set_rate_range() since after clk_put() completes the consumer's boundaries shouldn't be enforced anymore. Let's add a call to clk_set_rate_range() in clk_put() to make sure those rate boundaries are dropped and the clock provider drivers can react. Also add a few tests to make sure this case is covered. Fixes: c80ac50 ("clk: Always set the rate on clk_set_range_rate") Signed-off-by: Maxime Ripard <[email protected]> Link: https://lore.kernel.org/r/[email protected] [[email protected]: Reword commit text] Signed-off-by: Stephen Boyd <[email protected]>
1 parent 481f541 commit 7dabfa2

File tree

2 files changed

+136
-14
lines changed

2 files changed

+136
-14
lines changed

drivers/clk/clk.c

Lines changed: 28 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -2332,19 +2332,15 @@ int clk_set_rate_exclusive(struct clk *clk, unsigned long rate)
23322332
}
23332333
EXPORT_SYMBOL_GPL(clk_set_rate_exclusive);
23342334

2335-
/**
2336-
* clk_set_rate_range - set a rate range for a clock source
2337-
* @clk: clock source
2338-
* @min: desired minimum clock rate in Hz, inclusive
2339-
* @max: desired maximum clock rate in Hz, inclusive
2340-
*
2341-
* Returns success (0) or negative errno.
2342-
*/
2343-
int clk_set_rate_range(struct clk *clk, unsigned long min, unsigned long max)
2335+
static int clk_set_rate_range_nolock(struct clk *clk,
2336+
unsigned long min,
2337+
unsigned long max)
23442338
{
23452339
int ret = 0;
23462340
unsigned long old_min, old_max, rate;
23472341

2342+
lockdep_assert_held(&prepare_lock);
2343+
23482344
if (!clk)
23492345
return 0;
23502346

@@ -2357,8 +2353,6 @@ int clk_set_rate_range(struct clk *clk, unsigned long min, unsigned long max)
23572353
return -EINVAL;
23582354
}
23592355

2360-
clk_prepare_lock();
2361-
23622356
if (clk->exclusive_count)
23632357
clk_core_rate_unprotect(clk->core);
23642358

@@ -2402,6 +2396,28 @@ int clk_set_rate_range(struct clk *clk, unsigned long min, unsigned long max)
24022396
if (clk->exclusive_count)
24032397
clk_core_rate_protect(clk->core);
24042398

2399+
return ret;
2400+
}
2401+
2402+
/**
2403+
* clk_set_rate_range - set a rate range for a clock source
2404+
* @clk: clock source
2405+
* @min: desired minimum clock rate in Hz, inclusive
2406+
* @max: desired maximum clock rate in Hz, inclusive
2407+
*
2408+
* Return: 0 for success or negative errno on failure.
2409+
*/
2410+
int clk_set_rate_range(struct clk *clk, unsigned long min, unsigned long max)
2411+
{
2412+
int ret;
2413+
2414+
if (!clk)
2415+
return 0;
2416+
2417+
clk_prepare_lock();
2418+
2419+
ret = clk_set_rate_range_nolock(clk, min, max);
2420+
24052421
clk_prepare_unlock();
24062422

24072423
return ret;
@@ -4403,9 +4419,7 @@ void __clk_put(struct clk *clk)
44034419
}
44044420

44054421
hlist_del(&clk->clks_node);
4406-
if (clk->min_rate > clk->core->req_rate ||
4407-
clk->max_rate < clk->core->req_rate)
4408-
clk_core_set_rate_nolock(clk->core, clk->core->req_rate);
4422+
clk_set_rate_range_nolock(clk, 0, ULONG_MAX);
44094423

44104424
owner = clk->core->owner;
44114425
kref_put(&clk->core->ref, __clk_release);

drivers/clk/clk_test.c

Lines changed: 108 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -760,9 +760,65 @@ static void clk_range_test_multiple_set_range_rate_maximized(struct kunit *test)
760760
clk_put(user1);
761761
}
762762

763+
/*
764+
* Test that if we have several subsequent calls to
765+
* clk_set_rate_range(), across multiple users, the core will reevaluate
766+
* whether a new rate is needed, including when a user drop its clock.
767+
*
768+
* With clk_dummy_maximize_rate_ops, this means that the rate will
769+
* trail along the maximum as it evolves.
770+
*/
771+
static void clk_range_test_multiple_set_range_rate_put_maximized(struct kunit *test)
772+
{
773+
struct clk_dummy_context *ctx = test->priv;
774+
struct clk_hw *hw = &ctx->hw;
775+
struct clk *clk = hw->clk;
776+
struct clk *user1, *user2;
777+
unsigned long rate;
778+
779+
user1 = clk_hw_get_clk(hw, NULL);
780+
KUNIT_ASSERT_NOT_ERR_OR_NULL(test, user1);
781+
782+
user2 = clk_hw_get_clk(hw, NULL);
783+
KUNIT_ASSERT_NOT_ERR_OR_NULL(test, user2);
784+
785+
KUNIT_ASSERT_EQ(test,
786+
clk_set_rate(clk, DUMMY_CLOCK_RATE_2 + 1000),
787+
0);
788+
789+
KUNIT_ASSERT_EQ(test,
790+
clk_set_rate_range(user1,
791+
0,
792+
DUMMY_CLOCK_RATE_2),
793+
0);
794+
795+
rate = clk_get_rate(clk);
796+
KUNIT_ASSERT_GT(test, rate, 0);
797+
KUNIT_EXPECT_EQ(test, rate, DUMMY_CLOCK_RATE_2);
798+
799+
KUNIT_ASSERT_EQ(test,
800+
clk_set_rate_range(user2,
801+
0,
802+
DUMMY_CLOCK_RATE_1),
803+
0);
804+
805+
rate = clk_get_rate(clk);
806+
KUNIT_ASSERT_GT(test, rate, 0);
807+
KUNIT_EXPECT_EQ(test, rate, DUMMY_CLOCK_RATE_1);
808+
809+
clk_put(user2);
810+
811+
rate = clk_get_rate(clk);
812+
KUNIT_ASSERT_GT(test, rate, 0);
813+
KUNIT_EXPECT_EQ(test, rate, DUMMY_CLOCK_RATE_2);
814+
815+
clk_put(user1);
816+
}
817+
763818
static struct kunit_case clk_range_maximize_test_cases[] = {
764819
KUNIT_CASE(clk_range_test_set_range_rate_maximized),
765820
KUNIT_CASE(clk_range_test_multiple_set_range_rate_maximized),
821+
KUNIT_CASE(clk_range_test_multiple_set_range_rate_put_maximized),
766822
{}
767823
};
768824

@@ -877,9 +933,61 @@ static void clk_range_test_multiple_set_range_rate_minimized(struct kunit *test)
877933
clk_put(user1);
878934
}
879935

936+
/*
937+
* Test that if we have several subsequent calls to
938+
* clk_set_rate_range(), across multiple users, the core will reevaluate
939+
* whether a new rate is needed, including when a user drop its clock.
940+
*
941+
* With clk_dummy_minimize_rate_ops, this means that the rate will
942+
* trail along the minimum as it evolves.
943+
*/
944+
static void clk_range_test_multiple_set_range_rate_put_minimized(struct kunit *test)
945+
{
946+
struct clk_dummy_context *ctx = test->priv;
947+
struct clk_hw *hw = &ctx->hw;
948+
struct clk *clk = hw->clk;
949+
struct clk *user1, *user2;
950+
unsigned long rate;
951+
952+
user1 = clk_hw_get_clk(hw, NULL);
953+
KUNIT_ASSERT_NOT_ERR_OR_NULL(test, user1);
954+
955+
user2 = clk_hw_get_clk(hw, NULL);
956+
KUNIT_ASSERT_NOT_ERR_OR_NULL(test, user2);
957+
958+
KUNIT_ASSERT_EQ(test,
959+
clk_set_rate_range(user1,
960+
DUMMY_CLOCK_RATE_1,
961+
ULONG_MAX),
962+
0);
963+
964+
rate = clk_get_rate(clk);
965+
KUNIT_ASSERT_GT(test, rate, 0);
966+
KUNIT_EXPECT_EQ(test, rate, DUMMY_CLOCK_RATE_1);
967+
968+
KUNIT_ASSERT_EQ(test,
969+
clk_set_rate_range(user2,
970+
DUMMY_CLOCK_RATE_2,
971+
ULONG_MAX),
972+
0);
973+
974+
rate = clk_get_rate(clk);
975+
KUNIT_ASSERT_GT(test, rate, 0);
976+
KUNIT_EXPECT_EQ(test, rate, DUMMY_CLOCK_RATE_2);
977+
978+
clk_put(user2);
979+
980+
rate = clk_get_rate(clk);
981+
KUNIT_ASSERT_GT(test, rate, 0);
982+
KUNIT_EXPECT_EQ(test, rate, DUMMY_CLOCK_RATE_1);
983+
984+
clk_put(user1);
985+
}
986+
880987
static struct kunit_case clk_range_minimize_test_cases[] = {
881988
KUNIT_CASE(clk_range_test_set_range_rate_minimized),
882989
KUNIT_CASE(clk_range_test_multiple_set_range_rate_minimized),
990+
KUNIT_CASE(clk_range_test_multiple_set_range_rate_put_minimized),
883991
{}
884992
};
885993

0 commit comments

Comments
 (0)