Merge git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux-2.6
[cascardo/linux.git] / arch / i386 / kernel / cpu / cpufreq / speedstep-centrino.c
index 7a93253..35489fd 100644 (file)
@@ -36,6 +36,7 @@
 
 #define dprintk(msg...) cpufreq_debug_printk(CPUFREQ_DEBUG_DRIVER, "speedstep-centrino", msg)
 
+#define INTEL_MSR_RANGE        (0xffff)
 
 struct cpu_id
 {
@@ -379,6 +380,7 @@ static int centrino_cpu_early_init_acpi(void)
 }
 
 
+#ifdef CONFIG_SMP
 /*
  * Some BIOSes do SW_ANY coordination internally, either set it up in hw
  * or do it in BIOS firmware and won't inform about it to OS. If not
@@ -386,13 +388,12 @@ static int centrino_cpu_early_init_acpi(void)
  * than OS intended it to run at. Detect it and handle it cleanly.
  */
 static int bios_with_sw_any_bug;
-static int __init sw_any_bug_found(struct dmi_system_id *d)
+static int sw_any_bug_found(struct dmi_system_id *d)
 {
        bios_with_sw_any_bug = 1;
        return 0;
 }
 
-
 static struct dmi_system_id sw_any_bug_dmi_table[] = {
        {
                .callback = sw_any_bug_found,
@@ -405,7 +406,7 @@ static struct dmi_system_id sw_any_bug_dmi_table[] = {
        },
        { }
 };
-
+#endif
 
 /*
  * centrino_cpu_init_acpi - register with ACPI P-States library
@@ -463,8 +464,9 @@ static int centrino_cpu_init_acpi(struct cpufreq_policy *policy)
        }
 
        for (i=0; i<p->state_count; i++) {
-               if (p->states[i].control != p->states[i].status) {
-                       dprintk("Different control (%llu) and status values (%llu)\n",
+               if ((p->states[i].control & INTEL_MSR_RANGE) !=
+                   (p->states[i].status & INTEL_MSR_RANGE)) {
+                       dprintk("Different MSR bits in control (%llu) and status (%llu)\n",
                                p->states[i].control, p->states[i].status);
                        result = -EINVAL;
                        goto err_unreg;
@@ -500,7 +502,7 @@ static int centrino_cpu_init_acpi(struct cpufreq_policy *policy)
         }
 
         for (i=0; i<p->state_count; i++) {
-               centrino_model[cpu]->op_points[i].index = p->states[i].control;
+               centrino_model[cpu]->op_points[i].index = p->states[i].control & INTEL_MSR_RANGE;
                centrino_model[cpu]->op_points[i].frequency = p->states[i].core_frequency * 1000;
                dprintk("adding state %i with frequency %u and control value %04x\n", 
                        i, centrino_model[cpu]->op_points[i].frequency, centrino_model[cpu]->op_points[i].index);
@@ -531,6 +533,9 @@ static int centrino_cpu_init_acpi(struct cpufreq_policy *policy)
 
        /* notify BIOS that we exist */
        acpi_processor_notify_smm(THIS_MODULE);
+       printk("speedstep-centrino with X86_SPEEDSTEP_CENTRINO_ACPI "
+              "config is deprecated.\n "
+              "Use X86_ACPI_CPUFREQ (acpi-cpufreq) instead.\n" );
 
        return 0;
 
@@ -715,6 +720,7 @@ static int centrino_target (struct cpufreq_policy *policy,
                        cpu_set(j, set_mask);
 
                set_cpus_allowed(current, set_mask);
+               preempt_disable();
                if (unlikely(!cpu_isset(smp_processor_id(), set_mask))) {
                        dprintk("couldn't limit to CPUs in this domain\n");
                        retval = -EAGAIN;
@@ -722,6 +728,7 @@ static int centrino_target (struct cpufreq_policy *policy,
                                /* We haven't started the transition yet. */
                                goto migrate_end;
                        }
+                       preempt_enable();
                        break;
                }
 
@@ -756,10 +763,13 @@ static int centrino_target (struct cpufreq_policy *policy,
                }
 
                wrmsr(MSR_IA32_PERF_CTL, oldmsr, h);
-               if (policy->shared_type == CPUFREQ_SHARED_TYPE_ANY)
+               if (policy->shared_type == CPUFREQ_SHARED_TYPE_ANY) {
+                       preempt_enable();
                        break;
+               }
 
                cpu_set(j, covered_cpus);
+               preempt_enable();
        }
 
        for_each_cpu_mask(k, online_policy_cpus) {
@@ -791,8 +801,11 @@ static int centrino_target (struct cpufreq_policy *policy,
                        cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE);
                }
        }
+       set_cpus_allowed(current, saved_mask);
+       return 0;
 
 migrate_end:
+       preempt_enable();
        set_cpus_allowed(current, saved_mask);
        return 0;
 }