lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [thread-next>] [day] [month] [year] [list]
Message-Id: <1527775435-5017-1-git-send-email-mike.looijmans@topic.nl>
Date:   Thu, 31 May 2018 16:03:55 +0200
From:   Mike Looijmans <mike.looijmans@...ic.nl>
To:     linux-clk@...r.kernel.org
Cc:     linux-kernel@...r.kernel.org, mturquette@...libre.com,
        sboyd@...nel.org, Mike Looijmans <mike.looijmans@...ic.nl>
Subject: [PATCH] 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@...ic.nl>
---
 drivers/clk/clk-si544.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/clk/clk-si544.c b/drivers/clk/clk-si544.c
index d437722..e972ffb 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;
 
-- 
1.9.1

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ