aboutsummaryrefslogtreecommitdiffstats
path: root/arch/i386/kernel/cpu
diff options
context:
space:
mode:
authorVenkatesh Pallipadi <venkatesh.pallipadi@intel.com>2005-10-23 16:31:00 -0400
committerLen Brown <len.brown@intel.com>2005-12-01 01:30:35 -0500
commit05131ecc99ea9da7f45ba3058fe8a2c1d0ceeab8 (patch)
treedec76975406874cf677d6391302f42a6da55ac38 /arch/i386/kernel/cpu
parentd2149b542382bfc206cb28485108f6470c979566 (diff)
[ACPI] Avoid BIOS inflicted crashes by evaluating _PDC only once
Linux invokes the AML _PDC method (Processor Driver Capabilities) to tell the BIOS what features it can handle. While the ACPI spec says nothing about the OS invoking _PDC multiple times, doing so with changing bits seems to hopelessly confuse the BIOS on multiple platforms up to and including crashing the system. Factor out the _PDC invocation so Linux invokes it only once. http://bugzilla.kernel.org/show_bug.cgi?id=5483 Signed-off-by: Venkatesh Pallipadi <venkatesh.pallipadi@intel.com> Signed-off-by: Len Brown <len.brown@intel.com>
Diffstat (limited to 'arch/i386/kernel/cpu')
-rw-r--r--arch/i386/kernel/cpu/cpufreq/acpi-cpufreq.c67
-rw-r--r--arch/i386/kernel/cpu/cpufreq/speedstep-centrino.c12
2 files changed, 0 insertions, 79 deletions
diff --git a/arch/i386/kernel/cpu/cpufreq/acpi-cpufreq.c b/arch/i386/kernel/cpu/cpufreq/acpi-cpufreq.c
index 871366b83b3f..31ce890865d5 100644
--- a/arch/i386/kernel/cpu/cpufreq/acpi-cpufreq.c
+++ b/arch/i386/kernel/cpu/cpufreq/acpi-cpufreq.c
@@ -297,68 +297,6 @@ acpi_cpufreq_guess_freq (
297} 297}
298 298
299 299
300/*
301 * acpi_processor_cpu_init_pdc_est - let BIOS know about the SMP capabilities
302 * of this driver
303 * @perf: processor-specific acpi_io_data struct
304 * @cpu: CPU being initialized
305 *
306 * To avoid issues with legacy OSes, some BIOSes require to be informed of
307 * the SMP capabilities of OS P-state driver. Here we set the bits in _PDC
308 * accordingly, for Enhanced Speedstep. Actual call to _PDC is done in
309 * driver/acpi/processor.c
310 */
311static void
312acpi_processor_cpu_init_pdc_est(
313 struct acpi_processor_performance *perf,
314 unsigned int cpu,
315 struct acpi_object_list *obj_list
316 )
317{
318 union acpi_object *obj;
319 u32 *buf;
320 struct cpuinfo_x86 *c = cpu_data + cpu;
321 dprintk("acpi_processor_cpu_init_pdc_est\n");
322
323 if (!cpu_has(c, X86_FEATURE_EST))
324 return;
325
326 /* Initialize pdc. It will be used later. */
327 if (!obj_list)
328 return;
329
330 if (!(obj_list->count && obj_list->pointer))
331 return;
332
333 obj = obj_list->pointer;
334 if ((obj->buffer.length == 12) && obj->buffer.pointer) {
335 buf = (u32 *)obj->buffer.pointer;
336 buf[0] = ACPI_PDC_REVISION_ID;
337 buf[1] = 1;
338 buf[2] = ACPI_PDC_EST_CAPABILITY_SMP;
339 perf->pdc = obj_list;
340 }
341 return;
342}
343
344
345/* CPU specific PDC initialization */
346static void
347acpi_processor_cpu_init_pdc(
348 struct acpi_processor_performance *perf,
349 unsigned int cpu,
350 struct acpi_object_list *obj_list
351 )
352{
353 struct cpuinfo_x86 *c = cpu_data + cpu;
354 dprintk("acpi_processor_cpu_init_pdc\n");
355 perf->pdc = NULL;
356 if (cpu_has(c, X86_FEATURE_EST))
357 acpi_processor_cpu_init_pdc_est(perf, cpu, obj_list);
358 return;
359}
360
361
362static int 300static int
363acpi_cpufreq_cpu_init ( 301acpi_cpufreq_cpu_init (
364 struct cpufreq_policy *policy) 302 struct cpufreq_policy *policy)
@@ -373,9 +311,6 @@ acpi_cpufreq_cpu_init (
373 struct acpi_object_list arg_list = {1, &arg0}; 311 struct acpi_object_list arg_list = {1, &arg0};
374 312
375 dprintk("acpi_cpufreq_cpu_init\n"); 313 dprintk("acpi_cpufreq_cpu_init\n");
376 /* setup arg_list for _PDC settings */
377 arg0.buffer.length = 12;
378 arg0.buffer.pointer = (u8 *) arg0_buf;
379 314
380 data = kzalloc(sizeof(struct cpufreq_acpi_io), GFP_KERNEL); 315 data = kzalloc(sizeof(struct cpufreq_acpi_io), GFP_KERNEL);
381 if (!data) 316 if (!data)
@@ -383,9 +318,7 @@ acpi_cpufreq_cpu_init (
383 318
384 acpi_io_data[cpu] = data; 319 acpi_io_data[cpu] = data;
385 320
386 acpi_processor_cpu_init_pdc(&data->acpi_data, cpu, &arg_list);
387 result = acpi_processor_register_performance(&data->acpi_data, cpu); 321 result = acpi_processor_register_performance(&data->acpi_data, cpu);
388 data->acpi_data.pdc = NULL;
389 322
390 if (result) 323 if (result)
391 goto err_free; 324 goto err_free;
diff --git a/arch/i386/kernel/cpu/cpufreq/speedstep-centrino.c b/arch/i386/kernel/cpu/cpufreq/speedstep-centrino.c
index edb9873e27e3..d93023438c4f 100644
--- a/arch/i386/kernel/cpu/cpufreq/speedstep-centrino.c
+++ b/arch/i386/kernel/cpu/cpufreq/speedstep-centrino.c
@@ -364,22 +364,10 @@ static struct acpi_processor_performance p;
364 */ 364 */
365static int centrino_cpu_init_acpi(struct cpufreq_policy *policy) 365static int centrino_cpu_init_acpi(struct cpufreq_policy *policy)
366{ 366{
367 union acpi_object arg0 = {ACPI_TYPE_BUFFER};
368 u32 arg0_buf[3];
369 struct acpi_object_list arg_list = {1, &arg0};
370 unsigned long cur_freq; 367 unsigned long cur_freq;
371 int result = 0, i; 368 int result = 0, i;
372 unsigned int cpu = policy->cpu; 369 unsigned int cpu = policy->cpu;
373 370
374 /* _PDC settings */
375 arg0.buffer.length = 12;
376 arg0.buffer.pointer = (u8 *) arg0_buf;
377 arg0_buf[0] = ACPI_PDC_REVISION_ID;
378 arg0_buf[1] = 1;
379 arg0_buf[2] = ACPI_PDC_EST_CAPABILITY_SMP_MSR;
380
381 p.pdc = &arg_list;
382
383 /* register with ACPI core */ 371 /* register with ACPI core */
384 if (acpi_processor_register_performance(&p, cpu)) { 372 if (acpi_processor_register_performance(&p, cpu)) {
385 dprintk(KERN_INFO PFX "obtaining ACPI data failed\n"); 373 dprintk(KERN_INFO PFX "obtaining ACPI data failed\n");