diff options
Diffstat (limited to 'drivers/cpufreq/cpufreq_governor.c')
-rw-r--r-- | drivers/cpufreq/cpufreq_governor.c | 14 |
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 | } |
187 | EXPORT_SYMBOL_GPL(gov_queue_work); | 190 | EXPORT_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, |