Skip to content

Commit c80ac50

Browse files
mripardbebarino
authored andcommitted
clk: Always set the rate on clk_set_range_rate
When we change a clock minimum or maximum using clk_set_rate_range(), clk_set_min_rate() or clk_set_max_rate(), the current code will only trigger a new rate change if the rate is outside of the new boundaries. However, a clock driver might want to always keep the clock rate to one of its boundary, for example the minimum to keep the power consumption as low as possible. Since they don't always get called though, clock providers don't have the opportunity to implement this behaviour. Let's trigger a clk_set_rate() on the previous requested rate every time clk_set_rate_range() is called. That way, providers that care about the new boundaries have a chance to adjust the rate, while providers that don't care about those new boundaries will return the same rate than before, which will be ignored by clk_set_rate() and won't result in a new rate change. Suggested-by: Stephen Boyd <[email protected]> Signed-off-by: Maxime Ripard <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Stephen Boyd <[email protected]>
1 parent a9b2693 commit c80ac50

File tree

2 files changed

+47
-52
lines changed

2 files changed

+47
-52
lines changed

drivers/clk/clk.c

Lines changed: 23 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -2373,28 +2373,29 @@ int clk_set_rate_range(struct clk *clk, unsigned long min, unsigned long max)
23732373
goto out;
23742374
}
23752375

2376-
rate = clk_core_get_rate_nolock(clk->core);
2377-
if (rate < min || rate > max) {
2378-
/*
2379-
* FIXME:
2380-
* We are in bit of trouble here, current rate is outside the
2381-
* the requested range. We are going try to request appropriate
2382-
* range boundary but there is a catch. It may fail for the
2383-
* usual reason (clock broken, clock protected, etc) but also
2384-
* because:
2385-
* - round_rate() was not favorable and fell on the wrong
2386-
* side of the boundary
2387-
* - the determine_rate() callback does not really check for
2388-
* this corner case when determining the rate
2389-
*/
2390-
2391-
rate = clamp(clk->core->req_rate, min, max);
2392-
ret = clk_core_set_rate_nolock(clk->core, rate);
2393-
if (ret) {
2394-
/* rollback the changes */
2395-
clk->min_rate = old_min;
2396-
clk->max_rate = old_max;
2397-
}
2376+
/*
2377+
* Since the boundaries have been changed, let's give the
2378+
* opportunity to the provider to adjust the clock rate based on
2379+
* the new boundaries.
2380+
*
2381+
* We also need to handle the case where the clock is currently
2382+
* outside of the boundaries. Clamping the last requested rate
2383+
* to the current minimum and maximum will also handle this.
2384+
*
2385+
* FIXME:
2386+
* There is a catch. It may fail for the usual reason (clock
2387+
* broken, clock protected, etc) but also because:
2388+
* - round_rate() was not favorable and fell on the wrong
2389+
* side of the boundary
2390+
* - the determine_rate() callback does not really check for
2391+
* this corner case when determining the rate
2392+
*/
2393+
rate = clamp(clk->core->req_rate, min, max);
2394+
ret = clk_core_set_rate_nolock(clk->core, rate);
2395+
if (ret) {
2396+
/* rollback the changes */
2397+
clk->min_rate = old_min;
2398+
clk->max_rate = old_max;
23982399
}
23992400

24002401
out:

drivers/clk/clk_test.c

Lines changed: 24 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -549,13 +549,12 @@ static struct kunit_suite clk_range_test_suite = {
549549
};
550550

551551
/*
552-
* Test that if:
553-
* - we have several subsequent calls to clk_set_rate_range();
554-
* - and we have a round_rate ops that always return the maximum
555-
* frequency allowed;
552+
* Test that if we have several subsequent calls to
553+
* clk_set_rate_range(), the core will reevaluate whether a new rate is
554+
* needed each and every time.
556555
*
557-
* The clock will run at the minimum of all maximum boundaries
558-
* requested, even if those boundaries aren't there anymore.
556+
* With clk_dummy_maximize_rate_ops, this means that the rate will
557+
* trail along the maximum as it evolves.
559558
*/
560559
static void clk_range_test_set_range_rate_maximized(struct kunit *test)
561560
{
@@ -596,18 +595,16 @@ static void clk_range_test_set_range_rate_maximized(struct kunit *test)
596595

597596
rate = clk_get_rate(clk);
598597
KUNIT_ASSERT_GT(test, rate, 0);
599-
KUNIT_EXPECT_EQ(test, rate, DUMMY_CLOCK_RATE_2 - 1000);
598+
KUNIT_EXPECT_EQ(test, rate, DUMMY_CLOCK_RATE_2);
600599
}
601600

602601
/*
603-
* Test that if:
604-
* - we have several subsequent calls to clk_set_rate_range(), across
605-
* multiple users;
606-
* - and we have a round_rate ops that always return the maximum
607-
* frequency allowed;
602+
* Test that if we have several subsequent calls to
603+
* clk_set_rate_range(), across multiple users, the core will reevaluate
604+
* whether a new rate is needed each and every time.
608605
*
609-
* The clock will run at the minimum of all maximum boundaries
610-
* requested, even if those boundaries aren't there anymore.
606+
* With clk_dummy_maximize_rate_ops, this means that the rate will
607+
* trail along the maximum as it evolves.
611608
*/
612609
static void clk_range_test_multiple_set_range_rate_maximized(struct kunit *test)
613610
{
@@ -653,7 +650,7 @@ static void clk_range_test_multiple_set_range_rate_maximized(struct kunit *test)
653650

654651
rate = clk_get_rate(clk);
655652
KUNIT_ASSERT_GT(test, rate, 0);
656-
KUNIT_EXPECT_EQ(test, rate, DUMMY_CLOCK_RATE_1);
653+
KUNIT_EXPECT_EQ(test, rate, DUMMY_CLOCK_RATE_2);
657654

658655
clk_put(user2);
659656
clk_put(user1);
@@ -673,13 +670,12 @@ static struct kunit_suite clk_range_maximize_test_suite = {
673670
};
674671

675672
/*
676-
* Test that if:
677-
* - we have several subsequent calls to clk_set_rate_range()
678-
* - and we have a round_rate ops that always return the minimum
679-
* frequency allowed;
673+
* Test that if we have several subsequent calls to
674+
* clk_set_rate_range(), the core will reevaluate whether a new rate is
675+
* needed each and every time.
680676
*
681-
* The clock will run at the maximum of all minimum boundaries
682-
* requested, even if those boundaries aren't there anymore.
677+
* With clk_dummy_minimize_rate_ops, this means that the rate will
678+
* trail along the minimum as it evolves.
683679
*/
684680
static void clk_range_test_set_range_rate_minimized(struct kunit *test)
685681
{
@@ -720,18 +716,16 @@ static void clk_range_test_set_range_rate_minimized(struct kunit *test)
720716

721717
rate = clk_get_rate(clk);
722718
KUNIT_ASSERT_GT(test, rate, 0);
723-
KUNIT_EXPECT_EQ(test, rate, DUMMY_CLOCK_RATE_1 + 1000);
719+
KUNIT_EXPECT_EQ(test, rate, DUMMY_CLOCK_RATE_1);
724720
}
725721

726722
/*
727-
* Test that if:
728-
* - we have several subsequent calls to clk_set_rate_range(), across
729-
* multiple users;
730-
* - and we have a round_rate ops that always return the minimum
731-
* frequency allowed;
723+
* Test that if we have several subsequent calls to
724+
* clk_set_rate_range(), across multiple users, the core will reevaluate
725+
* whether a new rate is needed each and every time.
732726
*
733-
* The clock will run at the maximum of all minimum boundaries
734-
* requested, even if those boundaries aren't there anymore.
727+
* With clk_dummy_minimize_rate_ops, this means that the rate will
728+
* trail along the minimum as it evolves.
735729
*/
736730
static void clk_range_test_multiple_set_range_rate_minimized(struct kunit *test)
737731
{
@@ -773,7 +767,7 @@ static void clk_range_test_multiple_set_range_rate_minimized(struct kunit *test)
773767

774768
rate = clk_get_rate(clk);
775769
KUNIT_ASSERT_GT(test, rate, 0);
776-
KUNIT_EXPECT_EQ(test, rate, DUMMY_CLOCK_RATE_2);
770+
KUNIT_EXPECT_EQ(test, rate, DUMMY_CLOCK_RATE_1);
777771

778772
clk_put(user2);
779773
clk_put(user1);

0 commit comments

Comments
 (0)