Pārlūkot izejas kodu

[CPUFREQ] speedstep-centrino should ignore upper performance control bits

On some systems there could be bits set in the upper half of
the control value provided by the _PSS object.  These bits are
only relevant for cpufreq drivers that use IO ports which are not
currently supported by the speedstep-centrino driver.  The current
MSR oriented code assumes that upper bits are not set and thus
fails to work correctly when they are.  e.g. the control and status
value equality check failed on the IBM x3650 even though the ACPI
spec allows inequality.

Signed-off-by: Gary Hade <garyhade@us.ibm.com>
Signed-off-by: Dave Jones <davej@redhat.com>
Gary Hade 18 gadi atpakaļ
vecāks
revīzija
8b9c6671f8
1 mainītis faili ar 5 papildinājumiem un 3 dzēšanām
  1. 5 3
      arch/i386/kernel/cpu/cpufreq/speedstep-centrino.c

+ 5 - 3
arch/i386/kernel/cpu/cpufreq/speedstep-centrino.c

@@ -36,6 +36,7 @@
 
 
 #define dprintk(msg...) cpufreq_debug_printk(CPUFREQ_DEBUG_DRIVER, "speedstep-centrino", msg)
 #define dprintk(msg...) cpufreq_debug_printk(CPUFREQ_DEBUG_DRIVER, "speedstep-centrino", msg)
 
 
+#define INTEL_MSR_RANGE	(0xffff)
 
 
 struct cpu_id
 struct cpu_id
 {
 {
@@ -463,8 +464,9 @@ static int centrino_cpu_init_acpi(struct cpufreq_policy *policy)
 	}
 	}
 
 
 	for (i=0; i<p->state_count; i++) {
 	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);
 				p->states[i].control, p->states[i].status);
 			result = -EINVAL;
 			result = -EINVAL;
 			goto err_unreg;
 			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++) {
         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;
 		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", 
 		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);
 			i, centrino_model[cpu]->op_points[i].frequency, centrino_model[cpu]->op_points[i].index);