Skip to content

Commit 5f7e2af

Browse files
mripardbebarino
authored andcommitted
clk: Initialize orphan req_rate
When registering a clock that doesn't have a recalc_rate implementation, and doesn't have its parent registered yet, we initialize the clk_core rate and 'req_rate' fields to 0. The rate field is later updated when the parent is registered in clk_core_reparent_orphans_nolock() using __clk_recalc_rates(), but the 'req_rate' field is never updated. This leads to an issue in clk_set_rate_range() and clk_put(), since those functions will call clk_set_rate() with the content of 'req_rate' to provide drivers with the opportunity to change the rate based on the new boundaries. In this case, we would call clk_set_rate() with a rate of 0, effectively enforcing the minimum allowed for this clock whenever we would call one of those two functions, even though the actual rate might be within range. Let's fix this by setting 'req_rate' in clk_core_reparent_orphans_nolock() with the rate field content just updated by the call to __clk_recalc_rates(). Fixes: 1c8e600 ("clk: Add rate constraints to clocks") Reported-by: Dmitry Osipenko <[email protected]> Tested-by: Dmitry Osipenko <[email protected]> # T30 Nexus7 Signed-off-by: Maxime Ripard <[email protected]> Link: https://lore.kernel.org/r/[email protected] [[email protected]: Reword comment] Signed-off-by: Stephen Boyd <[email protected]>
1 parent e9d6cea commit 5f7e2af

File tree

1 file changed

+13
-0
lines changed

1 file changed

+13
-0
lines changed

drivers/clk/clk.c

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3479,6 +3479,19 @@ static void clk_core_reparent_orphans_nolock(void)
34793479
__clk_set_parent_after(orphan, parent, NULL);
34803480
__clk_recalc_accuracies(orphan);
34813481
__clk_recalc_rates(orphan, 0);
3482+
3483+
/*
3484+
* __clk_init_parent() will set the initial req_rate to
3485+
* 0 if the clock doesn't have clk_ops::recalc_rate and
3486+
* is an orphan when it's registered.
3487+
*
3488+
* 'req_rate' is used by clk_set_rate_range() and
3489+
* clk_put() to trigger a clk_set_rate() call whenever
3490+
* the boundaries are modified. Let's make sure
3491+
* 'req_rate' is set to something non-zero so that
3492+
* clk_set_rate_range() doesn't drop the frequency.
3493+
*/
3494+
orphan->req_rate = orphan->rate;
34823495
}
34833496
}
34843497
}

0 commit comments

Comments
 (0)