diff options
author | Venkatesh Pallipadi <venkatesh.pallipadi@intel.com> | 2005-10-23 16:31:00 -0400 |
---|---|---|
committer | Len Brown <len.brown@intel.com> | 2005-12-01 01:30:35 -0500 |
commit | 05131ecc99ea9da7f45ba3058fe8a2c1d0ceeab8 (patch) | |
tree | dec76975406874cf677d6391302f42a6da55ac38 /arch/i386/kernel/cpu | |
parent | d2149b542382bfc206cb28485108f6470c979566 (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.c | 67 | ||||
-rw-r--r-- | arch/i386/kernel/cpu/cpufreq/speedstep-centrino.c | 12 |
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 | */ | ||
311 | static void | ||
312 | acpi_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 */ | ||
346 | static void | ||
347 | acpi_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 | |||
362 | static int | 300 | static int |
363 | acpi_cpufreq_cpu_init ( | 301 | acpi_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 | */ |
365 | static int centrino_cpu_init_acpi(struct cpufreq_policy *policy) | 365 | static 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"); |