From patchwork Mon Dec 5 10:09:09 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Bartosz Golaszewski X-Patchwork-Id: 86535 Delivered-To: patch@linaro.org Received: by 10.140.20.101 with SMTP id 92csp1396091qgi; Mon, 5 Dec 2016 02:09:32 -0800 (PST) X-Received: by 10.99.245.21 with SMTP id w21mr102347933pgh.5.1480932572577; Mon, 05 Dec 2016 02:09:32 -0800 (PST) Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id a5si14072988pgh.296.2016.12.05.02.09.32; Mon, 05 Dec 2016 02:09:32 -0800 (PST) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; dkim=pass header.i=@baylibre-com.20150623.gappssmtp.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752269AbcLEKJ1 (ORCPT + 25 others); Mon, 5 Dec 2016 05:09:27 -0500 Received: from mail-wj0-f182.google.com ([209.85.210.182]:33222 "EHLO mail-wj0-f182.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752110AbcLEKJU (ORCPT ); Mon, 5 Dec 2016 05:09:20 -0500 Received: by mail-wj0-f182.google.com with SMTP id xy5so285322058wjc.0 for ; Mon, 05 Dec 2016 02:09:19 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=baylibre-com.20150623.gappssmtp.com; s=20150623; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=VIzVI2GCApzwsktF3nYdrh0TnRbl7XwzC2XClnz7/CY=; b=T7zg/z/ceQ2M8pXbV1/TJooy0BZoRfQwRsooOsoaXznwunqT9/ugPXWAFBCgOQIz7W OI1sp0OdT5QFnsaCmKCW6n+obGktIH2KgBtM7UT9cR00iwp+09a8l1tMVYLeg7bQxjNQ NqUlfYHq1tfRGvMGMam7BbxuEEvJOSYsBXRX3Qs0VIFW+yUxgKs3UbWkezp9u9c3HnOJ I2JCI/ck/F/KHEHeps5z5IADS4mKb17Ti3y8ssAkmYhSUZArnZXW5WpHbXS19qHnShVi AfJE9ATlzua08LdR5KUfsxdAsRtUh7her0XUjdEPQsNJ0mlphINa+JtQcRKKbBoGWDZb V45w== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=VIzVI2GCApzwsktF3nYdrh0TnRbl7XwzC2XClnz7/CY=; b=jiObXMZ0GF5dD6jWf6A2CMy/wAtAtsVUNUZQgKUGKNKgj/ls927TPl9Q0uAsmeWmJ3 4dSxRIDANwKtcOnbsrhvIUAokWgwimyRIuKD98S+mz694hQ5xcSJOlqmWRdXlP4d9uG0 r+pxS3eJ+XJyOmiK8pR9hakV0ZjJIU1CEvlXxErwcE0cWoHGY44NgTfoR8KzZ/Y8q0rq owAP8cMyaVCjpaa7RKogaBoxQPZNDzyF9iHayAu+Uqa4YR+GUu3u5eUYKpeI6X0Q/Ivm o39p2ftWPj/TJ+P+ry7v8NyFLh9VH6aBiuoRVBFsVcKXLhTKgA9FKx0fT//DVf5Wqwqr IO0g== X-Gm-Message-State: AKaTC00FBU3RGRD1wUqbJ0VUapr1DMEhmIxmNQ8uRrMVbDsW2SXfgv4ELnd7SqTGxbS9Cay9 X-Received: by 10.194.20.68 with SMTP id l4mr49193864wje.49.1480932558179; Mon, 05 Dec 2016 02:09:18 -0800 (PST) Received: from localhost.localdomain ([90.63.244.31]) by smtp.gmail.com with ESMTPSA id ef10sm19526939wjd.22.2016.12.05.02.09.17 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Mon, 05 Dec 2016 02:09:17 -0800 (PST) From: Bartosz Golaszewski To: Kevin Hilman , Michael Turquette , Sekhar Nori , Peter Ujfalusi , Russell King , Viresh Kumar , Boris Brezillon , "Rafael J. Wysocki" , Richard Weinberger , David Woodhouse , Brian Norris , Marek Vasut , Cyrille Pitchen Cc: LKML , arm-soc , linux-pm@vger.kernel.org, Bartosz Golaszewski Subject: [PATCH v3 3/3] ARM: da850: fix da850_set_pll0rate() Date: Mon, 5 Dec 2016 11:09:09 +0100 Message-Id: <1480932549-30811-4-git-send-email-bgolaszewski@baylibre.com> X-Mailer: git-send-email 2.1.4 In-Reply-To: <1480932549-30811-1-git-send-email-bgolaszewski@baylibre.com> References: <1480932549-30811-1-git-send-email-bgolaszewski@baylibre.com> Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org This function is confusing - its second argument is an index to the freq table, not the requested clock rate in Hz, but it's used as the set_rate callback for the pll0 clock. It leads to an oops when the caller doesn't know the internals and passes the rate in Hz as argument instead of the cpufreq index since this argument isn't bounds checked either. Fix it by iterating over the array of supported frequencies and selecting a one that matches or returning -EINVAL for unsupported rates. Also: update the davinci cpufreq driver. It's the only user of this clock and currently it passes the cpufreq table index to clk_set_rate(), which is confusing. Make it pass the requested clock rate in Hz. Signed-off-by: Bartosz Golaszewski Acked-by: Viresh Kumar --- arch/arm/mach-davinci/da850.c | 20 ++++++++++++++++---- drivers/cpufreq/davinci-cpufreq.c | 2 +- 2 files changed, 17 insertions(+), 5 deletions(-) -- 2.9.3 diff --git a/arch/arm/mach-davinci/da850.c b/arch/arm/mach-davinci/da850.c index 006ec56..9837541 100644 --- a/arch/arm/mach-davinci/da850.c +++ b/arch/arm/mach-davinci/da850.c @@ -1179,14 +1179,26 @@ static int da850_set_armrate(struct clk *clk, unsigned long index) return clk_set_rate(pllclk, index); } -static int da850_set_pll0rate(struct clk *clk, unsigned long index) +static int da850_set_pll0rate(struct clk *clk, unsigned long rate) { - unsigned int prediv, mult, postdiv; - struct da850_opp *opp; struct pll_data *pll = clk->pll_data; + struct cpufreq_frequency_table *freq; + unsigned int prediv, mult, postdiv; + struct da850_opp *opp = NULL; int ret; - opp = (struct da850_opp *) cpufreq_info.freq_table[index].driver_data; + for (freq = da850_freq_table; + freq->frequency != CPUFREQ_TABLE_END; freq++) { + /* rate is in Hz, freq->frequency is in KHz */ + if (freq->frequency == rate / 1000) { + opp = (struct da850_opp *)freq->driver_data; + break; + } + } + + if (opp == NULL) + return -EINVAL; + prediv = opp->prediv; mult = opp->mult; postdiv = opp->postdiv; diff --git a/drivers/cpufreq/davinci-cpufreq.c b/drivers/cpufreq/davinci-cpufreq.c index b95a872..d54a27c 100644 --- a/drivers/cpufreq/davinci-cpufreq.c +++ b/drivers/cpufreq/davinci-cpufreq.c @@ -55,7 +55,7 @@ static int davinci_target(struct cpufreq_policy *policy, unsigned int idx) return ret; } - ret = clk_set_rate(armclk, idx); + ret = clk_set_rate(armclk, new_freq * 1000); if (ret) return ret;