aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/cpufreq/cpufreq_governor.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/cpufreq/cpufreq_governor.c')
-rw-r--r--drivers/cpufreq/cpufreq_governor.c14
1 files changed, 10 insertions, 4 deletions
diff --git a/drivers/cpufreq/cpufreq_governor.c b/drivers/cpufreq/cpufreq_governor.c
index 443442df113b..dc9b72e25c1a 100644
--- a/drivers/cpufreq/cpufreq_governor.c
+++ b/drivers/cpufreq/cpufreq_governor.c
@@ -26,6 +26,7 @@
26#include <linux/tick.h> 26#include <linux/tick.h>
27#include <linux/types.h> 27#include <linux/types.h>
28#include <linux/workqueue.h> 28#include <linux/workqueue.h>
29#include <linux/cpu.h>
29 30
30#include "cpufreq_governor.h" 31#include "cpufreq_governor.h"
31 32
@@ -180,8 +181,10 @@ void gov_queue_work(struct dbs_data *dbs_data, struct cpufreq_policy *policy,
180 if (!all_cpus) { 181 if (!all_cpus) {
181 __gov_queue_work(smp_processor_id(), dbs_data, delay); 182 __gov_queue_work(smp_processor_id(), dbs_data, delay);
182 } else { 183 } else {
184 get_online_cpus();
183 for_each_cpu(i, policy->cpus) 185 for_each_cpu(i, policy->cpus)
184 __gov_queue_work(i, dbs_data, delay); 186 __gov_queue_work(i, dbs_data, delay);
187 put_online_cpus();
185 } 188 }
186} 189}
187EXPORT_SYMBOL_GPL(gov_queue_work); 190EXPORT_SYMBOL_GPL(gov_queue_work);
@@ -255,6 +258,7 @@ int cpufreq_governor_dbs(struct cpufreq_policy *policy,
255 if (have_governor_per_policy()) { 258 if (have_governor_per_policy()) {
256 WARN_ON(dbs_data); 259 WARN_ON(dbs_data);
257 } else if (dbs_data) { 260 } else if (dbs_data) {
261 dbs_data->usage_count++;
258 policy->governor_data = dbs_data; 262 policy->governor_data = dbs_data;
259 return 0; 263 return 0;
260 } 264 }
@@ -266,6 +270,7 @@ int cpufreq_governor_dbs(struct cpufreq_policy *policy,
266 } 270 }
267 271
268 dbs_data->cdata = cdata; 272 dbs_data->cdata = cdata;
273 dbs_data->usage_count = 1;
269 rc = cdata->init(dbs_data); 274 rc = cdata->init(dbs_data);
270 if (rc) { 275 if (rc) {
271 pr_err("%s: POLICY_INIT: init() failed\n", __func__); 276 pr_err("%s: POLICY_INIT: init() failed\n", __func__);
@@ -294,7 +299,8 @@ int cpufreq_governor_dbs(struct cpufreq_policy *policy,
294 set_sampling_rate(dbs_data, max(dbs_data->min_sampling_rate, 299 set_sampling_rate(dbs_data, max(dbs_data->min_sampling_rate,
295 latency * LATENCY_MULTIPLIER)); 300 latency * LATENCY_MULTIPLIER));
296 301
297 if (dbs_data->cdata->governor == GOV_CONSERVATIVE) { 302 if ((cdata->governor == GOV_CONSERVATIVE) &&
303 (!policy->governor->initialized)) {
298 struct cs_ops *cs_ops = dbs_data->cdata->gov_ops; 304 struct cs_ops *cs_ops = dbs_data->cdata->gov_ops;
299 305
300 cpufreq_register_notifier(cs_ops->notifier_block, 306 cpufreq_register_notifier(cs_ops->notifier_block,
@@ -306,12 +312,12 @@ int cpufreq_governor_dbs(struct cpufreq_policy *policy,
306 312
307 return 0; 313 return 0;
308 case CPUFREQ_GOV_POLICY_EXIT: 314 case CPUFREQ_GOV_POLICY_EXIT:
309 if ((policy->governor->initialized == 1) || 315 if (!--dbs_data->usage_count) {
310 have_governor_per_policy()) {
311 sysfs_remove_group(get_governor_parent_kobj(policy), 316 sysfs_remove_group(get_governor_parent_kobj(policy),
312 get_sysfs_attr(dbs_data)); 317 get_sysfs_attr(dbs_data));
313 318
314 if (dbs_data->cdata->governor == GOV_CONSERVATIVE) { 319 if ((dbs_data->cdata->governor == GOV_CONSERVATIVE) &&
320 (policy->governor->initialized == 1)) {
315 struct cs_ops *cs_ops = dbs_data->cdata->gov_ops; 321 struct cs_ops *cs_ops = dbs_data->cdata->gov_ops;
316 322
317 cpufreq_unregister_notifier(cs_ops->notifier_block, 323 cpufreq_unregister_notifier(cs_ops->notifier_block,