Commit 767b74a3 authored by Russell King's avatar Russell King

[ARM] cpufreq updates for ARM

This updates the Integrator cpufreq code to use the new interfaces,
and makes the sa1100 cpufreq round up the requested frequency.
parent 074a2e78
...@@ -73,36 +73,37 @@ static struct vco freq_to_vco(unsigned int freq_khz, int factor) ...@@ -73,36 +73,37 @@ static struct vco freq_to_vco(unsigned int freq_khz, int factor)
* Validate the speed in khz. If it is outside our * Validate the speed in khz. If it is outside our
* range, then return the lowest. * range, then return the lowest.
*/ */
static unsigned int static void integrator_verify_speed(struct cpufreq_policy *policy)
integrator_validatespeed(unsigned int cpu, unsigned int freq_khz)
{ {
struct vco vco; struct vco vco;
if (freq_khz < 12000) if (policy->max > policy->max_cpu_freq)
freq_khz = 12000; policy->max = policy->max_cpu_freq;
if (freq_khz > 160000)
freq_khz = 160000;
vco = freq_to_vco(freq_khz, 1); if (policy->max < 12000)
policy->max = 12000;
if (policy->max > 160000)
policy->max = 160000;
if (vco.vdw < 4 || vco.vdw > 152) vco = freq_to_vco(policy->max, 1);
return -EINVAL;
return vco_to_freq(vco, 1); if (vco.vdw < 4)
vco.vdw = 4;
if (vco.vdw > 152)
vco.vdw = 152;
policy->min = policy->max = vco_to_freq(vco, 1);
} }
static void integrator_setspeed(unsigned int cpu, unsigned int freq_khz) static void do_set_policy(int cpu, struct cpufreq_policy *policy)
{ {
struct vco vco = freq_to_vco(freq_khz, 1); struct vco vco = freq_to_vco(policy->max, 1);
unsigned long cpus_allowed;
u_int cm_osc; u_int cm_osc;
/* /*
* Save this threads cpus_allowed mask, and bind to the * Bind to the specified CPU. When this call returns,
* specified CPU. When this call returns, we should be * we should be running on the right CPU.
* running on the right CPU.
*/ */
cpus_allowed = current->cpus_allowed;
set_cpus_allowed(current, 1 << cpu); set_cpus_allowed(current, 1 << cpu);
BUG_ON(cpu != smp_processor_id()); BUG_ON(cpu != smp_processor_id());
...@@ -113,6 +114,26 @@ static void integrator_setspeed(unsigned int cpu, unsigned int freq_khz) ...@@ -113,6 +114,26 @@ static void integrator_setspeed(unsigned int cpu, unsigned int freq_khz)
__raw_writel(0xa05f, CM_LOCK); __raw_writel(0xa05f, CM_LOCK);
__raw_writel(cm_osc, CM_OSC); __raw_writel(cm_osc, CM_OSC);
__raw_writel(0, CM_LOCK); __raw_writel(0, CM_LOCK);
}
static void integrator_set_policy(struct cpufreq_policy *policy)
{
unsigned long cpus_allowed;
int cpu;
/*
* Save this threads cpus_allowed mask.
*/
cpus_allowed = current->cpus_allowed;
if (policy->cpu == CPUFREQ_ALL_CPUS) {
for (cpu = 0; cpu < NR_CPUS; cpu++) {
if (!cpu_online(cpu))
continue;
do_set_policy(cpu, policy);
}
} else
do_set_policy(policy->cpu, policy);
/* /*
* Restore the CPUs allowed mask. * Restore the CPUs allowed mask.
...@@ -120,23 +141,30 @@ static void integrator_setspeed(unsigned int cpu, unsigned int freq_khz) ...@@ -120,23 +141,30 @@ static void integrator_setspeed(unsigned int cpu, unsigned int freq_khz)
set_cpus_allowed(current, cpus_allowed); set_cpus_allowed(current, cpus_allowed);
} }
static struct cpufreq_policy integrator_policy = {
.cpu = 0,
.policy = CPUFREQ_POLICY_POWERSAVE,
.max_cpu_freq = 160000,
};
static struct cpufreq_driver integrator_driver = { static struct cpufreq_driver integrator_driver = {
.validate = integrator_validatespeed, .verify = integrator_verify_speed,
.setspeed = integrator_setspeed, .setpolicy = integrator_set_policy,
.sync = 1, .policy = &integrator_policy,
.cpu_min_freq = 12000,
}; };
#endif #endif
static int __init integrator_cpu_init(void) static int __init integrator_cpu_init(void)
{ {
struct cpufreq_freqs *freqs; struct cpufreq_policy *policies;
unsigned long cpus_allowed; unsigned long cpus_allowed;
int cpu; int cpu;
freqs = kmalloc(sizeof(struct cpufreq_freqs) * NR_CPUS, policies = kmalloc(sizeof(struct cpufreq_freqs) * NR_CPUS,
GFP_KERNEL); GFP_KERNEL);
if (!freqs) { if (!policies) {
printk(KERN_ERR "CPU: unable to allocate cpufreqs structure\n"); printk(KERN_ERR "CPU: unable to allocate policies structure\n");
return -ENOMEM; return -ENOMEM;
} }
...@@ -164,18 +192,20 @@ static int __init integrator_cpu_init(void) ...@@ -164,18 +192,20 @@ static int __init integrator_cpu_init(void)
vco.od = (cm_osc >> 8) & 7; vco.od = (cm_osc >> 8) & 7;
vco.vdw = cm_osc & 255; vco.vdw = cm_osc & 255;
freqs[cpu].min = 12000; policies[cpu].cpu = cpu;
freqs[cpu].max = 160000; policies[cpu].policy = CPUFREQ_POLICY_POWERSAVE,
freqs[cpu].cur = vco_to_freq(vco, 1); policies[cpu].max_cpu_freq = 160000;
policies[cpu].min =
policies[cpu].max = vco_to_freq(vco, 1);
} }
set_cpus_allowed(current, cpus_allowed); set_cpus_allowed(current, cpus_allowed);
#ifdef CONFIG_CPU_FREQ #ifdef CONFIG_CPU_FREQ
integrator_driver.freq = freqs; integrator_driver.policy = policies;
cpufreq_register(&integrator_driver); cpufreq_register(&integrator_driver);
#else #else
kfree(freqs); kfree(policies);
#endif #endif
return 0; return 0;
......
...@@ -55,8 +55,8 @@ unsigned int sa11x0_freq_to_ppcr(unsigned int khz) ...@@ -55,8 +55,8 @@ unsigned int sa11x0_freq_to_ppcr(unsigned int khz)
khz /= 100; khz /= 100;
for (i = 0; i < ARRAY_SIZE(cclk_frequency_100khz); i--) for (i = NR_FREQS - 1; i > 0; i--)
if (cclk_frequency_100khz[i] >= khz) if (cclk_frequency_100khz[i] <= khz)
break; break;
return i; return i;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment