aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRafael J. Wysocki <rafael.j.wysocki@intel.com>2014-02-26 18:19:19 -0500
committerRafael J. Wysocki <rafael.j.wysocki@intel.com>2014-02-26 18:19:19 -0500
commitecfc555c7485b64906f9713ef5eaafe6550b72b8 (patch)
tree1d428e68b54aa21ed019cc0a70a9d965030868f1
parente66c176837462928a05a135bbe16cdce70536d6e (diff)
parent1c0ca90207d61e4868043b5bbbbd7cc0bb1ac974 (diff)
Merge back earlier 'pm-cpufreq' material.
-rw-r--r--drivers/cpufreq/cpufreq.c100
1 files changed, 44 insertions, 56 deletions
diff --git a/drivers/cpufreq/cpufreq.c b/drivers/cpufreq/cpufreq.c
index cb003a6b72c8..c755b5fe317c 100644
--- a/drivers/cpufreq/cpufreq.c
+++ b/drivers/cpufreq/cpufreq.c
@@ -2017,22 +2017,21 @@ EXPORT_SYMBOL(cpufreq_get_policy);
2017static int cpufreq_set_policy(struct cpufreq_policy *policy, 2017static int cpufreq_set_policy(struct cpufreq_policy *policy,
2018 struct cpufreq_policy *new_policy) 2018 struct cpufreq_policy *new_policy)
2019{ 2019{
2020 int ret = 0, failed = 1; 2020 struct cpufreq_governor *old_gov;
2021 int ret;
2021 2022
2022 pr_debug("setting new policy for CPU %u: %u - %u kHz\n", new_policy->cpu, 2023 pr_debug("setting new policy for CPU %u: %u - %u kHz\n", new_policy->cpu,
2023 new_policy->min, new_policy->max); 2024 new_policy->min, new_policy->max);
2024 2025
2025 memcpy(&new_policy->cpuinfo, &policy->cpuinfo, sizeof(policy->cpuinfo)); 2026 memcpy(&new_policy->cpuinfo, &policy->cpuinfo, sizeof(policy->cpuinfo));
2026 2027
2027 if (new_policy->min > policy->max || new_policy->max < policy->min) { 2028 if (new_policy->min > policy->max || new_policy->max < policy->min)
2028 ret = -EINVAL; 2029 return -EINVAL;
2029 goto error_out;
2030 }
2031 2030
2032 /* verify the cpu speed can be set within this limit */ 2031 /* verify the cpu speed can be set within this limit */
2033 ret = cpufreq_driver->verify(new_policy); 2032 ret = cpufreq_driver->verify(new_policy);
2034 if (ret) 2033 if (ret)
2035 goto error_out; 2034 return ret;
2036 2035
2037 /* adjust if necessary - all reasons */ 2036 /* adjust if necessary - all reasons */
2038 blocking_notifier_call_chain(&cpufreq_policy_notifier_list, 2037 blocking_notifier_call_chain(&cpufreq_policy_notifier_list,
@@ -2048,7 +2047,7 @@ static int cpufreq_set_policy(struct cpufreq_policy *policy,
2048 */ 2047 */
2049 ret = cpufreq_driver->verify(new_policy); 2048 ret = cpufreq_driver->verify(new_policy);
2050 if (ret) 2049 if (ret)
2051 goto error_out; 2050 return ret;
2052 2051
2053 /* notification of the new policy */ 2052 /* notification of the new policy */
2054 blocking_notifier_call_chain(&cpufreq_policy_notifier_list, 2053 blocking_notifier_call_chain(&cpufreq_policy_notifier_list,
@@ -2063,58 +2062,48 @@ static int cpufreq_set_policy(struct cpufreq_policy *policy,
2063 if (cpufreq_driver->setpolicy) { 2062 if (cpufreq_driver->setpolicy) {
2064 policy->policy = new_policy->policy; 2063 policy->policy = new_policy->policy;
2065 pr_debug("setting range\n"); 2064 pr_debug("setting range\n");
2066 ret = cpufreq_driver->setpolicy(new_policy); 2065 return cpufreq_driver->setpolicy(new_policy);
2067 } else { 2066 }
2068 if (new_policy->governor != policy->governor) {
2069 /* save old, working values */
2070 struct cpufreq_governor *old_gov = policy->governor;
2071
2072 pr_debug("governor switch\n");
2073
2074 /* end old governor */
2075 if (policy->governor) {
2076 __cpufreq_governor(policy, CPUFREQ_GOV_STOP);
2077 up_write(&policy->rwsem);
2078 __cpufreq_governor(policy,
2079 CPUFREQ_GOV_POLICY_EXIT);
2080 down_write(&policy->rwsem);
2081 }
2082 2067
2083 /* start new governor */ 2068 if (new_policy->governor == policy->governor)
2084 policy->governor = new_policy->governor; 2069 goto out;
2085 if (!__cpufreq_governor(policy, CPUFREQ_GOV_POLICY_INIT)) {
2086 if (!__cpufreq_governor(policy, CPUFREQ_GOV_START)) {
2087 failed = 0;
2088 } else {
2089 up_write(&policy->rwsem);
2090 __cpufreq_governor(policy,
2091 CPUFREQ_GOV_POLICY_EXIT);
2092 down_write(&policy->rwsem);
2093 }
2094 }
2095 2070
2096 if (failed) { 2071 pr_debug("governor switch\n");
2097 /* new governor failed, so re-start old one */ 2072
2098 pr_debug("starting governor %s failed\n", 2073 /* save old, working values */
2099 policy->governor->name); 2074 old_gov = policy->governor;
2100 if (old_gov) { 2075 /* end old governor */
2101 policy->governor = old_gov; 2076 if (old_gov) {
2102 __cpufreq_governor(policy, 2077 __cpufreq_governor(policy, CPUFREQ_GOV_STOP);
2103 CPUFREQ_GOV_POLICY_INIT); 2078 up_write(&policy->rwsem);
2104 __cpufreq_governor(policy, 2079 __cpufreq_governor(policy,CPUFREQ_GOV_POLICY_EXIT);
2105 CPUFREQ_GOV_START); 2080 down_write(&policy->rwsem);
2106 }
2107 ret = -EINVAL;
2108 goto error_out;
2109 }
2110 /* might be a policy change, too, so fall through */
2111 }
2112 pr_debug("governor: change or update limits\n");
2113 ret = __cpufreq_governor(policy, CPUFREQ_GOV_LIMITS);
2114 } 2081 }
2115 2082
2116error_out: 2083 /* start new governor */
2117 return ret; 2084 policy->governor = new_policy->governor;
2085 if (!__cpufreq_governor(policy, CPUFREQ_GOV_POLICY_INIT)) {
2086 if (!__cpufreq_governor(policy, CPUFREQ_GOV_START))
2087 goto out;
2088
2089 up_write(&policy->rwsem);
2090 __cpufreq_governor(policy, CPUFREQ_GOV_POLICY_EXIT);
2091 down_write(&policy->rwsem);
2092 }
2093
2094 /* new governor failed, so re-start old one */
2095 pr_debug("starting governor %s failed\n", policy->governor->name);
2096 if (old_gov) {
2097 policy->governor = old_gov;
2098 __cpufreq_governor(policy, CPUFREQ_GOV_POLICY_INIT);
2099 __cpufreq_governor(policy, CPUFREQ_GOV_START);
2100 }
2101
2102 return -EINVAL;
2103
2104 out:
2105 pr_debug("governor: change or update limits\n");
2106 return __cpufreq_governor(policy, CPUFREQ_GOV_LIMITS);
2118} 2107}
2119 2108
2120/** 2109/**
@@ -2186,7 +2175,6 @@ static int cpufreq_cpu_callback(struct notifier_block *nfb,
2186 switch (action & ~CPU_TASKS_FROZEN) { 2175 switch (action & ~CPU_TASKS_FROZEN) {
2187 case CPU_ONLINE: 2176 case CPU_ONLINE:
2188 __cpufreq_add_dev(dev, NULL, frozen); 2177 __cpufreq_add_dev(dev, NULL, frozen);
2189 cpufreq_update_policy(cpu);
2190 break; 2178 break;
2191 2179
2192 case CPU_DOWN_PREPARE: 2180 case CPU_DOWN_PREPARE: