From patchwork Mon Aug 12 17:48:38 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Viresh Kumar X-Patchwork-Id: 19013 Return-Path: X-Original-To: linaro@patches.linaro.org Delivered-To: linaro@patches.linaro.org Received: from mail-qa0-f70.google.com (mail-qa0-f70.google.com [209.85.216.70]) by ip-10-151-82-157.ec2.internal (Postfix) with ESMTPS id E442B246B8 for ; Mon, 12 Aug 2013 17:49:49 +0000 (UTC) Received: by mail-qa0-f70.google.com with SMTP id cd7sf969758qab.9 for ; Mon, 12 Aug 2013 10:49:49 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20120113; h=mime-version:x-gm-message-state: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=MZrM0wxn9Y1y8qFmsZyjQyYDH48KvRW/ewP58WMwLQY=; b=kvmnVhv4mgnprfAJXwMxBZ/wncQVqQS1ZLYii4vsoQ1zAaxAUGX/k6IPoZD9gvcwiN /tsWPmVDviLAeLsj6gUS/xSymTUxHrnpKFMqjibPbLb726oaHIsobFlMWtmKSwScrht9 z9AqouGfWdl+c9s+WTRvwO96gWSH5vqi85/FN4vghPn8UEuSV5MsHgI9qN0vPLZTjy4v B1Zy/vBOSLmfolajxtIGG/vIBcztRWYkaXovj7yt3TlHcH2afc0TLyG/at66Y8JBlty5 HEDgChA+7eZFaBJFKW1k0luR+1d0r8qZO2lBns8lk+/bZD+xeME11ePRGku0PsH76ByN Ta8Q== X-Received: by 10.236.203.5 with SMTP id e5mr74003yho.3.1376329789766; Mon, 12 Aug 2013 10:49:49 -0700 (PDT) MIME-Version: 1.0 X-BeenThere: patchwork-forward@linaro.org Received: by 10.49.74.34 with SMTP id q2ls2337801qev.66.gmail; Mon, 12 Aug 2013 10:49:49 -0700 (PDT) X-Received: by 10.58.234.161 with SMTP id uf1mr140105vec.57.1376329789639; Mon, 12 Aug 2013 10:49:49 -0700 (PDT) Received: from mail-vc0-f178.google.com (mail-vc0-f178.google.com [209.85.220.178]) by mx.google.com with ESMTPS id wd10si8590322vcb.26.2013.08.12.10.49.49 for (version=TLSv1 cipher=ECDHE-RSA-RC4-SHA bits=128/128); Mon, 12 Aug 2013 10:49:49 -0700 (PDT) Received-SPF: neutral (google.com: 209.85.220.178 is neither permitted nor denied by best guess record for domain of patch+caf_=patchwork-forward=linaro.org@linaro.org) client-ip=209.85.220.178; Received: by mail-vc0-f178.google.com with SMTP id ha12so3083664vcb.9 for ; Mon, 12 Aug 2013 10:49:49 -0700 (PDT) X-Gm-Message-State: ALoCoQmHLS0B90fo2dDNeAZ6H/kLaYtLw0TX4j7YoVAoVEE2OZ6XIJKyCWukLYU1JA8GvRIRm9Xg X-Received: by 10.220.76.10 with SMTP id a10mr146157vck.31.1376329789515; Mon, 12 Aug 2013 10:49:49 -0700 (PDT) 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 u4csp108127vcz; Mon, 12 Aug 2013 10:49:48 -0700 (PDT) X-Received: by 10.68.52.200 with SMTP id v8mr245492pbo.48.1376329788438; Mon, 12 Aug 2013 10:49:48 -0700 (PDT) Received: from mail-pa0-f49.google.com (mail-pa0-f49.google.com [209.85.220.49]) by mx.google.com with ESMTPS id gh3si1208708pbc.287.2013.08.12.10.49.48 for (version=TLSv1 cipher=ECDHE-RSA-RC4-SHA bits=128/128); Mon, 12 Aug 2013 10:49:48 -0700 (PDT) Received-SPF: neutral (google.com: 209.85.220.49 is neither permitted nor denied by best guess record for domain of viresh.kumar@linaro.org) client-ip=209.85.220.49; Received: by mail-pa0-f49.google.com with SMTP id ld10so3244231pab.36 for ; Mon, 12 Aug 2013 10:49:48 -0700 (PDT) X-Received: by 10.68.34.97 with SMTP id y1mr210784pbi.198.1376329787992; Mon, 12 Aug 2013 10:49:47 -0700 (PDT) Received: from localhost ([122.172.193.46]) by mx.google.com with ESMTPSA id fk4sm41346462pab.23.2013.08.12.10.49.39 for (version=TLSv1.2 cipher=RC4-SHA bits=128/128); Mon, 12 Aug 2013 10:49:47 -0700 (PDT) From: Viresh Kumar To: rjw@sisk.pl Cc: linaro-kernel@lists.linaro.org, patches@linaro.org, cpufreq@vger.kernel.org, linux-pm@vger.kernel.org, linux-kernel@vger.kernel.org, Viresh Kumar , Andrew Lunn , "David S. Miller" , Dmitry Eremin-Solenikov , Eric Miao , Jesper Nilsson , John Crispin , Kukjin Kim , Linus Walleij , linux-cris-kernel@axis.com, Mikael Starvik , Santosh Shilimkar , Sekhar Nori , Shawn Guo , sparclinux@vger.kernel.org, Stephen Warren , Steven Miao , Tony Luck Subject: [PATCH 02/31] cpufreq: Implement light weight ->target() routine Date: Mon, 12 Aug 2013 23:18:38 +0530 Message-Id: <1e550a8b0292a64a6ba27d64b8d5f14b6194dcbd.1376329128.git.viresh.kumar@linaro.org> X-Mailer: git-send-email 1.7.12.rc2.18.g61b472e In-Reply-To: References: In-Reply-To: References: 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.220.178 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: , This patch implements the new light weight prototype for target() routine. It looks like this: int target(struct cpufreq_policy *policy, unsigned int index); CPUFreq core will call cpufreq_frequency_table_target() before calling this routine and pass index to it. This also marks target_old() interface as deprecated. So, that new drivers avoid using it. Cc: Andrew Lunn Cc: David S. Miller Cc: Dmitry Eremin-Solenikov Cc: Eric Miao Cc: Jesper Nilsson Cc: John Crispin Cc: Kukjin Kim Cc: Linus Walleij Cc: linux-cris-kernel@axis.com Cc: Mikael Starvik Cc: Santosh Shilimkar Cc: Sekhar Nori Cc: Shawn Guo Cc: sparclinux@vger.kernel.org Cc: Stephen Warren Cc: Steven Miao Cc: Tony Luck Signed-off-by: Viresh Kumar --- drivers/cpufreq/cpufreq.c | 55 +++++++++++++++++++++++++++++++++++++---------- include/linux/cpufreq.h | 4 +++- 2 files changed, 47 insertions(+), 12 deletions(-) diff --git a/drivers/cpufreq/cpufreq.c b/drivers/cpufreq/cpufreq.c index 1cbea5b..a897a70 100644 --- a/drivers/cpufreq/cpufreq.c +++ b/drivers/cpufreq/cpufreq.c @@ -47,6 +47,11 @@ static LIST_HEAD(cpufreq_policy_list); static DEFINE_PER_CPU(char[CPUFREQ_NAME_LEN], cpufreq_cpu_governor); #endif +static inline bool has_target(void) +{ + return cpufreq_driver->target || cpufreq_driver->target_old; +} + /* * cpu_policy_rwsem is a per CPU reader-writer semaphore designed to cure * all cpufreq/hotplug/workqueue/etc related lock issues. @@ -377,7 +382,7 @@ static int cpufreq_parse_governor(char *str_governor, unsigned int *policy, *policy = CPUFREQ_POLICY_POWERSAVE; err = 0; } - } else if (cpufreq_driver->target_old) { + } else if (has_target()) { struct cpufreq_governor *t; mutex_lock(&cpufreq_governor_mutex); @@ -539,7 +544,7 @@ static ssize_t show_scaling_available_governors(struct cpufreq_policy *policy, ssize_t i = 0; struct cpufreq_governor *t; - if (!cpufreq_driver->target_old) { + if (!has_target()) { i += sprintf(buf, "performance powersave"); goto out; } @@ -822,7 +827,7 @@ static int cpufreq_add_dev_interface(struct cpufreq_policy *policy, if (ret) goto err_out_kobj_put; } - if (cpufreq_driver->target_old) { + if (has_target()) { ret = sysfs_create_file(&policy->kobj, &scaling_cur_freq.attr); if (ret) goto err_out_kobj_put; @@ -871,10 +876,10 @@ static int cpufreq_add_policy_cpu(struct cpufreq_policy *policy, unsigned int cpu, struct device *dev, bool frozen) { - int ret = 0, has_target = !!cpufreq_driver->target_old; + int ret = 0; unsigned long flags; - if (has_target) { + if (has_target()) { ret = __cpufreq_governor(policy, CPUFREQ_GOV_STOP); if (ret) { pr_err("%s: Failed to stop governor\n", __func__); @@ -893,7 +898,7 @@ static int cpufreq_add_policy_cpu(struct cpufreq_policy *policy, unlock_policy_rwsem_write(policy->cpu); - if (has_target) { + if (has_target()) { if ((ret = __cpufreq_governor(policy, CPUFREQ_GOV_START)) || (ret = __cpufreq_governor(policy, CPUFREQ_GOV_LIMITS))) { pr_err("%s: Failed to start governor\n", __func__); @@ -1204,7 +1209,7 @@ static int __cpufreq_remove_dev(struct device *dev, return -EINVAL; } - if (cpufreq_driver->target_old) { + if (has_target()) { ret = __cpufreq_governor(policy, CPUFREQ_GOV_STOP); if (ret) { pr_err("%s: Failed to stop governor\n", __func__); @@ -1244,7 +1249,7 @@ static int __cpufreq_remove_dev(struct device *dev, /* If cpu is last user of policy, free policy */ if (cpus == 1) { - if (cpufreq_driver->target_old) { + if (has_target()) { ret = __cpufreq_governor(policy, CPUFREQ_GOV_POLICY_EXIT); if (ret) { @@ -1282,7 +1287,7 @@ static int __cpufreq_remove_dev(struct device *dev, if (!frozen) cpufreq_policy_free(policy); } else { - if (cpufreq_driver->target_old) { + if (has_target()) { if ((ret = __cpufreq_governor(policy, CPUFREQ_GOV_START)) || (ret = __cpufreq_governor(policy, CPUFREQ_GOV_LIMITS))) { pr_err("%s: Failed to start governor\n", @@ -1646,11 +1651,39 @@ int __cpufreq_driver_target(struct cpufreq_policy *policy, pr_debug("target for CPU %u: %u kHz, relation %u, requested %u kHz\n", policy->cpu, target_freq, relation, old_target_freq); + /* + * This might look like a redundant call as we are checking it again + * after finding index. But it is left intentionally for cases where + * exactly same freq is called again and so we can save on few function + * calls. + */ if (target_freq == policy->cur) return 0; if (cpufreq_driver->target_old) retval = cpufreq_driver->target_old(policy, target_freq, relation); + else if (cpufreq_driver->target) { + struct cpufreq_frequency_table *freq_table; + int index; + + freq_table = cpufreq_frequency_get_table(policy->cpu); + if (unlikely(!freq_table)) { + pr_err("%s: Unable to find freq_table\n", __func__); + return retval; + } + + retval = cpufreq_frequency_table_target(policy, freq_table, + target_freq, relation, &index); + if (unlikely(retval)) { + pr_err("%s: Unable to find matching freq\n", __func__); + return retval; + } + + if (freq_table[index].frequency == policy->cur) + return 0; + + retval = cpufreq_driver->target(policy, index); + } return retval; } @@ -1983,7 +2016,7 @@ int cpufreq_update_policy(unsigned int cpu) pr_debug("Driver did not initialize current freq"); policy->cur = new_policy.cur; } else { - if (policy->cur != new_policy.cur && cpufreq_driver->target_old) + if (policy->cur != new_policy.cur && has_target()) cpufreq_out_of_sync(cpu, policy->cur, new_policy.cur); } @@ -2058,7 +2091,7 @@ int cpufreq_register_driver(struct cpufreq_driver *driver_data) return -ENODEV; if (!driver_data || !driver_data->verify || !driver_data->init || - ((!driver_data->setpolicy) && (!driver_data->target_old))) + (!driver_data->setpolicy && !has_target())) return -EINVAL; pr_debug("trying to register driver %s\n", driver_data->name); diff --git a/include/linux/cpufreq.h b/include/linux/cpufreq.h index 47adf32..7c2e35b 100644 --- a/include/linux/cpufreq.h +++ b/include/linux/cpufreq.h @@ -195,9 +195,11 @@ struct cpufreq_driver { /* define one out of two */ int (*setpolicy) (struct cpufreq_policy *policy); - int (*target_old) (struct cpufreq_policy *policy, + int (*target_old) (struct cpufreq_policy *policy, /* Deprecated */ unsigned int target_freq, unsigned int relation); + int (*target) (struct cpufreq_policy *policy, + unsigned int index); /* should be defined, if possible */ unsigned int (*get) (unsigned int cpu);