diff options
| -rw-r--r-- | drivers/cpufreq/cpufreq.c | 3 | ||||
| -rw-r--r-- | drivers/cpufreq/cpufreq_conservative.c | 44 | ||||
| -rw-r--r-- | drivers/cpufreq/cpufreq_governor.c | 6 | ||||
| -rw-r--r-- | drivers/cpufreq/cpufreq_governor.h | 4 | ||||
| -rw-r--r-- | drivers/cpufreq/cpufreq_ondemand.c | 4 | ||||
| -rw-r--r-- | include/linux/cpufreq.h | 1 | 
6 files changed, 36 insertions, 26 deletions
diff --git a/drivers/cpufreq/cpufreq.c b/drivers/cpufreq/cpufreq.c index d98ff688b2f1..bdf1f280ae39 100644 --- a/drivers/cpufreq/cpufreq.c +++ b/drivers/cpufreq/cpufreq.c @@ -2031,7 +2031,6 @@ static int cpufreq_init_governor(struct cpufreq_policy *policy)  		}  	} -	policy->governor->initialized++;  	return 0;  } @@ -2045,7 +2044,6 @@ static void cpufreq_exit_governor(struct cpufreq_policy *policy)  	if (policy->governor->exit)  		policy->governor->exit(policy); -	policy->governor->initialized--;  	module_put(policy->governor->owner);  } @@ -2110,7 +2108,6 @@ int cpufreq_register_governor(struct cpufreq_governor *governor)  	mutex_lock(&cpufreq_governor_mutex); -	governor->initialized = 0;  	err = -EBUSY;  	if (!find_governor(governor->name)) {  		err = 0; diff --git a/drivers/cpufreq/cpufreq_conservative.c b/drivers/cpufreq/cpufreq_conservative.c index 78faa9fbc384..f967ec6c5720 100644 --- a/drivers/cpufreq/cpufreq_conservative.c +++ b/drivers/cpufreq/cpufreq_conservative.c @@ -127,7 +127,6 @@ static struct notifier_block cs_cpufreq_notifier_block = {  };  /************************** sysfs interface ************************/ -static struct dbs_governor cs_dbs_gov;  static ssize_t store_sampling_down_factor(struct gov_attr_set *attr_set,  					  const char *buf, size_t count) @@ -255,6 +254,13 @@ static struct attribute *cs_attributes[] = {  /************************** sysfs end ************************/ +struct cs_governor { +	struct dbs_governor dbs_gov; +	unsigned int usage_count; +}; + +static struct cs_governor cs_gov; +  static struct policy_dbs_info *cs_alloc(void)  {  	struct cs_policy_dbs_info *dbs_info; @@ -268,7 +274,7 @@ static void cs_free(struct policy_dbs_info *policy_dbs)  	kfree(to_dbs_info(policy_dbs));  } -static int cs_init(struct dbs_data *dbs_data, bool notify) +static int cs_init(struct dbs_data *dbs_data)  {  	struct cs_dbs_tuners *tuners; @@ -286,16 +292,22 @@ static int cs_init(struct dbs_data *dbs_data, bool notify)  	dbs_data->min_sampling_rate = MIN_SAMPLING_RATE_RATIO *  		jiffies_to_usecs(10); -	if (notify) +	/* +	 * This function and cs_exit() are only called under gov_dbs_data_mutex +	 * which is global, so the cs_gov.usage_count accesses are guaranteed +	 * to be serialized. +	 */ +	if (!cs_gov.usage_count++)  		cpufreq_register_notifier(&cs_cpufreq_notifier_block,  					  CPUFREQ_TRANSITION_NOTIFIER);  	return 0;  } -static void cs_exit(struct dbs_data *dbs_data, bool notify) +static void cs_exit(struct dbs_data *dbs_data)  { -	if (notify) +	/* Protected by gov_dbs_data_mutex - see the comment in cs_init(). */ +	if (!--cs_gov.usage_count)  		cpufreq_unregister_notifier(&cs_cpufreq_notifier_block,  					    CPUFREQ_TRANSITION_NOTIFIER); @@ -310,18 +322,20 @@ static void cs_start(struct cpufreq_policy *policy)  	dbs_info->requested_freq = policy->cur;  } -static struct dbs_governor cs_dbs_gov = { -	.gov = CPUFREQ_DBS_GOVERNOR_INITIALIZER("conservative"), -	.kobj_type = { .default_attrs = cs_attributes }, -	.gov_dbs_timer = cs_dbs_timer, -	.alloc = cs_alloc, -	.free = cs_free, -	.init = cs_init, -	.exit = cs_exit, -	.start = cs_start, +static struct cs_governor cs_gov = { +	.dbs_gov = { +		.gov = CPUFREQ_DBS_GOVERNOR_INITIALIZER("conservative"), +		.kobj_type = { .default_attrs = cs_attributes }, +		.gov_dbs_timer = cs_dbs_timer, +		.alloc = cs_alloc, +		.free = cs_free, +		.init = cs_init, +		.exit = cs_exit, +		.start = cs_start, +	},  }; -#define CPU_FREQ_GOV_CONSERVATIVE	(&cs_dbs_gov.gov) +#define CPU_FREQ_GOV_CONSERVATIVE	(&cs_gov.dbs_gov.gov)  static int dbs_cpufreq_notifier(struct notifier_block *nb, unsigned long val,  				void *data) diff --git a/drivers/cpufreq/cpufreq_governor.c b/drivers/cpufreq/cpufreq_governor.c index 4b88b5bec4ef..31369e247192 100644 --- a/drivers/cpufreq/cpufreq_governor.c +++ b/drivers/cpufreq/cpufreq_governor.c @@ -429,7 +429,7 @@ int cpufreq_dbs_governor_init(struct cpufreq_policy *policy)  	gov_attr_set_init(&dbs_data->attr_set, &policy_dbs->list); -	ret = gov->init(dbs_data, !policy->governor->initialized); +	ret = gov->init(dbs_data);  	if (ret)  		goto free_policy_dbs_info; @@ -464,7 +464,7 @@ int cpufreq_dbs_governor_init(struct cpufreq_policy *policy)  	if (!have_governor_per_policy())  		gov->gdbs_data = NULL; -	gov->exit(dbs_data, !policy->governor->initialized); +	gov->exit(dbs_data);  	kfree(dbs_data);  free_policy_dbs_info: @@ -494,7 +494,7 @@ void cpufreq_dbs_governor_exit(struct cpufreq_policy *policy)  		if (!have_governor_per_policy())  			gov->gdbs_data = NULL; -		gov->exit(dbs_data, policy->governor->initialized == 1); +		gov->exit(dbs_data);  		kfree(dbs_data);  	} diff --git a/drivers/cpufreq/cpufreq_governor.h b/drivers/cpufreq/cpufreq_governor.h index 36f0d19dd869..ef1037e9c92b 100644 --- a/drivers/cpufreq/cpufreq_governor.h +++ b/drivers/cpufreq/cpufreq_governor.h @@ -138,8 +138,8 @@ struct dbs_governor {  	unsigned int (*gov_dbs_timer)(struct cpufreq_policy *policy);  	struct policy_dbs_info *(*alloc)(void);  	void (*free)(struct policy_dbs_info *policy_dbs); -	int (*init)(struct dbs_data *dbs_data, bool notify); -	void (*exit)(struct dbs_data *dbs_data, bool notify); +	int (*init)(struct dbs_data *dbs_data); +	void (*exit)(struct dbs_data *dbs_data);  	void (*start)(struct cpufreq_policy *policy);  }; diff --git a/drivers/cpufreq/cpufreq_ondemand.c b/drivers/cpufreq/cpufreq_ondemand.c index 4441a11139f1..c84fc2240d49 100644 --- a/drivers/cpufreq/cpufreq_ondemand.c +++ b/drivers/cpufreq/cpufreq_ondemand.c @@ -361,7 +361,7 @@ static void od_free(struct policy_dbs_info *policy_dbs)  	kfree(to_dbs_info(policy_dbs));  } -static int od_init(struct dbs_data *dbs_data, bool notify) +static int od_init(struct dbs_data *dbs_data)  {  	struct od_dbs_tuners *tuners;  	u64 idle_time; @@ -400,7 +400,7 @@ static int od_init(struct dbs_data *dbs_data, bool notify)  	return 0;  } -static void od_exit(struct dbs_data *dbs_data, bool notify) +static void od_exit(struct dbs_data *dbs_data)  {  	kfree(dbs_data->tuners);  } diff --git a/include/linux/cpufreq.h b/include/linux/cpufreq.h index 3be54a0b4373..fbd696edf5bd 100644 --- a/include/linux/cpufreq.h +++ b/include/linux/cpufreq.h @@ -457,7 +457,6 @@ static inline unsigned long cpufreq_scale(unsigned long old, u_int div,  struct cpufreq_governor {  	char	name[CPUFREQ_NAME_LEN]; -	int	initialized;  	int	(*init)(struct cpufreq_policy *policy);  	void	(*exit)(struct cpufreq_policy *policy);  	int	(*start)(struct cpufreq_policy *policy);  | 
