diff options
author | Geert Uytterhoeven <geert+renesas@glider.be> | 2021-04-01 15:03:24 +0200 |
---|---|---|
committer | Geert Uytterhoeven <geert+renesas@glider.be> | 2021-05-11 10:00:40 +0200 |
commit | 6bd913f54f2f1973e741c6cf36b90175e8963175 (patch) | |
tree | 1cdacf28642d60cbb1dff58925bf4dd94dccb57b /drivers/clk | |
parent | 02c69593e62d51dd6b29b58724a6947ba72074f0 (diff) |
clk: renesas: r9a06g032: Switch to .determine_rate()
As the .round_rate() callback returns a long clock rate, it cannot
return clock rates that do not fit in signed long, but do fit in
unsigned long. Hence switch the divider clocks on RZ/N1 from the old
.round_rate() callback to the newer .determine_rate() callback, which
does not suffer from this limitation.
Note that range checking is not yet implemented.
Signed-off-by: Geert Uytterhoeven <geert+renesas@glider.be>
Link: https://lore.kernel.org/r/7a384d02b85cdaac4a0e2b357582c8244b9a6f98.1617282116.git.geert+renesas@glider.be
Diffstat (limited to 'drivers/clk')
-rw-r--r-- | drivers/clk/renesas/r9a06g032-clocks.c | 25 |
1 files changed, 13 insertions, 12 deletions
diff --git a/drivers/clk/renesas/r9a06g032-clocks.c b/drivers/clk/renesas/r9a06g032-clocks.c index 71b11443f6fc..c99942f0e4d4 100644 --- a/drivers/clk/renesas/r9a06g032-clocks.c +++ b/drivers/clk/renesas/r9a06g032-clocks.c @@ -604,20 +604,19 @@ r9a06g032_div_clamp_div(struct r9a06g032_clk_div *clk, return div; } -static long -r9a06g032_div_round_rate(struct clk_hw *hw, - unsigned long rate, unsigned long *prate) +static int +r9a06g032_div_determine_rate(struct clk_hw *hw, struct clk_rate_request *req) { struct r9a06g032_clk_div *clk = to_r9a06g032_div(hw); - u32 div = DIV_ROUND_UP(*prate, rate); + u32 div = DIV_ROUND_UP(req->best_parent_rate, req->rate); pr_devel("%s %pC %ld (prate %ld) (wanted div %u)\n", __func__, - hw->clk, rate, *prate, div); + hw->clk, req->rate, req->best_parent_rate, div); pr_devel(" min %d (%ld) max %d (%ld)\n", - clk->min, DIV_ROUND_UP(*prate, clk->min), - clk->max, DIV_ROUND_UP(*prate, clk->max)); + clk->min, DIV_ROUND_UP(req->best_parent_rate, clk->min), + clk->max, DIV_ROUND_UP(req->best_parent_rate, clk->max)); - div = r9a06g032_div_clamp_div(clk, rate, *prate); + div = r9a06g032_div_clamp_div(clk, req->rate, req->best_parent_rate); /* * this is a hack. Currently the serial driver asks for a clock rate * that is 16 times the baud rate -- and that is wildly outside the @@ -630,11 +629,13 @@ r9a06g032_div_round_rate(struct clk_hw *hw, if (clk->index == R9A06G032_DIV_UART || clk->index == R9A06G032_DIV_P2_PG) { pr_devel("%s div uart hack!\n", __func__); - return clk_get_rate(hw->clk); + req->rate = clk_get_rate(hw->clk); + return 0; } + req->rate = DIV_ROUND_UP(req->best_parent_rate, div); pr_devel("%s %pC %ld / %u = %ld\n", __func__, hw->clk, - *prate, div, DIV_ROUND_UP(*prate, div)); - return DIV_ROUND_UP(*prate, div); + req->best_parent_rate, div, req->rate); + return 0; } static int @@ -663,7 +664,7 @@ r9a06g032_div_set_rate(struct clk_hw *hw, static const struct clk_ops r9a06g032_clk_div_ops = { .recalc_rate = r9a06g032_div_recalc_rate, - .round_rate = r9a06g032_div_round_rate, + .determine_rate = r9a06g032_div_determine_rate, .set_rate = r9a06g032_div_set_rate, }; |