From patchwork Wed Mar 2 20:27:23 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Sasha Levin X-Patchwork-Id: 63423 Delivered-To: patch@linaro.org Received: by 10.112.199.169 with SMTP id jl9csp2582518lbc; Wed, 2 Mar 2016 12:29:17 -0800 (PST) X-Received: by 10.66.63.104 with SMTP id f8mr41648650pas.109.1456950527210; Wed, 02 Mar 2016 12:28:47 -0800 (PST) Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id 79si60163851pfm.61.2016.03.02.12.28.46; Wed, 02 Mar 2016 12:28:47 -0800 (PST) Received-SPF: pass (google.com: best guess record for domain of stable-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; spf=pass (google.com: best guess record for domain of stable-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=stable-owner@vger.kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1756599AbcCBU2p (ORCPT + 3 others); Wed, 2 Mar 2016 15:28:45 -0500 Received: from aserp1040.oracle.com ([141.146.126.69]:31500 "EHLO aserp1040.oracle.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1756636AbcCBU2j (ORCPT ); Wed, 2 Mar 2016 15:28:39 -0500 Received: from userv0022.oracle.com (userv0022.oracle.com [156.151.31.74]) by aserp1040.oracle.com (Sentrion-MTA-4.3.2/Sentrion-MTA-4.3.2) with ESMTP id u22KSPbi027779 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Wed, 2 Mar 2016 20:28:25 GMT Received: from userv0122.oracle.com (userv0122.oracle.com [156.151.31.75]) by userv0022.oracle.com (8.14.4/8.13.8) with ESMTP id u22KSPkZ028618 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=FAIL); Wed, 2 Mar 2016 20:28:25 GMT Received: from abhmp0015.oracle.com (abhmp0015.oracle.com [141.146.116.21]) by userv0122.oracle.com (8.14.4/8.14.4) with ESMTP id u22KSO4f022397; Wed, 2 Mar 2016 20:28:24 GMT Received: from lappy.us.oracle.com (/10.154.138.173) by default (Oracle Beehive Gateway v4.0) with ESMTP ; Wed, 02 Mar 2016 12:28:24 -0800 From: Sasha Levin To: stable@vger.kernel.org, stable-commits@vger.kernel.org Cc: Linus Walleij , linux-clk@vger.kernel.org, Pawel Moll , Russell King , Sasha Levin Subject: [added to the 3.18 stable tree] ARM: 8517/1: ICST: avoid arithmetic overflow in icst_hz() Date: Wed, 2 Mar 2016 15:27:23 -0500 Message-Id: <1456950474-1149-40-git-send-email-sasha.levin@oracle.com> X-Mailer: git-send-email 2.5.0 In-Reply-To: <1456950474-1149-1-git-send-email-sasha.levin@oracle.com> References: <1456950474-1149-1-git-send-email-sasha.levin@oracle.com> X-Source-IP: userv0022.oracle.com [156.151.31.74] Sender: stable-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: stable@vger.kernel.org From: Linus Walleij This patch has been added to the 3.18 stable tree. If you have any objections, please let us know. -- 2.5.0 -- To unsubscribe from this list: send the line "unsubscribe stable" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html =============== [ Upstream commit 5070fb14a0154f075c8b418e5bc58a620ae85a45 ] When trying to set the ICST 307 clock to 25174000 Hz I ran into this arithmetic error: the icst_hz_to_vco() correctly figure out DIVIDE=2, RDW=100 and VDW=99 yielding a frequency of 25174000 Hz out of the VCO. (I replicated the icst_hz() function in a spreadsheet to verify this.) However, when I called icst_hz() on these VCO settings it would instead return 4122709 Hz. This causes an error in the common clock driver for ICST as the common clock framework will call .round_rate() on the clock which will utilize icst_hz_to_vco() followed by icst_hz() suggesting the erroneous frequency, and then the clock gets set to this. The error did not manifest in the old clock framework since this high frequency was only used by the CLCD, which calls clk_set_rate() without first calling clk_round_rate() and since the old clock framework would not call clk_round_rate() before setting the frequency, the correct values propagated into the VCO. After some experimenting I figured out that it was due to a simple arithmetic overflow: the divisor for 24Mhz reference frequency as reference becomes 24000000*2*(99+8)=0x132212400 and the "1" in bit 32 overflows and is lost. But introducing an explicit 64-by-32 bit do_div() and casting the divisor into (u64) we get the right frequency back, and the right frequency gets set. Tested on the ARM Versatile. Cc: stable@vger.kernel.org Cc: linux-clk@vger.kernel.org Cc: Pawel Moll Signed-off-by: Linus Walleij Signed-off-by: Russell King Signed-off-by: Sasha Levin --- arch/arm/common/icst.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/arch/arm/common/icst.c b/arch/arm/common/icst.c index 2dc6da70..d3c0e69 100644 --- a/arch/arm/common/icst.c +++ b/arch/arm/common/icst.c @@ -16,7 +16,7 @@ */ #include #include - +#include #include /* @@ -29,7 +29,11 @@ EXPORT_SYMBOL(icst525_s2div); unsigned long icst_hz(const struct icst_params *p, struct icst_vco vco) { - return p->ref * 2 * (vco.v + 8) / ((vco.r + 2) * p->s2div[vco.s]); + u64 dividend = p->ref * 2 * (u64)(vco.v + 8); + u32 divisor = (vco.r + 2) * p->s2div[vco.s]; + + do_div(dividend, divisor); + return (unsigned long)dividend; } EXPORT_SYMBOL(icst_hz);