diff options
Diffstat (limited to 'drivers/cpufreq/s3c2416-cpufreq.c')
| -rw-r--r-- | drivers/cpufreq/s3c2416-cpufreq.c | 129 | 
1 files changed, 40 insertions, 89 deletions
diff --git a/drivers/cpufreq/s3c2416-cpufreq.c b/drivers/cpufreq/s3c2416-cpufreq.c index 22dcb81ef9d..2fd53eaaec2 100644 --- a/drivers/cpufreq/s3c2416-cpufreq.c +++ b/drivers/cpufreq/s3c2416-cpufreq.c @@ -72,31 +72,21 @@ static struct s3c2416_dvfs s3c2416_dvfs_table[] = {  #endif  static struct cpufreq_frequency_table s3c2416_freq_table[] = { -	{ SOURCE_HCLK, FREQ_DVS }, -	{ SOURCE_ARMDIV, 133333 }, -	{ SOURCE_ARMDIV, 266666 }, -	{ SOURCE_ARMDIV, 400000 }, -	{ 0, CPUFREQ_TABLE_END }, +	{ 0, SOURCE_HCLK, FREQ_DVS }, +	{ 0, SOURCE_ARMDIV, 133333 }, +	{ 0, SOURCE_ARMDIV, 266666 }, +	{ 0, SOURCE_ARMDIV, 400000 }, +	{ 0, 0, CPUFREQ_TABLE_END },  };  static struct cpufreq_frequency_table s3c2450_freq_table[] = { -	{ SOURCE_HCLK, FREQ_DVS }, -	{ SOURCE_ARMDIV, 133500 }, -	{ SOURCE_ARMDIV, 267000 }, -	{ SOURCE_ARMDIV, 534000 }, -	{ 0, CPUFREQ_TABLE_END }, +	{ 0, SOURCE_HCLK, FREQ_DVS }, +	{ 0, SOURCE_ARMDIV, 133500 }, +	{ 0, SOURCE_ARMDIV, 267000 }, +	{ 0, SOURCE_ARMDIV, 534000 }, +	{ 0, 0, CPUFREQ_TABLE_END },  }; -static int s3c2416_cpufreq_verify_speed(struct cpufreq_policy *policy) -{ -	struct s3c2416_data *s3c_freq = &s3c2416_cpufreq; - -	if (policy->cpu != 0) -		return -EINVAL; - -	return cpufreq_frequency_table_verify(policy, s3c_freq->freq_table); -} -  static unsigned int s3c2416_cpufreq_get_speed(unsigned int cpu)  {  	struct s3c2416_data *s3c_freq = &s3c2416_cpufreq; @@ -227,24 +217,15 @@ static int s3c2416_cpufreq_leave_dvs(struct s3c2416_data *s3c_freq, int idx)  }  static int s3c2416_cpufreq_set_target(struct cpufreq_policy *policy, -				      unsigned int target_freq, -				      unsigned int relation) +				      unsigned int index)  {  	struct s3c2416_data *s3c_freq = &s3c2416_cpufreq; -	struct cpufreq_freqs freqs; +	unsigned int new_freq;  	int idx, ret, to_dvs = 0; -	unsigned int i;  	mutex_lock(&cpufreq_lock); -	pr_debug("cpufreq: to %dKHz, relation %d\n", target_freq, relation); - -	ret = cpufreq_frequency_table_target(policy, s3c_freq->freq_table, -					     target_freq, relation, &i); -	if (ret != 0) -		goto out; - -	idx = s3c_freq->freq_table[i].driver_data; +	idx = s3c_freq->freq_table[index].driver_data;  	if (idx == SOURCE_HCLK)  		to_dvs = 1; @@ -256,24 +237,13 @@ static int s3c2416_cpufreq_set_target(struct cpufreq_policy *policy,  		goto out;  	} -	freqs.flags = 0; -	freqs.old = s3c_freq->is_dvs ? FREQ_DVS -				     : clk_get_rate(s3c_freq->armclk) / 1000; -  	/* When leavin dvs mode, always switch the armdiv to the hclk rate  	 * The S3C2416 has stability issues when switching directly to  	 * higher frequencies.  	 */ -	freqs.new = (s3c_freq->is_dvs && !to_dvs) +	new_freq = (s3c_freq->is_dvs && !to_dvs)  				? clk_get_rate(s3c_freq->hclk) / 1000 -				: s3c_freq->freq_table[i].frequency; - -	pr_debug("cpufreq: Transition %d-%dkHz\n", freqs.old, freqs.new); - -	if (!to_dvs && freqs.old == freqs.new) -		goto out; - -	cpufreq_notify_transition(policy, &freqs, CPUFREQ_PRECHANGE); +				: s3c_freq->freq_table[index].frequency;  	if (to_dvs) {  		pr_debug("cpufreq: enter dvs\n"); @@ -282,12 +252,10 @@ static int s3c2416_cpufreq_set_target(struct cpufreq_policy *policy,  		pr_debug("cpufreq: leave dvs\n");  		ret = s3c2416_cpufreq_leave_dvs(s3c_freq, idx);  	} else { -		pr_debug("cpufreq: change armdiv to %dkHz\n", freqs.new); -		ret = s3c2416_cpufreq_set_armdiv(s3c_freq, freqs.new); +		pr_debug("cpufreq: change armdiv to %dkHz\n", new_freq); +		ret = s3c2416_cpufreq_set_armdiv(s3c_freq, new_freq);  	} -	cpufreq_notify_transition(policy, &freqs, CPUFREQ_POSTCHANGE); -  out:  	mutex_unlock(&cpufreq_lock); @@ -298,7 +266,7 @@ out:  static void __init s3c2416_cpufreq_cfg_regulator(struct s3c2416_data *s3c_freq)  {  	int count, v, i, found; -	struct cpufreq_frequency_table *freq; +	struct cpufreq_frequency_table *pos;  	struct s3c2416_dvfs *dvfs;  	count = regulator_count_voltages(s3c_freq->vddarm); @@ -307,12 +275,11 @@ static void __init s3c2416_cpufreq_cfg_regulator(struct s3c2416_data *s3c_freq)  		return;  	} -	freq = s3c_freq->freq_table; -	while (count > 0 && freq->frequency != CPUFREQ_TABLE_END) { -		if (freq->frequency == CPUFREQ_ENTRY_INVALID) -			continue; +	if (!count) +		goto out; -		dvfs = &s3c2416_dvfs_table[freq->driver_data]; +	cpufreq_for_each_valid_entry(pos, s3c_freq->freq_table) { +		dvfs = &s3c2416_dvfs_table[pos->driver_data];  		found = 0;  		/* Check only the min-voltage, more is always ok on S3C2416 */ @@ -324,13 +291,12 @@ static void __init s3c2416_cpufreq_cfg_regulator(struct s3c2416_data *s3c_freq)  		if (!found) {  			pr_debug("cpufreq: %dkHz unsupported by regulator\n", -				 freq->frequency); -			freq->frequency = CPUFREQ_ENTRY_INVALID; +				 pos->frequency); +			pos->frequency = CPUFREQ_ENTRY_INVALID;  		} - -		freq++;  	} +out:  	/* Guessed */  	s3c_freq->regulator_latency = 1 * 1000 * 1000;  } @@ -370,7 +336,7 @@ static struct notifier_block s3c2416_cpufreq_reboot_notifier = {  static int __init s3c2416_cpufreq_driver_init(struct cpufreq_policy *policy)  {  	struct s3c2416_data *s3c_freq = &s3c2416_cpufreq; -	struct cpufreq_frequency_table *freq; +	struct cpufreq_frequency_table *pos;  	struct clk *msysclk;  	unsigned long rate;  	int ret; @@ -459,47 +425,37 @@ static int __init s3c2416_cpufreq_driver_init(struct cpufreq_policy *policy)  	s3c_freq->regulator_latency = 0;  #endif -	freq = s3c_freq->freq_table; -	while (freq->frequency != CPUFREQ_TABLE_END) { +	cpufreq_for_each_entry(pos, s3c_freq->freq_table) {  		/* special handling for dvs mode */ -		if (freq->driver_data == 0) { +		if (pos->driver_data == 0) {  			if (!s3c_freq->hclk) {  				pr_debug("cpufreq: %dkHz unsupported as it would need unavailable dvs mode\n", -					 freq->frequency); -				freq->frequency = CPUFREQ_ENTRY_INVALID; +					 pos->frequency); +				pos->frequency = CPUFREQ_ENTRY_INVALID;  			} else { -				freq++;  				continue;  			}  		}  		/* Check for frequencies we can generate */  		rate = clk_round_rate(s3c_freq->armdiv, -				      freq->frequency * 1000); +				      pos->frequency * 1000);  		rate /= 1000; -		if (rate != freq->frequency) { +		if (rate != pos->frequency) {  			pr_debug("cpufreq: %dkHz unsupported by clock (clk_round_rate return %lu)\n", -				 freq->frequency, rate); -			freq->frequency = CPUFREQ_ENTRY_INVALID; +				pos->frequency, rate); +			pos->frequency = CPUFREQ_ENTRY_INVALID;  		} - -		freq++;  	} -	policy->cur = clk_get_rate(s3c_freq->armclk) / 1000; -  	/* Datasheet says PLL stabalisation time must be at least 300us,  	 * so but add some fudge. (reference in LOCKCON0 register description)  	 */ -	policy->cpuinfo.transition_latency = (500 * 1000) + -					     s3c_freq->regulator_latency; - -	ret = cpufreq_frequency_table_cpuinfo(policy, s3c_freq->freq_table); +	ret = cpufreq_generic_init(policy, s3c_freq->freq_table, +			(500 * 1000) + s3c_freq->regulator_latency);  	if (ret)  		goto err_freq_table; -	cpufreq_frequency_table_get_attr(s3c_freq->freq_table, 0); -  	register_reboot_notifier(&s3c2416_cpufreq_reboot_notifier);  	return 0; @@ -518,19 +474,14 @@ err_hclk:  	return ret;  } -static struct freq_attr *s3c2416_cpufreq_attr[] = { -	&cpufreq_freq_attr_scaling_available_freqs, -	NULL, -}; -  static struct cpufreq_driver s3c2416_cpufreq_driver = { -	.flags          = 0, -	.verify		= s3c2416_cpufreq_verify_speed, -	.target		= s3c2416_cpufreq_set_target, +	.flags		= CPUFREQ_NEED_INITIAL_FREQ_CHECK, +	.verify		= cpufreq_generic_frequency_table_verify, +	.target_index	= s3c2416_cpufreq_set_target,  	.get		= s3c2416_cpufreq_get_speed,  	.init		= s3c2416_cpufreq_driver_init,  	.name		= "s3c2416", -	.attr		= s3c2416_cpufreq_attr, +	.attr		= cpufreq_generic_attr,  };  static int __init s3c2416_cpufreq_init(void)  | 
