From patchwork Tue Dec 3 05:50:46 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Viresh Kumar X-Patchwork-Id: 21944 Return-Path: X-Original-To: linaro@patches.linaro.org Delivered-To: linaro@patches.linaro.org Received: from mail-oa0-f71.google.com (mail-oa0-f71.google.com [209.85.219.71]) by ip-10-151-82-157.ec2.internal (Postfix) with ESMTPS id 6D68720299 for ; Tue, 3 Dec 2013 05:50:59 +0000 (UTC) Received: by mail-oa0-f71.google.com with SMTP id i4sf46085934oah.6 for ; Mon, 02 Dec 2013 21:50:59 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:mime-version:delivered-to:from:to:cc:subject :date:message-id:in-reply-to:references:in-reply-to:references :x-original-sender:x-original-authentication-results:precedence :mailing-list:list-id:list-post:list-help:list-archive :list-unsubscribe; bh=YBBmn6C9hKnurx+2bpLnYNlS0VFBfnyZpzIpI1+9hz0=; b=Mo03SXwcBcGYvM8QyNpnmnv6L8xKNrbho26QYjZbQunqGY0UV5mvz9nkyahI6UJqNc UkzFd6pw/J2ZUvWOA3f9AGAB59kSoYBbduPVql7HRdTKwqJwvfEnf0pwFzOXQahhbNYO z/XCtkA5Ehq0mxHKFuujyiWVRGH8iFt5ao7+5jDwOegTP4DrQ9GxDcrKtP7t57BRz9uX Wm8aaE0vF2ClFidiuwNFdicpnov7dIQmR8fIqcodCIKiFxwBN+ErlcMAa+o8Yeb1nN9z rM9y12NgGb85en8lVRV6xkSM1HhdAoNbSLA+eXAqKl1qE3q+WvlxQtA0NpteIriXadwZ 9j+g== X-Gm-Message-State: ALoCoQnHkgkS9WP7ieuSWukxvemnGJM5AsLuIDXVHOakGjIP/9d8sXT7/nyVZ3584u/9pW6YfB+W X-Received: by 10.50.122.100 with SMTP id lr4mr423784igb.0.1386049859060; Mon, 02 Dec 2013 21:50:59 -0800 (PST) MIME-Version: 1.0 X-BeenThere: patchwork-forward@linaro.org Received: by 10.49.118.233 with SMTP id kp9ls4523695qeb.4.gmail; Mon, 02 Dec 2013 21:50:59 -0800 (PST) X-Received: by 10.58.187.51 with SMTP id fp19mr35807vec.47.1386049858954; Mon, 02 Dec 2013 21:50:58 -0800 (PST) Received: from mail-ve0-f179.google.com (mail-ve0-f179.google.com [209.85.128.179]) by mx.google.com with ESMTPS id uh5si30745537vcb.127.2013.12.02.21.50.58 for (version=TLSv1 cipher=ECDHE-RSA-RC4-SHA bits=128/128); Mon, 02 Dec 2013 21:50:58 -0800 (PST) Received-SPF: neutral (google.com: 209.85.128.179 is neither permitted nor denied by best guess record for domain of patch+caf_=patchwork-forward=linaro.org@linaro.org) client-ip=209.85.128.179; Received: by mail-ve0-f179.google.com with SMTP id jw12so9625909veb.38 for ; Mon, 02 Dec 2013 21:50:58 -0800 (PST) X-Received: by 10.58.46.18 with SMTP id r18mr55348809vem.4.1386049858805; Mon, 02 Dec 2013 21:50:58 -0800 (PST) X-Forwarded-To: patchwork-forward@linaro.org X-Forwarded-For: patch@linaro.org patchwork-forward@linaro.org Delivered-To: patches@linaro.org Received: by 10.220.174.196 with SMTP id u4csp181469vcz; Mon, 2 Dec 2013 21:50:58 -0800 (PST) X-Received: by 10.49.15.3 with SMTP id t3mr19044651qec.22.1386049857821; Mon, 02 Dec 2013 21:50:57 -0800 (PST) Received: from mail-qe0-f42.google.com (mail-qe0-f42.google.com [209.85.128.42]) by mx.google.com with ESMTPS id l10si18715873qcn.101.2013.12.02.21.50.57 for (version=TLSv1 cipher=ECDHE-RSA-RC4-SHA bits=128/128); Mon, 02 Dec 2013 21:50:57 -0800 (PST) Received-SPF: neutral (google.com: 209.85.128.42 is neither permitted nor denied by best guess record for domain of viresh.kumar@linaro.org) client-ip=209.85.128.42; Received: by mail-qe0-f42.google.com with SMTP id b4so13736129qen.15 for ; Mon, 02 Dec 2013 21:50:57 -0800 (PST) X-Received: by 10.49.81.206 with SMTP id c14mr20727355qey.79.1386049857420; Mon, 02 Dec 2013 21:50:57 -0800 (PST) Received: from localhost (git.linaro.org. [54.235.93.228]) by mx.google.com with ESMTPSA id o10sm2662046qaa.6.2013.12.02.21.50.55 for (version=TLSv1.2 cipher=RC4-SHA bits=128/128); Mon, 02 Dec 2013 21:50:56 -0800 (PST) From: Viresh Kumar To: rjw@rjwysocki.net Cc: linaro-kernel@lists.linaro.org, patches@linaro.org, cpufreq@vger.kernel.org, linux-pm@vger.kernel.org, linux-kernel@vger.kernel.org, nm@ti.com, ceh@ti.com, dirk.brandewie@gmail.com, Viresh Kumar Subject: [PATCH V5 2/2] cpufreq: Make sure CPU is running on a freq from freq-table Date: Tue, 3 Dec 2013 11:20:46 +0530 Message-Id: X-Mailer: git-send-email 1.7.12.rc2.18.g61b472e In-Reply-To: <9d053f4218adb8b1b1527a3a37d5ceffbbc5f1c3.1386049700.git.viresh.kumar@linaro.org> References: <9d053f4218adb8b1b1527a3a37d5ceffbbc5f1c3.1386049700.git.viresh.kumar@linaro.org> In-Reply-To: <9d053f4218adb8b1b1527a3a37d5ceffbbc5f1c3.1386049700.git.viresh.kumar@linaro.org> References: <9d053f4218adb8b1b1527a3a37d5ceffbbc5f1c3.1386049700.git.viresh.kumar@linaro.org> X-Removed-Original-Auth: Dkim didn't pass. X-Original-Sender: viresh.kumar@linaro.org X-Original-Authentication-Results: mx.google.com; spf=neutral (google.com: 209.85.128.179 is neither permitted nor denied by best guess record for domain of patch+caf_=patchwork-forward=linaro.org@linaro.org) smtp.mail=patch+caf_=patchwork-forward=linaro.org@linaro.org Precedence: list Mailing-list: list patchwork-forward@linaro.org; contact patchwork-forward+owners@linaro.org List-ID: X-Google-Group-Id: 836684582541 List-Post: , List-Help: , List-Archive: List-Unsubscribe: , Sometimes boot loaders set CPU frequency to a value outside of frequency table present with cpufreq core. In such cases CPU might be unstable if it has to run on that frequency for long duration of time and so its better to set it to a frequency which is specified in freq-table. This also makes cpufreq stats inconsistent as cpufreq-stats would fail to register because current frequency of CPU isn't found in freq-table. Because we don't want this change to effect boot process badly, we go for the next freq which is >= policy->cur ('cur' must be set by now, otherwise we will end up setting freq to lowest of the table as 'cur' is initialized to zero). In case current frequency doesn't match any frequency from freq-table, we throw warnings to user, so that user can get this fixed in their bootloaders or freq-tables. Reported-by: Carlos Hernandez Reported-and-tested-by: Nishanth Menon Signed-off-by: Viresh Kumar --- drivers/cpufreq/cpufreq.c | 40 ++++++++++++++++++++++++++++++++++++++++ drivers/cpufreq/freq_table.c | 22 ++++++++++++++++++++++ include/linux/cpufreq.h | 2 ++ 3 files changed, 64 insertions(+) diff --git a/drivers/cpufreq/cpufreq.c b/drivers/cpufreq/cpufreq.c index 606224a..15a962e 100644 --- a/drivers/cpufreq/cpufreq.c +++ b/drivers/cpufreq/cpufreq.c @@ -1042,6 +1042,46 @@ static int __cpufreq_add_dev(struct device *dev, struct subsys_interface *sif, } } + /* + * Sometimes boot loaders set CPU frequency to a value outside of + * frequency table present with cpufreq core. In such cases CPU might be + * unstable if it has to run on that frequency for long duration of time + * and so its better to set it to a frequency which is specified in + * freq-table. This also makes cpufreq stats inconsistent as + * cpufreq-stats would fail to register because current frequency of CPU + * isn't found in freq-table. + * + * Because we don't want this change to effect boot process badly, we go + * for the next freq which is >= policy->cur ('cur' must be set by now, + * otherwise we will end up setting freq to lowest of the table as 'cur' + * is initialized to zero). + * + * We are passing target-freq as "policy->cur - 1" otherwise + * __cpufreq_driver_target() would simply fail, as policy->cur will be + * equal to target-freq. + */ + if ((cpufreq_driver->flags & CPUFREQ_NEED_INITIAL_FREQ_CHECK) + && has_target()) { + /* Are we running at unknown frequency ? */ + ret = cpufreq_frequency_table_get_index(policy, policy->cur); + if (ret == -EINVAL) { + /* Warn user and fix it */ + pr_warn("%s: CPU%d: Running at unlisted freq: %u KHz\n", + __func__, policy->cpu, policy->cur); + ret = __cpufreq_driver_target(policy, policy->cur - 1, + CPUFREQ_RELATION_L); + + /* + * Reaching here after boot in a few seconds may not + * mean that system will remain stable at "unknown" + * frequency for longer duration. Hence, a BUG_ON(). + */ + BUG_ON(ret); + pr_warn("%s: CPU%d: Unlisted initial frequency changed to: %u KHz\n", + __func__, policy->cpu, policy->cur); + } + } + /* related cpus should atleast have policy->cpus */ cpumask_or(policy->related_cpus, policy->related_cpus, policy->cpus); diff --git a/drivers/cpufreq/freq_table.c b/drivers/cpufreq/freq_table.c index 3458d27..a8ac042 100644 --- a/drivers/cpufreq/freq_table.c +++ b/drivers/cpufreq/freq_table.c @@ -178,7 +178,29 @@ int cpufreq_frequency_table_target(struct cpufreq_policy *policy, } EXPORT_SYMBOL_GPL(cpufreq_frequency_table_target); +int cpufreq_frequency_table_get_index(struct cpufreq_policy *policy, + unsigned int freq) +{ + struct cpufreq_frequency_table *table; + int i; + + table = cpufreq_frequency_get_table(policy->cpu); + if (unlikely(!table)) { + pr_debug("%s: Unable to find frequency table\n", __func__); + return -ENOENT; + } + + for (i = 0; table[i].frequency != CPUFREQ_TABLE_END; i++) { + if (table[i].frequency == freq) + return i; + } + + return -EINVAL; +} +EXPORT_SYMBOL_GPL(cpufreq_frequency_table_get_index); + static DEFINE_PER_CPU(struct cpufreq_frequency_table *, cpufreq_show_table); + /** * show_available_freqs - show available frequencies for the specified CPU */ diff --git a/include/linux/cpufreq.h b/include/linux/cpufreq.h index bfb62cb..115ceb4 100644 --- a/include/linux/cpufreq.h +++ b/include/linux/cpufreq.h @@ -456,6 +456,8 @@ int cpufreq_frequency_table_target(struct cpufreq_policy *policy, unsigned int target_freq, unsigned int relation, unsigned int *index); +int cpufreq_frequency_table_get_index(struct cpufreq_policy *policy, + unsigned int freq); void cpufreq_frequency_table_update_policy_cpu(struct cpufreq_policy *policy); ssize_t cpufreq_show_cpus(const struct cpumask *mask, char *buf);