diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2009-12-24 13:00:02 -0800 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2009-12-24 13:00:02 -0800 |
commit | 71492fd1bdd4734d8efd20fe00ebf31027d86d3c (patch) | |
tree | d98ce4131c47f0027dded482d25528b9a57f44ac /drivers/acpi/processor_pdc.c | |
parent | 45e62974fb110da926e2a6c5b357c15639bdc233 (diff) | |
parent | fcb11235d3910c39afece52f6e106a9ca565d34b (diff) | |
download | linux-71492fd1bdd4734d8efd20fe00ebf31027d86d3c.tar.bz2 |
Merge branch 'release' of git://git.kernel.org/pub/scm/linux/kernel/git/lenb/linux-acpi-2.6
* 'release' of git://git.kernel.org/pub/scm/linux/kernel/git/lenb/linux-acpi-2.6: (34 commits)
classmate-laptop: add support for Classmate PC ACPI devices
hp-wmi: Fix two memleaks
acer-wmi, msi-wmi: Remove needless DMI MODULE_ALIAS
dell-wmi: do not keep driver loaded on unsupported boxes
wmi: Free the allocated acpi objects through wmi_get_event_data
drivers/platform/x86/acerhdf.c: check BIOS information whether it begins with string of table
acerhdf: add new BIOS versions
acerhdf: limit modalias matching to supported
toshiba_acpi: convert to seq_file
asus_acpi: convert to seq_file
ACPI: do not select ACPI_DOCK from ATA_ACPI
sony-laptop: enumerate rfkill devices using SN06
sony-laptop: rfkill support for newer models
ACPI: fix OSC regression that caused aer and pciehp not to load
MAINTAINERS: add maintainer for msi-wmi driver
fujitu-laptop: fix tests of acpi_evaluate_integer() return value
arch/x86/kernel/cpu/cpufreq/acpi-cpufreq.c: avoid cross-CPU interrupts by using smp_call_function_any()
ACPI: processor: remove _PDC object list from struct acpi_processor
ACPI: processor: change acpi_processor_set_pdc() interface
ACPI: processor: open code acpi_processor_cleanup_pdc
...
Diffstat (limited to 'drivers/acpi/processor_pdc.c')
-rw-r--r-- | drivers/acpi/processor_pdc.c | 165 |
1 files changed, 165 insertions, 0 deletions
diff --git a/drivers/acpi/processor_pdc.c b/drivers/acpi/processor_pdc.c new file mode 100644 index 000000000000..30e4dc0cdf30 --- /dev/null +++ b/drivers/acpi/processor_pdc.c @@ -0,0 +1,165 @@ +/* + * Copyright (C) 2005 Intel Corporation + * Copyright (C) 2009 Hewlett-Packard Development Company, L.P. + * + * Alex Chiang <achiang@hp.com> + * - Unified x86/ia64 implementations + * Venkatesh Pallipadi <venkatesh.pallipadi@intel.com> + * - Added _PDC for platforms with Intel CPUs + */ +#include <linux/dmi.h> + +#include <acpi/acpi_drivers.h> +#include <acpi/processor.h> + +#include "internal.h" + +#define PREFIX "ACPI: " +#define _COMPONENT ACPI_PROCESSOR_COMPONENT +ACPI_MODULE_NAME("processor_pdc"); + +static int set_no_mwait(const struct dmi_system_id *id) +{ + printk(KERN_NOTICE PREFIX "%s detected - " + "disabling mwait for CPU C-states\n", id->ident); + idle_nomwait = 1; + return 0; +} + +static struct dmi_system_id __cpuinitdata processor_idle_dmi_table[] = { + { + set_no_mwait, "IFL91 board", { + DMI_MATCH(DMI_BIOS_VENDOR, "COMPAL"), + DMI_MATCH(DMI_SYS_VENDOR, "ZEPTO"), + DMI_MATCH(DMI_PRODUCT_VERSION, "3215W"), + DMI_MATCH(DMI_BOARD_NAME, "IFL91") }, NULL}, + { + set_no_mwait, "Extensa 5220", { + DMI_MATCH(DMI_BIOS_VENDOR, "Phoenix Technologies LTD"), + DMI_MATCH(DMI_SYS_VENDOR, "Acer"), + DMI_MATCH(DMI_PRODUCT_VERSION, "0100"), + DMI_MATCH(DMI_BOARD_NAME, "Columbia") }, NULL}, + {}, +}; + +static void acpi_set_pdc_bits(u32 *buf) +{ + buf[0] = ACPI_PDC_REVISION_ID; + buf[1] = 1; + + /* Enable coordination with firmware's _TSD info */ + buf[2] = ACPI_PDC_SMP_T_SWCOORD; + + /* Twiddle arch-specific bits needed for _PDC */ + arch_acpi_set_pdc_bits(buf); +} + +static struct acpi_object_list *acpi_processor_alloc_pdc(void) +{ + struct acpi_object_list *obj_list; + union acpi_object *obj; + u32 *buf; + + /* allocate and initialize pdc. It will be used later. */ + obj_list = kmalloc(sizeof(struct acpi_object_list), GFP_KERNEL); + if (!obj_list) { + printk(KERN_ERR "Memory allocation error\n"); + return NULL; + } + + obj = kmalloc(sizeof(union acpi_object), GFP_KERNEL); + if (!obj) { + printk(KERN_ERR "Memory allocation error\n"); + kfree(obj_list); + return NULL; + } + + buf = kmalloc(12, GFP_KERNEL); + if (!buf) { + printk(KERN_ERR "Memory allocation error\n"); + kfree(obj); + kfree(obj_list); + return NULL; + } + + acpi_set_pdc_bits(buf); + + obj->type = ACPI_TYPE_BUFFER; + obj->buffer.length = 12; + obj->buffer.pointer = (u8 *) buf; + obj_list->count = 1; + obj_list->pointer = obj; + + return obj_list; +} + +/* + * _PDC is required for a BIOS-OS handshake for most of the newer + * ACPI processor features. + */ +static int +acpi_processor_eval_pdc(acpi_handle handle, struct acpi_object_list *pdc_in) +{ + acpi_status status = AE_OK; + + if (idle_nomwait) { + /* + * If mwait is disabled for CPU C-states, the C2C3_FFH access + * mode will be disabled in the parameter of _PDC object. + * Of course C1_FFH access mode will also be disabled. + */ + union acpi_object *obj; + u32 *buffer = NULL; + + obj = pdc_in->pointer; + buffer = (u32 *)(obj->buffer.pointer); + buffer[2] &= ~(ACPI_PDC_C_C2C3_FFH | ACPI_PDC_C_C1_FFH); + + } + status = acpi_evaluate_object(handle, "_PDC", pdc_in, NULL); + + if (ACPI_FAILURE(status)) + ACPI_DEBUG_PRINT((ACPI_DB_INFO, + "Could not evaluate _PDC, using legacy perf. control.\n")); + + return status; +} + +void acpi_processor_set_pdc(acpi_handle handle) +{ + struct acpi_object_list *obj_list; + + if (arch_has_acpi_pdc() == false) + return; + + obj_list = acpi_processor_alloc_pdc(); + if (!obj_list) + return; + + acpi_processor_eval_pdc(handle, obj_list); + + kfree(obj_list->pointer->buffer.pointer); + kfree(obj_list->pointer); + kfree(obj_list); +} +EXPORT_SYMBOL_GPL(acpi_processor_set_pdc); + +static acpi_status +early_init_pdc(acpi_handle handle, u32 lvl, void *context, void **rv) +{ + acpi_processor_set_pdc(handle); + return AE_OK; +} + +void acpi_early_processor_set_pdc(void) +{ + /* + * Check whether the system is DMI table. If yes, OSPM + * should not use mwait for CPU-states. + */ + dmi_check_system(processor_idle_dmi_table); + + acpi_walk_namespace(ACPI_TYPE_PROCESSOR, ACPI_ROOT_OBJECT, + ACPI_UINT32_MAX, + early_init_pdc, NULL, NULL, NULL); +} |