diff options
author | Mike Looijmans <mike.looijmans@topic.nl> | 2018-05-31 16:03:55 +0200 |
---|---|---|
committer | Stephen Boyd <sboyd@kernel.org> | 2018-06-01 23:24:52 -0700 |
commit | 4d3f36c5e9ca0f947eed71660239c529c501141a (patch) | |
tree | 0ce6eb18c1bceef34d85a665ae8b7ad2bd08e2b8 /drivers/clk/clk-si544.c | |
parent | 60cc43fc888428bb2f18f08997432d426a243338 (diff) | |
download | lwn-4d3f36c5e9ca0f947eed71660239c529c501141a.tar.gz lwn-4d3f36c5e9ca0f947eed71660239c529c501141a.zip |
clk-si544: Properly round requested frequency to nearest match
The si544 driver had a rounding problem that using the result of clk_round_rate
may set the clock to yet another rate, for example:
clk_round_rate(195000000) = 194999999
clk_round_rate(194999999) = 194999998
Clients would expect that after clk_set_rate(clk, freq2=clk_round_rate(clk, freq)) the
chip will be running at exactly freq2.
The problem was in the calculation of the feedback divider, it was always rounded
down instead of to the nearest possible VCO value.
After this change, the following holds true for any supported frequency:
actual_freq = clk_round_rate(clk, freq);
clk_set_rate(clk, actual_freq);
clk_round_rate(clk, actual_freq) == actual_freq && clk_get_rate(clk) == actual_freq
Signed-off-by: Mike Looijmans <mike.looijmans@topic.nl>
Fixes: 953cc3e81170 ("clk: Add driver for the si544 clock generator chip")
Signed-off-by: Stephen Boyd <sboyd@kernel.org>
Diffstat (limited to 'drivers/clk/clk-si544.c')
-rw-r--r-- | drivers/clk/clk-si544.c | 1 |
1 files changed, 1 insertions, 0 deletions
diff --git a/drivers/clk/clk-si544.c b/drivers/clk/clk-si544.c index 1c96a9f6c022..1e2a3b8f9454 100644 --- a/drivers/clk/clk-si544.c +++ b/drivers/clk/clk-si544.c @@ -207,6 +207,7 @@ static int si544_calc_muldiv(struct clk_si544_muldiv *settings, /* And the fractional bits using the remainder */ vco = (u64)tmp << 32; + vco += FXO / 2; /* Round to nearest multiple */ do_div(vco, FXO); settings->fb_div_frac = vco; |