From dab36ad8d50dc9424dfc4926f62aaf9bd52dcf13 Mon Sep 17 00:00:00 2001 From: Carlos Corbacho Date: Sat, 2 Aug 2008 17:28:45 +0100 Subject: [PATCH 1/8] ACPI: WMI: Set instance for query block calls Although the necessary data structure was set up, it was never actually passed in, so data block calls have only been working by sheer chance. (On Acer laptops. the data block methods we've been calling never look at the instance value, hence acer-wmi never triggered this before). f3454ae8104efb2dbf0d08ec42c6f5d0fe9225bc brought this to light. Signed-off-by: Carlos Corbacho Signed-off-by: Andi Kleen --- drivers/acpi/wmi.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/acpi/wmi.c b/drivers/acpi/wmi.c index c33b1c6e93b1..cfe2c833474d 100644 --- a/drivers/acpi/wmi.c +++ b/drivers/acpi/wmi.c @@ -347,7 +347,7 @@ struct acpi_buffer *out) strcpy(method, "WQ"); strncat(method, block->object_id, 2); - status = acpi_evaluate_object(handle, method, NULL, out); + status = acpi_evaluate_object(handle, method, &input, out); /* * If ACPI_WMI_EXPENSIVE, call the relevant WCxx method, even if From 5c742b45dd5fbbb6cf74d3378341704f4b23c5e8 Mon Sep 17 00:00:00 2001 From: Carlos Corbacho Date: Wed, 6 Aug 2008 19:13:56 +0100 Subject: [PATCH 2/8] acer-wmi: Fix wireless and bluetooth on early AMW0 v2 laptops In the old acer_acpi, I discovered that on some of the newer AMW0 laptops that supported the WMID methods, they don't work properly for setting the wireless and bluetooth values. So for the AMW0 V2 laptops, we want to use both the 'old' AMW0 and the 'new' WMID methods for setting wireless & bluetooth to guarantee we always enable it. This was fixed in acer_acpi some time ago, but I forgot to port the patch over to acer-wmi when it was merged. (Without this patch, early AMW0 V2 laptops such as the Aspire 5040 won't work with acer-wmi, where-as they did with the old acer_acpi). AK: fix compilation Signed-off-by: Carlos Corbacho CC: stable@kernel.org Signed-off-by: Andi Kleen --- drivers/misc/acer-wmi.c | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/drivers/misc/acer-wmi.c b/drivers/misc/acer-wmi.c index e7a3fe508dff..b2d9878dc3f0 100644 --- a/drivers/misc/acer-wmi.c +++ b/drivers/misc/acer-wmi.c @@ -803,11 +803,30 @@ static acpi_status get_u32(u32 *value, u32 cap) static acpi_status set_u32(u32 value, u32 cap) { + acpi_status status; + if (interface->capability & cap) { switch (interface->type) { case ACER_AMW0: return AMW0_set_u32(value, cap, interface); case ACER_AMW0_V2: + if (cap == ACER_CAP_MAILLED) + return AMW0_set_u32(value, cap, interface); + + /* + * On some models, some WMID methods don't toggle + * properly. For those cases, we want to run the AMW0 + * method afterwards to be certain we've really toggled + * the device state. + */ + if (cap == ACER_CAP_WIRELESS || + cap == ACER_CAP_BLUETOOTH) { + status = WMID_set_u32(value, cap, interface); + if (ACPI_FAILURE(status)) + return status; + + return AMW0_set_u32(value, cap, interface); + } case ACER_WMID: return WMID_set_u32(value, cap, interface); default: From d0057413a7a277e104cf315faa1b55b60b4a5482 Mon Sep 17 00:00:00 2001 From: Pavel Machek Date: Tue, 12 Aug 2008 12:24:34 +0200 Subject: [PATCH 3/8] acpi: trivial cleanups Trivial cleanups for ACPI. Fix misspelling in printk(), fix mismerge, add file header. AK: removed file header Signed-off-by: Pavel Machek Signed-off-by: Andi Kleen --- drivers/acpi/processor_core.c | 2 +- drivers/acpi/processor_idle.c | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/acpi/processor_core.c b/drivers/acpi/processor_core.c index e36422a7122c..d3f0a62efcc1 100644 --- a/drivers/acpi/processor_core.c +++ b/drivers/acpi/processor_core.c @@ -123,7 +123,7 @@ struct acpi_processor_errata errata __read_mostly; static int set_no_mwait(const struct dmi_system_id *id) { printk(KERN_NOTICE PREFIX "%s detected - " - "disable mwait for CPU C-stetes\n", id->ident); + "disabling mwait for CPU C-states\n", id->ident); idle_nomwait = 1; return 0; } diff --git a/drivers/acpi/processor_idle.c b/drivers/acpi/processor_idle.c index 283c08f5f4d4..cf5b1b7b684f 100644 --- a/drivers/acpi/processor_idle.c +++ b/drivers/acpi/processor_idle.c @@ -41,7 +41,6 @@ #include #include #include -#include /* * Include the apic definitions for x86 to have the APIC timer related defines From afd7301ddb762b66bf1831b0820b402e5d2c439d Mon Sep 17 00:00:00 2001 From: Holger Macht Date: Wed, 6 Aug 2008 17:56:01 +0200 Subject: [PATCH 4/8] ACPI: Properly clear flags on false-positives and send uevent on sudden unplug Some devices emit a ACPI_NOTIFY_DEVICE_CHECK while physically unplugging even if the software undock has already been done and dock_present() check fails. However, the internal flags need to be cleared (complete_undock()). Also, even notify userspace if the dock station suddently went away without proper software undocking. This happens on a Acer TravelMate 3000 Signed-off-by: Holger Macht Signed-off-by: Andi Kleen --- drivers/acpi/dock.c | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/drivers/acpi/dock.c b/drivers/acpi/dock.c index bb7c51f712bd..7d2edf143f16 100644 --- a/drivers/acpi/dock.c +++ b/drivers/acpi/dock.c @@ -563,9 +563,6 @@ EXPORT_SYMBOL_GPL(unregister_hotplug_dock_device); */ static int handle_eject_request(struct dock_station *ds, u32 event) { - if (!dock_present(ds)) - return -ENODEV; - if (dock_in_progress(ds)) return -EBUSY; @@ -573,8 +570,16 @@ static int handle_eject_request(struct dock_station *ds, u32 event) * here we need to generate the undock * event prior to actually doing the undock * so that the device struct still exists. + * Also, even send the dock event if the + * device is not present anymore */ dock_event(ds, event, UNDOCK_EVENT); + + if (!dock_present(ds)) { + complete_undock(ds); + return -ENODEV; + } + hotplug_dock_devices(ds, ACPI_NOTIFY_EJECT_REQUEST); undock(ds); eject_dock(ds); From 2500822bf4eb0179ef80e5b072c1e0fa83037381 Mon Sep 17 00:00:00 2001 From: Zhao Yakui Date: Tue, 12 Aug 2008 10:40:10 +0800 Subject: [PATCH 5/8] ACPI : Add the EC dmi table to fix the incorrect ECDT table On some ASUS laptops the ECDT gives the incorrect command/status & Data I/O register address. AK: it seems like the command/data addresses are exchanged. In such case it will cause that EC device can't be initialized correctly. To add the EC dmi table is to fix this issue. If the laptop falls into the EC dmi table, the EC command/data I/O address will be fixed. AK: Add comments describing this better http://bugzilla.kernel.org/show_bug.cgi?id=9399 Signed-off-by: Zhao Yakui tested-by : Jan Kasprzak Signed-off-by: Andi Kleen --- drivers/acpi/ec.c | 34 ++++++++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) diff --git a/drivers/acpi/ec.c b/drivers/acpi/ec.c index 5622aee996b2..76784ae7e6a1 100644 --- a/drivers/acpi/ec.c +++ b/drivers/acpi/ec.c @@ -110,6 +110,31 @@ static struct acpi_ec { u8 handlers_installed; } *boot_ec, *first_ec; +/* + * Some Asus system have exchanged ECDT data/command IO addresses. + */ +static int print_ecdt_error(const struct dmi_system_id *id) +{ + printk(KERN_NOTICE PREFIX "%s detected - " + "ECDT has exchanged control/data I/O address\n", + id->ident); + return 0; +} + +static struct dmi_system_id __cpuinitdata ec_dmi_table[] = { + { + print_ecdt_error, "Asus L4R", { + DMI_MATCH(DMI_BIOS_VERSION, "1008.006"), + DMI_MATCH(DMI_PRODUCT_NAME, "L4R"), + DMI_MATCH(DMI_BOARD_NAME, "L4R") }, NULL}, + { + print_ecdt_error, "Asus M6R", { + DMI_MATCH(DMI_BIOS_VERSION, "0207"), + DMI_MATCH(DMI_PRODUCT_NAME, "M6R"), + DMI_MATCH(DMI_BOARD_NAME, "M6R") }, NULL}, + {}, +}; + /* -------------------------------------------------------------------------- Transaction Management -------------------------------------------------------------------------- */ @@ -911,6 +936,15 @@ int __init acpi_ec_ecdt_probe(void) pr_info(PREFIX "EC description table is found, configuring boot EC\n"); boot_ec->command_addr = ecdt_ptr->control.address; boot_ec->data_addr = ecdt_ptr->data.address; + if (dmi_check_system(ec_dmi_table)) { + /* + * If the board falls into ec_dmi_table, it means + * that ECDT table gives the incorrect command/status + * & data I/O address. Just fix it. + */ + boot_ec->data_addr = ecdt_ptr->control.address; + boot_ec->command_addr = ecdt_ptr->data.address; + } boot_ec->gpe = ecdt_ptr->gpe; boot_ec->handle = ACPI_ROOT_OBJECT; acpi_get_handle(ACPI_ROOT_OBJECT, ecdt_ptr->id, &boot_ec->handle); From 9d699ed92a459cb408e2577e8bbeabc8ec3989e1 Mon Sep 17 00:00:00 2001 From: Zhao Yakui Date: Mon, 11 Aug 2008 10:33:31 +0800 Subject: [PATCH 6/8] ACPI: Avoid bogus EC timeout when EC is in Polling mode When EC is in Polling mode, OS will check the EC status continually by using the following source code: clear_bit(EC_FLAGS_WAIT_GPE, &ec->flags); while (time_before(jiffies, delay)) { if (acpi_ec_check_status(ec, event)) return 0; msleep(1); } But msleep is realized by the function of schedule_timeout. At the same time although one process is already waken up by some events, it won't be scheduled immediately. So maybe there exists the following phenomena: a. The current jiffies is already after the predefined jiffies. But before timeout happens, OS has no chance to check the EC status again. b. If preemptible schedule is enabled, maybe preempt schedule will happen before checking loop. When the process is resumed again, maybe timeout already happens, which means that OS has no chance to check the EC status. In such case maybe EC status is already what OS expects when timeout happens. But OS has no chance to check the EC status and regards it as AE_TIME. So it will be more appropriate that OS will try to check the EC status again when timeout happens. If the EC status is what we expect, it won't be regarded as timeout. Only when the EC status is not what we expect, it will be regarded as timeout, which means that EC controller can't give a response in time. http://bugzilla.kernel.org/show_bug.cgi?id=9823 http://bugzilla.kernel.org/show_bug.cgi?id=11141 Signed-off-by: Zhao Yakui Signed-off-by: Zhang Rui Signed-off-by: Andi Kleen --- drivers/acpi/ec.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/acpi/ec.c b/drivers/acpi/ec.c index 76784ae7e6a1..13593f9f2197 100644 --- a/drivers/acpi/ec.c +++ b/drivers/acpi/ec.c @@ -221,6 +221,8 @@ static int acpi_ec_wait(struct acpi_ec *ec, enum ec_event event, int force_poll) return 0; msleep(1); } + if (acpi_ec_check_status(ec,event)) + return 0; } pr_err(PREFIX "acpi_ec_wait timeout, status = 0x%2.2x, event = %s\n", acpi_ec_read_status(ec), From fa46d3526461e8aa7c0fb39cc1b98ac656695a43 Mon Sep 17 00:00:00 2001 From: Bjorn Helgaas Date: Fri, 1 Aug 2008 15:58:17 -0600 Subject: [PATCH 7/8] ACPI: bounds check IRQ to prevent memory corruption acpi_penalize_isa_irq() should validate irq before using it to index the acpi_irq_penalty[] table. Here's the path I'm concerned about: pnpacpi_parse_allocated_irqresource() { ... irq = acpi_register_gsi(gsi, triggering, polarity); if (irq >= 0) pcibios_penalize_isa_irq(irq, 1); There's no guarantee that acpi_register_gsi() will return an IRQ within the bounds of acpi_irq_penalty[]. I have not seen a failure I can attribute to this. However, ACPI_MAX_IRQS is only 256, and I'm pretty sure ia64 can have IRQs larger than that. I think this should go in 2.6.27. Signed-off-by: Bjorn Helgaas Signed-off-by: Andi Kleen --- drivers/acpi/pci_link.c | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/drivers/acpi/pci_link.c b/drivers/acpi/pci_link.c index 89f3b2abfdc7..cf47805a7448 100644 --- a/drivers/acpi/pci_link.c +++ b/drivers/acpi/pci_link.c @@ -849,7 +849,7 @@ static int __init acpi_irq_penalty_update(char *str, int used) if (irq < 0) continue; - if (irq >= ACPI_MAX_IRQS) + if (irq >= ARRAY_SIZE(acpi_irq_penalty)) continue; if (used) @@ -872,10 +872,12 @@ static int __init acpi_irq_penalty_update(char *str, int used) */ void acpi_penalize_isa_irq(int irq, int active) { - if (active) - acpi_irq_penalty[irq] += PIRQ_PENALTY_ISA_USED; - else - acpi_irq_penalty[irq] += PIRQ_PENALTY_PCI_USING; + if (irq >= 0 && irq < ARRAY_SIZE(acpi_irq_penalty)) { + if (active) + acpi_irq_penalty[irq] += PIRQ_PENALTY_ISA_USED; + else + acpi_irq_penalty[irq] += PIRQ_PENALTY_PCI_USING; + } } /* From 9f497bcc695fb828da023d74ad3c966b1e58ad21 Mon Sep 17 00:00:00 2001 From: Milan Broz Date: Tue, 12 Aug 2008 17:48:27 +0200 Subject: [PATCH 8/8] ACPI: Fix thermal shutdowns Do not use unsigned int if there is test for negative number... See drivers/acpi/processor_perflib.c static unsigned int ignore_ppc = -1; ... if (event == CPUFREQ_START && ignore_ppc <= 0) { ignore_ppc = 0; ... Signed-off-by: Milan Broz Signed-off-by: Andi Kleen --- drivers/acpi/processor_perflib.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/acpi/processor_perflib.c b/drivers/acpi/processor_perflib.c index 0133af49cf06..80e32093e977 100644 --- a/drivers/acpi/processor_perflib.c +++ b/drivers/acpi/processor_perflib.c @@ -70,7 +70,7 @@ static DEFINE_MUTEX(performance_mutex); * 0 -> cpufreq low level drivers initialized -> consider _PPC values * 1 -> ignore _PPC totally -> forced by user through boot param */ -static unsigned int ignore_ppc = -1; +static int ignore_ppc = -1; module_param(ignore_ppc, uint, 0644); MODULE_PARM_DESC(ignore_ppc, "If the frequency of your machine gets wrongly" \ "limited by BIOS, this should help");