summaryrefslogtreecommitdiffstats
path: root/drivers/cpufreq/cpufreq.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/cpufreq/cpufreq.c')
-rw-r--r--drivers/cpufreq/cpufreq.c118
1 files changed, 117 insertions, 1 deletions
diff --git a/drivers/cpufreq/cpufreq.c b/drivers/cpufreq/cpufreq.c
index d7efdfe0c12c..08ca8c9f41cd 100644
--- a/drivers/cpufreq/cpufreq.c
+++ b/drivers/cpufreq/cpufreq.c
@@ -352,6 +352,33 @@ EXPORT_SYMBOL_GPL(cpufreq_notify_post_transition);
352/********************************************************************* 352/*********************************************************************
353 * SYSFS INTERFACE * 353 * SYSFS INTERFACE *
354 *********************************************************************/ 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);
355 382
356static struct cpufreq_governor *__find_governor(const char *str_governor) 383static struct cpufreq_governor *__find_governor(const char *str_governor)
357{ 384{
@@ -2184,6 +2211,73 @@ static struct notifier_block __refdata cpufreq_cpu_notifier = {
2184}; 2211};
2185 2212
2186/********************************************************************* 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/*********************************************************************
2187 * REGISTER / UNREGISTER CPUFREQ DRIVER * 2281 * REGISTER / UNREGISTER CPUFREQ DRIVER *
2188 *********************************************************************/ 2282 *********************************************************************/
2189 2283
@@ -2223,9 +2317,25 @@ int cpufreq_register_driver(struct cpufreq_driver *driver_data)
2223 cpufreq_driver = driver_data; 2317 cpufreq_driver = driver_data;
2224 write_unlock_irqrestore(&cpufreq_driver_lock, flags); 2318 write_unlock_irqrestore(&cpufreq_driver_lock, flags);
2225 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
2226 ret = subsys_interface_register(&cpufreq_interface); 2336 ret = subsys_interface_register(&cpufreq_interface);
2227 if (ret) 2337 if (ret)
2228 goto err_null_driver; 2338 goto err_boost_unreg;
2229 2339
2230 if (!(cpufreq_driver->flags & CPUFREQ_STICKY)) { 2340 if (!(cpufreq_driver->flags & CPUFREQ_STICKY)) {
2231 int i; 2341 int i;
@@ -2252,6 +2362,9 @@ int cpufreq_register_driver(struct cpufreq_driver *driver_data)
2252 return 0; 2362 return 0;
2253err_if_unreg: 2363err_if_unreg:
2254 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);
2255err_null_driver: 2368err_null_driver:
2256 write_lock_irqsave(&cpufreq_driver_lock, flags); 2369 write_lock_irqsave(&cpufreq_driver_lock, flags);
2257 cpufreq_driver = NULL; 2370 cpufreq_driver = NULL;
@@ -2278,6 +2391,9 @@ int cpufreq_unregister_driver(struct cpufreq_driver *driver)
2278 pr_debug("unregistering driver %s\n", driver->name); 2391 pr_debug("unregistering driver %s\n", driver->name);
2279 2392
2280 subsys_interface_unregister(&cpufreq_interface); 2393 subsys_interface_unregister(&cpufreq_interface);
2394 if (cpufreq_boost_supported())
2395 cpufreq_sysfs_remove_file(&boost.attr);
2396
2281 unregister_hotcpu_notifier(&cpufreq_cpu_notifier); 2397 unregister_hotcpu_notifier(&cpufreq_cpu_notifier);
2282 2398
2283 down_write(&cpufreq_rwsem); 2399 down_write(&cpufreq_rwsem);