From d9a789c7a07e96eda7515e43932ee608dcece34d Mon Sep 17 00:00:00 2001 From: "Rafael J. Wysocki" Date: Mon, 17 Feb 2014 22:56:35 +0100 Subject: [PATCH 1/2] cpufreq: Refactor cpufreq_set_policy() Reduce the rampant usage of goto and the indentation level in cpufreq_set_policy() to improve the readability of that code. No functional changes should result from that. Signed-off-by: Rafael J. Wysocki Acked-by: Viresh Kumar Reviewed-by: Srivatsa S. Bhat --- drivers/cpufreq/cpufreq.c | 103 +++++++++++++++++--------------------- 1 file changed, 46 insertions(+), 57 deletions(-) diff --git a/drivers/cpufreq/cpufreq.c b/drivers/cpufreq/cpufreq.c index cb003a6b72c8..37f30550522a 100644 --- a/drivers/cpufreq/cpufreq.c +++ b/drivers/cpufreq/cpufreq.c @@ -2017,22 +2017,21 @@ EXPORT_SYMBOL(cpufreq_get_policy); static int cpufreq_set_policy(struct cpufreq_policy *policy, struct cpufreq_policy *new_policy) { - int ret = 0, failed = 1; + struct cpufreq_governor *old_gov; + int ret; pr_debug("setting new policy for CPU %u: %u - %u kHz\n", new_policy->cpu, new_policy->min, new_policy->max); memcpy(&new_policy->cpuinfo, &policy->cpuinfo, sizeof(policy->cpuinfo)); - if (new_policy->min > policy->max || new_policy->max < policy->min) { - ret = -EINVAL; - goto error_out; - } + if (new_policy->min > policy->max || new_policy->max < policy->min) + return -EINVAL; /* verify the cpu speed can be set within this limit */ ret = cpufreq_driver->verify(new_policy); if (ret) - goto error_out; + return ret; /* adjust if necessary - all reasons */ blocking_notifier_call_chain(&cpufreq_policy_notifier_list, @@ -2048,7 +2047,7 @@ static int cpufreq_set_policy(struct cpufreq_policy *policy, */ ret = cpufreq_driver->verify(new_policy); if (ret) - goto error_out; + return ret; /* notification of the new policy */ blocking_notifier_call_chain(&cpufreq_policy_notifier_list, @@ -2063,58 +2062,48 @@ static int cpufreq_set_policy(struct cpufreq_policy *policy, if (cpufreq_driver->setpolicy) { policy->policy = new_policy->policy; pr_debug("setting range\n"); - ret = cpufreq_driver->setpolicy(new_policy); - } else { - if (new_policy->governor != policy->governor) { - /* save old, working values */ - struct cpufreq_governor *old_gov = policy->governor; - - pr_debug("governor switch\n"); - - /* end old governor */ - if (policy->governor) { - __cpufreq_governor(policy, CPUFREQ_GOV_STOP); - up_write(&policy->rwsem); - __cpufreq_governor(policy, - CPUFREQ_GOV_POLICY_EXIT); - down_write(&policy->rwsem); - } - - /* start new governor */ - policy->governor = new_policy->governor; - if (!__cpufreq_governor(policy, CPUFREQ_GOV_POLICY_INIT)) { - if (!__cpufreq_governor(policy, CPUFREQ_GOV_START)) { - failed = 0; - } else { - up_write(&policy->rwsem); - __cpufreq_governor(policy, - CPUFREQ_GOV_POLICY_EXIT); - down_write(&policy->rwsem); - } - } - - if (failed) { - /* new governor failed, so re-start old one */ - pr_debug("starting governor %s failed\n", - policy->governor->name); - if (old_gov) { - policy->governor = old_gov; - __cpufreq_governor(policy, - CPUFREQ_GOV_POLICY_INIT); - __cpufreq_governor(policy, - CPUFREQ_GOV_START); - } - ret = -EINVAL; - goto error_out; - } - /* might be a policy change, too, so fall through */ - } - pr_debug("governor: change or update limits\n"); - ret = __cpufreq_governor(policy, CPUFREQ_GOV_LIMITS); + return cpufreq_driver->setpolicy(new_policy); } -error_out: - return ret; + if (new_policy->governor == policy->governor) + goto out; + + pr_debug("governor switch\n"); + + /* save old, working values */ + old_gov = policy->governor; + /* end old governor */ + if (old_gov) { + __cpufreq_governor(policy, CPUFREQ_GOV_STOP); + up_write(&policy->rwsem); + __cpufreq_governor(policy,CPUFREQ_GOV_POLICY_EXIT); + down_write(&policy->rwsem); + } + + /* start new governor */ + policy->governor = new_policy->governor; + if (!__cpufreq_governor(policy, CPUFREQ_GOV_POLICY_INIT)) { + if (!__cpufreq_governor(policy, CPUFREQ_GOV_START)) + goto out; + + up_write(&policy->rwsem); + __cpufreq_governor(policy, CPUFREQ_GOV_POLICY_EXIT); + down_write(&policy->rwsem); + } + + /* new governor failed, so re-start old one */ + pr_debug("starting governor %s failed\n", policy->governor->name); + if (old_gov) { + policy->governor = old_gov; + __cpufreq_governor(policy, CPUFREQ_GOV_POLICY_INIT); + __cpufreq_governor(policy, CPUFREQ_GOV_START); + } + + return -EINVAL; + + out: + pr_debug("governor: change or update limits\n"); + return __cpufreq_governor(policy, CPUFREQ_GOV_LIMITS); } /** From 1c0ca90207d61e4868043b5bbbbd7cc0bb1ac974 Mon Sep 17 00:00:00 2001 From: Viresh Kumar Date: Fri, 14 Feb 2014 16:30:41 +0530 Subject: [PATCH 2/2] cpufreq: don't call cpufreq_update_policy() on CPU addition cpufreq_update_policy() is called from two places currently. From a workqueue handled queued from cpufreq_bp_resume() for boot CPU and from cpufreq_cpu_callback() whenever a CPU is added. The first one makes sure that boot CPU is running on the frequency present in policy->cpu. But we don't really need a call from cpufreq_cpu_callback(), because we always call cpufreq_driver->init() (which will set policy->cur correctly) whenever first CPU of any policy is added back. And so every policy structure is guaranteed to have the right frequency in policy->cur. Signed-off-by: Viresh Kumar Reviewed-by: Srivatsa S. Bhat Signed-off-by: Rafael J. Wysocki --- drivers/cpufreq/cpufreq.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/cpufreq/cpufreq.c b/drivers/cpufreq/cpufreq.c index 37f30550522a..c755b5fe317c 100644 --- a/drivers/cpufreq/cpufreq.c +++ b/drivers/cpufreq/cpufreq.c @@ -2175,7 +2175,6 @@ static int cpufreq_cpu_callback(struct notifier_block *nfb, switch (action & ~CPU_TASKS_FROZEN) { case CPU_ONLINE: __cpufreq_add_dev(dev, NULL, frozen); - cpufreq_update_policy(cpu); break; case CPU_DOWN_PREPARE: