diff options
| author | 2016-06-13 23:33:17 +0200 | |
|---|---|---|
| committer | 2016-06-13 23:33:17 +0200 | |
| commit | bb4b9933e2bc0554cf4db37aa07b19ff69a85f8f (patch) | |
| tree | 92ec230e0292874d6a53ff33534e8637fa315479 /drivers/cpufreq | |
| parent | Linux 4.7-rc3 (diff) | |
| parent | cpufreq: governor: Drop gov_cancel_work() (diff) | |
| download | linux-dev-bb4b9933e2bc0554cf4db37aa07b19ff69a85f8f.tar.xz linux-dev-bb4b9933e2bc0554cf4db37aa07b19ff69a85f8f.zip  | |
Merge back earlier cpufreq changes for v4.8.
Diffstat (limited to 'drivers/cpufreq')
| -rw-r--r-- | drivers/cpufreq/Kconfig | 13 | ||||
| -rw-r--r-- | drivers/cpufreq/amd_freq_sensitivity.c | 10 | ||||
| -rw-r--r-- | drivers/cpufreq/cpufreq.c | 186 | ||||
| -rw-r--r-- | drivers/cpufreq/cpufreq_conservative.c | 51 | ||||
| -rw-r--r-- | drivers/cpufreq/cpufreq_governor.c | 73 | ||||
| -rw-r--r-- | drivers/cpufreq/cpufreq_governor.h | 24 | ||||
| -rw-r--r-- | drivers/cpufreq/cpufreq_ondemand.c | 40 | ||||
| -rw-r--r-- | drivers/cpufreq/cpufreq_ondemand.h | 1 | ||||
| -rw-r--r-- | drivers/cpufreq/cpufreq_performance.c | 19 | ||||
| -rw-r--r-- | drivers/cpufreq/cpufreq_powersave.c | 19 | ||||
| -rw-r--r-- | drivers/cpufreq/cpufreq_stats.c | 157 | ||||
| -rw-r--r-- | drivers/cpufreq/cpufreq_userspace.c | 104 | ||||
| -rw-r--r-- | drivers/cpufreq/davinci-cpufreq.c | 22 | ||||
| -rw-r--r-- | drivers/cpufreq/freq_table.c | 37 | ||||
| -rw-r--r-- | drivers/cpufreq/powernv-cpufreq.c | 5 | ||||
| -rw-r--r-- | drivers/cpufreq/ppc_cbe_cpufreq_pmi.c | 3 | ||||
| -rw-r--r-- | drivers/cpufreq/s3c24xx-cpufreq.c | 33 | ||||
| -rw-r--r-- | drivers/cpufreq/s5pv210-cpufreq.c | 8 | 
18 files changed, 309 insertions, 496 deletions
diff --git a/drivers/cpufreq/Kconfig b/drivers/cpufreq/Kconfig index b7445b6ae5a4..c822d72629d5 100644 --- a/drivers/cpufreq/Kconfig +++ b/drivers/cpufreq/Kconfig @@ -31,23 +31,18 @@ config CPU_FREQ_BOOST_SW  	depends on THERMAL  config CPU_FREQ_STAT -	tristate "CPU frequency translation statistics" +	bool "CPU frequency transition statistics"  	default y  	help -	  This driver exports CPU frequency statistics information through sysfs -	  file system. - -	  To compile this driver as a module, choose M here: the -	  module will be called cpufreq_stats. +	  Export CPU frequency statistics information through sysfs.  	  If in doubt, say N.  config CPU_FREQ_STAT_DETAILS -	bool "CPU frequency translation statistics details" +	bool "CPU frequency transition statistics details"  	depends on CPU_FREQ_STAT  	help -	  This will show detail CPU frequency translation table in sysfs file -	  system. +	  Show detailed CPU frequency transition table in sysfs.  	  If in doubt, say N. diff --git a/drivers/cpufreq/amd_freq_sensitivity.c b/drivers/cpufreq/amd_freq_sensitivity.c index 404360cad25c..6d5dc04c3a37 100644 --- a/drivers/cpufreq/amd_freq_sensitivity.c +++ b/drivers/cpufreq/amd_freq_sensitivity.c @@ -48,9 +48,8 @@ static unsigned int amd_powersave_bias_target(struct cpufreq_policy *policy,  	struct policy_dbs_info *policy_dbs = policy->governor_data;  	struct dbs_data *od_data = policy_dbs->dbs_data;  	struct od_dbs_tuners *od_tuners = od_data->tuners; -	struct od_policy_dbs_info *od_info = to_dbs_info(policy_dbs); -	if (!od_info->freq_table) +	if (!policy->freq_table)  		return freq_next;  	rdmsr_on_cpu(policy->cpu, MSR_AMD64_FREQ_SENSITIVITY_ACTUAL, @@ -92,10 +91,9 @@ static unsigned int amd_powersave_bias_target(struct cpufreq_policy *policy,  		else {  			unsigned int index; -			cpufreq_frequency_table_target(policy, -				od_info->freq_table, policy->cur - 1, -				CPUFREQ_RELATION_H, &index); -			freq_next = od_info->freq_table[index].frequency; +			index = cpufreq_frequency_table_target(policy, +				policy->cur - 1, CPUFREQ_RELATION_H); +			freq_next = policy->freq_table[index].frequency;  		}  		data->freq_prev = freq_next; diff --git a/drivers/cpufreq/cpufreq.c b/drivers/cpufreq/cpufreq.c index 9009295f5134..9ae58a18ccb9 100644 --- a/drivers/cpufreq/cpufreq.c +++ b/drivers/cpufreq/cpufreq.c @@ -74,19 +74,12 @@ static inline bool has_target(void)  }  /* internal prototypes */ -static int cpufreq_governor(struct cpufreq_policy *policy, unsigned int event);  static unsigned int __cpufreq_get(struct cpufreq_policy *policy); +static int cpufreq_init_governor(struct cpufreq_policy *policy); +static void cpufreq_exit_governor(struct cpufreq_policy *policy);  static int cpufreq_start_governor(struct cpufreq_policy *policy); - -static inline void cpufreq_exit_governor(struct cpufreq_policy *policy) -{ -	(void)cpufreq_governor(policy, CPUFREQ_GOV_POLICY_EXIT); -} - -static inline void cpufreq_stop_governor(struct cpufreq_policy *policy) -{ -	(void)cpufreq_governor(policy, CPUFREQ_GOV_STOP); -} +static void cpufreq_stop_governor(struct cpufreq_policy *policy); +static void cpufreq_governor_limits(struct cpufreq_policy *policy);  /**   * Two notifier lists: the "policy" list is involved in the @@ -133,15 +126,6 @@ struct kobject *get_governor_parent_kobj(struct cpufreq_policy *policy)  }  EXPORT_SYMBOL_GPL(get_governor_parent_kobj); -struct cpufreq_frequency_table *cpufreq_frequency_get_table(unsigned int cpu) -{ -	struct cpufreq_policy *policy = per_cpu(cpufreq_cpu_data, cpu); - -	return policy && !policy_is_inactive(policy) ? -		policy->freq_table : NULL; -} -EXPORT_SYMBOL_GPL(cpufreq_frequency_get_table); -  static inline u64 get_cpu_idle_time_jiffy(unsigned int cpu, u64 *wall)  {  	u64 idle_time; @@ -354,6 +338,7 @@ static void __cpufreq_notify_transition(struct cpufreq_policy *policy,  		pr_debug("FREQ: %lu - CPU: %lu\n",  			 (unsigned long)freqs->new, (unsigned long)freqs->cpu);  		trace_cpu_frequency(freqs->new, freqs->cpu); +		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)) @@ -1115,6 +1100,7 @@ static void cpufreq_policy_put_kobj(struct cpufreq_policy *policy, bool notify)  					     CPUFREQ_REMOVE_POLICY, policy);  	down_write(&policy->rwsem); +	cpufreq_stats_free_table(policy);  	cpufreq_remove_dev_symlink(policy);  	kobj = &policy->kobj;  	cmp = &policy->kobj_unregister; @@ -1265,13 +1251,12 @@ static int cpufreq_online(unsigned int cpu)  		}  	} -	blocking_notifier_call_chain(&cpufreq_policy_notifier_list, -				     CPUFREQ_START, policy); -  	if (new_policy) {  		ret = cpufreq_add_dev_interface(policy);  		if (ret)  			goto out_exit_policy; + +		cpufreq_stats_create_table(policy);  		blocking_notifier_call_chain(&cpufreq_policy_notifier_list,  				CPUFREQ_CREATE_POLICY, policy); @@ -1280,6 +1265,9 @@ static int cpufreq_online(unsigned int cpu)  		write_unlock_irqrestore(&cpufreq_driver_lock, flags);  	} +	blocking_notifier_call_chain(&cpufreq_policy_notifier_list, +				     CPUFREQ_START, policy); +  	ret = cpufreq_init_policy(policy);  	if (ret) {  		pr_err("%s: Failed to initialize policy for cpu: %d (%d)\n", @@ -1864,14 +1852,17 @@ static int __target_intermediate(struct cpufreq_policy *policy,  	return ret;  } -static int __target_index(struct cpufreq_policy *policy, -			  struct cpufreq_frequency_table *freq_table, int index) +static int __target_index(struct cpufreq_policy *policy, int index)  {  	struct cpufreq_freqs freqs = {.old = policy->cur, .flags = 0};  	unsigned int intermediate_freq = 0; +	unsigned int newfreq = policy->freq_table[index].frequency;  	int retval = -EINVAL;  	bool notify; +	if (newfreq == policy->cur) +		return 0; +  	notify = !(cpufreq_driver->flags & CPUFREQ_ASYNC_NOTIFICATION);  	if (notify) {  		/* Handle switching to intermediate frequency */ @@ -1886,7 +1877,7 @@ static int __target_index(struct cpufreq_policy *policy,  				freqs.old = freqs.new;  		} -		freqs.new = freq_table[index].frequency; +		freqs.new = newfreq;  		pr_debug("%s: cpu: %d, oldfreq: %u, new freq: %u\n",  			 __func__, policy->cpu, freqs.old, freqs.new); @@ -1923,17 +1914,13 @@ int __cpufreq_driver_target(struct cpufreq_policy *policy,  			    unsigned int relation)  {  	unsigned int old_target_freq = target_freq; -	struct cpufreq_frequency_table *freq_table; -	int index, retval; +	int index;  	if (cpufreq_disabled())  		return -ENODEV;  	/* Make sure that target_freq is within supported range */ -	if (target_freq > policy->max) -		target_freq = policy->max; -	if (target_freq < policy->min) -		target_freq = policy->min; +	target_freq = clamp_val(target_freq, policy->min, policy->max);  	pr_debug("target for CPU %u: %u kHz, relation %u, requested %u kHz\n",  		 policy->cpu, target_freq, relation, old_target_freq); @@ -1956,23 +1943,9 @@ int __cpufreq_driver_target(struct cpufreq_policy *policy,  	if (!cpufreq_driver->target_index)  		return -EINVAL; -	freq_table = cpufreq_frequency_get_table(policy->cpu); -	if (unlikely(!freq_table)) { -		pr_err("%s: Unable to find freq_table\n", __func__); -		return -EINVAL; -	} - -	retval = cpufreq_frequency_table_target(policy, freq_table, target_freq, -						relation, &index); -	if (unlikely(retval)) { -		pr_err("%s: Unable to find matching freq\n", __func__); -		return retval; -	} - -	if (freq_table[index].frequency == policy->cur) -		return 0; +	index = cpufreq_frequency_table_target(policy, target_freq, relation); -	return __target_index(policy, freq_table, index); +	return __target_index(policy, index);  }  EXPORT_SYMBOL_GPL(__cpufreq_driver_target); @@ -1997,7 +1970,7 @@ __weak struct cpufreq_governor *cpufreq_fallback_governor(void)  	return NULL;  } -static int cpufreq_governor(struct cpufreq_policy *policy, unsigned int event) +static int cpufreq_init_governor(struct cpufreq_policy *policy)  {  	int ret; @@ -2025,36 +1998,82 @@ static int cpufreq_governor(struct cpufreq_policy *policy, unsigned int event)  		}  	} -	if (event == CPUFREQ_GOV_POLICY_INIT) -		if (!try_module_get(policy->governor->owner)) -			return -EINVAL; - -	pr_debug("%s: for CPU %u, event %u\n", __func__, policy->cpu, event); +	if (!try_module_get(policy->governor->owner)) +		return -EINVAL; -	ret = policy->governor->governor(policy, event); +	pr_debug("%s: for CPU %u\n", __func__, policy->cpu); -	if (event == CPUFREQ_GOV_POLICY_INIT) { -		if (ret) +	if (policy->governor->init) { +		ret = policy->governor->init(policy); +		if (ret) {  			module_put(policy->governor->owner); -		else -			policy->governor->initialized++; -	} else if (event == CPUFREQ_GOV_POLICY_EXIT) { -		policy->governor->initialized--; -		module_put(policy->governor->owner); +			return ret; +		}  	} -	return ret; +	return 0; +} + +static void cpufreq_exit_governor(struct cpufreq_policy *policy) +{ +	if (cpufreq_suspended || !policy->governor) +		return; + +	pr_debug("%s: for CPU %u\n", __func__, policy->cpu); + +	if (policy->governor->exit) +		policy->governor->exit(policy); + +	module_put(policy->governor->owner);  }  static int cpufreq_start_governor(struct cpufreq_policy *policy)  {  	int ret; +	if (cpufreq_suspended) +		return 0; + +	if (!policy->governor) +		return -EINVAL; + +	pr_debug("%s: for CPU %u\n", __func__, policy->cpu); +  	if (cpufreq_driver->get && !cpufreq_driver->setpolicy)  		cpufreq_update_current_freq(policy); -	ret = cpufreq_governor(policy, CPUFREQ_GOV_START); -	return ret ? ret : cpufreq_governor(policy, CPUFREQ_GOV_LIMITS); +	if (policy->governor->start) { +		ret = policy->governor->start(policy); +		if (ret) +			return ret; +	} + +	if (policy->governor->limits) +		policy->governor->limits(policy); + +	return 0; +} + +static void cpufreq_stop_governor(struct cpufreq_policy *policy) +{ +	if (cpufreq_suspended || !policy->governor) +		return; + +	pr_debug("%s: for CPU %u\n", __func__, policy->cpu); + +	if (policy->governor->stop) +		policy->governor->stop(policy); +} + +static void cpufreq_governor_limits(struct cpufreq_policy *policy) +{ +	if (cpufreq_suspended || !policy->governor) +		return; + +	pr_debug("%s: for CPU %u\n", __func__, policy->cpu); + +	if (policy->governor->limits) +		policy->governor->limits(policy);  }  int cpufreq_register_governor(struct cpufreq_governor *governor) @@ -2069,7 +2088,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; @@ -2195,7 +2213,8 @@ static int cpufreq_set_policy(struct cpufreq_policy *policy,  	if (new_policy->governor == policy->governor) {  		pr_debug("cpufreq: governor limits update\n"); -		return cpufreq_governor(policy, CPUFREQ_GOV_LIMITS); +		cpufreq_governor_limits(policy); +		return 0;  	}  	pr_debug("governor switch\n"); @@ -2210,7 +2229,7 @@ static int cpufreq_set_policy(struct cpufreq_policy *policy,  	/* start new governor */  	policy->governor = new_policy->governor; -	ret = cpufreq_governor(policy, CPUFREQ_GOV_POLICY_INIT); +	ret = cpufreq_init_governor(policy);  	if (!ret) {  		ret = cpufreq_start_governor(policy);  		if (!ret) { @@ -2224,7 +2243,7 @@ static int cpufreq_set_policy(struct cpufreq_policy *policy,  	pr_debug("starting governor %s failed\n", policy->governor->name);  	if (old_gov) {  		policy->governor = old_gov; -		if (cpufreq_governor(policy, CPUFREQ_GOV_POLICY_INIT)) +		if (cpufreq_init_governor(policy))  			policy->governor = NULL;  		else  			cpufreq_start_governor(policy); @@ -2305,26 +2324,25 @@ static struct notifier_block __refdata cpufreq_cpu_notifier = {   *********************************************************************/  static int cpufreq_boost_set_sw(int state)  { -	struct cpufreq_frequency_table *freq_table;  	struct cpufreq_policy *policy;  	int ret = -EINVAL;  	for_each_active_policy(policy) { -		freq_table = cpufreq_frequency_get_table(policy->cpu); -		if (freq_table) { -			ret = cpufreq_frequency_table_cpuinfo(policy, -							freq_table); -			if (ret) { -				pr_err("%s: Policy frequency update failed\n", -				       __func__); -				break; -			} - -			down_write(&policy->rwsem); -			policy->user_policy.max = policy->max; -			cpufreq_governor(policy, CPUFREQ_GOV_LIMITS); -			up_write(&policy->rwsem); +		if (!policy->freq_table) +			continue; + +		ret = cpufreq_frequency_table_cpuinfo(policy, +						      policy->freq_table); +		if (ret) { +			pr_err("%s: Policy frequency update failed\n", +			       __func__); +			break;  		} + +		down_write(&policy->rwsem); +		policy->user_policy.max = policy->max; +		cpufreq_governor_limits(policy); +		up_write(&policy->rwsem);  	}  	return ret; diff --git a/drivers/cpufreq/cpufreq_conservative.c b/drivers/cpufreq/cpufreq_conservative.c index 316df247e00d..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,15 +274,13 @@ 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;  	tuners = kzalloc(sizeof(*tuners), GFP_KERNEL); -	if (!tuners) { -		pr_err("%s: kzalloc failed\n", __func__); +	if (!tuners)  		return -ENOMEM; -	}  	tuners->down_threshold = DEF_FREQUENCY_DOWN_THRESHOLD;  	tuners->freq_step = DEF_FREQUENCY_STEP; @@ -288,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); @@ -312,23 +322,20 @@ static void cs_start(struct cpufreq_policy *policy)  	dbs_info->requested_freq = policy->cur;  } -static struct dbs_governor cs_dbs_gov = { -	.gov = { -		.name = "conservative", -		.governor = cpufreq_governor_dbs, -		.max_transition_latency = TRANSITION_LATENCY_LIMIT, -		.owner = THIS_MODULE, +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,  	}, -	.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 be498d56dd69..e415349ab31b 100644 --- a/drivers/cpufreq/cpufreq_governor.c +++ b/drivers/cpufreq/cpufreq_governor.c @@ -336,17 +336,6 @@ static inline void gov_clear_update_util(struct cpufreq_policy *policy)  	synchronize_sched();  } -static void gov_cancel_work(struct cpufreq_policy *policy) -{ -	struct policy_dbs_info *policy_dbs = policy->governor_data; - -	gov_clear_update_util(policy_dbs->policy); -	irq_work_sync(&policy_dbs->irq_work); -	cancel_work_sync(&policy_dbs->work); -	atomic_set(&policy_dbs->work_count, 0); -	policy_dbs->work_in_progress = false; -} -  static struct policy_dbs_info *alloc_policy_dbs_info(struct cpufreq_policy *policy,  						     struct dbs_governor *gov)  { @@ -389,7 +378,7 @@ static void free_policy_dbs_info(struct policy_dbs_info *policy_dbs,  	gov->free(policy_dbs);  } -static int cpufreq_governor_init(struct cpufreq_policy *policy) +int cpufreq_dbs_governor_init(struct cpufreq_policy *policy)  {  	struct dbs_governor *gov = dbs_governor_of(policy);  	struct dbs_data *dbs_data; @@ -429,7 +418,7 @@ static int cpufreq_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; @@ -458,13 +447,13 @@ static int cpufreq_governor_init(struct cpufreq_policy *policy)  		goto out;  	/* Failure, so roll back. */ -	pr_err("cpufreq: Governor initialization failed (dbs_data kobject init error %d)\n", ret); +	pr_err("initialization failed (dbs_data kobject init error %d)\n", ret);  	policy->governor_data = NULL;  	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: @@ -474,8 +463,9 @@ out:  	mutex_unlock(&gov_dbs_data_mutex);  	return ret;  } +EXPORT_SYMBOL_GPL(cpufreq_dbs_governor_init); -static int cpufreq_governor_exit(struct cpufreq_policy *policy) +void cpufreq_dbs_governor_exit(struct cpufreq_policy *policy)  {  	struct dbs_governor *gov = dbs_governor_of(policy);  	struct policy_dbs_info *policy_dbs = policy->governor_data; @@ -493,17 +483,17 @@ static int cpufreq_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);  	}  	free_policy_dbs_info(policy_dbs, gov);  	mutex_unlock(&gov_dbs_data_mutex); -	return 0;  } +EXPORT_SYMBOL_GPL(cpufreq_dbs_governor_exit); -static int cpufreq_governor_start(struct cpufreq_policy *policy) +int cpufreq_dbs_governor_start(struct cpufreq_policy *policy)  {  	struct dbs_governor *gov = dbs_governor_of(policy);  	struct policy_dbs_info *policy_dbs = policy->governor_data; @@ -539,47 +529,28 @@ static int cpufreq_governor_start(struct cpufreq_policy *policy)  	gov_set_update_util(policy_dbs, sampling_rate);  	return 0;  } +EXPORT_SYMBOL_GPL(cpufreq_dbs_governor_start); -static int cpufreq_governor_stop(struct cpufreq_policy *policy) +void cpufreq_dbs_governor_stop(struct cpufreq_policy *policy)  { -	gov_cancel_work(policy); -	return 0; +	struct policy_dbs_info *policy_dbs = policy->governor_data; + +	gov_clear_update_util(policy_dbs->policy); +	irq_work_sync(&policy_dbs->irq_work); +	cancel_work_sync(&policy_dbs->work); +	atomic_set(&policy_dbs->work_count, 0); +	policy_dbs->work_in_progress = false;  } +EXPORT_SYMBOL_GPL(cpufreq_dbs_governor_stop); -static int cpufreq_governor_limits(struct cpufreq_policy *policy) +void cpufreq_dbs_governor_limits(struct cpufreq_policy *policy)  {  	struct policy_dbs_info *policy_dbs = policy->governor_data;  	mutex_lock(&policy_dbs->timer_mutex); - -	if (policy->max < policy->cur) -		__cpufreq_driver_target(policy, policy->max, CPUFREQ_RELATION_H); -	else if (policy->min > policy->cur) -		__cpufreq_driver_target(policy, policy->min, CPUFREQ_RELATION_L); - +	cpufreq_policy_apply_limits(policy);  	gov_update_sample_delay(policy_dbs, 0);  	mutex_unlock(&policy_dbs->timer_mutex); - -	return 0; -} - -int cpufreq_governor_dbs(struct cpufreq_policy *policy, unsigned int event) -{ -	if (event == CPUFREQ_GOV_POLICY_INIT) { -		return cpufreq_governor_init(policy); -	} else if (policy->governor_data) { -		switch (event) { -		case CPUFREQ_GOV_POLICY_EXIT: -			return cpufreq_governor_exit(policy); -		case CPUFREQ_GOV_START: -			return cpufreq_governor_start(policy); -		case CPUFREQ_GOV_STOP: -			return cpufreq_governor_stop(policy); -		case CPUFREQ_GOV_LIMITS: -			return cpufreq_governor_limits(policy); -		} -	} -	return -EINVAL;  } -EXPORT_SYMBOL_GPL(cpufreq_governor_dbs); +EXPORT_SYMBOL_GPL(cpufreq_dbs_governor_limits); diff --git a/drivers/cpufreq/cpufreq_governor.h b/drivers/cpufreq/cpufreq_governor.h index 34eb214b6d57..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);  }; @@ -148,6 +148,25 @@ static inline struct dbs_governor *dbs_governor_of(struct cpufreq_policy *policy  	return container_of(policy->governor, struct dbs_governor, gov);  } +/* Governor callback routines */ +int cpufreq_dbs_governor_init(struct cpufreq_policy *policy); +void cpufreq_dbs_governor_exit(struct cpufreq_policy *policy); +int cpufreq_dbs_governor_start(struct cpufreq_policy *policy); +void cpufreq_dbs_governor_stop(struct cpufreq_policy *policy); +void cpufreq_dbs_governor_limits(struct cpufreq_policy *policy); + +#define CPUFREQ_DBS_GOVERNOR_INITIALIZER(_name_)			\ +	{								\ +		.name = _name_,						\ +		.max_transition_latency	= TRANSITION_LATENCY_LIMIT,	\ +		.owner = THIS_MODULE,					\ +		.init = cpufreq_dbs_governor_init,			\ +		.exit = cpufreq_dbs_governor_exit,			\ +		.start = cpufreq_dbs_governor_start,			\ +		.stop = cpufreq_dbs_governor_stop,			\ +		.limits = cpufreq_dbs_governor_limits,			\ +	} +  /* Governor specific operations */  struct od_ops {  	unsigned int (*powersave_bias_target)(struct cpufreq_policy *policy, @@ -155,7 +174,6 @@ struct od_ops {  };  unsigned int dbs_update(struct cpufreq_policy *policy); -int cpufreq_governor_dbs(struct cpufreq_policy *policy, unsigned int event);  void od_register_powersave_bias_handler(unsigned int (*f)  		(struct cpufreq_policy *, unsigned int, unsigned int),  		unsigned int powersave_bias); diff --git a/drivers/cpufreq/cpufreq_ondemand.c b/drivers/cpufreq/cpufreq_ondemand.c index 300163430516..0c93cd9dee99 100644 --- a/drivers/cpufreq/cpufreq_ondemand.c +++ b/drivers/cpufreq/cpufreq_ondemand.c @@ -65,34 +65,32 @@ static unsigned int generic_powersave_bias_target(struct cpufreq_policy *policy,  {  	unsigned int freq_req, freq_reduc, freq_avg;  	unsigned int freq_hi, freq_lo; -	unsigned int index = 0; +	unsigned int index;  	unsigned int delay_hi_us;  	struct policy_dbs_info *policy_dbs = policy->governor_data;  	struct od_policy_dbs_info *dbs_info = to_dbs_info(policy_dbs);  	struct dbs_data *dbs_data = policy_dbs->dbs_data;  	struct od_dbs_tuners *od_tuners = dbs_data->tuners; +	struct cpufreq_frequency_table *freq_table = policy->freq_table; -	if (!dbs_info->freq_table) { +	if (!freq_table) {  		dbs_info->freq_lo = 0;  		dbs_info->freq_lo_delay_us = 0;  		return freq_next;  	} -	cpufreq_frequency_table_target(policy, dbs_info->freq_table, freq_next, -			relation, &index); -	freq_req = dbs_info->freq_table[index].frequency; +	index = cpufreq_frequency_table_target(policy, freq_next, relation); +	freq_req = freq_table[index].frequency;  	freq_reduc = freq_req * od_tuners->powersave_bias / 1000;  	freq_avg = freq_req - freq_reduc;  	/* Find freq bounds for freq_avg in freq_table */ -	index = 0; -	cpufreq_frequency_table_target(policy, dbs_info->freq_table, freq_avg, -			CPUFREQ_RELATION_H, &index); -	freq_lo = dbs_info->freq_table[index].frequency; -	index = 0; -	cpufreq_frequency_table_target(policy, dbs_info->freq_table, freq_avg, -			CPUFREQ_RELATION_L, &index); -	freq_hi = dbs_info->freq_table[index].frequency; +	index = cpufreq_frequency_table_target(policy, freq_avg, +					       CPUFREQ_RELATION_H); +	freq_lo = freq_table[index].frequency; +	index = cpufreq_frequency_table_target(policy, freq_avg, +					       CPUFREQ_RELATION_L); +	freq_hi = freq_table[index].frequency;  	/* Find out how long we have to be in hi and lo freqs */  	if (freq_hi == freq_lo) { @@ -113,7 +111,6 @@ static void ondemand_powersave_bias_init(struct cpufreq_policy *policy)  {  	struct od_policy_dbs_info *dbs_info = to_dbs_info(policy->governor_data); -	dbs_info->freq_table = cpufreq_frequency_get_table(policy->cpu);  	dbs_info->freq_lo = 0;  } @@ -361,17 +358,15 @@ 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;  	int cpu;  	tuners = kzalloc(sizeof(*tuners), GFP_KERNEL); -	if (!tuners) { -		pr_err("%s: kzalloc failed\n", __func__); +	if (!tuners)  		return -ENOMEM; -	}  	cpu = get_cpu();  	idle_time = get_cpu_idle_time_us(cpu, NULL); @@ -402,7 +397,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);  } @@ -420,12 +415,7 @@ static struct od_ops od_ops = {  };  static struct dbs_governor od_dbs_gov = { -	.gov = { -		.name = "ondemand", -		.governor = cpufreq_governor_dbs, -		.max_transition_latency	= TRANSITION_LATENCY_LIMIT, -		.owner = THIS_MODULE, -	}, +	.gov = CPUFREQ_DBS_GOVERNOR_INITIALIZER("ondemand"),  	.kobj_type = { .default_attrs = od_attributes },  	.gov_dbs_timer = od_dbs_timer,  	.alloc = od_alloc, diff --git a/drivers/cpufreq/cpufreq_ondemand.h b/drivers/cpufreq/cpufreq_ondemand.h index f0121db3cd9e..640ea4e97106 100644 --- a/drivers/cpufreq/cpufreq_ondemand.h +++ b/drivers/cpufreq/cpufreq_ondemand.h @@ -13,7 +13,6 @@  struct od_policy_dbs_info {  	struct policy_dbs_info policy_dbs; -	struct cpufreq_frequency_table *freq_table;  	unsigned int freq_lo;  	unsigned int freq_lo_delay_us;  	unsigned int freq_hi_delay_us; diff --git a/drivers/cpufreq/cpufreq_performance.c b/drivers/cpufreq/cpufreq_performance.c index af9f4b96f5a8..dafb679adc58 100644 --- a/drivers/cpufreq/cpufreq_performance.c +++ b/drivers/cpufreq/cpufreq_performance.c @@ -16,27 +16,16 @@  #include <linux/init.h>  #include <linux/module.h> -static int cpufreq_governor_performance(struct cpufreq_policy *policy, -					unsigned int event) +static void cpufreq_gov_performance_limits(struct cpufreq_policy *policy)  { -	switch (event) { -	case CPUFREQ_GOV_START: -	case CPUFREQ_GOV_LIMITS: -		pr_debug("setting to %u kHz because of event %u\n", -						policy->max, event); -		__cpufreq_driver_target(policy, policy->max, -						CPUFREQ_RELATION_H); -		break; -	default: -		break; -	} -	return 0; +	pr_debug("setting to %u kHz\n", policy->max); +	__cpufreq_driver_target(policy, policy->max, CPUFREQ_RELATION_H);  }  static struct cpufreq_governor cpufreq_gov_performance = {  	.name		= "performance", -	.governor	= cpufreq_governor_performance,  	.owner		= THIS_MODULE, +	.limits		= cpufreq_gov_performance_limits,  };  static int __init cpufreq_gov_performance_init(void) diff --git a/drivers/cpufreq/cpufreq_powersave.c b/drivers/cpufreq/cpufreq_powersave.c index b8b400232a74..78a651038faf 100644 --- a/drivers/cpufreq/cpufreq_powersave.c +++ b/drivers/cpufreq/cpufreq_powersave.c @@ -16,26 +16,15 @@  #include <linux/init.h>  #include <linux/module.h> -static int cpufreq_governor_powersave(struct cpufreq_policy *policy, -					unsigned int event) +static void cpufreq_gov_powersave_limits(struct cpufreq_policy *policy)  { -	switch (event) { -	case CPUFREQ_GOV_START: -	case CPUFREQ_GOV_LIMITS: -		pr_debug("setting to %u kHz because of event %u\n", -							policy->min, event); -		__cpufreq_driver_target(policy, policy->min, -						CPUFREQ_RELATION_L); -		break; -	default: -		break; -	} -	return 0; +	pr_debug("setting to %u kHz\n", policy->min); +	__cpufreq_driver_target(policy, policy->min, CPUFREQ_RELATION_L);  }  static struct cpufreq_governor cpufreq_gov_powersave = {  	.name		= "powersave", -	.governor	= cpufreq_governor_powersave, +	.limits		= cpufreq_gov_powersave_limits,  	.owner		= THIS_MODULE,  }; diff --git a/drivers/cpufreq/cpufreq_stats.c b/drivers/cpufreq/cpufreq_stats.c index 5e370a30a964..06d3abdffd3a 100644 --- a/drivers/cpufreq/cpufreq_stats.c +++ b/drivers/cpufreq/cpufreq_stats.c @@ -15,7 +15,7 @@  #include <linux/slab.h>  #include <linux/cputime.h> -static spinlock_t cpufreq_stats_lock; +static DEFINE_SPINLOCK(cpufreq_stats_lock);  struct cpufreq_stats {  	unsigned int total_trans; @@ -52,6 +52,9 @@ static ssize_t show_time_in_state(struct cpufreq_policy *policy, char *buf)  	ssize_t len = 0;  	int i; +	if (policy->fast_switch_enabled) +		return 0; +  	cpufreq_stats_update(stats);  	for (i = 0; i < stats->state_num; i++) {  		len += sprintf(buf + len, "%u %llu\n", stats->freq_table[i], @@ -68,6 +71,9 @@ static ssize_t show_trans_table(struct cpufreq_policy *policy, char *buf)  	ssize_t len = 0;  	int i, j; +	if (policy->fast_switch_enabled) +		return 0; +  	len += snprintf(buf + len, PAGE_SIZE - len, "   From  :    To\n");  	len += snprintf(buf + len, PAGE_SIZE - len, "         : ");  	for (i = 0; i < stats->state_num; i++) { @@ -130,7 +136,7 @@ static int freq_table_get_index(struct cpufreq_stats *stats, unsigned int freq)  	return -1;  } -static void __cpufreq_stats_free_table(struct cpufreq_policy *policy) +void cpufreq_stats_free_table(struct cpufreq_policy *policy)  {  	struct cpufreq_stats *stats = policy->stats; @@ -146,39 +152,25 @@ static void __cpufreq_stats_free_table(struct cpufreq_policy *policy)  	policy->stats = NULL;  } -static void cpufreq_stats_free_table(unsigned int cpu) -{ -	struct cpufreq_policy *policy; - -	policy = cpufreq_cpu_get(cpu); -	if (!policy) -		return; - -	__cpufreq_stats_free_table(policy); - -	cpufreq_cpu_put(policy); -} - -static int __cpufreq_stats_create_table(struct cpufreq_policy *policy) +void cpufreq_stats_create_table(struct cpufreq_policy *policy)  {  	unsigned int i = 0, count = 0, ret = -ENOMEM;  	struct cpufreq_stats *stats;  	unsigned int alloc_size; -	unsigned int cpu = policy->cpu;  	struct cpufreq_frequency_table *pos, *table;  	/* We need cpufreq table for creating stats table */ -	table = cpufreq_frequency_get_table(cpu); +	table = policy->freq_table;  	if (unlikely(!table)) -		return 0; +		return;  	/* stats already initialized */  	if (policy->stats) -		return -EEXIST; +		return;  	stats = kzalloc(sizeof(*stats), GFP_KERNEL);  	if (!stats) -		return -ENOMEM; +		return;  	/* Find total allocation size */  	cpufreq_for_each_valid_entry(pos, table) @@ -215,80 +207,32 @@ static int __cpufreq_stats_create_table(struct cpufreq_policy *policy)  	policy->stats = stats;  	ret = sysfs_create_group(&policy->kobj, &stats_attr_group);  	if (!ret) -		return 0; +		return;  	/* We failed, release resources */  	policy->stats = NULL;  	kfree(stats->time_in_state);  free_stat:  	kfree(stats); - -	return ret; -} - -static void cpufreq_stats_create_table(unsigned int cpu) -{ -	struct cpufreq_policy *policy; - -	/* -	 * "likely(!policy)" because normally cpufreq_stats will be registered -	 * before cpufreq driver -	 */ -	policy = cpufreq_cpu_get(cpu); -	if (likely(!policy)) -		return; - -	__cpufreq_stats_create_table(policy); - -	cpufreq_cpu_put(policy);  } -static int cpufreq_stat_notifier_policy(struct notifier_block *nb, -		unsigned long val, void *data) +void cpufreq_stats_record_transition(struct cpufreq_policy *policy, +				     unsigned int new_freq)  { -	int ret = 0; -	struct cpufreq_policy *policy = data; - -	if (val == CPUFREQ_CREATE_POLICY) -		ret = __cpufreq_stats_create_table(policy); -	else if (val == CPUFREQ_REMOVE_POLICY) -		__cpufreq_stats_free_table(policy); - -	return ret; -} - -static int cpufreq_stat_notifier_trans(struct notifier_block *nb, -		unsigned long val, void *data) -{ -	struct cpufreq_freqs *freq = data; -	struct cpufreq_policy *policy = cpufreq_cpu_get(freq->cpu); -	struct cpufreq_stats *stats; +	struct cpufreq_stats *stats = policy->stats;  	int old_index, new_index; -	if (!policy) { -		pr_err("%s: No policy found\n", __func__); -		return 0; -	} - -	if (val != CPUFREQ_POSTCHANGE) -		goto put_policy; - -	if (!policy->stats) { +	if (!stats) {  		pr_debug("%s: No stats found\n", __func__); -		goto put_policy; +		return;  	} -	stats = policy->stats; -  	old_index = stats->last_index; -	new_index = freq_table_get_index(stats, freq->new); +	new_index = freq_table_get_index(stats, new_freq);  	/* We can't do stats->time_in_state[-1]= .. */ -	if (old_index == -1 || new_index == -1) -		goto put_policy; - -	if (old_index == new_index) -		goto put_policy; +	if (old_index == -1 || new_index == -1 || old_index == new_index) +		return;  	cpufreq_stats_update(stats); @@ -297,61 +241,4 @@ static int cpufreq_stat_notifier_trans(struct notifier_block *nb,  	stats->trans_table[old_index * stats->max_state + new_index]++;  #endif  	stats->total_trans++; - -put_policy: -	cpufreq_cpu_put(policy); -	return 0;  } - -static struct notifier_block notifier_policy_block = { -	.notifier_call = cpufreq_stat_notifier_policy -}; - -static struct notifier_block notifier_trans_block = { -	.notifier_call = cpufreq_stat_notifier_trans -}; - -static int __init cpufreq_stats_init(void) -{ -	int ret; -	unsigned int cpu; - -	spin_lock_init(&cpufreq_stats_lock); -	ret = cpufreq_register_notifier(¬ifier_policy_block, -				CPUFREQ_POLICY_NOTIFIER); -	if (ret) -		return ret; - -	for_each_online_cpu(cpu) -		cpufreq_stats_create_table(cpu); - -	ret = cpufreq_register_notifier(¬ifier_trans_block, -				CPUFREQ_TRANSITION_NOTIFIER); -	if (ret) { -		cpufreq_unregister_notifier(¬ifier_policy_block, -				CPUFREQ_POLICY_NOTIFIER); -		for_each_online_cpu(cpu) -			cpufreq_stats_free_table(cpu); -		return ret; -	} - -	return 0; -} -static void __exit cpufreq_stats_exit(void) -{ -	unsigned int cpu; - -	cpufreq_unregister_notifier(¬ifier_policy_block, -			CPUFREQ_POLICY_NOTIFIER); -	cpufreq_unregister_notifier(¬ifier_trans_block, -			CPUFREQ_TRANSITION_NOTIFIER); -	for_each_online_cpu(cpu) -		cpufreq_stats_free_table(cpu); -} - -MODULE_AUTHOR("Zou Nan hai <nanhai.zou@intel.com>"); -MODULE_DESCRIPTION("Export cpufreq stats via sysfs"); -MODULE_LICENSE("GPL"); - -module_init(cpufreq_stats_init); -module_exit(cpufreq_stats_exit); diff --git a/drivers/cpufreq/cpufreq_userspace.c b/drivers/cpufreq/cpufreq_userspace.c index 9f3dec9a3f36..bd897e3e134d 100644 --- a/drivers/cpufreq/cpufreq_userspace.c +++ b/drivers/cpufreq/cpufreq_userspace.c @@ -65,66 +65,66 @@ static int cpufreq_userspace_policy_init(struct cpufreq_policy *policy)  	return 0;  } -static int cpufreq_governor_userspace(struct cpufreq_policy *policy, -				   unsigned int event) +static void cpufreq_userspace_policy_exit(struct cpufreq_policy *policy) +{ +	mutex_lock(&userspace_mutex); +	kfree(policy->governor_data); +	policy->governor_data = NULL; +	mutex_unlock(&userspace_mutex); +} + +static int cpufreq_userspace_policy_start(struct cpufreq_policy *policy)  {  	unsigned int *setspeed = policy->governor_data; -	unsigned int cpu = policy->cpu; -	int rc = 0; -	if (event == CPUFREQ_GOV_POLICY_INIT) -		return cpufreq_userspace_policy_init(policy); +	BUG_ON(!policy->cur); +	pr_debug("started managing cpu %u\n", policy->cpu); -	if (!setspeed) -		return -EINVAL; - -	switch (event) { -	case CPUFREQ_GOV_POLICY_EXIT: -		mutex_lock(&userspace_mutex); -		policy->governor_data = NULL; -		kfree(setspeed); -		mutex_unlock(&userspace_mutex); -		break; -	case CPUFREQ_GOV_START: -		BUG_ON(!policy->cur); -		pr_debug("started managing cpu %u\n", cpu); - -		mutex_lock(&userspace_mutex); -		per_cpu(cpu_is_managed, cpu) = 1; -		*setspeed = policy->cur; -		mutex_unlock(&userspace_mutex); -		break; -	case CPUFREQ_GOV_STOP: -		pr_debug("managing cpu %u stopped\n", cpu); - -		mutex_lock(&userspace_mutex); -		per_cpu(cpu_is_managed, cpu) = 0; -		*setspeed = 0; -		mutex_unlock(&userspace_mutex); -		break; -	case CPUFREQ_GOV_LIMITS: -		mutex_lock(&userspace_mutex); -		pr_debug("limit event for cpu %u: %u - %u kHz, currently %u kHz, last set to %u kHz\n", -			cpu, policy->min, policy->max, policy->cur, *setspeed); - -		if (policy->max < *setspeed) -			__cpufreq_driver_target(policy, policy->max, -						CPUFREQ_RELATION_H); -		else if (policy->min > *setspeed) -			__cpufreq_driver_target(policy, policy->min, -						CPUFREQ_RELATION_L); -		else -			__cpufreq_driver_target(policy, *setspeed, -						CPUFREQ_RELATION_L); -		mutex_unlock(&userspace_mutex); -		break; -	} -	return rc; +	mutex_lock(&userspace_mutex); +	per_cpu(cpu_is_managed, policy->cpu) = 1; +	*setspeed = policy->cur; +	mutex_unlock(&userspace_mutex); +	return 0; +} + +static void cpufreq_userspace_policy_stop(struct cpufreq_policy *policy) +{ +	unsigned int *setspeed = policy->governor_data; + +	pr_debug("managing cpu %u stopped\n", policy->cpu); + +	mutex_lock(&userspace_mutex); +	per_cpu(cpu_is_managed, policy->cpu) = 0; +	*setspeed = 0; +	mutex_unlock(&userspace_mutex); +} + +static void cpufreq_userspace_policy_limits(struct cpufreq_policy *policy) +{ +	unsigned int *setspeed = policy->governor_data; + +	mutex_lock(&userspace_mutex); + +	pr_debug("limit event for cpu %u: %u - %u kHz, currently %u kHz, last set to %u kHz\n", +		 policy->cpu, policy->min, policy->max, policy->cur, *setspeed); + +	if (policy->max < *setspeed) +		__cpufreq_driver_target(policy, policy->max, CPUFREQ_RELATION_H); +	else if (policy->min > *setspeed) +		__cpufreq_driver_target(policy, policy->min, CPUFREQ_RELATION_L); +	else +		__cpufreq_driver_target(policy, *setspeed, CPUFREQ_RELATION_L); + +	mutex_unlock(&userspace_mutex);  }  static struct cpufreq_governor cpufreq_gov_userspace = {  	.name		= "userspace", -	.governor	= cpufreq_governor_userspace, +	.init		= cpufreq_userspace_policy_init, +	.exit		= cpufreq_userspace_policy_exit, +	.start		= cpufreq_userspace_policy_start, +	.stop		= cpufreq_userspace_policy_stop, +	.limits		= cpufreq_userspace_policy_limits,  	.store_setspeed	= cpufreq_set,  	.show_setspeed	= show_speed,  	.owner		= THIS_MODULE, diff --git a/drivers/cpufreq/davinci-cpufreq.c b/drivers/cpufreq/davinci-cpufreq.c index 7e336d20c184..b95a872800ec 100644 --- a/drivers/cpufreq/davinci-cpufreq.c +++ b/drivers/cpufreq/davinci-cpufreq.c @@ -38,26 +38,6 @@ struct davinci_cpufreq {  };  static struct davinci_cpufreq cpufreq; -static int davinci_verify_speed(struct cpufreq_policy *policy) -{ -	struct davinci_cpufreq_config *pdata = cpufreq.dev->platform_data; -	struct cpufreq_frequency_table *freq_table = pdata->freq_table; -	struct clk *armclk = cpufreq.armclk; - -	if (freq_table) -		return cpufreq_frequency_table_verify(policy, freq_table); - -	if (policy->cpu) -		return -EINVAL; - -	cpufreq_verify_within_cpu_limits(policy); -	policy->min = clk_round_rate(armclk, policy->min * 1000) / 1000; -	policy->max = clk_round_rate(armclk, policy->max * 1000) / 1000; -	cpufreq_verify_within_limits(policy, policy->cpuinfo.min_freq, -						policy->cpuinfo.max_freq); -	return 0; -} -  static int davinci_target(struct cpufreq_policy *policy, unsigned int idx)  {  	struct davinci_cpufreq_config *pdata = cpufreq.dev->platform_data; @@ -121,7 +101,7 @@ static int davinci_cpu_init(struct cpufreq_policy *policy)  static struct cpufreq_driver davinci_driver = {  	.flags		= CPUFREQ_STICKY | CPUFREQ_NEED_INITIAL_FREQ_CHECK, -	.verify		= davinci_verify_speed, +	.verify		= cpufreq_generic_frequency_table_verify,  	.target_index	= davinci_target,  	.get		= cpufreq_generic_get,  	.init		= davinci_cpu_init, diff --git a/drivers/cpufreq/freq_table.c b/drivers/cpufreq/freq_table.c index a8f1daffc9bc..eac8bcbdaad1 100644 --- a/drivers/cpufreq/freq_table.c +++ b/drivers/cpufreq/freq_table.c @@ -63,8 +63,6 @@ int cpufreq_frequency_table_cpuinfo(struct cpufreq_policy *policy,  	else  		return 0;  } -EXPORT_SYMBOL_GPL(cpufreq_frequency_table_cpuinfo); -  int cpufreq_frequency_table_verify(struct cpufreq_policy *policy,  				   struct cpufreq_frequency_table *table) @@ -108,20 +106,16 @@ EXPORT_SYMBOL_GPL(cpufreq_frequency_table_verify);   */  int cpufreq_generic_frequency_table_verify(struct cpufreq_policy *policy)  { -	struct cpufreq_frequency_table *table = -		cpufreq_frequency_get_table(policy->cpu); -	if (!table) +	if (!policy->freq_table)  		return -ENODEV; -	return cpufreq_frequency_table_verify(policy, table); +	return cpufreq_frequency_table_verify(policy, policy->freq_table);  }  EXPORT_SYMBOL_GPL(cpufreq_generic_frequency_table_verify);  int cpufreq_frequency_table_target(struct cpufreq_policy *policy, -				   struct cpufreq_frequency_table *table, -				   unsigned int target_freq, -				   unsigned int relation, -				   unsigned int *index) +				    unsigned int target_freq, +				    unsigned int relation)  {  	struct cpufreq_frequency_table optimal = {  		.driver_data = ~0, @@ -132,7 +126,9 @@ int cpufreq_frequency_table_target(struct cpufreq_policy *policy,  		.frequency = 0,  	};  	struct cpufreq_frequency_table *pos; +	struct cpufreq_frequency_table *table = policy->freq_table;  	unsigned int freq, diff, i = 0; +	int index;  	pr_debug("request for target %u kHz (relation: %u) for cpu %u\n",  					target_freq, relation, policy->cpu); @@ -196,25 +192,26 @@ int cpufreq_frequency_table_target(struct cpufreq_policy *policy,  		}  	}  	if (optimal.driver_data > i) { -		if (suboptimal.driver_data > i) -			return -EINVAL; -		*index = suboptimal.driver_data; -	} else -		*index = optimal.driver_data; +		if (suboptimal.driver_data > i) { +			WARN(1, "Invalid frequency table: %d\n", policy->cpu); +			return 0; +		} -	pr_debug("target index is %u, freq is:%u kHz\n", *index, -		 table[*index].frequency); +		index = suboptimal.driver_data; +	} else +		index = optimal.driver_data; -	return 0; +	pr_debug("target index is %u, freq is:%u kHz\n", index, +		 table[index].frequency); +	return index;  }  EXPORT_SYMBOL_GPL(cpufreq_frequency_table_target);  int cpufreq_frequency_table_get_index(struct cpufreq_policy *policy,  		unsigned int freq)  { -	struct cpufreq_frequency_table *pos, *table; +	struct cpufreq_frequency_table *pos, *table = policy->freq_table; -	table = cpufreq_frequency_get_table(policy->cpu);  	if (unlikely(!table)) {  		pr_debug("%s: Unable to find frequency table\n", __func__);  		return -ENOENT; diff --git a/drivers/cpufreq/powernv-cpufreq.c b/drivers/cpufreq/powernv-cpufreq.c index 54c45368e3f1..b29c5c20c3a1 100644 --- a/drivers/cpufreq/powernv-cpufreq.c +++ b/drivers/cpufreq/powernv-cpufreq.c @@ -760,9 +760,8 @@ void powernv_cpufreq_work_fn(struct work_struct *work)  		struct cpufreq_policy policy;  		cpufreq_get_policy(&policy, cpu); -		cpufreq_frequency_table_target(&policy, policy.freq_table, -					       policy.cur, -					       CPUFREQ_RELATION_C, &index); +		index = cpufreq_frequency_table_target(&policy, policy.cur, +					       CPUFREQ_RELATION_C);  		powernv_cpufreq_target_index(&policy, index);  		cpumask_andnot(&mask, &mask, policy.cpus);  	} diff --git a/drivers/cpufreq/ppc_cbe_cpufreq_pmi.c b/drivers/cpufreq/ppc_cbe_cpufreq_pmi.c index 7c4cd5c634f2..dc112481a408 100644 --- a/drivers/cpufreq/ppc_cbe_cpufreq_pmi.c +++ b/drivers/cpufreq/ppc_cbe_cpufreq_pmi.c @@ -94,7 +94,7 @@ static int pmi_notifier(struct notifier_block *nb,  				       unsigned long event, void *data)  {  	struct cpufreq_policy *policy = data; -	struct cpufreq_frequency_table *cbe_freqs; +	struct cpufreq_frequency_table *cbe_freqs = policy->freq_table;  	u8 node;  	/* Should this really be called for CPUFREQ_ADJUST and CPUFREQ_NOTIFY @@ -103,7 +103,6 @@ static int pmi_notifier(struct notifier_block *nb,  	if (event == CPUFREQ_START)  		return 0; -	cbe_freqs = cpufreq_frequency_get_table(policy->cpu);  	node = cbe_cpu_to_node(policy->cpu);  	pr_debug("got notified, event=%lu, node=%u\n", event, node); diff --git a/drivers/cpufreq/s3c24xx-cpufreq.c b/drivers/cpufreq/s3c24xx-cpufreq.c index ae8eaed77b70..7b596fa38ad2 100644 --- a/drivers/cpufreq/s3c24xx-cpufreq.c +++ b/drivers/cpufreq/s3c24xx-cpufreq.c @@ -293,12 +293,8 @@ static int s3c_cpufreq_target(struct cpufreq_policy *policy,  		     __func__, policy, target_freq, relation);  	if (ftab) { -		if (cpufreq_frequency_table_target(policy, ftab, -						   target_freq, relation, -						   &index)) { -			s3c_freq_dbg("%s: table failed\n", __func__); -			return -EINVAL; -		} +		index = cpufreq_frequency_table_target(policy, target_freq, +						       relation);  		s3c_freq_dbg("%s: adjust %d to entry %d (%u)\n", __func__,  			     target_freq, index, ftab[index].frequency); @@ -315,7 +311,6 @@ static int s3c_cpufreq_target(struct cpufreq_policy *policy,  		pll = NULL;  	} else {  		struct cpufreq_policy tmp_policy; -		int ret;  		/* we keep the cpu pll table in Hz, to ensure we get an  		 * accurate value for the PLL output. */ @@ -323,20 +318,14 @@ static int s3c_cpufreq_target(struct cpufreq_policy *policy,  		tmp_policy.min = policy->min * 1000;  		tmp_policy.max = policy->max * 1000;  		tmp_policy.cpu = policy->cpu; +		tmp_policy.freq_table = pll_reg; -		/* cpufreq_frequency_table_target uses a pointer to 'index' -		 * which is the number of the table entry, not the value of +		/* cpufreq_frequency_table_target returns the index +		 * of the table entry, not the value of  		 * the table entry's index field. */ -		ret = cpufreq_frequency_table_target(&tmp_policy, pll_reg, -						     target_freq, relation, -						     &index); - -		if (ret < 0) { -			pr_err("%s: no PLL available\n", __func__); -			goto err_notpossible; -		} - +		index = cpufreq_frequency_table_target(&tmp_policy, target_freq, +						       relation);  		pll = pll_reg + index;  		s3c_freq_dbg("%s: target %u => %u\n", @@ -346,10 +335,6 @@ static int s3c_cpufreq_target(struct cpufreq_policy *policy,  	}  	return s3c_cpufreq_settarget(policy, target_freq, pll); - - err_notpossible: -	pr_err("no compatible settings for %d\n", target_freq); -	return -EINVAL;  }  struct clk *s3c_cpufreq_clk_get(struct device *dev, const char *name) @@ -571,11 +556,7 @@ static int s3c_cpufreq_build_freq(void)  {  	int size, ret; -	if (!cpu_cur.info->calc_freqtable) -		return -EINVAL; -  	kfree(ftab); -	ftab = NULL;  	size = cpu_cur.info->calc_freqtable(&cpu_cur, NULL, 0);  	size++; diff --git a/drivers/cpufreq/s5pv210-cpufreq.c b/drivers/cpufreq/s5pv210-cpufreq.c index 06d85917b6d5..4f4e9df9b7fc 100644 --- a/drivers/cpufreq/s5pv210-cpufreq.c +++ b/drivers/cpufreq/s5pv210-cpufreq.c @@ -246,12 +246,8 @@ static int s5pv210_target(struct cpufreq_policy *policy, unsigned int index)  	new_freq = s5pv210_freq_table[index].frequency;  	/* Finding current running level index */ -	if (cpufreq_frequency_table_target(policy, s5pv210_freq_table, -					   old_freq, CPUFREQ_RELATION_H, -					   &priv_index)) { -		ret = -EINVAL; -		goto exit; -	} +	priv_index = cpufreq_frequency_table_target(policy, old_freq, +						    CPUFREQ_RELATION_H);  	arm_volt = dvs_conf[index].arm_volt;  	int_volt = dvs_conf[index].int_volt;  | 
