diff options
author | Geert Uytterhoeven <geert+renesas@glider.be> | 2021-04-01 15:01:38 +0200 |
---|---|---|
committer | Geert Uytterhoeven <geert+renesas@glider.be> | 2021-05-11 09:58:13 +0200 |
commit | 02c69593e62d51dd6b29b58724a6947ba72074f0 (patch) | |
tree | 72aebf3369d313463915a1d090fe5229eb32f295 /drivers/clk/renesas | |
parent | 1c924fc679123e6057239693d226c8d8c5780626 (diff) |
clk: renesas: div6: Implement range checking
Consider the minimum and maximum clock rates imposed by clock users when
calculating the most appropriate clock rate in the .determine_rate()
callback.
Signed-off-by: Geert Uytterhoeven <geert+renesas@glider.be>
Link: https://lore.kernel.org/r/35ceb262c71f1b2e9864a39bde9dafd78b2981f4.1617281699.git.geert+renesas@glider.be
Diffstat (limited to 'drivers/clk/renesas')
-rw-r--r-- | drivers/clk/renesas/clk-div6.c | 8 |
1 files changed, 7 insertions, 1 deletions
diff --git a/drivers/clk/renesas/clk-div6.c b/drivers/clk/renesas/clk-div6.c index a9ac2a83c1d0..3abd6e5400ad 100644 --- a/drivers/clk/renesas/clk-div6.c +++ b/drivers/clk/renesas/clk-div6.c @@ -106,8 +106,8 @@ static int cpg_div6_clock_determine_rate(struct clk_hw *hw, unsigned long prate, calc_rate, diff, best_rate, best_prate; unsigned int num_parents = clk_hw_get_num_parents(hw); struct clk_hw *parent, *best_parent = NULL; + unsigned int i, min_div, max_div, div; unsigned long min_diff = ULONG_MAX; - unsigned int i, div; for (i = 0; i < num_parents; i++) { parent = clk_hw_get_parent_by_index(hw, i); @@ -118,7 +118,13 @@ static int cpg_div6_clock_determine_rate(struct clk_hw *hw, if (!prate) continue; + min_div = max(DIV_ROUND_UP(prate, req->max_rate), 1UL); + max_div = req->min_rate ? min(prate / req->min_rate, 64UL) : 64; + if (max_div < min_div) + continue; + div = cpg_div6_clock_calc_div(req->rate, prate); + div = clamp(div, min_div, max_div); calc_rate = prate / div; diff = calc_rate > req->rate ? calc_rate - req->rate : req->rate - calc_rate; |