aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/cpufreq/cpufreq.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/cpufreq/cpufreq.c')
-rw-r--r--drivers/cpufreq/cpufreq.c218
1 files changed, 199 insertions, 19 deletions
diff --git a/drivers/cpufreq/cpufreq.c b/drivers/cpufreq/cpufreq.c
index 8d19f7c06010..08ca8c9f41cd 100644
--- a/drivers/cpufreq/cpufreq.c
+++ b/drivers/cpufreq/cpufreq.c
@@ -39,7 +39,7 @@ static struct cpufreq_driver *cpufreq_driver;
39static DEFINE_PER_CPU(struct cpufreq_policy *, cpufreq_cpu_data); 39static DEFINE_PER_CPU(struct cpufreq_policy *, cpufreq_cpu_data);
40static DEFINE_PER_CPU(struct cpufreq_policy *, cpufreq_cpu_data_fallback); 40static DEFINE_PER_CPU(struct cpufreq_policy *, cpufreq_cpu_data_fallback);
41static DEFINE_RWLOCK(cpufreq_driver_lock); 41static DEFINE_RWLOCK(cpufreq_driver_lock);
42static DEFINE_MUTEX(cpufreq_governor_lock); 42DEFINE_MUTEX(cpufreq_governor_lock);
43static LIST_HEAD(cpufreq_policy_list); 43static LIST_HEAD(cpufreq_policy_list);
44 44
45#ifdef CONFIG_HOTPLUG_CPU 45#ifdef CONFIG_HOTPLUG_CPU
@@ -176,6 +176,20 @@ int cpufreq_generic_init(struct cpufreq_policy *policy,
176} 176}
177EXPORT_SYMBOL_GPL(cpufreq_generic_init); 177EXPORT_SYMBOL_GPL(cpufreq_generic_init);
178 178
179unsigned int cpufreq_generic_get(unsigned int cpu)
180{
181 struct cpufreq_policy *policy = per_cpu(cpufreq_cpu_data, cpu);
182
183 if (!policy || IS_ERR(policy->clk)) {
184 pr_err("%s: No %s associated to cpu: %d\n", __func__,
185 policy ? "clk" : "policy", cpu);
186 return 0;
187 }
188
189 return clk_get_rate(policy->clk) / 1000;
190}
191EXPORT_SYMBOL_GPL(cpufreq_generic_get);
192
179struct cpufreq_policy *cpufreq_cpu_get(unsigned int cpu) 193struct cpufreq_policy *cpufreq_cpu_get(unsigned int cpu)
180{ 194{
181 struct cpufreq_policy *policy = NULL; 195 struct cpufreq_policy *policy = NULL;
@@ -320,10 +334,51 @@ void cpufreq_notify_transition(struct cpufreq_policy *policy,
320} 334}
321EXPORT_SYMBOL_GPL(cpufreq_notify_transition); 335EXPORT_SYMBOL_GPL(cpufreq_notify_transition);
322 336
337/* Do post notifications when there are chances that transition has failed */
338void cpufreq_notify_post_transition(struct cpufreq_policy *policy,
339 struct cpufreq_freqs *freqs, int transition_failed)
340{
341 cpufreq_notify_transition(policy, freqs, CPUFREQ_POSTCHANGE);
342 if (!transition_failed)
343 return;
344
345 swap(freqs->old, freqs->new);
346 cpufreq_notify_transition(policy, freqs, CPUFREQ_PRECHANGE);
347 cpufreq_notify_transition(policy, freqs, CPUFREQ_POSTCHANGE);
348}
349EXPORT_SYMBOL_GPL(cpufreq_notify_post_transition);
350
323 351
324/********************************************************************* 352/*********************************************************************
325 * SYSFS INTERFACE * 353 * SYSFS INTERFACE *
326 *********************************************************************/ 354 *********************************************************************/
355ssize_t show_boost(struct kobject *kobj,
356 struct attribute *attr, char *buf)
357{
358 return sprintf(buf, "%d\n", cpufreq_driver->boost_enabled);
359}
360
361static ssize_t store_boost(struct kobject *kobj, struct attribute *attr,
362 const char *buf, size_t count)
363{
364 int ret, enable;
365
366 ret = sscanf(buf, "%d", &enable);
367 if (ret != 1 || enable < 0 || enable > 1)
368 return -EINVAL;
369
370 if (cpufreq_boost_trigger_state(enable)) {
371 pr_err("%s: Cannot %s BOOST!\n", __func__,
372 enable ? "enable" : "disable");
373 return -EINVAL;
374 }
375
376 pr_debug("%s: cpufreq BOOST %s\n", __func__,
377 enable ? "enabled" : "disabled");
378
379 return count;
380}
381define_one_global_rw(boost);
327 382
328static struct cpufreq_governor *__find_governor(const char *str_governor) 383static struct cpufreq_governor *__find_governor(const char *str_governor)
329{ 384{
@@ -929,6 +984,9 @@ static void cpufreq_policy_put_kobj(struct cpufreq_policy *policy)
929 struct kobject *kobj; 984 struct kobject *kobj;
930 struct completion *cmp; 985 struct completion *cmp;
931 986
987 blocking_notifier_call_chain(&cpufreq_policy_notifier_list,
988 CPUFREQ_REMOVE_POLICY, policy);
989
932 down_read(&policy->rwsem); 990 down_read(&policy->rwsem);
933 kobj = &policy->kobj; 991 kobj = &policy->kobj;
934 cmp = &policy->kobj_unregister; 992 cmp = &policy->kobj_unregister;
@@ -1051,6 +1109,11 @@ static int __cpufreq_add_dev(struct device *dev, struct subsys_interface *sif,
1051 goto err_set_policy_cpu; 1109 goto err_set_policy_cpu;
1052 } 1110 }
1053 1111
1112 write_lock_irqsave(&cpufreq_driver_lock, flags);
1113 for_each_cpu(j, policy->cpus)
1114 per_cpu(cpufreq_cpu_data, j) = policy;
1115 write_unlock_irqrestore(&cpufreq_driver_lock, flags);
1116
1054 if (cpufreq_driver->get) { 1117 if (cpufreq_driver->get) {
1055 policy->cur = cpufreq_driver->get(policy->cpu); 1118 policy->cur = cpufreq_driver->get(policy->cpu);
1056 if (!policy->cur) { 1119 if (!policy->cur) {
@@ -1059,6 +1122,46 @@ static int __cpufreq_add_dev(struct device *dev, struct subsys_interface *sif,
1059 } 1122 }
1060 } 1123 }
1061 1124
1125 /*
1126 * Sometimes boot loaders set CPU frequency to a value outside of
1127 * frequency table present with cpufreq core. In such cases CPU might be
1128 * unstable if it has to run on that frequency for long duration of time
1129 * and so its better to set it to a frequency which is specified in
1130 * freq-table. This also makes cpufreq stats inconsistent as
1131 * cpufreq-stats would fail to register because current frequency of CPU
1132 * isn't found in freq-table.
1133 *
1134 * Because we don't want this change to effect boot process badly, we go
1135 * for the next freq which is >= policy->cur ('cur' must be set by now,
1136 * otherwise we will end up setting freq to lowest of the table as 'cur'
1137 * is initialized to zero).
1138 *
1139 * We are passing target-freq as "policy->cur - 1" otherwise
1140 * __cpufreq_driver_target() would simply fail, as policy->cur will be
1141 * equal to target-freq.
1142 */
1143 if ((cpufreq_driver->flags & CPUFREQ_NEED_INITIAL_FREQ_CHECK)
1144 && has_target()) {
1145 /* Are we running at unknown frequency ? */
1146 ret = cpufreq_frequency_table_get_index(policy, policy->cur);
1147 if (ret == -EINVAL) {
1148 /* Warn user and fix it */
1149 pr_warn("%s: CPU%d: Running at unlisted freq: %u KHz\n",
1150 __func__, policy->cpu, policy->cur);
1151 ret = __cpufreq_driver_target(policy, policy->cur - 1,
1152 CPUFREQ_RELATION_L);
1153
1154 /*
1155 * Reaching here after boot in a few seconds may not
1156 * mean that system will remain stable at "unknown"
1157 * frequency for longer duration. Hence, a BUG_ON().
1158 */
1159 BUG_ON(ret);
1160 pr_warn("%s: CPU%d: Unlisted initial frequency changed to: %u KHz\n",
1161 __func__, policy->cpu, policy->cur);
1162 }
1163 }
1164
1062 /* related cpus should atleast have policy->cpus */ 1165 /* related cpus should atleast have policy->cpus */
1063 cpumask_or(policy->related_cpus, policy->related_cpus, policy->cpus); 1166 cpumask_or(policy->related_cpus, policy->related_cpus, policy->cpus);
1064 1167
@@ -1085,15 +1188,12 @@ static int __cpufreq_add_dev(struct device *dev, struct subsys_interface *sif,
1085 } 1188 }
1086#endif 1189#endif
1087 1190
1088 write_lock_irqsave(&cpufreq_driver_lock, flags);
1089 for_each_cpu(j, policy->cpus)
1090 per_cpu(cpufreq_cpu_data, j) = policy;
1091 write_unlock_irqrestore(&cpufreq_driver_lock, flags);
1092
1093 if (!frozen) { 1191 if (!frozen) {
1094 ret = cpufreq_add_dev_interface(policy, dev); 1192 ret = cpufreq_add_dev_interface(policy, dev);
1095 if (ret) 1193 if (ret)
1096 goto err_out_unregister; 1194 goto err_out_unregister;
1195 blocking_notifier_call_chain(&cpufreq_policy_notifier_list,
1196 CPUFREQ_CREATE_POLICY, policy);
1097 } 1197 }
1098 1198
1099 write_lock_irqsave(&cpufreq_driver_lock, flags); 1199 write_lock_irqsave(&cpufreq_driver_lock, flags);
@@ -1115,12 +1215,12 @@ static int __cpufreq_add_dev(struct device *dev, struct subsys_interface *sif,
1115 return 0; 1215 return 0;
1116 1216
1117err_out_unregister: 1217err_out_unregister:
1218err_get_freq:
1118 write_lock_irqsave(&cpufreq_driver_lock, flags); 1219 write_lock_irqsave(&cpufreq_driver_lock, flags);
1119 for_each_cpu(j, policy->cpus) 1220 for_each_cpu(j, policy->cpus)
1120 per_cpu(cpufreq_cpu_data, j) = NULL; 1221 per_cpu(cpufreq_cpu_data, j) = NULL;
1121 write_unlock_irqrestore(&cpufreq_driver_lock, flags); 1222 write_unlock_irqrestore(&cpufreq_driver_lock, flags);
1122 1223
1123err_get_freq:
1124 if (cpufreq_driver->exit) 1224 if (cpufreq_driver->exit)
1125 cpufreq_driver->exit(policy); 1225 cpufreq_driver->exit(policy);
1126err_set_policy_cpu: 1226err_set_policy_cpu:
@@ -1725,17 +1825,8 @@ int __cpufreq_driver_target(struct cpufreq_policy *policy,
1725 pr_err("%s: Failed to change cpu frequency: %d\n", 1825 pr_err("%s: Failed to change cpu frequency: %d\n",
1726 __func__, retval); 1826 __func__, retval);
1727 1827
1728 if (notify) { 1828 if (notify)
1729 /* 1829 cpufreq_notify_post_transition(policy, &freqs, retval);
1730 * Notify with old freq in case we failed to change
1731 * frequency
1732 */
1733 if (retval)
1734 freqs.new = freqs.old;
1735
1736 cpufreq_notify_transition(policy, &freqs,
1737 CPUFREQ_POSTCHANGE);
1738 }
1739 } 1830 }
1740 1831
1741out: 1832out:
@@ -2120,6 +2211,73 @@ static struct notifier_block __refdata cpufreq_cpu_notifier = {
2120}; 2211};
2121 2212
2122/********************************************************************* 2213/*********************************************************************
2214 * BOOST *
2215 *********************************************************************/
2216static int cpufreq_boost_set_sw(int state)
2217{
2218 struct cpufreq_frequency_table *freq_table;
2219 struct cpufreq_policy *policy;
2220 int ret = -EINVAL;
2221
2222 list_for_each_entry(policy, &cpufreq_policy_list, policy_list) {
2223 freq_table = cpufreq_frequency_get_table(policy->cpu);
2224 if (freq_table) {
2225 ret = cpufreq_frequency_table_cpuinfo(policy,
2226 freq_table);
2227 if (ret) {
2228 pr_err("%s: Policy frequency update failed\n",
2229 __func__);
2230 break;
2231 }
2232 policy->user_policy.max = policy->max;
2233 __cpufreq_governor(policy, CPUFREQ_GOV_LIMITS);
2234 }
2235 }
2236
2237 return ret;
2238}
2239
2240int cpufreq_boost_trigger_state(int state)
2241{
2242 unsigned long flags;
2243 int ret = 0;
2244
2245 if (cpufreq_driver->boost_enabled == state)
2246 return 0;
2247
2248 write_lock_irqsave(&cpufreq_driver_lock, flags);
2249 cpufreq_driver->boost_enabled = state;
2250 write_unlock_irqrestore(&cpufreq_driver_lock, flags);
2251
2252 ret = cpufreq_driver->set_boost(state);
2253 if (ret) {
2254 write_lock_irqsave(&cpufreq_driver_lock, flags);
2255 cpufreq_driver->boost_enabled = !state;
2256 write_unlock_irqrestore(&cpufreq_driver_lock, flags);
2257
2258 pr_err("%s: Cannot %s BOOST\n", __func__,
2259 state ? "enable" : "disable");
2260 }
2261
2262 return ret;
2263}
2264
2265int cpufreq_boost_supported(void)
2266{
2267 if (likely(cpufreq_driver))
2268 return cpufreq_driver->boost_supported;
2269
2270 return 0;
2271}
2272EXPORT_SYMBOL_GPL(cpufreq_boost_supported);
2273
2274int cpufreq_boost_enabled(void)
2275{
2276 return cpufreq_driver->boost_enabled;
2277}
2278EXPORT_SYMBOL_GPL(cpufreq_boost_enabled);
2279
2280/*********************************************************************
2123 * REGISTER / UNREGISTER CPUFREQ DRIVER * 2281 * REGISTER / UNREGISTER CPUFREQ DRIVER *
2124 *********************************************************************/ 2282 *********************************************************************/
2125 2283
@@ -2159,9 +2317,25 @@ int cpufreq_register_driver(struct cpufreq_driver *driver_data)
2159 cpufreq_driver = driver_data; 2317 cpufreq_driver = driver_data;
2160 write_unlock_irqrestore(&cpufreq_driver_lock, flags); 2318 write_unlock_irqrestore(&cpufreq_driver_lock, flags);
2161 2319
2320 if (cpufreq_boost_supported()) {
2321 /*
2322 * Check if driver provides function to enable boost -
2323 * if not, use cpufreq_boost_set_sw as default
2324 */
2325 if (!cpufreq_driver->set_boost)
2326 cpufreq_driver->set_boost = cpufreq_boost_set_sw;
2327
2328 ret = cpufreq_sysfs_create_file(&boost.attr);
2329 if (ret) {
2330 pr_err("%s: cannot register global BOOST sysfs file\n",
2331 __func__);
2332 goto err_null_driver;
2333 }
2334 }
2335
2162 ret = subsys_interface_register(&cpufreq_interface); 2336 ret = subsys_interface_register(&cpufreq_interface);
2163 if (ret) 2337 if (ret)
2164 goto err_null_driver; 2338 goto err_boost_unreg;
2165 2339
2166 if (!(cpufreq_driver->flags & CPUFREQ_STICKY)) { 2340 if (!(cpufreq_driver->flags & CPUFREQ_STICKY)) {
2167 int i; 2341 int i;
@@ -2188,6 +2362,9 @@ int cpufreq_register_driver(struct cpufreq_driver *driver_data)
2188 return 0; 2362 return 0;
2189err_if_unreg: 2363err_if_unreg:
2190 subsys_interface_unregister(&cpufreq_interface); 2364 subsys_interface_unregister(&cpufreq_interface);
2365err_boost_unreg:
2366 if (cpufreq_boost_supported())
2367 cpufreq_sysfs_remove_file(&boost.attr);
2191err_null_driver: 2368err_null_driver:
2192 write_lock_irqsave(&cpufreq_driver_lock, flags); 2369 write_lock_irqsave(&cpufreq_driver_lock, flags);
2193 cpufreq_driver = NULL; 2370 cpufreq_driver = NULL;
@@ -2214,6 +2391,9 @@ int cpufreq_unregister_driver(struct cpufreq_driver *driver)
2214 pr_debug("unregistering driver %s\n", driver->name); 2391 pr_debug("unregistering driver %s\n", driver->name);
2215 2392
2216 subsys_interface_unregister(&cpufreq_interface); 2393 subsys_interface_unregister(&cpufreq_interface);
2394 if (cpufreq_boost_supported())
2395 cpufreq_sysfs_remove_file(&boost.attr);
2396
2217 unregister_hotcpu_notifier(&cpufreq_cpu_notifier); 2397 unregister_hotcpu_notifier(&cpufreq_cpu_notifier);
2218 2398
2219 down_write(&cpufreq_rwsem); 2399 down_write(&cpufreq_rwsem);