diff options
Diffstat (limited to 'drivers/cpufreq/cpufreq.c')
| -rw-r--r-- | drivers/cpufreq/cpufreq.c | 78 | 
1 files changed, 35 insertions, 43 deletions
diff --git a/drivers/cpufreq/cpufreq.c b/drivers/cpufreq/cpufreq.c index 075d18f6ba7a..b0dfd3222013 100644 --- a/drivers/cpufreq/cpufreq.c +++ b/drivers/cpufreq/cpufreq.c @@ -89,16 +89,7 @@ static void cpufreq_governor_limits(struct cpufreq_policy *policy);   * The mutex locks both lists.   */  static BLOCKING_NOTIFIER_HEAD(cpufreq_policy_notifier_list); -static struct srcu_notifier_head cpufreq_transition_notifier_list; - -static bool init_cpufreq_transition_notifier_list_called; -static int __init init_cpufreq_transition_notifier_list(void) -{ -	srcu_init_notifier_head(&cpufreq_transition_notifier_list); -	init_cpufreq_transition_notifier_list_called = true; -	return 0; -} -pure_initcall(init_cpufreq_transition_notifier_list); +SRCU_NOTIFIER_HEAD_STATIC(cpufreq_transition_notifier_list);  static int off __read_mostly;  static int cpufreq_disabled(void) @@ -300,8 +291,19 @@ static void adjust_jiffies(unsigned long val, struct cpufreq_freqs *ci)  #endif  } -static void __cpufreq_notify_transition(struct cpufreq_policy *policy, -		struct cpufreq_freqs *freqs, unsigned int state) +/** + * cpufreq_notify_transition - Notify frequency transition and adjust_jiffies. + * @policy: cpufreq policy to enable fast frequency switching for. + * @freqs: contain details of the frequency update. + * @state: set to CPUFREQ_PRECHANGE or CPUFREQ_POSTCHANGE. + * + * This function calls the transition notifiers and the "adjust_jiffies" + * function. It is called twice on all CPU frequency changes that have + * external effects. + */ +static void cpufreq_notify_transition(struct cpufreq_policy *policy, +				      struct cpufreq_freqs *freqs, +				      unsigned int state)  {  	BUG_ON(irqs_disabled()); @@ -313,54 +315,44 @@ static void __cpufreq_notify_transition(struct cpufreq_policy *policy,  		 state, freqs->new);  	switch (state) { -  	case CPUFREQ_PRECHANGE: -		/* detect if the driver reported a value as "old frequency" +		/* +		 * Detect if the driver reported a value as "old frequency"  		 * which is not equal to what the cpufreq core thinks is  		 * "old frequency".  		 */  		if (!(cpufreq_driver->flags & CPUFREQ_CONST_LOOPS)) { -			if ((policy) && (policy->cpu == freqs->cpu) && -			    (policy->cur) && (policy->cur != freqs->old)) { +			if (policy->cur && (policy->cur != freqs->old)) {  				pr_debug("Warning: CPU frequency is %u, cpufreq assumed %u kHz\n",  					 freqs->old, policy->cur);  				freqs->old = policy->cur;  			}  		} -		srcu_notifier_call_chain(&cpufreq_transition_notifier_list, -				CPUFREQ_PRECHANGE, freqs); + +		for_each_cpu(freqs->cpu, policy->cpus) { +			srcu_notifier_call_chain(&cpufreq_transition_notifier_list, +						 CPUFREQ_PRECHANGE, freqs); +		} +  		adjust_jiffies(CPUFREQ_PRECHANGE, freqs);  		break;  	case CPUFREQ_POSTCHANGE:  		adjust_jiffies(CPUFREQ_POSTCHANGE, freqs); -		pr_debug("FREQ: %lu - CPU: %lu\n", -			 (unsigned long)freqs->new, (unsigned long)freqs->cpu); -		trace_cpu_frequency(freqs->new, freqs->cpu); +		pr_debug("FREQ: %u - CPUs: %*pbl\n", freqs->new, +			 cpumask_pr_args(policy->cpus)); + +		for_each_cpu(freqs->cpu, policy->cpus) { +			trace_cpu_frequency(freqs->new, freqs->cpu); +			srcu_notifier_call_chain(&cpufreq_transition_notifier_list, +						 CPUFREQ_POSTCHANGE, freqs); +		} +  		cpufreq_stats_record_transition(policy, freqs->new); -		srcu_notifier_call_chain(&cpufreq_transition_notifier_list, -				CPUFREQ_POSTCHANGE, freqs); -		if (likely(policy) && likely(policy->cpu == freqs->cpu)) -			policy->cur = freqs->new; -		break; +		policy->cur = freqs->new;  	}  } -/** - * cpufreq_notify_transition - call notifier chain and adjust_jiffies - * on frequency transition. - * - * This function calls the transition notifiers and the "adjust_jiffies" - * function. It is called twice on all CPU frequency changes that have - * external effects. - */ -static void cpufreq_notify_transition(struct cpufreq_policy *policy, -		struct cpufreq_freqs *freqs, unsigned int state) -{ -	for_each_cpu(freqs->cpu, policy->cpus) -		__cpufreq_notify_transition(policy, freqs, state); -} -  /* Do post notifications when there are chances that transition has failed */  static void cpufreq_notify_post_transition(struct cpufreq_policy *policy,  		struct cpufreq_freqs *freqs, int transition_failed) @@ -696,6 +688,8 @@ static ssize_t store_##file_name					\  	struct cpufreq_policy new_policy;				\  									\  	memcpy(&new_policy, policy, sizeof(*policy));			\ +	new_policy.min = policy->user_policy.min;			\ +	new_policy.max = policy->user_policy.max;			\  									\  	ret = sscanf(buf, "%u", &new_policy.object);			\  	if (ret != 1)							\ @@ -1764,8 +1758,6 @@ int cpufreq_register_notifier(struct notifier_block *nb, unsigned int list)  	if (cpufreq_disabled())  		return -EINVAL; -	WARN_ON(!init_cpufreq_transition_notifier_list_called); -  	switch (list) {  	case CPUFREQ_TRANSITION_NOTIFIER:  		mutex_lock(&cpufreq_fast_switch_lock);  |