aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorViresh Kumar <viresh.kumar@linaro.org>2013-04-30 10:32:17 -0400
committerRafael J. Wysocki <rafael.j.wysocki@intel.com>2013-05-12 08:04:16 -0400
commita97c98adddbe98e824b69e6d7b320c8dc91fe581 (patch)
tree2811ba6a9cbc3e594a74734c5c69a6a3e6683d52
parent2b80f3138e8470194745a6b954b4905060ab4067 (diff)
cpufreq: governors: Fix CPUFREQ_GOV_POLICY_{INIT|EXIT} notifiers
There are two types of INIT/EXIT activities that we need to do for governors: - Done only once per governor (doesn't depend how many instances of the governor there are). eg: cpufreq_register_notifier() for conservative governor. - Done per governor instance, eg: sysfs_{create|remove}_group(). There were some corner cases where current code isn't able to handle them separately and so failing for some test cases. We use two separate variables now for keeping track of above two requirements. - governor->initialized for first one - dbs_data->usage_count for per governor instance Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org> Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
-rw-r--r--drivers/cpufreq/cpufreq_governor.c11
-rw-r--r--drivers/cpufreq/cpufreq_governor.h1
2 files changed, 8 insertions, 4 deletions
diff --git a/drivers/cpufreq/cpufreq_governor.c b/drivers/cpufreq/cpufreq_governor.c
index 443442df113b..5af40ad82d23 100644
--- a/drivers/cpufreq/cpufreq_governor.c
+++ b/drivers/cpufreq/cpufreq_governor.c
@@ -255,6 +255,7 @@ int cpufreq_governor_dbs(struct cpufreq_policy *policy,
255 if (have_governor_per_policy()) { 255 if (have_governor_per_policy()) {
256 WARN_ON(dbs_data); 256 WARN_ON(dbs_data);
257 } else if (dbs_data) { 257 } else if (dbs_data) {
258 dbs_data->usage_count++;
258 policy->governor_data = dbs_data; 259 policy->governor_data = dbs_data;
259 return 0; 260 return 0;
260 } 261 }
@@ -266,6 +267,7 @@ int cpufreq_governor_dbs(struct cpufreq_policy *policy,
266 } 267 }
267 268
268 dbs_data->cdata = cdata; 269 dbs_data->cdata = cdata;
270 dbs_data->usage_count = 1;
269 rc = cdata->init(dbs_data); 271 rc = cdata->init(dbs_data);
270 if (rc) { 272 if (rc) {
271 pr_err("%s: POLICY_INIT: init() failed\n", __func__); 273 pr_err("%s: POLICY_INIT: init() failed\n", __func__);
@@ -294,7 +296,8 @@ int cpufreq_governor_dbs(struct cpufreq_policy *policy,
294 set_sampling_rate(dbs_data, max(dbs_data->min_sampling_rate, 296 set_sampling_rate(dbs_data, max(dbs_data->min_sampling_rate,
295 latency * LATENCY_MULTIPLIER)); 297 latency * LATENCY_MULTIPLIER));
296 298
297 if (dbs_data->cdata->governor == GOV_CONSERVATIVE) { 299 if ((cdata->governor == GOV_CONSERVATIVE) &&
300 (!policy->governor->initialized)) {
298 struct cs_ops *cs_ops = dbs_data->cdata->gov_ops; 301 struct cs_ops *cs_ops = dbs_data->cdata->gov_ops;
299 302
300 cpufreq_register_notifier(cs_ops->notifier_block, 303 cpufreq_register_notifier(cs_ops->notifier_block,
@@ -306,12 +309,12 @@ int cpufreq_governor_dbs(struct cpufreq_policy *policy,
306 309
307 return 0; 310 return 0;
308 case CPUFREQ_GOV_POLICY_EXIT: 311 case CPUFREQ_GOV_POLICY_EXIT:
309 if ((policy->governor->initialized == 1) || 312 if (!--dbs_data->usage_count) {
310 have_governor_per_policy()) {
311 sysfs_remove_group(get_governor_parent_kobj(policy), 313 sysfs_remove_group(get_governor_parent_kobj(policy),
312 get_sysfs_attr(dbs_data)); 314 get_sysfs_attr(dbs_data));
313 315
314 if (dbs_data->cdata->governor == GOV_CONSERVATIVE) { 316 if ((dbs_data->cdata->governor == GOV_CONSERVATIVE) &&
317 (policy->governor->initialized == 1)) {
315 struct cs_ops *cs_ops = dbs_data->cdata->gov_ops; 318 struct cs_ops *cs_ops = dbs_data->cdata->gov_ops;
316 319
317 cpufreq_unregister_notifier(cs_ops->notifier_block, 320 cpufreq_unregister_notifier(cs_ops->notifier_block,
diff --git a/drivers/cpufreq/cpufreq_governor.h b/drivers/cpufreq/cpufreq_governor.h
index 8ac33538d0bd..e16a96130cb3 100644
--- a/drivers/cpufreq/cpufreq_governor.h
+++ b/drivers/cpufreq/cpufreq_governor.h
@@ -211,6 +211,7 @@ struct common_dbs_data {
211struct dbs_data { 211struct dbs_data {
212 struct common_dbs_data *cdata; 212 struct common_dbs_data *cdata;
213 unsigned int min_sampling_rate; 213 unsigned int min_sampling_rate;
214 int usage_count;
214 void *tuners; 215 void *tuners;
215 216
216 /* dbs_mutex protects dbs_enable in governor start/stop */ 217 /* dbs_mutex protects dbs_enable in governor start/stop */