From 0406ad336c066190770cbf350b552d608e43ed09 Mon Sep 17 00:00:00 2001 From: Alex Chiang Date: Wed, 20 Jan 2010 00:06:30 -0700 Subject: [PATCH 01/10] ACPI: processor: add kernel command line support for early _PDC eval Allow platforms not listed in DMI table to opt-in and evaluate _PDC early. Signed-off-by: Alex Chiang Signed-off-by: Len Brown --- Documentation/kernel-parameters.txt | 4 ++++ drivers/acpi/processor_pdc.c | 7 +++++++ 2 files changed, 11 insertions(+) diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt index 736d45602886..826b6e148316 100644 --- a/Documentation/kernel-parameters.txt +++ b/Documentation/kernel-parameters.txt @@ -199,6 +199,10 @@ and is between 256 and 4096 characters. It is defined in the file acpi_display_output=video See above. + acpi_early_pdc_eval [HW,ACPI] Evaluate processor _PDC methods + early. Needed on some platforms to properly + initialize the EC. + acpi_irq_balance [HW,ACPI] ACPI will balance active IRQs default in APIC mode diff --git a/drivers/acpi/processor_pdc.c b/drivers/acpi/processor_pdc.c index 7247819dbd80..3bbafe9576ae 100644 --- a/drivers/acpi/processor_pdc.c +++ b/drivers/acpi/processor_pdc.c @@ -151,6 +151,13 @@ static int set_early_pdc_optin(const struct dmi_system_id *id) return 0; } +static int param_early_pdc_optin(char *s) +{ + early_pdc_optin = 1; + return 1; +} +__setup("acpi_early_pdc_eval", param_early_pdc_optin); + static struct dmi_system_id __cpuinitdata early_pdc_optin_table[] = { { set_early_pdc_optin, "HP Envy", { From a4932299d03a1c20e58e4cc40a66fb0a048fb3a7 Mon Sep 17 00:00:00 2001 From: Alex Chiang Date: Wed, 20 Jan 2010 00:06:35 -0700 Subject: [PATCH 02/10] ACPI: processor: only evaluate _PDC once per processor If we evaluate _PDC in the early path, we do not want to evaluate it again when the processor driver is loaded. Cc: Venkatesh Pallipadi Signed-off-by: Alex Chiang Signed-off-by: Len Brown --- drivers/acpi/processor_pdc.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/drivers/acpi/processor_pdc.c b/drivers/acpi/processor_pdc.c index 3bbafe9576ae..e306ba9aa34e 100644 --- a/drivers/acpi/processor_pdc.c +++ b/drivers/acpi/processor_pdc.c @@ -125,6 +125,8 @@ acpi_processor_eval_pdc(acpi_handle handle, struct acpi_object_list *pdc_in) return status; } +static int early_pdc_done; + void acpi_processor_set_pdc(acpi_handle handle) { struct acpi_object_list *obj_list; @@ -132,6 +134,9 @@ void acpi_processor_set_pdc(acpi_handle handle) if (arch_has_acpi_pdc() == false) return; + if (early_pdc_done) + return; + obj_list = acpi_processor_alloc_pdc(); if (!obj_list) return; @@ -199,4 +204,6 @@ void __init acpi_early_processor_set_pdc(void) acpi_walk_namespace(ACPI_TYPE_PROCESSOR, ACPI_ROOT_OBJECT, ACPI_UINT32_MAX, early_init_pdc, NULL, NULL, NULL); + + early_pdc_done = 1; } From d2f6650a950dadd20667a04a9dc785f240d43695 Mon Sep 17 00:00:00 2001 From: Thomas Renninger Date: Fri, 29 Jan 2010 17:48:51 +0100 Subject: [PATCH 03/10] ACPI: Add NULL pointer check in acpi_bus_start If acpi_bus_add does not return a device and it's passed to acpi_bus_start, bad things will happen: BUG: unable to handle kernel NULL pointer dereference at 0000000000000008 IP: [] acpi_bus_start+0x14/0x24 ... [] acpiphp_bus_add+0xba/0x130 [acpiphp] [] enable_device+0x132/0x2ff [acpiphp] [] acpiphp_enable_slot+0xb8/0x130 [acpiphp] [] handle_hotplug_event_func+0x87/0x190 [acpiphp] Next patch would make this NULL pointer check obsolete, but better having one more than one missing... Signed-off-by: Thomas Renninger Acked-by: Bjorn Helgaas CC: stable@kernel.org Signed-off-by: Len Brown --- drivers/acpi/scan.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c index ff9f6226085d..8044583f3034 100644 --- a/drivers/acpi/scan.c +++ b/drivers/acpi/scan.c @@ -1357,6 +1357,9 @@ int acpi_bus_start(struct acpi_device *device) { struct acpi_bus_ops ops; + if (!device) + return -EINVAL; + memset(&ops, 0, sizeof(ops)); ops.acpi_op_start = 1; From 7779688fc3d1ceddad84846a7b0affbe8e78ec6e Mon Sep 17 00:00:00 2001 From: Thomas Renninger Date: Fri, 29 Jan 2010 17:48:52 +0100 Subject: [PATCH 04/10] ACPI: acpi_bus_{scan,bus,add}: return -ENODEV if no device was found Callers (acpi_memhotplug.c, dock.c and others) check for the return value of acpi_bus_add() and assume a valid device was returned in case zero was returned. Thus return -ENODEV if no device was found in acpi_bus_scan and propagate this through acpi_bus_add and acpi_bus_start. Also remove a confusing comment in acpiphp_glue.c, acpi_bus_scan will and cannot invoke if acpi_bus_add returns no valid device. Signed-off-by: Thomas Renninger Acked-by: Bjorn Helgaas Signed-off-by: Len Brown --- drivers/acpi/scan.c | 24 +++++++++++++++++++----- drivers/pci/hotplug/acpiphp_glue.c | 6 ------ 2 files changed, 19 insertions(+), 11 deletions(-) diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c index 8044583f3034..3e009674f333 100644 --- a/drivers/acpi/scan.c +++ b/drivers/acpi/scan.c @@ -1336,9 +1336,25 @@ static int acpi_bus_scan(acpi_handle handle, struct acpi_bus_ops *ops, if (child) *child = device; - return 0; + + if (device) + return 0; + else + return -ENODEV; } +/* + * acpi_bus_add and acpi_bus_start + * + * scan a given ACPI tree and (probably recently hot-plugged) + * create and add or starts found devices. + * + * If no devices were found -ENODEV is returned which does not + * mean that this is a real error, there just have been no suitable + * ACPI objects in the table trunk from which the kernel could create + * a device and add/start an appropriate driver. + */ + int acpi_bus_add(struct acpi_device **child, struct acpi_device *parent, acpi_handle handle, int type) @@ -1348,8 +1364,7 @@ acpi_bus_add(struct acpi_device **child, memset(&ops, 0, sizeof(ops)); ops.acpi_op_add = 1; - acpi_bus_scan(handle, &ops, child); - return 0; + return acpi_bus_scan(handle, &ops, child); } EXPORT_SYMBOL(acpi_bus_add); @@ -1363,8 +1378,7 @@ int acpi_bus_start(struct acpi_device *device) memset(&ops, 0, sizeof(ops)); ops.acpi_op_start = 1; - acpi_bus_scan(device->handle, &ops, NULL); - return 0; + return acpi_bus_scan(device->handle, &ops, NULL); } EXPORT_SYMBOL(acpi_bus_start); diff --git a/drivers/pci/hotplug/acpiphp_glue.c b/drivers/pci/hotplug/acpiphp_glue.c index 8e952fdab764..cb2fd01eddae 100644 --- a/drivers/pci/hotplug/acpiphp_glue.c +++ b/drivers/pci/hotplug/acpiphp_glue.c @@ -720,12 +720,6 @@ static int acpiphp_bus_add(struct acpiphp_func *func) -ret_val); goto acpiphp_bus_add_out; } - /* - * try to start anyway. We could have failed to add - * simply because this bus had previously been added - * on another add. Don't bother with the return value - * we just keep going. - */ ret_val = acpi_bus_start(device); acpiphp_bus_add_out: From f04d5e012d73ea441bd39804ace39fd6d1ce5611 Mon Sep 17 00:00:00 2001 From: Roel Kluin Date: Tue, 2 Feb 2010 14:37:58 -0800 Subject: [PATCH 05/10] thinkpad-acpi: wrong thermal attribute_group removed in thermal_exit() sysfs_remove_group() removed the wrong attribute_group for thermal_read_mode TPEC_8, ACPI_TMP07 and ACPI_UPDT Signed-off-by: Roel Kluin Acked-by: Henrique de Moraes Holschuh Signed-off-by: Andrew Morton Signed-off-by: Len Brown --- drivers/platform/x86/thinkpad_acpi.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/platform/x86/thinkpad_acpi.c b/drivers/platform/x86/thinkpad_acpi.c index e67e4feb35cb..eb603f1d55ca 100644 --- a/drivers/platform/x86/thinkpad_acpi.c +++ b/drivers/platform/x86/thinkpad_acpi.c @@ -5771,7 +5771,7 @@ static void thermal_exit(void) case TPACPI_THERMAL_ACPI_TMP07: case TPACPI_THERMAL_ACPI_UPDT: sysfs_remove_group(&tpacpi_sensors_pdev->dev.kobj, - &thermal_temp_input16_group); + &thermal_temp_input8_group); break; case TPACPI_THERMAL_NONE: default: From 97c169d39b6846a564dc8d883832e7fef9bdb77d Mon Sep 17 00:00:00 2001 From: Len Brown Date: Tue, 16 Feb 2010 03:30:06 -0500 Subject: [PATCH 06/10] ACPI: remove Asus P2B-DS from acpi=ht blacklist We realized when we broke acpi=ht http://bugzilla.kernel.org/show_bug.cgi?id=14886 that acpi=ht is not needed on this box and folks have been using acpi=force on it anyway. Signed-off-by: Len Brown --- arch/x86/kernel/acpi/boot.c | 8 -------- 1 file changed, 8 deletions(-) diff --git a/arch/x86/kernel/acpi/boot.c b/arch/x86/kernel/acpi/boot.c index 0acbcdfa5ca4..af1c5833ff23 100644 --- a/arch/x86/kernel/acpi/boot.c +++ b/arch/x86/kernel/acpi/boot.c @@ -1342,14 +1342,6 @@ static struct dmi_system_id __initdata acpi_dmi_table[] = { DMI_MATCH(DMI_PRODUCT_NAME, "Workstation W8000"), }, }, - { - .callback = force_acpi_ht, - .ident = "ASUS P2B-DS", - .matches = { - DMI_MATCH(DMI_BOARD_VENDOR, "ASUSTeK Computer INC."), - DMI_MATCH(DMI_BOARD_NAME, "P2B-DS"), - }, - }, { .callback = force_acpi_ht, .ident = "ASUS CUR-DLS", From 49c6fb2e41d41c4c0c5c753b6960bc81fe658d20 Mon Sep 17 00:00:00 2001 From: Alex Chiang Date: Mon, 1 Feb 2010 10:35:18 -0700 Subject: [PATCH 07/10] ACPI: dock: properly initialize local struct dock_station in dock_add() Commit fe06fba2 (ACPI: dock: add struct dock_station * directly to platform device data) changed dock_add() to use the platform_device_register_data() API. We passed that interface a stack variable, which is kmemdup'ed and assigned to the device's platform_data pointer. Unfortunately, whatever random garbage is in the stack variable gets coped during the kmemdup, and that leads to broken behavior. Explicitly zero out the structure before passing it to the API. This fixes the T41 docking button issue: http://bugzilla.kernel.org/show_bug.cgi?id=15000 Cc: stable@kernel.org Reported-by: Chris Mason Signed-off-by: Alex Chiang Signed-off-by: Len Brown --- drivers/acpi/dock.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/acpi/dock.c b/drivers/acpi/dock.c index bbc2c1315c47..b2586f57e1f5 100644 --- a/drivers/acpi/dock.c +++ b/drivers/acpi/dock.c @@ -935,6 +935,7 @@ static int dock_add(acpi_handle handle) struct platform_device *dd; id = dock_station_count; + memset(&ds, 0, sizeof(ds)); dd = platform_device_register_data(NULL, "dock", id, &ds, sizeof(ds)); if (IS_ERR(dd)) return PTR_ERR(dd); From 370d5cd88509b93b76eb2f5f97efbd71c25061cb Mon Sep 17 00:00:00 2001 From: Arjan van de Ven Date: Wed, 27 Jan 2010 15:25:39 -0800 Subject: [PATCH 08/10] ACPI: fix High cpu temperature with 2.6.32 Since the rewrite of the CPU idle governor in 2.6.32, two laptops have surfaced where the BIOS advertises a C2 power state, but for some reason this state is not functioning (as verified in both cases by powertop before the patch in .32). The old governor had the accidental behavior that if a non-working state was chosen too many times, it would end up falling back to C1. The new governor works differently and this accidental behavior is no longer there; the result is a high temperature on these two machines. This patch adds these 2 machines to the DMI table for C state anomalies; by just not using C2 both these machines are better off (the TSC can be used instead of the pm timer, giving a performance boost for example). Addresses http://bugzilla.kernel.org/show_bug.cgi?id=14742 Signed-off-by: Arjan van de Ven Reported-by: Cc: Signed-off-by: Andrew Morton Signed-off-by: Len Brown --- drivers/acpi/processor_idle.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/drivers/acpi/processor_idle.c b/drivers/acpi/processor_idle.c index 7c0441f63b39..e88e8ae04fdb 100644 --- a/drivers/acpi/processor_idle.c +++ b/drivers/acpi/processor_idle.c @@ -110,6 +110,14 @@ static struct dmi_system_id __cpuinitdata processor_power_dmi_table[] = { DMI_MATCH(DMI_BIOS_VENDOR,"Phoenix Technologies LTD"), DMI_MATCH(DMI_BIOS_VERSION,"SHE845M0.86C.0013.D.0302131307")}, (void *)2}, + { set_max_cstate, "Pavilion zv5000", { + DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"), + DMI_MATCH(DMI_PRODUCT_NAME,"Pavilion zv5000 (DS502A#ABA)")}, + (void *)1}, + { set_max_cstate, "Asus L8400B", { + DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK Computer Inc."), + DMI_MATCH(DMI_PRODUCT_NAME,"L8400B series Notebook PC")}, + (void *)1}, {}, }; From 1379d2fef0ec07c7027a5e89036025ce761470c8 Mon Sep 17 00:00:00 2001 From: Zhang Rui Date: Tue, 16 Feb 2010 04:16:55 -0500 Subject: [PATCH 09/10] ACPI, i915: blacklist Clevo M5x0N bad_lid state Wrong Lid state reported. Need to blacklist this machine for LVDS detection. Signed-off-by: Zhang Rui Signed-off-by: Len Brown --- drivers/gpu/drm/i915/intel_lvds.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/drivers/gpu/drm/i915/intel_lvds.c b/drivers/gpu/drm/i915/intel_lvds.c index b1d0acbae4e4..c2e8a45780d5 100644 --- a/drivers/gpu/drm/i915/intel_lvds.c +++ b/drivers/gpu/drm/i915/intel_lvds.c @@ -636,6 +636,13 @@ static const struct dmi_system_id bad_lid_status[] = { DMI_MATCH(DMI_PRODUCT_NAME, "PC-81005"), }, }, + { + .ident = "Clevo M5x0N", + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "CLEVO Co."), + DMI_MATCH(DMI_BOARD_NAME, "M5x0N"), + }, + }, { } }; From 49bf83a45fc677db1ed44d0e072e6aaeabe4e124 Mon Sep 17 00:00:00 2001 From: Len Brown Date: Tue, 16 Feb 2010 03:45:45 -0500 Subject: [PATCH 10/10] ACPI: fix "acpi=ht" boot option We broke "acpi=ht" in 2.6.32 by disabling MADT parsing for acpi=disabled. e5b8fc6ac158f65598f58dba2c0d52ba3b412f52 This also broke systems which invoked acpi=ht via DMI blacklist. acpi=ht is a really ugly hack, but restore it for those that still use it. http://bugzilla.kernel.org/show_bug.cgi?id=14886 Signed-off-by: Len Brown --- arch/ia64/include/asm/acpi.h | 1 + drivers/acpi/tables.c | 4 ++-- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/arch/ia64/include/asm/acpi.h b/arch/ia64/include/asm/acpi.h index 7ae58892ba8d..e97b255d97bc 100644 --- a/arch/ia64/include/asm/acpi.h +++ b/arch/ia64/include/asm/acpi.h @@ -94,6 +94,7 @@ ia64_acpi_release_global_lock (unsigned int *lock) #define acpi_noirq 0 /* ACPI always enabled on IA64 */ #define acpi_pci_disabled 0 /* ACPI PCI always enabled on IA64 */ #define acpi_strict 1 /* no ACPI spec workarounds on IA64 */ +#define acpi_ht 0 /* no HT-only mode on IA64 */ #endif #define acpi_processor_cstate_check(x) (x) /* no idle limits on IA64 :) */ static inline void disable_acpi(void) { } diff --git a/drivers/acpi/tables.c b/drivers/acpi/tables.c index f336bca7c450..8a0ed2800e63 100644 --- a/drivers/acpi/tables.c +++ b/drivers/acpi/tables.c @@ -213,7 +213,7 @@ acpi_table_parse_entries(char *id, unsigned long table_end; acpi_size tbl_size; - if (acpi_disabled) + if (acpi_disabled && !acpi_ht) return -ENODEV; if (!handler) @@ -280,7 +280,7 @@ int __init acpi_table_parse(char *id, acpi_table_handler handler) struct acpi_table_header *table = NULL; acpi_size tbl_size; - if (acpi_disabled) + if (acpi_disabled && !acpi_ht) return -ENODEV; if (!handler)