An instance of 'struct dbs_data' can support multiple 'struct policy_dbs_info' instances. To traverse all policy_dbs supported by a dbs_data, create a list of policy_dbs within dbs_data.
Signed-off-by: Viresh Kumar viresh.kumar@linaro.org --- drivers/cpufreq/cpufreq_governor.c | 12 ++++++++++++ drivers/cpufreq/cpufreq_governor.h | 7 ++++++- 2 files changed, 18 insertions(+), 1 deletion(-)
diff --git a/drivers/cpufreq/cpufreq_governor.c b/drivers/cpufreq/cpufreq_governor.c index ee3c2d92da53..e267acc67067 100644 --- a/drivers/cpufreq/cpufreq_governor.c +++ b/drivers/cpufreq/cpufreq_governor.c @@ -489,6 +489,11 @@ static int cpufreq_governor_init(struct cpufreq_policy *policy) dbs_data->usage_count++; policy_dbs->dbs_data = dbs_data; policy->governor_data = policy_dbs; + + mutex_lock(&dbs_data->mutex); + list_add(&policy_dbs->list, &dbs_data->policy_dbs_list); + mutex_unlock(&dbs_data->mutex); + return 0; }
@@ -500,8 +505,11 @@ static int cpufreq_governor_init(struct cpufreq_policy *policy)
dbs_data->usage_count = 1; dbs_data->gov = gov; + INIT_LIST_HEAD(&dbs_data->policy_dbs_list); mutex_init(&dbs_data->mutex);
+ list_add(&policy_dbs->list, &dbs_data->policy_dbs_list); + ret = gov->init(dbs_data, !policy->governor->initialized); if (ret) goto free_policy_dbs_info; @@ -554,6 +562,10 @@ static int cpufreq_governor_exit(struct cpufreq_policy *policy) struct policy_dbs_info *policy_dbs = policy->governor_data; struct dbs_data *dbs_data = policy_dbs->dbs_data;
+ mutex_lock(&dbs_data->mutex); + list_del(&policy_dbs->list); + mutex_unlock(&dbs_data->mutex); + if (!--dbs_data->usage_count) { kobject_put(&dbs_data->kobj);
diff --git a/drivers/cpufreq/cpufreq_governor.h b/drivers/cpufreq/cpufreq_governor.h index ced34ba5a18d..b740633c2fbe 100644 --- a/drivers/cpufreq/cpufreq_governor.h +++ b/drivers/cpufreq/cpufreq_governor.h @@ -74,7 +74,11 @@ struct dbs_data { unsigned int up_threshold;
struct kobject kobj; - /* Protect concurrent updates to governor tunables from sysfs */ + struct list_head policy_dbs_list; + /* + * Protect concurrent updates to governor tunables from sysfs and + * policy_dbs_list. + */ struct mutex mutex; };
@@ -132,6 +136,7 @@ struct policy_dbs_info { struct work_struct work; /* dbs_data may be shared between multiple policy objects */ struct dbs_data *dbs_data; + struct list_head list; };
static inline void gov_update_sample_delay(struct policy_dbs_info *policy_dbs,