Commit ef44e465 authored by Dave Jones's avatar Dave Jones Committed by Dave Jones

[CPUFREQ] numerous powernow-k8 cpu_init() fixes/cleanups.

parent 3395b201
...@@ -796,8 +796,12 @@ static int powernowk8_verify(struct cpufreq_policy *pol) ...@@ -796,8 +796,12 @@ static int powernowk8_verify(struct cpufreq_policy *pol)
static int __init powernowk8_cpu_init(struct cpufreq_policy *pol) static int __init powernowk8_cpu_init(struct cpufreq_policy *pol)
{ {
struct powernow_k8_data *data; struct powernow_k8_data *data;
cpumask_t oldmask = CPU_MASK_ALL;
int rc; int rc;
if (!check_supported_cpu(pol->cpu))
return -ENODEV;
data = kmalloc(sizeof(struct powernow_k8_data), GFP_KERNEL); data = kmalloc(sizeof(struct powernow_k8_data), GFP_KERNEL);
if (!data) { if (!data) {
printk(KERN_ERR PFX "unable to alloc powernow_k8_data"); printk(KERN_ERR PFX "unable to alloc powernow_k8_data");
...@@ -812,29 +816,49 @@ static int __init powernowk8_cpu_init(struct cpufreq_policy *pol) ...@@ -812,29 +816,49 @@ static int __init powernowk8_cpu_init(struct cpufreq_policy *pol)
kfree(data); kfree(data);
return -ENODEV; return -ENODEV;
} }
if ((num_online_cpus() != 1) || (num_possible_cpus() != 1)) {
pol->governor = CPUFREQ_DEFAULT_GOVERNOR; printk(KERN_INFO PFX "MP systems not supported by PSB BIOS structure\n");
kfree(data);
return 0;
}
rc = find_psb_table(data); rc = find_psb_table(data);
if (rc) { if (rc) {
kfree(data); kfree(data);
return -ENODEV; return -ENODEV;
} }
/* only run on specific CPU from here on */
oldmask = current->cpus_allowed;
set_cpus_allowed(current, cpumask_of_cpu(pol->cpu));
schedule();
if (smp_processor_id() != pol->cpu) {
printk(KERN_ERR "limiting to cpu %u failed\n", pol->cpu);
goto err_out;
}
if (pending_bit_stuck()) { if (pending_bit_stuck()) {
printk(KERN_ERR PFX "failing init, change pending bit set\n"); printk(KERN_ERR PFX "failing init, change pending bit set\n");
goto err_out; goto err_out;
} }
if (query_current_values_with_pending_wait(data))
goto err_out;
fidvid_msr_init();
/* run on any CPU again */
set_cpus_allowed(current, oldmask);
schedule();
pol->governor = CPUFREQ_DEFAULT_GOVERNOR;
/* Take a crude guess here. /* Take a crude guess here.
* That guess was in microseconds, so multply with 1000 */ * That guess was in microseconds, so multiply with 1000 */
pol->cpuinfo.transition_latency = (((data->rvo + 8) * data->vstable * VST_UNITS_20US) pol->cpuinfo.transition_latency = (((data->rvo + 8) * data->vstable * VST_UNITS_20US)
+ (3 * (1 << data->irt) * 10)) * 1000; + (3 * (1 << data->irt) * 10)) * 1000;
if (query_current_values_with_pending_wait(data)) pol->cur = find_khz_freq_from_fid(data->currfid);
return -EIO;
pol->cur = 1000 * find_freq_from_fid(data->currfid);
dprintk(KERN_DEBUG PFX "policy current frequency %d kHz\n", pol->cur); dprintk(KERN_DEBUG PFX "policy current frequency %d kHz\n", pol->cur);
/* min/max the cpu is capable of */ /* min/max the cpu is capable of */
...@@ -855,6 +879,9 @@ static int __init powernowk8_cpu_init(struct cpufreq_policy *pol) ...@@ -855,6 +879,9 @@ static int __init powernowk8_cpu_init(struct cpufreq_policy *pol)
return 0; return 0;
err_out: err_out:
set_cpus_allowed(current, oldmask);
schedule();
kfree(data); kfree(data);
return -ENODEV; return -ENODEV;
} }
......
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