From b1b57fbe9bb10d94682a975456de7a727d1dbc84 Mon Sep 17 00:00:00 2001 From: Zhao Yakui Date: Mon, 27 Oct 2008 16:04:53 +0800 Subject: ACPI: fix de-reference bug in power resource driver change state to *state in the function of acpi_power_get_state() Signed-off-by: yakui.zhao@intel.com Signed-off-by: Len Brown --- drivers/acpi/power.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'drivers/acpi') diff --git a/drivers/acpi/power.c b/drivers/acpi/power.c index a1718e56103..30d4a5282a2 100644 --- a/drivers/acpi/power.c +++ b/drivers/acpi/power.c @@ -153,7 +153,8 @@ static int acpi_power_get_state(acpi_handle handle, int *state) ACPI_POWER_RESOURCE_STATE_OFF; ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Resource [%s] is %s\n", - acpi_ut_get_node_name(handle), state ? "on" : "off")); + acpi_ut_get_node_name(handle), + *state ? "on" : "off")); return 0; } -- cgit v1.2.3 From 676962dac6e267ce7c13f73962208f9124a084bb Mon Sep 17 00:00:00 2001 From: Zhao Yakui Date: Mon, 27 Oct 2008 16:05:39 +0800 Subject: ACPI: fan: Delete the strict check in power transition On some laptops the Fan device is turned on/off by controlling the corresponding power resource. For example: If the power resource defined in _PR0 object is turned off, it indicates that the FAN device is in off state(the ACPI state is in D3 state). Maybe the device is already in D3 state and expected to be transited to D3 state. As there is no _PR3 object, the power transition can't be finished and it will be switched to the Unknown state. Maybe it is more reasonable that the strick check in power transistion is deleted. http://bugzilla.kernel.org/show_bug.cgi?id=9485 Signed-off-by: yakui.zhao@intel.com Signed-off-by: Len Brown --- drivers/acpi/power.c | 5 ----- 1 file changed, 5 deletions(-) (limited to 'drivers/acpi') diff --git a/drivers/acpi/power.c b/drivers/acpi/power.c index 30d4a5282a2..89111cd28ed 100644 --- a/drivers/acpi/power.c +++ b/drivers/acpi/power.c @@ -517,11 +517,6 @@ int acpi_power_transition(struct acpi_device *device, int state) cl = &device->power.states[device->power.state].resources; tl = &device->power.states[state].resources; - if (!cl->count && !tl->count) { - result = -ENODEV; - goto end; - } - /* TBD: Resources must be ordered. */ /* -- cgit v1.2.3 From ed206fac87d65917280b6c3edd3f01125d4095c9 Mon Sep 17 00:00:00 2001 From: Zhang Rui Date: Mon, 27 Oct 2008 14:01:02 -0700 Subject: ACPI: bugfix reporting of event handler status Introduce a new flag showing whether the event has an event handler/method. For all the GPEs and Fixed Events, 1. ACPI_EVENT_FLAG_HANDLE is cleared, it's an "invalid" ACPI event. 2. Both ACPI_EVENT_FLAG_HANDLE and ACPI_EVENT_FLAG_DISABLE are set, it's "disabled". 3. Both ACPI_EVENT_FLAG_HANDLE and ACPI_EVENT_FLAG_ENABLE are set, it's "enabled". 4. Both ACPI_EVENT_FLAG_HANDLE and ACPI_EVENT_FLAG_WAKE_ENABLE are set, it's "wake_enabled". Among other things, this prevents incorrect reporting of ACPI events as being "invalid" when it's really just (temporarily) "disabled". Signed-off-by: Zhang Rui Signed-off-by: David Brownell Signed-off-by: Len Brown --- drivers/acpi/events/evxfevnt.c | 6 ++++++ drivers/acpi/system.c | 19 +++++++------------ 2 files changed, 13 insertions(+), 12 deletions(-) (limited to 'drivers/acpi') diff --git a/drivers/acpi/events/evxfevnt.c b/drivers/acpi/events/evxfevnt.c index 73bfd6bf962..211e93a90e9 100644 --- a/drivers/acpi/events/evxfevnt.c +++ b/drivers/acpi/events/evxfevnt.c @@ -521,6 +521,9 @@ acpi_status acpi_get_event_status(u32 event, acpi_event_status * event_status) if (value) *event_status |= ACPI_EVENT_FLAG_SET; + if (acpi_gbl_fixed_event_handlers[event].handler) + *event_status |= ACPI_EVENT_FLAG_HANDLE; + return_ACPI_STATUS(status); } @@ -571,6 +574,9 @@ acpi_get_gpe_status(acpi_handle gpe_device, status = acpi_hw_get_gpe_status(gpe_event_info, event_status); + if (gpe_event_info->flags & ACPI_GPE_DISPATCH_MASK) + *event_status |= ACPI_EVENT_FLAG_HANDLE; + unlock_and_exit: if (flags & ACPI_NOT_ISR) { (void)acpi_ut_release_mutex(ACPI_MTX_EVENTS); diff --git a/drivers/acpi/system.c b/drivers/acpi/system.c index 1d74171b794..6d348dce081 100644 --- a/drivers/acpi/system.c +++ b/drivers/acpi/system.c @@ -167,7 +167,6 @@ static int acpi_system_sysfs_init(void) #define COUNT_ERROR 2 /* other */ #define NUM_COUNTERS_EXTRA 3 -#define ACPI_EVENT_VALID 0x01 struct event_counter { u32 count; u32 flags; @@ -312,12 +311,6 @@ static int get_status(u32 index, acpi_event_status *status, acpi_handle *handle) } else if (index < (num_gpes + ACPI_NUM_FIXED_EVENTS)) result = acpi_get_event_status(index - num_gpes, status); - /* - * sleep/power button GPE/Fixed Event is enabled after acpi_system_init, - * check the status at runtime and mark it as valid once it's enabled - */ - if (!result && (*status & ACPI_EVENT_FLAG_ENABLED)) - all_counters[index].flags |= ACPI_EVENT_VALID; end: return result; } @@ -346,12 +339,14 @@ static ssize_t counter_show(struct kobject *kobj, if (result) goto end; - if (!(all_counters[index].flags & ACPI_EVENT_VALID)) - size += sprintf(buf + size, " invalid"); + if (!(status & ACPI_EVENT_FLAG_HANDLE)) + size += sprintf(buf + size, " invalid"); else if (status & ACPI_EVENT_FLAG_ENABLED) - size += sprintf(buf + size, " enable"); + size += sprintf(buf + size, " enabled"); + else if (status & ACPI_EVENT_FLAG_WAKE_ENABLED) + size += sprintf(buf + size, " wake_enabled"); else - size += sprintf(buf + size, " disable"); + size += sprintf(buf + size, " disabled"); end: size += sprintf(buf + size, "\n"); @@ -385,7 +380,7 @@ static ssize_t counter_set(struct kobject *kobj, if (result) goto end; - if (!(all_counters[index].flags & ACPI_EVENT_VALID)) { + if (!(status & ACPI_EVENT_FLAG_HANDLE)) { printk(KERN_WARNING PREFIX "Can not change Invalid GPE/Fixed Event status\n"); return -EINVAL; -- cgit v1.2.3 From 5704d626e7c770ef4a984a697bac7eff07420a39 Mon Sep 17 00:00:00 2001 From: Bjorn Helgaas Date: Wed, 5 Nov 2008 16:17:42 -0700 Subject: ACPI: remove comments about debug layer/level to use I don't think there's any point in cluttering the code with these. Better to improve the documentation so *anybody* can figure out what layer & level to use. Signed-off-by: Bjorn Helgaas Signed-off-by: Len Brown --- drivers/acpi/pci_root.c | 6 ------ drivers/acpi/video.c | 6 ------ 2 files changed, 12 deletions(-) (limited to 'drivers/acpi') diff --git a/drivers/acpi/pci_root.c b/drivers/acpi/pci_root.c index 1b8f67d21d5..642554b1b60 100644 --- a/drivers/acpi/pci_root.c +++ b/drivers/acpi/pci_root.c @@ -376,15 +376,9 @@ static int acpi_pci_root_remove(struct acpi_device *device, int type) static int __init acpi_pci_root_init(void) { - if (acpi_pci_disabled) return 0; - /* DEBUG: - acpi_dbg_layer = ACPI_PCI_COMPONENT; - acpi_dbg_level = 0xFFFFFFFF; - */ - if (acpi_bus_register_driver(&acpi_pci_root_driver) < 0) return -ENODEV; diff --git a/drivers/acpi/video.c b/drivers/acpi/video.c index a29b0ccac65..bf0c26a7368 100644 --- a/drivers/acpi/video.c +++ b/drivers/acpi/video.c @@ -2094,12 +2094,6 @@ static int __init acpi_video_init(void) { int result = 0; - - /* - acpi_dbg_level = 0xFFFFFFFF; - acpi_dbg_layer = 0x08000000; - */ - acpi_video_dir = proc_mkdir(ACPI_VIDEO_CLASS, acpi_root_dir); if (!acpi_video_dir) return -ENODEV; -- cgit v1.2.3 From 5b881479af4352791e5004b74e3639f1416c5fe4 Mon Sep 17 00:00:00 2001 From: Bjorn Helgaas Date: Wed, 5 Nov 2008 16:17:47 -0700 Subject: ACPI: SBS: remove useless acpi_cm_sbs_init() initcall acpi_cm_sbs_init() doesn't do anything, so we can just remove it. Signed-off-by: Bjorn Helgaas Signed-off-by: Len Brown --- drivers/acpi/cm_sbs.c | 6 ------ 1 file changed, 6 deletions(-) (limited to 'drivers/acpi') diff --git a/drivers/acpi/cm_sbs.c b/drivers/acpi/cm_sbs.c index 4441e84b28a..80d5c88e68c 100644 --- a/drivers/acpi/cm_sbs.c +++ b/drivers/acpi/cm_sbs.c @@ -105,9 +105,3 @@ void acpi_unlock_battery_dir(struct proc_dir_entry *acpi_battery_dir_param) return; } EXPORT_SYMBOL(acpi_unlock_battery_dir); - -static int __init acpi_cm_sbs_init(void) -{ - return 0; -} -subsys_initcall(acpi_cm_sbs_init); -- cgit v1.2.3 From fefe5ab3d67b0ade6200fec5ed6f2812cbcbb658 Mon Sep 17 00:00:00 2001 From: Bjorn Helgaas Date: Wed, 5 Nov 2008 16:17:58 -0700 Subject: ACPI: remove CONFIG_ACPI_POWER Remove CONFIG_ACPI_POWER. It was always set the same as CONFIG_ACPI, and it had no menu label, so there was no way to set it to anything other than "y". The interfaces under CONFIG_ACPI_POWER (acpi_device_sleep_wake(), acpi_power_transition(), etc) are called unconditionally from the ACPI core, so we already depend on it always being present. Signed-off-by: Bjorn Helgaas Signed-off-by: Len Brown --- drivers/acpi/Kconfig | 4 ---- drivers/acpi/Makefile | 2 +- 2 files changed, 1 insertion(+), 5 deletions(-) (limited to 'drivers/acpi') diff --git a/drivers/acpi/Kconfig b/drivers/acpi/Kconfig index f4f63291750..4fa7866a9a5 100644 --- a/drivers/acpi/Kconfig +++ b/drivers/acpi/Kconfig @@ -341,10 +341,6 @@ config ACPI_PCI_SLOT help you correlate PCI bus addresses with the physical geography of your slots. If you are unsure, say N. -config ACPI_POWER - bool - default y - config ACPI_SYSTEM bool default y diff --git a/drivers/acpi/Makefile b/drivers/acpi/Makefile index d91c027ece8..8017f63920c 100644 --- a/drivers/acpi/Makefile +++ b/drivers/acpi/Makefile @@ -51,7 +51,7 @@ obj-$(CONFIG_ACPI_PCI_SLOT) += pci_slot.o obj-$(CONFIG_ACPI_PROCESSOR) += processor.o obj-$(CONFIG_ACPI_CONTAINER) += container.o obj-$(CONFIG_ACPI_THERMAL) += thermal.o -obj-$(CONFIG_ACPI_POWER) += power.o +obj-y += power.o obj-$(CONFIG_ACPI_SYSTEM) += system.o event.o obj-$(CONFIG_ACPI_DEBUG) += debug.o obj-$(CONFIG_ACPI_NUMA) += numa.o -- cgit v1.2.3 From 8950d89acaa8c353869e681772479d7955ae6f7a Mon Sep 17 00:00:00 2001 From: Bjorn Helgaas Date: Wed, 5 Nov 2008 16:18:03 -0700 Subject: ACPI: remove CONFIG_ACPI_EC Remove CONFIG_ACPI_EC. It was always set the same as CONFIG_ACPI, and it had no menu label, so there was no way to set it to anything other than "y". Per section 6.5.4 of the ACPI 3.0b specification, OSPM must make Embedded Controller operation regions, accessed via the Embedded Controllers described in ECDT, available before executing any control method. The ECDT table is optional, but if it is present, the above text means that the EC it describes is a required part of the ACPI subsystem, so CONFIG_ACPI_EC=n wouldn't make sense. Signed-off-by: Bjorn Helgaas Acked-by: Alexey Starikovskiy Signed-off-by: Len Brown --- drivers/acpi/Kconfig | 8 -------- drivers/acpi/Makefile | 2 +- drivers/acpi/bus.c | 3 +-- 3 files changed, 2 insertions(+), 11 deletions(-) (limited to 'drivers/acpi') diff --git a/drivers/acpi/Kconfig b/drivers/acpi/Kconfig index 4fa7866a9a5..90cb2a823b5 100644 --- a/drivers/acpi/Kconfig +++ b/drivers/acpi/Kconfig @@ -324,14 +324,6 @@ config ACPI_DEBUG_FUNC_TRACE ACPI Debug Statements slow down ACPI processing. Function trace is about half of the penalty and is rarely useful. -config ACPI_EC - bool - default y - help - This driver is required on some systems for the proper operation of - the battery and thermal drivers. If you are compiling for a - mobile system, say Y. - config ACPI_PCI_SLOT tristate "PCI slot detection driver" default n diff --git a/drivers/acpi/Makefile b/drivers/acpi/Makefile index 8017f63920c..fc622316a7d 100644 --- a/drivers/acpi/Makefile +++ b/drivers/acpi/Makefile @@ -39,7 +39,7 @@ obj-y += sleep/ obj-y += bus.o glue.o obj-y += scan.o # Keep EC driver first. Initialization of others depend on it. -obj-$(CONFIG_ACPI_EC) += ec.o +obj-y += ec.o obj-$(CONFIG_ACPI_AC) += ac.o obj-$(CONFIG_ACPI_BATTERY) += battery.o obj-$(CONFIG_ACPI_BUTTON) += button.o diff --git a/drivers/acpi/bus.c b/drivers/acpi/bus.c index c797c6473f3..765fd1c56cd 100644 --- a/drivers/acpi/bus.c +++ b/drivers/acpi/bus.c @@ -774,7 +774,7 @@ static int __init acpi_bus_init(void) "Unable to initialize ACPI OS objects\n"); goto error1; } -#ifdef CONFIG_ACPI_EC + /* * ACPI 2.0 requires the EC driver to be loaded and work before * the EC device is found in the namespace (i.e. before acpi_initialize_objects() @@ -785,7 +785,6 @@ static int __init acpi_bus_init(void) */ status = acpi_ec_ecdt_probe(); /* Ignore result. Not having an ECDT is not fatal. */ -#endif status = acpi_initialize_objects(ACPI_FULL_INITIALIZATION); if (ACPI_FAILURE(status)) { -- cgit v1.2.3 From ad93a765c1834db031b5bf1c2baf2a50d0462ca4 Mon Sep 17 00:00:00 2001 From: Myron Stowe Date: Tue, 4 Nov 2008 14:52:55 -0700 Subject: ACPI: Disambiguate processor declaration type Declaring processors in ACPI namespace can be done using either a "Processor" definition or a "Device" definition (see section 8.4 - Declaring Processors; "Advanced Configuration and Power Interface Specification", Revision 3.0b). Currently the two processor declaration types are conflated. This patch disambiguates the processor declaration's definition type enabling subsequent code to behave uniquely based explicitly on the declaration's type. Signed-off-by: Myron Stowe Signed-off-by: Len Brown --- drivers/acpi/processor_core.c | 1 + drivers/acpi/scan.c | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) (limited to 'drivers/acpi') diff --git a/drivers/acpi/processor_core.c b/drivers/acpi/processor_core.c index 24a362f8034..0c670dd297d 100644 --- a/drivers/acpi/processor_core.c +++ b/drivers/acpi/processor_core.c @@ -89,6 +89,7 @@ static int acpi_processor_handle_eject(struct acpi_processor *pr); static const struct acpi_device_id processor_device_ids[] = { + {ACPI_PROCESSOR_OBJECT_HID, 0}, {ACPI_PROCESSOR_HID, 0}, {"", 0}, }; diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c index a9dda8e0f9f..3fb6e2db585 100644 --- a/drivers/acpi/scan.c +++ b/drivers/acpi/scan.c @@ -1043,7 +1043,7 @@ static void acpi_device_set_id(struct acpi_device *device, hid = ACPI_POWER_HID; break; case ACPI_BUS_TYPE_PROCESSOR: - hid = ACPI_PROCESSOR_HID; + hid = ACPI_PROCESSOR_OBJECT_HID; break; case ACPI_BUS_TYPE_SYSTEM: hid = ACPI_SYSTEM_HID; -- cgit v1.2.3 From b26e9286fb438eb78bcdb68b67a3dbb8bc539125 Mon Sep 17 00:00:00 2001 From: Myron Stowe Date: Tue, 4 Nov 2008 14:53:00 -0700 Subject: ACPI: Behave uniquely based on processor declaration definition type Associating a Local SAPIC with a processor object is dependent upon the processor object's definition type. CPUs declared as "Processor" should use the Local SAPIC's 'processor_id', and CPUs declared as "Device" should use the 'uid'. Note that for "Processor" declarations, even if a '_UID' child object exists, it has no bearing with respect to mapping Local SAPICs (see section 5.2.11.13 - Local SAPIC Structure; "Advanced Configuration and Power Interface Specification", Revision 3.0b). This patch changes the lsapic mapping logic to rely on the distinction of how the processor object was declared - the mapping can't just try both types of matches regardless of declaration type and rely on one failing as is currently being done. Signed-off-by: Myron Stowe Signed-off-by: Len Brown --- drivers/acpi/processor_core.c | 78 ++++++++++++++++++++++++------------------- 1 file changed, 44 insertions(+), 34 deletions(-) (limited to 'drivers/acpi') diff --git a/drivers/acpi/processor_core.c b/drivers/acpi/processor_core.c index 0c670dd297d..bc332fc28d7 100644 --- a/drivers/acpi/processor_core.c +++ b/drivers/acpi/processor_core.c @@ -410,7 +410,7 @@ static int acpi_processor_remove_fs(struct acpi_device *device) /* Use the acpiid in MADT to map cpus in case of SMP */ #ifndef CONFIG_SMP -static int get_cpu_id(acpi_handle handle, u32 acpi_id) {return -1;} +static int get_cpu_id(acpi_handle handle, int type, u32 acpi_id) { return -1; } #else static struct acpi_table_madt *madt; @@ -429,27 +429,35 @@ static int map_lapic_id(struct acpi_subtable_header *entry, } static int map_lsapic_id(struct acpi_subtable_header *entry, - u32 acpi_id, int *apic_id) + int device_declaration, u32 acpi_id, int *apic_id) { struct acpi_madt_local_sapic *lsapic = (struct acpi_madt_local_sapic *)entry; + u32 tmp = (lsapic->id << 8) | lsapic->eid; + /* Only check enabled APICs*/ - if (lsapic->lapic_flags & ACPI_MADT_ENABLED) { - /* First check against id */ - if (lsapic->processor_id == acpi_id) { - *apic_id = (lsapic->id << 8) | lsapic->eid; - return 1; - /* Check against optional uid */ - } else if (entry->length >= 16 && - lsapic->uid == acpi_id) { - *apic_id = lsapic->uid; - return 1; - } - } + if (!(lsapic->lapic_flags & ACPI_MADT_ENABLED)) + return 0; + + /* Device statement declaration type */ + if (device_declaration) { + if (entry->length < 16) + printk(KERN_ERR PREFIX + "Invalid LSAPIC with Device type processor (SAPIC ID %#x)\n", + tmp); + else if (lsapic->uid == acpi_id) + goto found; + /* Processor statement declaration type */ + } else if (lsapic->processor_id == acpi_id) + goto found; + return 0; +found: + *apic_id = tmp; + return 1; } -static int map_madt_entry(u32 acpi_id) +static int map_madt_entry(int type, u32 acpi_id) { unsigned long madt_end, entry; int apic_id = -1; @@ -470,7 +478,7 @@ static int map_madt_entry(u32 acpi_id) if (map_lapic_id(header, acpi_id, &apic_id)) break; } else if (header->type == ACPI_MADT_TYPE_LOCAL_SAPIC) { - if (map_lsapic_id(header, acpi_id, &apic_id)) + if (map_lsapic_id(header, type, acpi_id, &apic_id)) break; } entry += header->length; @@ -478,7 +486,7 @@ static int map_madt_entry(u32 acpi_id) return apic_id; } -static int map_mat_entry(acpi_handle handle, u32 acpi_id) +static int map_mat_entry(acpi_handle handle, int type, u32 acpi_id) { struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL }; union acpi_object *obj; @@ -501,7 +509,7 @@ static int map_mat_entry(acpi_handle handle, u32 acpi_id) if (header->type == ACPI_MADT_TYPE_LOCAL_APIC) { map_lapic_id(header, acpi_id, &apic_id); } else if (header->type == ACPI_MADT_TYPE_LOCAL_SAPIC) { - map_lsapic_id(header, acpi_id, &apic_id); + map_lsapic_id(header, type, acpi_id, &apic_id); } exit: @@ -510,14 +518,14 @@ exit: return apic_id; } -static int get_cpu_id(acpi_handle handle, u32 acpi_id) +static int get_cpu_id(acpi_handle handle, int type, u32 acpi_id) { int i; int apic_id = -1; - apic_id = map_mat_entry(handle, acpi_id); + apic_id = map_mat_entry(handle, type, acpi_id); if (apic_id == -1) - apic_id = map_madt_entry(acpi_id); + apic_id = map_madt_entry(type, acpi_id); if (apic_id == -1) return apic_id; @@ -533,15 +541,16 @@ static int get_cpu_id(acpi_handle handle, u32 acpi_id) Driver Interface -------------------------------------------------------------------------- */ -static int acpi_processor_get_info(struct acpi_processor *pr, unsigned has_uid) +static int acpi_processor_get_info(struct acpi_device *device) { acpi_status status = 0; union acpi_object object = { 0 }; struct acpi_buffer buffer = { sizeof(union acpi_object), &object }; - int cpu_index; + struct acpi_processor *pr; + int cpu_index, device_declaration = 0; static int cpu0_initialized; - + pr = acpi_driver_data(device); if (!pr) return -EINVAL; @@ -562,22 +571,23 @@ static int acpi_processor_get_info(struct acpi_processor *pr, unsigned has_uid) ACPI_DEBUG_PRINT((ACPI_DB_INFO, "No bus mastering arbitration control\n")); - /* Check if it is a Device with HID and UID */ - if (has_uid) { + if (!strcmp(acpi_device_hid(device), ACPI_PROCESSOR_HID)) { + /* + * Declared with "Device" statement; match _UID. + * Note that we don't handle string _UIDs yet. + */ unsigned long long value; status = acpi_evaluate_integer(pr->handle, METHOD_NAME__UID, NULL, &value); if (ACPI_FAILURE(status)) { - printk(KERN_ERR PREFIX "Evaluating processor _UID\n"); + printk(KERN_ERR PREFIX + "Evaluating processor _UID [%#x]\n", status); return -ENODEV; } + device_declaration = 1; pr->acpi_id = value; } else { - /* - * Evalute the processor object. Note that it is common on SMP to - * have the first (boot) processor with a valid PBLK address while - * all others have a NULL address. - */ + /* Declared with "Processor" statement; match ProcessorID */ status = acpi_evaluate_object(pr->handle, NULL, NULL, &buffer); if (ACPI_FAILURE(status)) { printk(KERN_ERR PREFIX "Evaluating processor object\n"); @@ -590,7 +600,7 @@ static int acpi_processor_get_info(struct acpi_processor *pr, unsigned has_uid) */ pr->acpi_id = object.processor.proc_id; } - cpu_index = get_cpu_id(pr->handle, pr->acpi_id); + cpu_index = get_cpu_id(pr->handle, device_declaration, pr->acpi_id); /* Handle UP system running SMP kernel, with no LAPIC in MADT */ if (!cpu0_initialized && (cpu_index == -1) && @@ -662,7 +672,7 @@ static int __cpuinit acpi_processor_start(struct acpi_device *device) pr = acpi_driver_data(device); - result = acpi_processor_get_info(pr, device->flags.unique_id); + result = acpi_processor_get_info(device); if (result) { /* Processor is physically not present */ return 0; -- cgit v1.2.3 From 5b53ed69158eeff115004f246193d07a083445f6 Mon Sep 17 00:00:00 2001 From: Myron Stowe Date: Tue, 4 Nov 2008 14:53:05 -0700 Subject: ACPI: 80 column adherence and spelling fix (no functional change) Signed-off-by: Myron Stowe Signed-off-by: Len Brown --- drivers/acpi/processor_core.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'drivers/acpi') diff --git a/drivers/acpi/processor_core.c b/drivers/acpi/processor_core.c index bc332fc28d7..b57b1f05cb3 100644 --- a/drivers/acpi/processor_core.c +++ b/drivers/acpi/processor_core.c @@ -595,9 +595,10 @@ static int acpi_processor_get_info(struct acpi_device *device) } /* - * TBD: Synch processor ID (via LAPIC/LSAPIC structures) on SMP. - * >>> 'acpi_get_processor_id(acpi_id, &id)' in arch/xxx/acpi.c - */ + * TBD: Synch processor ID (via LAPIC/LSAPIC structures) on SMP. + * >>> 'acpi_get_processor_id(acpi_id, &id)' in + * arch/xxx/acpi.c + */ pr->acpi_id = object.processor.proc_id; } cpu_index = get_cpu_id(pr->handle, device_declaration, pr->acpi_id); -- cgit v1.2.3 From d17cb18a07c587b8f9ff174a1bf6d03413eabe64 Mon Sep 17 00:00:00 2001 From: Len Brown Date: Thu, 6 Nov 2008 20:51:59 -0500 Subject: Revert "ACPI: Ingore the RESET_REG_SUP bit when using ACPI reset mechanism" This reverts commit 8fd145917fb62368a9b80db59562c20576238f5a. http://bugzilla.kernel.org/show_bug.cgi?id=11942 Signed-off-by: Len Brown --- drivers/acpi/reboot.c | 25 +++---------------------- 1 file changed, 3 insertions(+), 22 deletions(-) (limited to 'drivers/acpi') diff --git a/drivers/acpi/reboot.c b/drivers/acpi/reboot.c index 755baf2ca70..a6b662c00b6 100644 --- a/drivers/acpi/reboot.c +++ b/drivers/acpi/reboot.c @@ -15,28 +15,9 @@ void acpi_reboot(void) rr = &acpi_gbl_FADT.reset_register; - /* - * Is the ACPI reset register supported? - * - * According to ACPI 3.0, FADT.flags.RESET_REG_SUP indicates - * whether the ACPI reset mechanism is supported. - * - * However, some boxes have this bit clear, yet a valid - * ACPI_RESET_REG & RESET_VALUE, and ACPI reboot is the only - * mechanism that works for them after S3. - * - * This suggests that other operating systems may not be checking - * the RESET_REG_SUP bit, and are using other means to decide - * whether to use the ACPI reboot mechanism or not. - * - * So when acpi reboot is requested, - * only the reset_register is checked. If the following - * conditions are met, it indicates that the reset register is supported. - * a. reset_register is not zero - * b. the access width is eight - * c. the bit_offset is zero - */ - if (!(rr->address) || rr->bit_width != 8 || rr->bit_offset != 0) + /* Is the reset register supported? */ + if (!(acpi_gbl_FADT.flags & ACPI_FADT_RESET_REGISTER) || + rr->bit_width != 8 || rr->bit_offset != 0) return; reset_value = acpi_gbl_FADT.reset_value; -- cgit v1.2.3 From 0794469da3f7b2093575cbdfc1108308dd3641ce Mon Sep 17 00:00:00 2001 From: Kay Sievers Date: Thu, 30 Oct 2008 01:18:59 +0100 Subject: ACPI: struct device - replace bus_id with dev_name(), dev_set_name() This patch is part of a larger patch series which will remove the "char bus_id[20]" name string from struct device. The device name is managed in the kobject anyway, and without any size limitation, and just needlessly copied into "struct device". To set and read the device name dev_name(dev) and dev_set_name(dev) must be used. If your code uses static kobjects, which it shouldn't do, "const char *init_name" can be used to statically provide the name the registered device should have. At registration time, the init_name field is cleared, to enforce the use of dev_name(dev) to access the device name at a later time. We need to get rid of all occurrences of bus_id in the entire tree to be able to enable the new interface. Please apply this patch, and possibly convert any remaining remaining occurrences of bus_id. We want to submit a patch to -next, which will remove bus_id from "struct device", to find the remaining pieces to convert, and finally switch over to the new api, which will remove the 20 bytes array and does no longer have a size limitation. Acked-by: Greg Kroah-Hartman Signed-Off-By: Kay Sievers Signed-off-by: Len Brown --- drivers/acpi/ac.c | 2 +- drivers/acpi/battery.c | 2 +- drivers/acpi/processor_core.c | 6 +++--- drivers/acpi/scan.c | 8 ++++---- drivers/acpi/sleep/proc.c | 4 ++-- drivers/acpi/thermal.c | 8 ++++---- drivers/acpi/wmi.c | 2 +- 7 files changed, 16 insertions(+), 16 deletions(-) (limited to 'drivers/acpi') diff --git a/drivers/acpi/ac.c b/drivers/acpi/ac.c index d72a1b6c8a9..2d467326d9e 100644 --- a/drivers/acpi/ac.c +++ b/drivers/acpi/ac.c @@ -242,7 +242,7 @@ static void acpi_ac_notify(acpi_handle handle, u32 event, void *data) acpi_ac_get_state(ac); acpi_bus_generate_proc_event(device, event, (u32) ac->state); acpi_bus_generate_netlink_event(device->pnp.device_class, - device->dev.bus_id, event, + dev_name(&device->dev), event, (u32) ac->state); #ifdef CONFIG_ACPI_SYSFS_POWER kobject_uevent(&ac->charger.dev->kobj, KOBJ_CHANGE); diff --git a/drivers/acpi/battery.c b/drivers/acpi/battery.c index b2133e89ad9..e68f2187ed6 100644 --- a/drivers/acpi/battery.c +++ b/drivers/acpi/battery.c @@ -782,7 +782,7 @@ static void acpi_battery_notify(acpi_handle handle, u32 event, void *data) acpi_bus_generate_proc_event(device, event, acpi_battery_present(battery)); acpi_bus_generate_netlink_event(device->pnp.device_class, - device->dev.bus_id, event, + dev_name(&device->dev), event, acpi_battery_present(battery)); #ifdef CONFIG_ACPI_SYSFS_POWER /* acpi_batter_update could remove power_supply object */ diff --git a/drivers/acpi/processor_core.c b/drivers/acpi/processor_core.c index 24a362f8034..cf7e8856a4c 100644 --- a/drivers/acpi/processor_core.c +++ b/drivers/acpi/processor_core.c @@ -761,20 +761,20 @@ static void acpi_processor_notify(acpi_handle handle, u32 event, void *data) acpi_bus_generate_proc_event(device, event, pr->performance_platform_limit); acpi_bus_generate_netlink_event(device->pnp.device_class, - device->dev.bus_id, event, + dev_name(&device->dev), event, pr->performance_platform_limit); break; case ACPI_PROCESSOR_NOTIFY_POWER: acpi_processor_cst_has_changed(pr); acpi_bus_generate_proc_event(device, event, 0); acpi_bus_generate_netlink_event(device->pnp.device_class, - device->dev.bus_id, event, 0); + dev_name(&device->dev), event, 0); break; case ACPI_PROCESSOR_NOTIFY_THROTTLING: acpi_processor_tstate_has_changed(pr); acpi_bus_generate_proc_event(device, event, 0); acpi_bus_generate_netlink_event(device->pnp.device_class, - device->dev.bus_id, event, 0); + dev_name(&device->dev), event, 0); default: ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Unsupported event [0x%x]\n", event)); diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c index a9dda8e0f9f..4dd1f31930b 100644 --- a/drivers/acpi/scan.c +++ b/drivers/acpi/scan.c @@ -109,8 +109,7 @@ static int acpi_bus_hot_remove_device(void *context) return 0; ACPI_DEBUG_PRINT((ACPI_DB_INFO, - "Hot-removing device %s...\n", device->dev.bus_id)); - + "Hot-removing device %s...\n", dev_name(&device->dev))); if (acpi_bus_trim(device, 1)) { printk(KERN_ERR PREFIX @@ -460,7 +459,7 @@ static int acpi_device_register(struct acpi_device *device, acpi_device_bus_id->instance_no = 0; list_add_tail(&acpi_device_bus_id->node, &acpi_bus_id_list); } - sprintf(device->dev.bus_id, "%s:%02x", acpi_device_bus_id->bus_id, acpi_device_bus_id->instance_no); + dev_set_name(&device->dev, "%s:%02x", acpi_device_bus_id->bus_id, acpi_device_bus_id->instance_no); if (device->parent) { list_add_tail(&device->node, &device->parent->children); @@ -484,7 +483,8 @@ static int acpi_device_register(struct acpi_device *device, result = acpi_device_setup_files(device); if(result) - printk(KERN_ERR PREFIX "Error creating sysfs interface for device %s\n", device->dev.bus_id); + printk(KERN_ERR PREFIX "Error creating sysfs interface for device %s\n", + dev_name(&device->dev)); device->removal_type = ACPI_BUS_REMOVAL_NORMAL; return 0; diff --git a/drivers/acpi/sleep/proc.c b/drivers/acpi/sleep/proc.c index 631ee2ee2ca..64e591ba86f 100644 --- a/drivers/acpi/sleep/proc.c +++ b/drivers/acpi/sleep/proc.c @@ -366,8 +366,8 @@ acpi_system_wakeup_device_seq_show(struct seq_file *seq, void *offset) dev->wakeup.state.enabled ? "enabled" : "disabled"); if (ldev) seq_printf(seq, "%s:%s", - ldev->bus ? ldev->bus->name : "no-bus", - ldev->bus_id); + dev_name(ldev) ? ldev->bus->name : "no-bus", + dev_name(ldev)); seq_printf(seq, "\n"); put_device(ldev); diff --git a/drivers/acpi/thermal.c b/drivers/acpi/thermal.c index ad6cae938f0..462b1687885 100644 --- a/drivers/acpi/thermal.c +++ b/drivers/acpi/thermal.c @@ -576,7 +576,7 @@ static int acpi_thermal_critical(struct acpi_thermal *tz) acpi_bus_generate_proc_event(tz->device, ACPI_THERMAL_NOTIFY_CRITICAL, tz->trips.critical.flags.enabled); acpi_bus_generate_netlink_event(tz->device->pnp.device_class, - tz->device->dev.bus_id, + dev_name(&tz->device->dev), ACPI_THERMAL_NOTIFY_CRITICAL, tz->trips.critical.flags.enabled); @@ -605,7 +605,7 @@ static int acpi_thermal_hot(struct acpi_thermal *tz) acpi_bus_generate_proc_event(tz->device, ACPI_THERMAL_NOTIFY_HOT, tz->trips.hot.flags.enabled); acpi_bus_generate_netlink_event(tz->device->pnp.device_class, - tz->device->dev.bus_id, + dev_name(&tz->device->dev), ACPI_THERMAL_NOTIFY_HOT, tz->trips.hot.flags.enabled); @@ -1592,14 +1592,14 @@ static void acpi_thermal_notify(acpi_handle handle, u32 event, void *data) acpi_thermal_check(tz); acpi_bus_generate_proc_event(device, event, 0); acpi_bus_generate_netlink_event(device->pnp.device_class, - device->dev.bus_id, event, 0); + dev_name(&device->dev), event, 0); break; case ACPI_THERMAL_NOTIFY_DEVICES: acpi_thermal_trips_update(tz, ACPI_TRIPS_REFRESH_DEVICES); acpi_thermal_check(tz); acpi_bus_generate_proc_event(device, event, 0); acpi_bus_generate_netlink_event(device->pnp.device_class, - device->dev.bus_id, event, 0); + dev_name(&device->dev), event, 0); break; default: ACPI_DEBUG_PRINT((ACPI_DB_INFO, diff --git a/drivers/acpi/wmi.c b/drivers/acpi/wmi.c index 47cd7baf9b1..8a8b377712c 100644 --- a/drivers/acpi/wmi.c +++ b/drivers/acpi/wmi.c @@ -660,7 +660,7 @@ static void acpi_wmi_notify(acpi_handle handle, u32 event, void *data) wblock->handler(event, wblock->handler_data); acpi_bus_generate_netlink_event( - device->pnp.device_class, device->dev.bus_id, + device->pnp.device_class, dev_name(&device->dev), event, 0); break; } -- cgit v1.2.3 From 14a63ba821ac2a0f5166789b31241c0b7eb147d9 Mon Sep 17 00:00:00 2001 From: Yinghai Lu Date: Wed, 29 Oct 2008 14:13:22 -0700 Subject: ACPI: use macro to replace hard number Impact: cleanup Use MACRO for rev 3 fadt id instead of 3 directly. Signed-off-by: Yinghai Lu Signed-off-by: Andrew Morton Signed-off-by: Len Brown --- drivers/acpi/tables/tbfadt.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/acpi') diff --git a/drivers/acpi/tables/tbfadt.c b/drivers/acpi/tables/tbfadt.c index 2c7885e7ffb..2817158fb6a 100644 --- a/drivers/acpi/tables/tbfadt.c +++ b/drivers/acpi/tables/tbfadt.c @@ -304,7 +304,7 @@ static void acpi_tb_convert_fadt(void) * The ACPI 1.0 reserved fields that will be zeroed are the bytes located at * offset 45, 55, 95, and the word located at offset 109, 110. */ - if (acpi_gbl_FADT.header.revision < 3) { + if (acpi_gbl_FADT.header.revision < FADT2_REVISION_ID) { acpi_gbl_FADT.preferred_profile = 0; acpi_gbl_FADT.pstate_control = 0; acpi_gbl_FADT.cst_control = 0; -- cgit v1.2.3 From 4feba70a2c1a1a0c96909f657f48b2e11e682370 Mon Sep 17 00:00:00 2001 From: Peter Gruber Date: Mon, 27 Oct 2008 23:59:36 -0400 Subject: ACPI: avoid empty file name in sysfs Since commit bc45b1d39a925b56796bebf8a397a0491489d85c acpi tables are allowed to have an empty signature and /sys/firmware/acpi/tables uses the signature as filename. Applications using naive recursion through /sys loop forever. A possible solution would be: (replacing the zero length filename with the string "NULL") http://bugzilla.kernel.org/show_bug.cgi?id=11539 Acked-by: Zhang Rui Signed-off-by: Andrew Morton Signed-off-by: Len Brown --- drivers/acpi/system.c | 25 +++++++++++++++++-------- 1 file changed, 17 insertions(+), 8 deletions(-) (limited to 'drivers/acpi') diff --git a/drivers/acpi/system.c b/drivers/acpi/system.c index 1d74171b794..62ec75e7912 100644 --- a/drivers/acpi/system.c +++ b/drivers/acpi/system.c @@ -78,9 +78,15 @@ static ssize_t acpi_table_show(struct kobject *kobj, container_of(bin_attr, struct acpi_table_attr, attr); struct acpi_table_header *table_header = NULL; acpi_status status; + char name[ACPI_NAME_SIZE]; + + if (strncmp(table_attr->name, "NULL", 4)) + memcpy(name, table_attr->name, ACPI_NAME_SIZE); + else + memcpy(name, "\0\0\0\0", 4); status = - acpi_get_table(table_attr->name, table_attr->instance, + acpi_get_table(name, table_attr->instance, &table_header); if (ACPI_FAILURE(status)) return -ENODEV; @@ -95,21 +101,24 @@ static void acpi_table_attr_init(struct acpi_table_attr *table_attr, struct acpi_table_header *header = NULL; struct acpi_table_attr *attr = NULL; - memcpy(table_attr->name, table_header->signature, ACPI_NAME_SIZE); + if (table_header->signature[0] != '\0') + memcpy(table_attr->name, table_header->signature, + ACPI_NAME_SIZE); + else + memcpy(table_attr->name, "NULL", 4); list_for_each_entry(attr, &acpi_table_attr_list, node) { - if (!memcmp(table_header->signature, attr->name, - ACPI_NAME_SIZE)) + if (!memcmp(table_attr->name, attr->name, ACPI_NAME_SIZE)) if (table_attr->instance < attr->instance) table_attr->instance = attr->instance; } table_attr->instance++; if (table_attr->instance > 1 || (table_attr->instance == 1 && - !acpi_get_table(table_header-> - signature, 2, - &header))) - sprintf(table_attr->name + 4, "%d", table_attr->instance); + !acpi_get_table + (table_header->signature, 2, &header))) + sprintf(table_attr->name + ACPI_NAME_SIZE, "%d", + table_attr->instance); table_attr->attr.size = 0; table_attr->attr.read = acpi_table_show; -- cgit v1.2.3 From d21cf3c16b1191f3154a51e0b20c82bf851cc553 Mon Sep 17 00:00:00 2001 From: Alexey Starikovskiy Date: Mon, 3 Nov 2008 14:26:40 -0500 Subject: ACPI EC: Fix regression due to use of uninitialized variable breakage introduced by following patch commit 27663c5855b10af9ec67bc7dfba001426ba21222 Author: Matthew Wilcox Date: Fri Oct 10 02:22:59 2008 -0400 acpi_evaluate_integer() does not clear passed variable if there is an error at evaluation. So if we ignore error, we must supply initialized variable. http://bugzilla.kernel.org/show_bug.cgi?id=11917 Signed-off-by: Alexey Starikovskiy Tested-by: Alan Jenkins Signed-off-by: Len Brown --- drivers/acpi/ec.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'drivers/acpi') diff --git a/drivers/acpi/ec.c b/drivers/acpi/ec.c index ef42316f89f..523ac5b229a 100644 --- a/drivers/acpi/ec.c +++ b/drivers/acpi/ec.c @@ -736,7 +736,7 @@ static acpi_status ec_parse_device(acpi_handle handle, u32 Level, void *context, void **retval) { acpi_status status; - unsigned long long tmp; + unsigned long long tmp = 0; struct acpi_ec *ec = context; status = acpi_walk_resources(handle, METHOD_NAME__CRS, @@ -751,6 +751,7 @@ ec_parse_device(acpi_handle handle, u32 Level, void *context, void **retval) return status; ec->gpe = tmp; /* Use the global lock for all EC transactions? */ + tmp = 0; acpi_evaluate_integer(handle, "_GLK", NULL, &tmp); ec->global_lock = tmp; ec->handle = handle; -- cgit v1.2.3 From 89595b8f2850a080d290bf778ec933ea1d99f78e Mon Sep 17 00:00:00 2001 From: Bjorn Helgaas Date: Fri, 7 Nov 2008 16:57:45 -0700 Subject: ACPI: consolidate ACPI_*_COMPONENT definitions in acpi_drivers.h Move all the component definitions for drivers to a single shared place, include/acpi/acpi_drivers.h. Signed-off-by: Bjorn Helgaas Signed-off-by: Len Brown --- drivers/acpi/ac.c | 1 - drivers/acpi/acpi_memhotplug.c | 1 - drivers/acpi/battery.c | 1 - drivers/acpi/button.c | 1 - drivers/acpi/cm_sbs.c | 1 - drivers/acpi/container.c | 1 - drivers/acpi/fan.c | 1 - drivers/acpi/power.c | 3 +-- drivers/acpi/processor_core.c | 1 - drivers/acpi/processor_idle.c | 1 - drivers/acpi/processor_perflib.c | 2 +- drivers/acpi/processor_thermal.c | 1 - drivers/acpi/processor_throttling.c | 2 +- drivers/acpi/thermal.c | 1 - drivers/acpi/video.c | 1 - 15 files changed, 3 insertions(+), 16 deletions(-) (limited to 'drivers/acpi') diff --git a/drivers/acpi/ac.c b/drivers/acpi/ac.c index d72a1b6c8a9..5cdd713a0ea 100644 --- a/drivers/acpi/ac.c +++ b/drivers/acpi/ac.c @@ -37,7 +37,6 @@ #include #include -#define ACPI_AC_COMPONENT 0x00020000 #define ACPI_AC_CLASS "ac_adapter" #define ACPI_AC_DEVICE_NAME "AC Adapter" #define ACPI_AC_FILE_STATE "state" diff --git a/drivers/acpi/acpi_memhotplug.c b/drivers/acpi/acpi_memhotplug.c index 71d21c51c45..63a17b55b39 100644 --- a/drivers/acpi/acpi_memhotplug.c +++ b/drivers/acpi/acpi_memhotplug.c @@ -32,7 +32,6 @@ #include #include -#define ACPI_MEMORY_DEVICE_COMPONENT 0x08000000UL #define ACPI_MEMORY_DEVICE_CLASS "memory" #define ACPI_MEMORY_DEVICE_HID "PNP0C80" #define ACPI_MEMORY_DEVICE_NAME "Hotplug Mem Device" diff --git a/drivers/acpi/battery.c b/drivers/acpi/battery.c index b2133e89ad9..47f6e38fa6c 100644 --- a/drivers/acpi/battery.c +++ b/drivers/acpi/battery.c @@ -46,7 +46,6 @@ #define ACPI_BATTERY_VALUE_UNKNOWN 0xFFFFFFFF -#define ACPI_BATTERY_COMPONENT 0x00040000 #define ACPI_BATTERY_CLASS "battery" #define ACPI_BATTERY_DEVICE_NAME "Battery" #define ACPI_BATTERY_NOTIFY_STATUS 0x80 diff --git a/drivers/acpi/button.c b/drivers/acpi/button.c index cb046c3fc3f..fd7ca289cb0 100644 --- a/drivers/acpi/button.c +++ b/drivers/acpi/button.c @@ -33,7 +33,6 @@ #include #include -#define ACPI_BUTTON_COMPONENT 0x00080000 #define ACPI_BUTTON_CLASS "button" #define ACPI_BUTTON_FILE_INFO "info" #define ACPI_BUTTON_FILE_STATE "state" diff --git a/drivers/acpi/cm_sbs.c b/drivers/acpi/cm_sbs.c index 80d5c88e68c..307963bd104 100644 --- a/drivers/acpi/cm_sbs.c +++ b/drivers/acpi/cm_sbs.c @@ -34,7 +34,6 @@ ACPI_MODULE_NAME("cm_sbs"); #define ACPI_AC_CLASS "ac_adapter" #define ACPI_BATTERY_CLASS "battery" -#define ACPI_SBS_COMPONENT 0x00080000 #define _COMPONENT ACPI_SBS_COMPONENT static struct proc_dir_entry *acpi_ac_dir; static struct proc_dir_entry *acpi_battery_dir; diff --git a/drivers/acpi/container.c b/drivers/acpi/container.c index 134818b265a..17020c12623 100644 --- a/drivers/acpi/container.c +++ b/drivers/acpi/container.c @@ -41,7 +41,6 @@ #define INSTALL_NOTIFY_HANDLER 1 #define UNINSTALL_NOTIFY_HANDLER 2 -#define ACPI_CONTAINER_COMPONENT 0x01000000 #define _COMPONENT ACPI_CONTAINER_COMPONENT ACPI_MODULE_NAME("container"); diff --git a/drivers/acpi/fan.c b/drivers/acpi/fan.c index 60d54d1f6b1..eaaee1660bd 100644 --- a/drivers/acpi/fan.c +++ b/drivers/acpi/fan.c @@ -34,7 +34,6 @@ #include #include -#define ACPI_FAN_COMPONENT 0x00200000 #define ACPI_FAN_CLASS "fan" #define ACPI_FAN_FILE_STATE "state" diff --git a/drivers/acpi/power.c b/drivers/acpi/power.c index a1718e56103..81f583f8098 100644 --- a/drivers/acpi/power.c +++ b/drivers/acpi/power.c @@ -44,9 +44,8 @@ #include #include -#define _COMPONENT ACPI_POWER_COMPONENT +#define _COMPONENT ACPI_POWER_COMPONENT ACPI_MODULE_NAME("power"); -#define ACPI_POWER_COMPONENT 0x00800000 #define ACPI_POWER_CLASS "power_resource" #define ACPI_POWER_DEVICE_NAME "Power Resource" #define ACPI_POWER_FILE_INFO "info" diff --git a/drivers/acpi/processor_core.c b/drivers/acpi/processor_core.c index 24a362f8034..105e0ff8384 100644 --- a/drivers/acpi/processor_core.c +++ b/drivers/acpi/processor_core.c @@ -59,7 +59,6 @@ #include #include -#define ACPI_PROCESSOR_COMPONENT 0x01000000 #define ACPI_PROCESSOR_CLASS "processor" #define ACPI_PROCESSOR_DEVICE_NAME "Processor" #define ACPI_PROCESSOR_FILE_INFO "info" diff --git a/drivers/acpi/processor_idle.c b/drivers/acpi/processor_idle.c index 81b40ed5379..5f8d746a9b8 100644 --- a/drivers/acpi/processor_idle.c +++ b/drivers/acpi/processor_idle.c @@ -59,7 +59,6 @@ #include #include -#define ACPI_PROCESSOR_COMPONENT 0x01000000 #define ACPI_PROCESSOR_CLASS "processor" #define _COMPONENT ACPI_PROCESSOR_COMPONENT ACPI_MODULE_NAME("processor_idle"); diff --git a/drivers/acpi/processor_perflib.c b/drivers/acpi/processor_perflib.c index dbcf260ea93..0d7b772bef5 100644 --- a/drivers/acpi/processor_perflib.c +++ b/drivers/acpi/processor_perflib.c @@ -44,9 +44,9 @@ #endif #include +#include #include -#define ACPI_PROCESSOR_COMPONENT 0x01000000 #define ACPI_PROCESSOR_CLASS "processor" #define ACPI_PROCESSOR_FILE_PERFORMANCE "performance" #define _COMPONENT ACPI_PROCESSOR_COMPONENT diff --git a/drivers/acpi/processor_thermal.c b/drivers/acpi/processor_thermal.c index ef34b18f95c..b1eb376fae4 100644 --- a/drivers/acpi/processor_thermal.c +++ b/drivers/acpi/processor_thermal.c @@ -40,7 +40,6 @@ #include #include -#define ACPI_PROCESSOR_COMPONENT 0x01000000 #define ACPI_PROCESSOR_CLASS "processor" #define _COMPONENT ACPI_PROCESSOR_COMPONENT ACPI_MODULE_NAME("processor_thermal"); diff --git a/drivers/acpi/processor_throttling.c b/drivers/acpi/processor_throttling.c index 3da2df93d92..a0c38c94a8a 100644 --- a/drivers/acpi/processor_throttling.c +++ b/drivers/acpi/processor_throttling.c @@ -38,9 +38,9 @@ #include #include +#include #include -#define ACPI_PROCESSOR_COMPONENT 0x01000000 #define ACPI_PROCESSOR_CLASS "processor" #define _COMPONENT ACPI_PROCESSOR_COMPONENT ACPI_MODULE_NAME("processor_throttling"); diff --git a/drivers/acpi/thermal.c b/drivers/acpi/thermal.c index ad6cae938f0..a6da1d9918c 100644 --- a/drivers/acpi/thermal.c +++ b/drivers/acpi/thermal.c @@ -47,7 +47,6 @@ #include #include -#define ACPI_THERMAL_COMPONENT 0x04000000 #define ACPI_THERMAL_CLASS "thermal_zone" #define ACPI_THERMAL_DEVICE_NAME "Thermal Zone" #define ACPI_THERMAL_FILE_STATE "state" diff --git a/drivers/acpi/video.c b/drivers/acpi/video.c index bf0c26a7368..a3aad30d39f 100644 --- a/drivers/acpi/video.c +++ b/drivers/acpi/video.c @@ -41,7 +41,6 @@ #include #include -#define ACPI_VIDEO_COMPONENT 0x08000000 #define ACPI_VIDEO_CLASS "video" #define ACPI_VIDEO_BUS_NAME "Video Bus" #define ACPI_VIDEO_DEVICE_NAME "Video Device" -- cgit v1.2.3 From bdd7279919f682da8752fb47784a1ee302f8b7ea Mon Sep 17 00:00:00 2001 From: Bjorn Helgaas Date: Fri, 7 Nov 2008 16:57:55 -0700 Subject: ACPI: add driver component definitions to sysfs debug_layers /sys/module/acpi/parameters/debug_layers used to contain only the debug layers defined by the ACPI CA. This patch adds the additional layer definitions for ACPI drivers. Signed-off-by: Bjorn Helgaas Signed-off-by: Len Brown --- drivers/acpi/debug.c | 15 +++++++++++++++ 1 file changed, 15 insertions(+) (limited to 'drivers/acpi') diff --git a/drivers/acpi/debug.c b/drivers/acpi/debug.c index abf36b4b1d1..c4839689200 100644 --- a/drivers/acpi/debug.c +++ b/drivers/acpi/debug.c @@ -44,6 +44,21 @@ static const struct acpi_dlayer acpi_debug_layers[] = { ACPI_DEBUG_INIT(ACPI_CA_DISASSEMBLER), ACPI_DEBUG_INIT(ACPI_COMPILER), ACPI_DEBUG_INIT(ACPI_TOOLS), + + ACPI_DEBUG_INIT(ACPI_BUS_COMPONENT), + ACPI_DEBUG_INIT(ACPI_AC_COMPONENT), + ACPI_DEBUG_INIT(ACPI_BATTERY_COMPONENT), + ACPI_DEBUG_INIT(ACPI_BUTTON_COMPONENT), + ACPI_DEBUG_INIT(ACPI_SBS_COMPONENT), + ACPI_DEBUG_INIT(ACPI_FAN_COMPONENT), + ACPI_DEBUG_INIT(ACPI_PCI_COMPONENT), + ACPI_DEBUG_INIT(ACPI_POWER_COMPONENT), + ACPI_DEBUG_INIT(ACPI_CONTAINER_COMPONENT), + ACPI_DEBUG_INIT(ACPI_SYSTEM_COMPONENT), + ACPI_DEBUG_INIT(ACPI_THERMAL_COMPONENT), + ACPI_DEBUG_INIT(ACPI_MEMORY_DEVICE_COMPONENT), + ACPI_DEBUG_INIT(ACPI_VIDEO_COMPONENT), + ACPI_DEBUG_INIT(ACPI_PROCESSOR_COMPONENT), }; static const struct acpi_dlevel acpi_debug_levels[] = { -- cgit v1.2.3 From 87b586088ef953c602680e5aff8ab83a2e299498 Mon Sep 17 00:00:00 2001 From: Bjorn Helgaas Date: Fri, 7 Nov 2008 16:58:00 -0700 Subject: ACPI: turn off all debug output by default When CONFIG_ACPI_DEBUG=y, the default acpi_dbg_layer and acpi_dbg_level values built into the ACPI CA have some debug output enabled. We'd rather be quiet unless the user actually specified the acpi.debug_level argument. This enables distros to ship with CONFIG_ACPI_DEBUG=y without inundating users with debug output. Signed-off-by: Bjorn Helgaas Signed-off-by: Len Brown --- drivers/acpi/bus.c | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'drivers/acpi') diff --git a/drivers/acpi/bus.c b/drivers/acpi/bus.c index 765fd1c56cd..7edf6d913c1 100644 --- a/drivers/acpi/bus.c +++ b/drivers/acpi/bus.c @@ -688,6 +688,14 @@ void __init acpi_early_init(void) if (acpi_disabled) return; + /* + * ACPI CA initializes acpi_dbg_level to non-zero, which means + * we get debug output merely by turning on CONFIG_ACPI_DEBUG. + * Turn it off so we don't get output unless the user specifies + * acpi.debug_level. + */ + acpi_dbg_level = 0; + printk(KERN_INFO PREFIX "Core revision %08x\n", ACPI_CA_VERSION); /* enable workarounds, unless strict ACPI spec. compliance */ -- cgit v1.2.3 From a0d84a92df43b7206b9c1330a2cccf109cf0a41a Mon Sep 17 00:00:00 2001 From: Bjorn Helgaas Date: Fri, 7 Nov 2008 16:58:05 -0700 Subject: ACPI: update debug parameter documentation Reformat acpi.debug_layer and acpi.debug_level documentation so it's more readable, add some clues about how to figure out the mask bits that enable a specific ACPI_DEBUG_PRINT statement, and include some useful examples. Move the list of masks to Documentation/acpi/debug.txt (these are copies of the authoritative values in acoutput.h and acpi_drivers.h). Signed-off-by: Bjorn Helgaas Signed-off-by: Len Brown --- drivers/acpi/Kconfig | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) (limited to 'drivers/acpi') diff --git a/drivers/acpi/Kconfig b/drivers/acpi/Kconfig index 90cb2a823b5..b0243fd55ac 100644 --- a/drivers/acpi/Kconfig +++ b/drivers/acpi/Kconfig @@ -312,9 +312,13 @@ config ACPI_DEBUG bool "Debug Statements" default n help - The ACPI driver can optionally report errors with a great deal - of verbosity. Saying Y enables these statements. This will increase - your kernel size by around 50K. + The ACPI subsystem can produce debug output. Saying Y enables this + output and increases the kernel size by around 50K. + + Use the acpi.debug_layer and acpi.debug_level kernel command-line + parameters documented in Documentation/acpi/debug.txt and + Documentation/kernel-parameters.txt to control the type and + amount of debug output. config ACPI_DEBUG_FUNC_TRACE bool "Additionally enable ACPI function tracing" -- cgit v1.2.3 From a1a8d334f9e8c89a15bba8f34e443a37c29079c3 Mon Sep 17 00:00:00 2001 From: Lin Ming Date: Thu, 31 Jul 2008 23:02:28 +0200 Subject: Delete an unwanted return statement at evgpe.c Len's tree branch release-2.6.27, found an unwanted return statement at evgpe.c. (git://git.kernel.org/pub/scm/linux/kernel/git/lenb/linux-acpi-2.6 release-2.6.27) Signed-of-by Lin Ming Signed-off-by: Andi Kleen Signed-off-by: Len Brown --- drivers/acpi/events/evgpe.c | 2 -- 1 file changed, 2 deletions(-) (limited to 'drivers/acpi') diff --git a/drivers/acpi/events/evgpe.c b/drivers/acpi/events/evgpe.c index c5e53aae86f..f45c74fe745 100644 --- a/drivers/acpi/events/evgpe.c +++ b/drivers/acpi/events/evgpe.c @@ -289,8 +289,6 @@ acpi_status acpi_ev_disable_gpe(struct acpi_gpe_event_info *gpe_event_info) */ status = acpi_hw_low_disable_gpe(gpe_event_info); return_ACPI_STATUS(status); - - return_ACPI_STATUS(AE_OK); } /******************************************************************************* -- cgit v1.2.3 From 22c13f9d8179f4c9caecfcb60a95214562b9addc Mon Sep 17 00:00:00 2001 From: Thomas Renninger Date: Fri, 1 Aug 2008 17:37:54 +0200 Subject: ACPI: video: Ignore devices that aren't present in hardware This is a reimplemention of commit 0119509c4fbc9adcef1472817fda295334612976 from Matthew Garrett This patch got removed because of a regression: ThinkPads with a Intel graphics card and an Integrated Graphics Device BIOS implementation stopped working. In fact, they only worked because the ACPI device of the discrete, the wrong one, got used (via int10). So ACPI functions were poking on the wrong hardware used which is a sever bug. The next patch provides support for above ThinkPads to be able to switch brightness via the legacy thinkpad_acpi driver and automatically detect when to use it. Original commit message from Matthew Garrett: Vendors often ship machines with a choice of integrated or discrete graphics, and use the same DSDT for both. As a result, the ACPI video module will locate devices that may not exist on this specific platform. Attempt to determine whether the device exists or not, and abort the device creation if it doesn't. http://bugzilla.kernel.org/show_bug.cgi?id=9614 Signed-off-by: Thomas Renninger Acked-by: Zhang Rui Signed-off-by: Andi Kleen Signed-off-by: Len Brown --- drivers/acpi/glue.c | 40 ++++++++++++++++++++++++++++++++++++++++ drivers/acpi/video.c | 7 ++++++- 2 files changed, 46 insertions(+), 1 deletion(-) (limited to 'drivers/acpi') diff --git a/drivers/acpi/glue.c b/drivers/acpi/glue.c index 24649ada08d..adec3d15810 100644 --- a/drivers/acpi/glue.c +++ b/drivers/acpi/glue.c @@ -140,6 +140,46 @@ struct device *acpi_get_physical_device(acpi_handle handle) EXPORT_SYMBOL(acpi_get_physical_device); +/* ToDo: When a PCI bridge is found, return the PCI device behind the bridge + * This should work in general, but did not on a Lenovo T61 for the + * graphics card. But this must be fixed when the PCI device is + * bound and the kernel device struct is attached to the acpi device + * Note: A success call will increase reference count by one + * Do call put_device(dev) on the returned device then + */ +struct device *acpi_get_physical_pci_device(acpi_handle handle) +{ + struct device *dev; + long long device_id; + acpi_status status; + + status = + acpi_evaluate_integer(handle, "_ADR", NULL, &device_id); + + if (ACPI_FAILURE(status)) + return NULL; + + /* We need to attempt to determine whether the _ADR refers to a + PCI device or not. There's no terribly good way to do this, + so the best we can hope for is to assume that there'll never + be a device in the host bridge */ + if (device_id >= 0x10000) { + /* It looks like a PCI device. Does it exist? */ + dev = acpi_get_physical_device(handle); + } else { + /* It doesn't look like a PCI device. Does its parent + exist? */ + acpi_handle phandle; + if (acpi_get_parent(handle, &phandle)) + return NULL; + dev = acpi_get_physical_device(phandle); + } + if (!dev) + return NULL; + return dev; +} +EXPORT_SYMBOL(acpi_get_physical_pci_device); + static int acpi_bind_one(struct device *dev, acpi_handle handle) { struct acpi_device *acpi_dev; diff --git a/drivers/acpi/video.c b/drivers/acpi/video.c index a29b0ccac65..6597c2a37c3 100644 --- a/drivers/acpi/video.c +++ b/drivers/acpi/video.c @@ -842,11 +842,16 @@ static void acpi_video_bus_find_cap(struct acpi_video_bus *video) static int acpi_video_bus_check(struct acpi_video_bus *video) { acpi_status status = -ENOENT; - + struct device *dev; if (!video) return -EINVAL; + dev = acpi_get_physical_pci_device(video->device->handle); + if (!dev) + return -ENODEV; + put_device(dev); + /* Since there is no HID, CID and so on for VGA driver, we have * to check well known required nodes. */ -- cgit v1.2.3 From c3d6de698c84efdbdd3781b7058bcc339ab43da8 Mon Sep 17 00:00:00 2001 From: Thomas Renninger Date: Fri, 1 Aug 2008 17:37:55 +0200 Subject: ACPI video: if no ACPI backlight support, use vendor drivers If an ACPI graphics device supports backlight brightness functions (cmp. with latest ACPI spec Appendix B), let the ACPI video driver control backlight and switch backlight control off in vendor specific ACPI drivers (asus_acpi, thinkpad_acpi, eeepc, fujitsu_laptop, msi_laptop, sony_laptop, acer-wmi). Currently it is possible to load above drivers and let both poke on the brightness HW registers, the video and vendor specific ACPI drivers -> bad. This patch provides the basic support to check for BIOS capabilities before driver loading time. Driver specific modifications are in separate follow up patches. "acpi_backlight=vendor" Prever vendor driver over ACPI driver for backlight. "acpi_backlight=video" (default) Prever ACPI driver over vendor driver for backlight. Signed-off-by: Thomas Renninger Acked-by: Zhang Rui Signed-off-by: Andi Kleen Signed-off-by: Len Brown --- drivers/acpi/Makefile | 4 + drivers/acpi/scan.c | 32 +----- drivers/acpi/video.c | 28 +++-- drivers/acpi/video_detect.c | 268 ++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 289 insertions(+), 43 deletions(-) create mode 100644 drivers/acpi/video_detect.c (limited to 'drivers/acpi') diff --git a/drivers/acpi/Makefile b/drivers/acpi/Makefile index d91c027ece8..c03810aa19c 100644 --- a/drivers/acpi/Makefile +++ b/drivers/acpi/Makefile @@ -46,6 +46,10 @@ obj-$(CONFIG_ACPI_BUTTON) += button.o obj-$(CONFIG_ACPI_FAN) += fan.o obj-$(CONFIG_ACPI_DOCK) += dock.o obj-$(CONFIG_ACPI_VIDEO) += video.o +ifdef CONFIG_ACPI_VIDEO +obj-y += video_detect.o +endif + obj-y += pci_root.o pci_link.o pci_irq.o pci_bind.o obj-$(CONFIG_ACPI_PCI_SLOT) += pci_slot.o obj-$(CONFIG_ACPI_PROCESSOR) += processor.o diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c index a9dda8e0f9f..556b182001c 100644 --- a/drivers/acpi/scan.c +++ b/drivers/acpi/scan.c @@ -919,36 +919,6 @@ static void acpi_device_get_busid(struct acpi_device *device, } } -static int -acpi_video_bus_match(struct acpi_device *device) -{ - acpi_handle h_dummy; - - if (!device) - return -EINVAL; - - /* Since there is no HID, CID for ACPI Video drivers, we have - * to check well known required nodes for each feature we support. - */ - - /* Does this device able to support video switching ? */ - if (ACPI_SUCCESS(acpi_get_handle(device->handle, "_DOD", &h_dummy)) && - ACPI_SUCCESS(acpi_get_handle(device->handle, "_DOS", &h_dummy))) - return 0; - - /* Does this device able to retrieve a video ROM ? */ - if (ACPI_SUCCESS(acpi_get_handle(device->handle, "_ROM", &h_dummy))) - return 0; - - /* Does this device able to configure which video head to be POSTed ? */ - if (ACPI_SUCCESS(acpi_get_handle(device->handle, "_VPO", &h_dummy)) && - ACPI_SUCCESS(acpi_get_handle(device->handle, "_GPD", &h_dummy)) && - ACPI_SUCCESS(acpi_get_handle(device->handle, "_SPD", &h_dummy))) - return 0; - - return -ENODEV; -} - /* * acpi_bay_match - see if a device is an ejectable driver bay * @@ -1031,7 +1001,7 @@ static void acpi_device_set_id(struct acpi_device *device, will get autoloaded and the device might still match against another driver. */ - if (ACPI_SUCCESS(acpi_video_bus_match(device))) + if (acpi_is_video_device(device)) cid_add = ACPI_VIDEO_HID; else if (ACPI_SUCCESS(acpi_bay_match(device))) cid_add = ACPI_BAY_HID; diff --git a/drivers/acpi/video.c b/drivers/acpi/video.c index 6597c2a37c3..2097c399dd0 100644 --- a/drivers/acpi/video.c +++ b/drivers/acpi/video.c @@ -739,7 +739,8 @@ static void acpi_video_device_find_cap(struct acpi_video_device *device) device->cap._DSS = 1; } - max_level = acpi_video_init_brightness(device); + if (acpi_video_backlight_support()) + max_level = acpi_video_init_brightness(device); if (device->cap._BCL && device->cap._BCM && max_level > 0) { int result; @@ -785,18 +786,21 @@ static void acpi_video_device_find_cap(struct acpi_video_device *device) printk(KERN_ERR PREFIX "Create sysfs link\n"); } - if (device->cap._DCS && device->cap._DSS){ - static int count = 0; - char *name; - name = kzalloc(MAX_NAME_LEN, GFP_KERNEL); - if (!name) - return; - sprintf(name, "acpi_video%d", count++); - device->output_dev = video_output_register(name, - NULL, device, &acpi_output_properties); - kfree(name); + + if (acpi_video_display_switch_support()) { + + if (device->cap._DCS && device->cap._DSS) { + static int count; + char *name; + name = kzalloc(MAX_NAME_LEN, GFP_KERNEL); + if (!name) + return; + sprintf(name, "acpi_video%d", count++); + device->output_dev = video_output_register(name, + NULL, device, &acpi_output_properties); + kfree(name); + } } - return; } /* diff --git a/drivers/acpi/video_detect.c b/drivers/acpi/video_detect.c new file mode 100644 index 00000000000..70b1e91ae2a --- /dev/null +++ b/drivers/acpi/video_detect.c @@ -0,0 +1,268 @@ +/* + * Copyright (C) 2008 SuSE Linux Products GmbH + * Thomas Renninger + * + * May be copied or modified under the terms of the GNU General Public License + * + * video_detect.c: + * Provides acpi_is_video_device() for early scanning of ACPI devices in scan.c + * There a Linux specific (Spec does not provide a HID for video devices) is + * assinged + * + * After PCI devices are glued with ACPI devices + * acpi_get_physical_pci_device() can be called to identify ACPI graphics + * devices for which a real graphics card is plugged in + * + * Now acpi_video_get_capabilities() can be called to check which + * capabilities the graphics cards plugged in support. The check for general + * video capabilities will be triggered by the first caller of + * acpi_video_get_capabilities(NULL); which will happen when the first + * backlight (or display output) switching supporting driver calls: + * acpi_video_backlight_support(); + * + * Depending on whether ACPI graphics extensions (cmp. ACPI spec Appendix B) + * are available, video.ko should be used to handle the device. + * + * Otherwise vendor specific drivers like thinkpad_acpi, asus_acpi, + * sony_acpi,... can take care about backlight brightness and display output + * switching. + * + * If CONFIG_ACPI_VIDEO is neither set as "compiled in" (y) nor as a module (m) + * this file will not be compiled, acpi_video_get_capabilities() and + * acpi_video_backlight_support() will always return 0 and vendor specific + * drivers always can handle backlight. + * + */ + +#include +#include + +ACPI_MODULE_NAME("video"); +#define ACPI_VIDEO_COMPONENT 0x08000000 +#define _COMPONENT ACPI_VIDEO_COMPONENT + +static long acpi_video_support; +static bool acpi_video_caps_checked; + +static acpi_status +acpi_backlight_cap_match(acpi_handle handle, u32 level, void *context, + void **retyurn_value) +{ + long *cap = context; + acpi_handle h_dummy; + + if (ACPI_SUCCESS(acpi_get_handle(handle, "_BCM", &h_dummy)) && + ACPI_SUCCESS(acpi_get_handle(handle, "_BCL", &h_dummy))) { + ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Found generic backlight " + "support\n")); + *cap |= ACPI_VIDEO_BACKLIGHT; + /* We have backlight support, no need to scan further */ + return AE_CTRL_TERMINATE; + } + return 0; +} + +/* Returns true if the device is a video device which can be handled by + * video.ko. + * The device will get a Linux specific CID added in scan.c to + * identify the device as an ACPI graphics device + * Be aware that the graphics device may not be physically present + * Use acpi_video_get_capabilities() to detect general ACPI video + * capabilities of present cards + */ +long acpi_is_video_device(struct acpi_device *device) +{ + acpi_handle h_dummy; + long video_caps = 0; + + if (!device) + return 0; + + /* Does this device able to support video switching ? */ + if (ACPI_SUCCESS(acpi_get_handle(device->handle, "_DOD", &h_dummy)) && + ACPI_SUCCESS(acpi_get_handle(device->handle, "_DOS", &h_dummy))) + video_caps |= ACPI_VIDEO_OUTPUT_SWITCHING; + + /* Does this device able to retrieve a video ROM ? */ + if (ACPI_SUCCESS(acpi_get_handle(device->handle, "_ROM", &h_dummy))) + video_caps |= ACPI_VIDEO_ROM_AVAILABLE; + + /* Does this device able to configure which video head to be POSTed ? */ + if (ACPI_SUCCESS(acpi_get_handle(device->handle, "_VPO", &h_dummy)) && + ACPI_SUCCESS(acpi_get_handle(device->handle, "_GPD", &h_dummy)) && + ACPI_SUCCESS(acpi_get_handle(device->handle, "_SPD", &h_dummy))) + video_caps |= ACPI_VIDEO_DEVICE_POSTING; + + /* Only check for backlight functionality if one of the above hit. */ + if (video_caps) + acpi_walk_namespace(ACPI_TYPE_DEVICE, device->handle, + ACPI_UINT32_MAX, acpi_backlight_cap_match, + &video_caps, NULL); + + return video_caps; +} +EXPORT_SYMBOL(acpi_is_video_device); + +static acpi_status +find_video(acpi_handle handle, u32 lvl, void *context, void **rv) +{ + long *cap = context; + struct device *dev; + struct acpi_device *acpi_dev; + + const struct acpi_device_id video_ids[] = { + {ACPI_VIDEO_HID, 0}, + {"", 0}, + }; + if (acpi_bus_get_device(handle, &acpi_dev)) + return AE_OK; + + if (!acpi_match_device_ids(acpi_dev, video_ids)) { + dev = acpi_get_physical_pci_device(handle); + if (!dev) + return AE_OK; + put_device(dev); + *cap |= acpi_is_video_device(acpi_dev); + } + return AE_OK; +} + +/* + * Returns the video capabilities of a specific ACPI graphics device + * + * if NULL is passed as argument all ACPI devices are enumerated and + * all graphics capabilities of physically present devices are + * summerized and returned. This is cached and done only once. + */ +long acpi_video_get_capabilities(acpi_handle graphics_handle) +{ + long caps = 0; + struct acpi_device *tmp_dev; + acpi_status status; + + if (acpi_video_caps_checked && graphics_handle == NULL) + return acpi_video_support; + + if (!graphics_handle) { + /* Only do the global walk through all graphics devices once */ + acpi_walk_namespace(ACPI_TYPE_DEVICE, ACPI_ROOT_OBJECT, + ACPI_UINT32_MAX, find_video, + &caps, NULL); + /* There might be boot param flags set already... */ + acpi_video_support |= caps; + acpi_video_caps_checked = 1; + /* Add blacklists here. Be careful to use the right *DMI* bits + * to still be able to override logic via boot params, e.g.: + * + * if (dmi_name_in_vendors("XY")) { + * acpi_video_support |= + * ACPI_VIDEO_OUTPUT_SWITCHING_DMI_VENDOR; + * acpi_video_support |= + * ACPI_VIDEO_BACKLIGHT_DMI_VENDOR; + *} + */ + } else { + status = acpi_bus_get_device(graphics_handle, &tmp_dev); + if (ACPI_FAILURE(status)) { + ACPI_EXCEPTION((AE_INFO, status, "Invalid device")); + return 0; + } + acpi_walk_namespace(ACPI_TYPE_DEVICE, graphics_handle, + ACPI_UINT32_MAX, find_video, + &caps, NULL); + } + ACPI_DEBUG_PRINT((ACPI_DB_INFO, "We have 0x%lX video support %s %s\n", + graphics_handle ? caps : acpi_video_support, + graphics_handle ? "on device " : "in general", + graphics_handle ? acpi_device_bid(tmp_dev) : "")); + return caps; +} +EXPORT_SYMBOL(acpi_video_get_capabilities); + +/* Returns true if video.ko can do backlight switching */ +int acpi_video_backlight_support(void) +{ + /* + * We must check whether the ACPI graphics device is physically plugged + * in. Therefore this must be called after binding PCI and ACPI devices + */ + if (!acpi_video_caps_checked) + acpi_video_get_capabilities(NULL); + + /* First check for boot param -> highest prio */ + if (acpi_video_support & ACPI_VIDEO_BACKLIGHT_FORCE_VENDOR) + return 0; + else if (acpi_video_support & ACPI_VIDEO_BACKLIGHT_FORCE_VIDEO) + return 1; + + /* Then check for DMI blacklist -> second highest prio */ + if (acpi_video_support & ACPI_VIDEO_BACKLIGHT_DMI_VENDOR) + return 0; + else if (acpi_video_support & ACPI_VIDEO_BACKLIGHT_DMI_VIDEO) + return 1; + + /* Then go the default way */ + return acpi_video_support & ACPI_VIDEO_BACKLIGHT; +} +EXPORT_SYMBOL(acpi_video_backlight_support); + +/* + * Returns true if video.ko can do display output switching. + * This does not work well/at all with binary graphics drivers + * which disable system io ranges and do it on their own. + */ +int acpi_video_display_switch_support(void) +{ + if (!acpi_video_caps_checked) + acpi_video_get_capabilities(NULL); + + if (acpi_video_support & ACPI_VIDEO_OUTPUT_SWITCHING_FORCE_VENDOR) + return 0; + else if (acpi_video_support & ACPI_VIDEO_OUTPUT_SWITCHING_FORCE_VIDEO) + return 1; + + if (acpi_video_support & ACPI_VIDEO_OUTPUT_SWITCHING_DMI_VENDOR) + return 0; + else if (acpi_video_support & ACPI_VIDEO_OUTPUT_SWITCHING_DMI_VIDEO) + return 1; + + return acpi_video_support & ACPI_VIDEO_OUTPUT_SWITCHING; +} +EXPORT_SYMBOL(acpi_video_display_switch_support); + +/* + * Use acpi_display_output=vendor/video or acpi_backlight=vendor/video + * To force that backlight or display output switching is processed by vendor + * specific acpi drivers or video.ko driver. + */ +int __init acpi_backlight(char *str) +{ + if (str == NULL || *str == '\0') + return 1; + else { + if (!strcmp("vendor", str)) + acpi_video_support |= + ACPI_VIDEO_BACKLIGHT_FORCE_VENDOR; + if (!strcmp("video", str)) + acpi_video_support |= + ACPI_VIDEO_OUTPUT_SWITCHING_FORCE_VIDEO; + } + return 1; +} +__setup("acpi_backlight=", acpi_backlight); + +int __init acpi_display_output(char *str) +{ + if (str == NULL || *str == '\0') + return 1; + else { + if (!strcmp("vendor", str)) + acpi_video_support |= + ACPI_VIDEO_OUTPUT_SWITCHING_FORCE_VENDOR; + if (!strcmp("video", str)) + acpi_video_support |= + ACPI_VIDEO_OUTPUT_SWITCHING_FORCE_VIDEO; + } + return 1; +} +__setup("acpi_display_output=", acpi_display_output); -- cgit v1.2.3 From 1cfe62c8010ac56e1bd3827e30386a87cc2f3594 Mon Sep 17 00:00:00 2001 From: Alexey Starikovskiy Date: Tue, 28 Oct 2008 00:35:30 +0300 Subject: ACPI: EC: revert msleep patch With the better solution for EC interrupt storm issue, there is no need to use msleep over udelay. References: http://bugzilla.kernel.org/show_bug.cgi?id=11810 http://bugzilla.kernel.org/show_bug.cgi?id=10724 Signed-off-by: Alexey Starikovskiy Signed-off-by: Len Brown --- drivers/acpi/ec.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers/acpi') diff --git a/drivers/acpi/ec.c b/drivers/acpi/ec.c index ef42316f89f..3ef5b796a68 100644 --- a/drivers/acpi/ec.c +++ b/drivers/acpi/ec.c @@ -239,10 +239,10 @@ static int ec_check_sci(struct acpi_ec *ec, u8 state) static int ec_poll(struct acpi_ec *ec) { unsigned long delay = jiffies + msecs_to_jiffies(ACPI_EC_DELAY); - msleep(1); + udelay(ACPI_EC_UDELAY); while (time_before(jiffies, delay)) { gpe_transaction(ec, acpi_ec_read_status(ec)); - msleep(1); + udelay(ACPI_EC_UDELAY); if (ec_transaction_done(ec)) return 0; } -- cgit v1.2.3 From f8248434e6a11d7cd314281be3b39bbcf82fc243 Mon Sep 17 00:00:00 2001 From: Alan Jenkins Date: Sat, 1 Nov 2008 11:05:26 +0000 Subject: ACPI: EC: make kernel messages more useful when GPE storm is detected Make sure we can tell if the GPE storm workaround gets activated, and avoid flooding the logs afterwards. http://bugzilla.kernel.org/show_bug.cgi?id=11841 "plenty of line "ACPI: EC: non-query interrupt received, switching to interrupt mode" in dmesg" Signed-off-by: Alan Jenkins Acked-by: Alexey Starikovskiy Signed-off-by: Len Brown --- drivers/acpi/ec.c | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) (limited to 'drivers/acpi') diff --git a/drivers/acpi/ec.c b/drivers/acpi/ec.c index 3ef5b796a68..b340e08cf1d 100644 --- a/drivers/acpi/ec.c +++ b/drivers/acpi/ec.c @@ -286,7 +286,8 @@ static int acpi_ec_transaction_unlocked(struct acpi_ec *ec, acpi_enable_gpe(NULL, ec->gpe, ACPI_NOT_ISR); } else if (test_bit(EC_FLAGS_GPE_MODE, &ec->flags) && t->irq_count > ACPI_EC_STORM_THRESHOLD) { - pr_debug(PREFIX "GPE storm detected\n"); + pr_info(PREFIX "GPE storm detected, " + "transactions will use polling mode\n"); set_bit(EC_FLAGS_GPE_STORM, &ec->flags); } return ret; @@ -566,9 +567,15 @@ static u32 acpi_ec_gpe_handler(void *data) if (!test_bit(EC_FLAGS_GPE_MODE, &ec->flags) && !test_bit(EC_FLAGS_NO_GPE, &ec->flags)) { /* this is non-query, must be confirmation */ - if (printk_ratelimit()) - pr_info(PREFIX "non-query interrupt received," + if (!test_bit(EC_FLAGS_GPE_STORM, &ec->flags)) { + if (printk_ratelimit()) + pr_info(PREFIX "non-query interrupt received," + " switching to interrupt mode\n"); + } else { + /* hush, STORM switches the mode every transaction */ + pr_debug(PREFIX "non-query interrupt received," " switching to interrupt mode\n"); + } set_bit(EC_FLAGS_GPE_MODE, &ec->flags); } return ACPI_INTERRUPT_HANDLED; -- cgit v1.2.3 From dd15f8c42af09031e27da5b4d697ce925511f2e1 Mon Sep 17 00:00:00 2001 From: Alexey Starikovskiy Date: Sat, 8 Nov 2008 21:42:30 +0300 Subject: ACPI: EC: wait for last write gpe There is a possibility that EC might break if next command is issued within 1 us after write or burst-disable command. Suggestd-by: Zhao Yakui Signed-off-by: Alexey Starikovskiy Signed-off-by: Len Brown --- drivers/acpi/ec.c | 21 +++++++++++++-------- 1 file changed, 13 insertions(+), 8 deletions(-) (limited to 'drivers/acpi') diff --git a/drivers/acpi/ec.c b/drivers/acpi/ec.c index b340e08cf1d..cebd65d2e2a 100644 --- a/drivers/acpi/ec.c +++ b/drivers/acpi/ec.c @@ -102,6 +102,7 @@ struct transaction { u8 command; u8 wlen; u8 rlen; + bool done; }; static struct acpi_ec { @@ -178,7 +179,7 @@ static int ec_transaction_done(struct acpi_ec *ec) unsigned long flags; int ret = 0; spin_lock_irqsave(&ec->curr_lock, flags); - if (!ec->curr || (!ec->curr->wlen && !ec->curr->rlen)) + if (!ec->curr || ec->curr->done) ret = 1; spin_unlock_irqrestore(&ec->curr_lock, flags); return ret; @@ -195,17 +196,20 @@ static void gpe_transaction(struct acpi_ec *ec, u8 status) acpi_ec_write_data(ec, *(ec->curr->wdata++)); --ec->curr->wlen; } else - /* false interrupt, state didn't change */ - ++ec->curr->irq_count; - + goto err; } else if (ec->curr->rlen > 0) { if ((status & ACPI_EC_FLAG_OBF) == 1) { *(ec->curr->rdata++) = acpi_ec_read_data(ec); - --ec->curr->rlen; + if (--ec->curr->rlen == 0) + ec->curr->done = true; } else - /* false interrupt, state didn't change */ - ++ec->curr->irq_count; - } + goto err; + } else if (ec->curr->wlen == 0 && (status & ACPI_EC_FLAG_IBF) == 0) + ec->curr->done = true; + goto unlock; +err: + /* false interrupt, state didn't change */ + ++ec->curr->irq_count; unlock: spin_unlock_irqrestore(&ec->curr_lock, flags); } @@ -265,6 +269,7 @@ static int acpi_ec_transaction_unlocked(struct acpi_ec *ec, spin_lock_irqsave(&ec->curr_lock, tmp); /* following two actions should be kept atomic */ t->irq_count = 0; + t->done = false; ec->curr = t; acpi_ec_write_cmd(ec, ec->curr->command); if (ec->curr->command == ACPI_EC_COMMAND_QUERY) -- cgit v1.2.3 From a2f93aeadf97e870ff385030633a73e21146815d Mon Sep 17 00:00:00 2001 From: Alexey Starikovskiy Date: Wed, 12 Nov 2008 01:40:19 +0300 Subject: ACPI: EC: restart failed command Restart current transaction if we recieved unexpected GPEs instead of needed ones. http://bugzilla.kernel.org/show_bug.cgi?id=11896 Signed-off-by: Alexey Starikovskiy Signed-off-by: Len Brown --- drivers/acpi/ec.c | 41 +++++++++++++++++++++++++++++------------ 1 file changed, 29 insertions(+), 12 deletions(-) (limited to 'drivers/acpi') diff --git a/drivers/acpi/ec.c b/drivers/acpi/ec.c index cebd65d2e2a..34c67ca3beb 100644 --- a/drivers/acpi/ec.c +++ b/drivers/acpi/ec.c @@ -100,6 +100,8 @@ struct transaction { u8 *rdata; unsigned short irq_count; u8 command; + u8 wi; + u8 ri; u8 wlen; u8 rlen; bool done; @@ -185,26 +187,34 @@ static int ec_transaction_done(struct acpi_ec *ec) return ret; } +static void start_transaction(struct acpi_ec *ec) +{ + ec->curr->irq_count = ec->curr->wi = ec->curr->ri = 0; + ec->curr->done = false; + acpi_ec_write_cmd(ec, ec->curr->command); +} + static void gpe_transaction(struct acpi_ec *ec, u8 status) { unsigned long flags; spin_lock_irqsave(&ec->curr_lock, flags); if (!ec->curr) goto unlock; - if (ec->curr->wlen > 0) { - if ((status & ACPI_EC_FLAG_IBF) == 0) { - acpi_ec_write_data(ec, *(ec->curr->wdata++)); - --ec->curr->wlen; - } else + if (ec->curr->wlen > ec->curr->wi) { + if ((status & ACPI_EC_FLAG_IBF) == 0) + acpi_ec_write_data(ec, + ec->curr->wdata[ec->curr->wi++]); + else goto err; - } else if (ec->curr->rlen > 0) { + } else if (ec->curr->rlen > ec->curr->ri) { if ((status & ACPI_EC_FLAG_OBF) == 1) { - *(ec->curr->rdata++) = acpi_ec_read_data(ec); - if (--ec->curr->rlen == 0) + ec->curr->rdata[ec->curr->ri++] = acpi_ec_read_data(ec); + if (ec->curr->rlen == ec->curr->ri) ec->curr->done = true; } else goto err; - } else if (ec->curr->wlen == 0 && (status & ACPI_EC_FLAG_IBF) == 0) + } else if (ec->curr->wlen == ec->curr->wi && + (status & ACPI_EC_FLAG_IBF) == 0) ec->curr->done = true; goto unlock; err: @@ -219,6 +229,15 @@ static int acpi_ec_wait(struct acpi_ec *ec) if (wait_event_timeout(ec->wait, ec_transaction_done(ec), msecs_to_jiffies(ACPI_EC_DELAY))) return 0; + /* try restart command if we get any false interrupts */ + if (ec->curr->irq_count && + (acpi_ec_read_status(ec) & ACPI_EC_FLAG_IBF) == 0) { + pr_debug(PREFIX "controller reset, restart transaction\n"); + start_transaction(ec); + if (wait_event_timeout(ec->wait, ec_transaction_done(ec), + msecs_to_jiffies(ACPI_EC_DELAY))) + return 0; + } /* missing GPEs, switch back to poll mode */ if (printk_ratelimit()) pr_info(PREFIX "missing confirmations, " @@ -268,10 +287,8 @@ static int acpi_ec_transaction_unlocked(struct acpi_ec *ec, /* start transaction */ spin_lock_irqsave(&ec->curr_lock, tmp); /* following two actions should be kept atomic */ - t->irq_count = 0; - t->done = false; ec->curr = t; - acpi_ec_write_cmd(ec, ec->curr->command); + start_transaction(ec); if (ec->curr->command == ACPI_EC_COMMAND_QUERY) clear_bit(EC_FLAGS_QUERY_PENDING, &ec->flags); spin_unlock_irqrestore(&ec->curr_lock, tmp); -- cgit v1.2.3 From 0b7084ac67fb84f0cf2f8bc02d7e0dea8521dd2d Mon Sep 17 00:00:00 2001 From: Alexey Starikovskiy Date: Sat, 25 Oct 2008 21:48:46 +0400 Subject: ACPICA: Use spinlock for acpi_{en|dis}able_gpe Disabling gpe might interfere with gpe detection/handling, thus producing "interrupt not handled" errors. Ironically, disabling of GPE from interrupt context is already under spinlock, so only userspace needs to start using it. Signed-off-by: Alexey Starikovskiy Signed-off-by: Len Brown --- drivers/acpi/button.c | 2 +- drivers/acpi/ec.c | 10 +++++----- drivers/acpi/events/evxfevnt.c | 35 +++++++++-------------------------- drivers/acpi/sleep/wakeup.c | 8 ++++---- drivers/acpi/system.c | 4 ++-- 5 files changed, 21 insertions(+), 38 deletions(-) (limited to 'drivers/acpi') diff --git a/drivers/acpi/button.c b/drivers/acpi/button.c index cb046c3fc3f..eb6bf3025f9 100644 --- a/drivers/acpi/button.c +++ b/drivers/acpi/button.c @@ -479,7 +479,7 @@ static int acpi_button_add(struct acpi_device *device) device->wakeup.gpe_number, ACPI_GPE_TYPE_WAKE_RUN); acpi_enable_gpe(device->wakeup.gpe_device, - device->wakeup.gpe_number, ACPI_NOT_ISR); + device->wakeup.gpe_number); device->wakeup.state.enabled = 1; } diff --git a/drivers/acpi/ec.c b/drivers/acpi/ec.c index 34c67ca3beb..89d6d2868e8 100644 --- a/drivers/acpi/ec.c +++ b/drivers/acpi/ec.c @@ -282,7 +282,7 @@ static int acpi_ec_transaction_unlocked(struct acpi_ec *ec, /* disable GPE during transaction if storm is detected */ if (test_bit(EC_FLAGS_GPE_STORM, &ec->flags)) { clear_bit(EC_FLAGS_GPE_MODE, &ec->flags); - acpi_disable_gpe(NULL, ec->gpe, ACPI_NOT_ISR); + acpi_disable_gpe(NULL, ec->gpe); } /* start transaction */ spin_lock_irqsave(&ec->curr_lock, tmp); @@ -305,7 +305,7 @@ static int acpi_ec_transaction_unlocked(struct acpi_ec *ec, /* check if we received SCI during transaction */ ec_check_sci(ec, acpi_ec_read_status(ec)); /* it is safe to enable GPE outside of transaction */ - acpi_enable_gpe(NULL, ec->gpe, ACPI_NOT_ISR); + acpi_enable_gpe(NULL, ec->gpe); } else if (test_bit(EC_FLAGS_GPE_MODE, &ec->flags) && t->irq_count > ACPI_EC_STORM_THRESHOLD) { pr_info(PREFIX "GPE storm detected, " @@ -897,7 +897,7 @@ static int ec_install_handlers(struct acpi_ec *ec) if (ACPI_FAILURE(status)) return -ENODEV; acpi_set_gpe_type(NULL, ec->gpe, ACPI_GPE_TYPE_RUNTIME); - acpi_enable_gpe(NULL, ec->gpe, ACPI_NOT_ISR); + acpi_enable_gpe(NULL, ec->gpe); status = acpi_install_address_space_handler(ec->handle, ACPI_ADR_SPACE_EC, &acpi_ec_space_handler, @@ -1036,7 +1036,7 @@ static int acpi_ec_suspend(struct acpi_device *device, pm_message_t state) /* Stop using GPE */ set_bit(EC_FLAGS_NO_GPE, &ec->flags); clear_bit(EC_FLAGS_GPE_MODE, &ec->flags); - acpi_disable_gpe(NULL, ec->gpe, ACPI_NOT_ISR); + acpi_disable_gpe(NULL, ec->gpe); return 0; } @@ -1045,7 +1045,7 @@ static int acpi_ec_resume(struct acpi_device *device) struct acpi_ec *ec = acpi_driver_data(device); /* Enable use of GPE back */ clear_bit(EC_FLAGS_NO_GPE, &ec->flags); - acpi_enable_gpe(NULL, ec->gpe, ACPI_NOT_ISR); + acpi_enable_gpe(NULL, ec->gpe); return 0; } diff --git a/drivers/acpi/events/evxfevnt.c b/drivers/acpi/events/evxfevnt.c index 73bfd6bf962..39db00874a2 100644 --- a/drivers/acpi/events/evxfevnt.c +++ b/drivers/acpi/events/evxfevnt.c @@ -248,21 +248,15 @@ ACPI_EXPORT_SYMBOL(acpi_set_gpe_type) * DESCRIPTION: Enable an ACPI event (general purpose) * ******************************************************************************/ -acpi_status acpi_enable_gpe(acpi_handle gpe_device, u32 gpe_number, u32 flags) +acpi_status acpi_enable_gpe(acpi_handle gpe_device, u32 gpe_number) { acpi_status status = AE_OK; + acpi_cpu_flags flags; struct acpi_gpe_event_info *gpe_event_info; ACPI_FUNCTION_TRACE(acpi_enable_gpe); - /* Use semaphore lock if not executing at interrupt level */ - - if (flags & ACPI_NOT_ISR) { - status = acpi_ut_acquire_mutex(ACPI_MTX_EVENTS); - if (ACPI_FAILURE(status)) { - return_ACPI_STATUS(status); - } - } + flags = acpi_os_acquire_lock(acpi_gbl_gpe_lock); /* Ensure that we have a valid GPE number */ @@ -277,9 +271,7 @@ acpi_status acpi_enable_gpe(acpi_handle gpe_device, u32 gpe_number, u32 flags) status = acpi_ev_enable_gpe(gpe_event_info, TRUE); unlock_and_exit: - if (flags & ACPI_NOT_ISR) { - (void)acpi_ut_release_mutex(ACPI_MTX_EVENTS); - } + acpi_os_release_lock(acpi_gbl_gpe_lock, flags); return_ACPI_STATUS(status); } @@ -299,22 +291,15 @@ ACPI_EXPORT_SYMBOL(acpi_enable_gpe) * DESCRIPTION: Disable an ACPI event (general purpose) * ******************************************************************************/ -acpi_status acpi_disable_gpe(acpi_handle gpe_device, u32 gpe_number, u32 flags) +acpi_status acpi_disable_gpe(acpi_handle gpe_device, u32 gpe_number) { acpi_status status = AE_OK; + acpi_cpu_flags flags; struct acpi_gpe_event_info *gpe_event_info; ACPI_FUNCTION_TRACE(acpi_disable_gpe); - /* Use semaphore lock if not executing at interrupt level */ - - if (flags & ACPI_NOT_ISR) { - status = acpi_ut_acquire_mutex(ACPI_MTX_EVENTS); - if (ACPI_FAILURE(status)) { - return_ACPI_STATUS(status); - } - } - + flags = acpi_os_acquire_lock(acpi_gbl_gpe_lock); /* Ensure that we have a valid GPE number */ gpe_event_info = acpi_ev_get_gpe_event_info(gpe_device, gpe_number); @@ -325,10 +310,8 @@ acpi_status acpi_disable_gpe(acpi_handle gpe_device, u32 gpe_number, u32 flags) status = acpi_ev_disable_gpe(gpe_event_info); - unlock_and_exit: - if (flags & ACPI_NOT_ISR) { - (void)acpi_ut_release_mutex(ACPI_MTX_EVENTS); - } +unlock_and_exit: + acpi_os_release_lock(acpi_gbl_gpe_lock, flags); return_ACPI_STATUS(status); } diff --git a/drivers/acpi/sleep/wakeup.c b/drivers/acpi/sleep/wakeup.c index 38655eb132d..dea4c23df76 100644 --- a/drivers/acpi/sleep/wakeup.c +++ b/drivers/acpi/sleep/wakeup.c @@ -88,7 +88,7 @@ void acpi_enable_wakeup_device(u8 sleep_state) spin_unlock(&acpi_device_lock); if (!dev->wakeup.flags.run_wake) acpi_enable_gpe(dev->wakeup.gpe_device, - dev->wakeup.gpe_number, ACPI_ISR); + dev->wakeup.gpe_number); spin_lock(&acpi_device_lock); } spin_unlock(&acpi_device_lock); @@ -122,7 +122,7 @@ void acpi_disable_wakeup_device(u8 sleep_state) ACPI_GPE_TYPE_WAKE_RUN); /* Re-enable it, since set_gpe_type will disable it */ acpi_enable_gpe(dev->wakeup.gpe_device, - dev->wakeup.gpe_number, ACPI_NOT_ISR); + dev->wakeup.gpe_number); spin_lock(&acpi_device_lock); } continue; @@ -133,7 +133,7 @@ void acpi_disable_wakeup_device(u8 sleep_state) /* Never disable run-wake GPE */ if (!dev->wakeup.flags.run_wake) { acpi_disable_gpe(dev->wakeup.gpe_device, - dev->wakeup.gpe_number, ACPI_NOT_ISR); + dev->wakeup.gpe_number); acpi_clear_gpe(dev->wakeup.gpe_device, dev->wakeup.gpe_number, ACPI_NOT_ISR); } @@ -162,7 +162,7 @@ static int __init acpi_wakeup_device_init(void) dev->wakeup.gpe_number, ACPI_GPE_TYPE_WAKE_RUN); acpi_enable_gpe(dev->wakeup.gpe_device, - dev->wakeup.gpe_number, ACPI_NOT_ISR); + dev->wakeup.gpe_number); dev->wakeup.state.enabled = 1; spin_lock(&acpi_device_lock); } diff --git a/drivers/acpi/system.c b/drivers/acpi/system.c index 1d74171b794..11995b612ad 100644 --- a/drivers/acpi/system.c +++ b/drivers/acpi/system.c @@ -394,10 +394,10 @@ static ssize_t counter_set(struct kobject *kobj, if (index < num_gpes) { if (!strcmp(buf, "disable\n") && (status & ACPI_EVENT_FLAG_ENABLED)) - result = acpi_disable_gpe(handle, index, ACPI_NOT_ISR); + result = acpi_disable_gpe(handle, index); else if (!strcmp(buf, "enable\n") && !(status & ACPI_EVENT_FLAG_ENABLED)) - result = acpi_enable_gpe(handle, index, ACPI_NOT_ISR); + result = acpi_enable_gpe(handle, index); else if (!strcmp(buf, "clear\n") && (status & ACPI_EVENT_FLAG_SET)) result = acpi_clear_gpe(handle, index, ACPI_NOT_ISR); -- cgit v1.2.3 From 06cf7d3c7af902939cd1754abcafb2464060cba8 Mon Sep 17 00:00:00 2001 From: Alexey Starikovskiy Date: Sun, 9 Nov 2008 19:01:06 +0300 Subject: ACPI: EC: lower interrupt storm treshold http://bugzilla.kernel.org/show_bug.cgi?id=11892 Signed-off-by: Alexey Starikovskiy Signed-off-by: Len Brown --- drivers/acpi/ec.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/acpi') diff --git a/drivers/acpi/ec.c b/drivers/acpi/ec.c index 89d6d2868e8..ab84f99f136 100644 --- a/drivers/acpi/ec.c +++ b/drivers/acpi/ec.c @@ -70,7 +70,7 @@ enum ec_command { #define ACPI_EC_UDELAY_GLK 1000 /* Wait 1ms max. to get global lock */ #define ACPI_EC_UDELAY 100 /* Wait 100us before polling EC again */ -#define ACPI_EC_STORM_THRESHOLD 20 /* number of false interrupts +#define ACPI_EC_STORM_THRESHOLD 8 /* number of false interrupts per one transaction */ enum { -- cgit v1.2.3 From 8517934ef6aaa28d6e055b98df65b31cedbd1372 Mon Sep 17 00:00:00 2001 From: Alexey Starikovskiy Date: Tue, 11 Nov 2008 12:54:11 +0300 Subject: ACPI: EC: Don't do transaction from GPE handler in poll mode. Referencies: http://bugzilla.kernel.org/show_bug.cgi?id=12004 Signed-off-by: Alexey Starikovskiy Signed-off-by: Len Brown --- drivers/acpi/ec.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) (limited to 'drivers/acpi') diff --git a/drivers/acpi/ec.c b/drivers/acpi/ec.c index ab84f99f136..bd1af3e9e4c 100644 --- a/drivers/acpi/ec.c +++ b/drivers/acpi/ec.c @@ -581,9 +581,12 @@ static u32 acpi_ec_gpe_handler(void *data) pr_debug(PREFIX "~~~> interrupt\n"); status = acpi_ec_read_status(ec); - gpe_transaction(ec, status); - if (ec_transaction_done(ec) && (status & ACPI_EC_FLAG_IBF) == 0) - wake_up(&ec->wait); + if (test_bit(EC_FLAGS_GPE_MODE, &ec->flags)) { + gpe_transaction(ec, status); + if (ec_transaction_done(ec) && + (status & ACPI_EC_FLAG_IBF) == 0) + wake_up(&ec->wait); + } ec_check_sci(ec, status); if (!test_bit(EC_FLAGS_GPE_MODE, &ec->flags) && -- cgit v1.2.3 From 32836259ff25ce97010569706cd33ba94de81d62 Mon Sep 17 00:00:00 2001 From: Bjorn Helgaas Date: Wed, 5 Nov 2008 16:17:52 -0700 Subject: ACPI: pci_link: remove acpi_irq_balance_set() interface This removes the acpi_irq_balance_set() interface from the PCI interrupt link driver. x86 used acpi_irq_balance_set() to tell the PCI interrupt link driver to configure links to minimize IRQ sharing. But the link driver can easily figure out whether to turn on IRQ balancing based on the IRQ model (PIC/IOAPIC/etc), so we can get rid of that external interface. It's better for the driver to figure this out at init-time. If we set it externally via the x86 code, the interface reduces modularity, and we depend on the fact that acpi_process_madt() happens before we process the kernel command line. Signed-off-by: Bjorn Helgaas Signed-off-by: Len Brown --- drivers/acpi/pci_link.c | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) (limited to 'drivers/acpi') diff --git a/drivers/acpi/pci_link.c b/drivers/acpi/pci_link.c index fcfdef7b4fd..e52ad91ce2d 100644 --- a/drivers/acpi/pci_link.c +++ b/drivers/acpi/pci_link.c @@ -531,7 +531,7 @@ int __init acpi_irq_penalty_init(void) return 0; } -static int acpi_irq_balance; /* 0: static, 1: balance */ +static int acpi_irq_balance = -1; /* 0: static, 1: balance */ static int acpi_pci_link_allocate(struct acpi_pci_link *link) { @@ -950,10 +950,17 @@ device_initcall(irqrouter_init_sysfs); static int __init acpi_pci_link_init(void) { - if (acpi_noirq) return 0; + if (acpi_irq_balance == -1) { + /* no command line switch: enable balancing in IOAPIC mode */ + if (acpi_irq_model == ACPI_IRQ_MODEL_IOAPIC) + acpi_irq_balance = 1; + else + acpi_irq_balance = 0; + } + acpi_link.count = 0; INIT_LIST_HEAD(&acpi_link.entries); -- cgit v1.2.3 From 77fb61a04a0483ad274ce5c51b02c46c12db3693 Mon Sep 17 00:00:00 2001 From: Linus Torvalds Date: Sun, 16 Nov 2008 10:09:34 -0800 Subject: acpi: fix oops in acpi_system_wakeup_device_seq_show MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Commit 0794469da3f7b2093575cbdfc1108308dd3641ce: ("ACPI: struct device - replace bus_id with dev_name(), dev_set_name()") introduced a bug by testing 'dev_name(ldev)' instead of 'ldev->bus' for NULL when printing out the bus information. So if ldev->bus was NULL, we'd oops. Reported-and-tested-by: Bruno Prémont Cc: Kay Sievers Cc: Len Brown Cc: Greg Kroah-Hartman Signed-off-by: Linus Torvalds --- drivers/acpi/sleep/proc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/acpi') diff --git a/drivers/acpi/sleep/proc.c b/drivers/acpi/sleep/proc.c index 64e591ba86f..4dbc2271acf 100644 --- a/drivers/acpi/sleep/proc.c +++ b/drivers/acpi/sleep/proc.c @@ -366,7 +366,7 @@ acpi_system_wakeup_device_seq_show(struct seq_file *seq, void *offset) dev->wakeup.state.enabled ? "enabled" : "disabled"); if (ldev) seq_printf(seq, "%s:%s", - dev_name(ldev) ? ldev->bus->name : "no-bus", + ldev->bus ? ldev->bus->name : "no-bus", dev_name(ldev)); seq_printf(seq, "\n"); put_device(ldev); -- cgit v1.2.3 From 7b4d469228a92a00e412675817cedd60133de38a Mon Sep 17 00:00:00 2001 From: Alexey Starikovskiy Date: Thu, 13 Nov 2008 12:00:03 +0300 Subject: ACPI: EC: count interrupts only if called from interrupt handler. fix 2.6.28 EC interrupt storm regression Signed-off-by: Alexey Starikovskiy Signed-off-by: Len Brown --- drivers/acpi/ec.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'drivers/acpi') diff --git a/drivers/acpi/ec.c b/drivers/acpi/ec.c index cf41f9fc24a..30f3ef236ec 100644 --- a/drivers/acpi/ec.c +++ b/drivers/acpi/ec.c @@ -219,7 +219,8 @@ static void gpe_transaction(struct acpi_ec *ec, u8 status) goto unlock; err: /* false interrupt, state didn't change */ - ++ec->curr->irq_count; + if (in_interrupt()) + ++ec->curr->irq_count; unlock: spin_unlock_irqrestore(&ec->curr_lock, flags); } -- cgit v1.2.3 From 558073dd56707864f09d563b64e7c37c021e89d2 Mon Sep 17 00:00:00 2001 From: Alexey Starikovskiy Date: Fri, 21 Nov 2008 22:41:01 +0800 Subject: ACPI: battery: Convert discharge energy rate to current properly ACPI battery interface reports its state either in mW or in mA, and discharge rate in your case is reported in mW. power_supply interface does not have such a parameter, so current_now parameter is used for all cases. But in case of mW, reported discharge should be converted into mA. Signed-off-by: Alexey Starikovskiy Tested-by: Ferenc Wagner Signed-off-by: Len Brown --- drivers/acpi/battery.c | 9 +++++++++ 1 file changed, 9 insertions(+) (limited to 'drivers/acpi') diff --git a/drivers/acpi/battery.c b/drivers/acpi/battery.c index 1423b0c0cd2..a0a178dd189 100644 --- a/drivers/acpi/battery.c +++ b/drivers/acpi/battery.c @@ -174,6 +174,15 @@ static int acpi_battery_get_property(struct power_supply *psy, break; case POWER_SUPPLY_PROP_CURRENT_NOW: val->intval = battery->current_now * 1000; + /* if power units are mW, convert to mA by + dividing by current voltage (mV/1000) */ + if (!battery->power_unit) { + if (battery->voltage_now) { + val->intval /= battery->voltage_now; + val->intval *= 1000; + } else + val->intval = -1; + } break; case POWER_SUPPLY_PROP_CHARGE_FULL_DESIGN: case POWER_SUPPLY_PROP_ENERGY_FULL_DESIGN: -- cgit v1.2.3 From 40599072dca3ec7d4c9ff8271978be169f974638 Mon Sep 17 00:00:00 2001 From: Pavel Machek Date: Tue, 25 Nov 2008 12:05:08 +0100 Subject: ACPI: scheduling in atomic via acpi_evaluate_integer () Now I know why I had strange "scheduling in atomic" problems: acpi_evaluate_integer() does malloc(..., irqs_disabled() ? GFP_ATOMIC : GFP_KERNEL)... which is (of course) broken. There's no way to reliably tell if we need GFP_ATOMIC or not from code, this one for example fails to detect spinlocks held. Fortunately, allocation seems small enough to be done on stack. Signed-off-by: Pavel Machek Acked-by: Bob Moore Signed-off-by: Len Brown --- drivers/acpi/utils.c | 16 ++++------------ 1 file changed, 4 insertions(+), 12 deletions(-) (limited to 'drivers/acpi') diff --git a/drivers/acpi/utils.c b/drivers/acpi/utils.c index e827be36ee8..f844941089b 100644 --- a/drivers/acpi/utils.c +++ b/drivers/acpi/utils.c @@ -259,34 +259,26 @@ acpi_evaluate_integer(acpi_handle handle, struct acpi_object_list *arguments, unsigned long long *data) { acpi_status status = AE_OK; - union acpi_object *element; + union acpi_object element; struct acpi_buffer buffer = { 0, NULL }; - if (!data) return AE_BAD_PARAMETER; - element = kzalloc(sizeof(union acpi_object), irqs_disabled() ? GFP_ATOMIC: GFP_KERNEL); - if (!element) - return AE_NO_MEMORY; - buffer.length = sizeof(union acpi_object); - buffer.pointer = element; + buffer.pointer = &element; status = acpi_evaluate_object(handle, pathname, arguments, &buffer); if (ACPI_FAILURE(status)) { acpi_util_eval_error(handle, pathname, status); - kfree(element); return status; } - if (element->type != ACPI_TYPE_INTEGER) { + if (element.type != ACPI_TYPE_INTEGER) { acpi_util_eval_error(handle, pathname, AE_BAD_DATA); - kfree(element); return AE_BAD_DATA; } - *data = element->integer.value; - kfree(element); + *data = element.integer.value; ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Return value [%llu]\n", *data)); -- cgit v1.2.3 From 65df78473ffbf3bff5e2034df1638acc4f3ddd50 Mon Sep 17 00:00:00 2001 From: "Rafael J. Wysocki" Date: Wed, 26 Nov 2008 17:53:13 -0500 Subject: ACPI suspend: Blacklist boxes that require us to set SCI_EN directly on resume Some Apple boxes evidently require us to set SCI_EN on resume directly, because if we don't do that, they hung somewhere in the resume code path. Moreover, on these boxes it is not sufficient to use acpi_enable() to turn ACPI on during resume. All of this is against the ACPI specification which states that (1) the BIOS is supposed to return from the S3 sleep state with ACPI enabled (SCI_EN set) and (2) the SCI_EN bit is owned by the hardware and we are not supposed to change it. For this reason, blacklist the affected systems so that the SCI_EN bit is set during resume on them. [NOTE: Unconditional setting SCI_EN for all system on resume doesn't work, because it makes some other systems crash (that's to be expected). Also, it is not entirely clear right now if all of the Apple boxes require this workaround.] This patch fixes the recent regression tracked as http://bugzilla.kernel.org/show_bug.cgi?id=12038 Signed-off-by: Rafael J. Wysocki Tested-by: Tino Keitel Tested-by: Bob Copeland Signed-off-by: Len Brown --- drivers/acpi/sleep/main.c | 40 +++++++++++++++++++++++++++++++++++++++- 1 file changed, 39 insertions(+), 1 deletion(-) (limited to 'drivers/acpi') diff --git a/drivers/acpi/sleep/main.c b/drivers/acpi/sleep/main.c index 80c0868d048..28a691cc625 100644 --- a/drivers/acpi/sleep/main.c +++ b/drivers/acpi/sleep/main.c @@ -90,6 +90,18 @@ void __init acpi_old_suspend_ordering(void) old_suspend_ordering = true; } +/* + * According to the ACPI specification the BIOS should make sure that ACPI is + * enabled and SCI_EN bit is set on wake-up from S1 - S3 sleep states. Still, + * some BIOSes don't do that and therefore we use acpi_enable() to enable ACPI + * on such systems during resume. Unfortunately that doesn't help in + * particularly pathological cases in which SCI_EN has to be set directly on + * resume, although the specification states very clearly that this flag is + * owned by the hardware. The set_sci_en_on_resume variable will be set in such + * cases. + */ +static bool set_sci_en_on_resume; + /** * acpi_pm_disable_gpes - Disable the GPEs. */ @@ -235,7 +247,11 @@ static int acpi_suspend_enter(suspend_state_t pm_state) } /* If ACPI is not enabled by the BIOS, we need to enable it here. */ - acpi_enable(); + if (set_sci_en_on_resume) + acpi_set_register(ACPI_BITREG_SCI_ENABLE, 1); + else + acpi_enable(); + /* Reprogram control registers and execute _BFS */ acpi_leave_sleep_state_prep(acpi_state); @@ -323,6 +339,12 @@ static int __init init_old_suspend_ordering(const struct dmi_system_id *d) return 0; } +static int __init init_set_sci_en_on_resume(const struct dmi_system_id *d) +{ + set_sci_en_on_resume = true; + return 0; +} + static struct dmi_system_id __initdata acpisleep_dmi_table[] = { { .callback = init_old_suspend_ordering, @@ -340,6 +362,22 @@ static struct dmi_system_id __initdata acpisleep_dmi_table[] = { DMI_MATCH(DMI_PRODUCT_NAME, "HP xw4600 Workstation"), }, }, + { + .callback = init_set_sci_en_on_resume, + .ident = "Apple MacBook 1,1", + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "Apple Computer, Inc."), + DMI_MATCH(DMI_PRODUCT_NAME, "MacBook1,1"), + }, + }, + { + .callback = init_set_sci_en_on_resume, + .ident = "Apple MacMini 1,1", + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "Apple Computer, Inc."), + DMI_MATCH(DMI_PRODUCT_NAME, "Macmini1,1"), + }, + }, {}, }; #endif /* CONFIG_SUSPEND */ -- cgit v1.2.3 From 3bdca1b863c1ebcb2244fc0cb683876d7330e62b Mon Sep 17 00:00:00 2001 From: Len Brown Date: Wed, 26 Nov 2008 17:55:15 -0500 Subject: Revert "ACPI: don't enable control method power button as wakeup device when Fixed Power button is used" This reverts commit faee816b1502385dc9bc5abf2960d1cc645844d1. http://bugzilla.kernel.org/show_bug.cgi?id=12091 Signed-off-by: Len Brown --- drivers/acpi/scan.c | 10 ---------- 1 file changed, 10 deletions(-) (limited to 'drivers/acpi') diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c index bd5253ee5c8..39b7233c348 100644 --- a/drivers/acpi/scan.c +++ b/drivers/acpi/scan.c @@ -751,16 +751,6 @@ static int acpi_bus_get_wakeup_device_flags(struct acpi_device *device) if (!acpi_match_device_ids(device, button_device_ids)) device->wakeup.flags.run_wake = 1; - /* - * Don't set Power button GPE as run_wake - * if Fixed Power button is used - */ - if (!strcmp(device->pnp.hardware_id, "PNP0C0C") && - !(acpi_gbl_FADT.flags & ACPI_FADT_POWER_BUTTON)) { - device->wakeup.flags.run_wake = 0; - device->wakeup.flags.valid = 0; - } - end: if (ACPI_FAILURE(status)) device->flags.wake_capable = 0; -- cgit v1.2.3 From a6e0887f21bbab337ee32d9c0a84d7c0b6e9141b Mon Sep 17 00:00:00 2001 From: Len Brown Date: Sat, 8 Nov 2008 01:21:10 -0500 Subject: ACPI: delete OSI(Linux) DMI dmesg spam Linux will continue to ignore OSI(Linux), except for a white-list containing a few systems. So delete the black-list, and stop soliciting user-feedback on the console. Signed-off-by: Len Brown --- drivers/acpi/blacklist.c | 401 +---------------------------------------------- drivers/acpi/osl.c | 104 +++--------- 2 files changed, 30 insertions(+), 475 deletions(-) (limited to 'drivers/acpi') diff --git a/drivers/acpi/blacklist.c b/drivers/acpi/blacklist.c index ea92bac42c5..09c69806c1f 100644 --- a/drivers/acpi/blacklist.c +++ b/drivers/acpi/blacklist.c @@ -176,16 +176,6 @@ static int __init dmi_enable_osi_linux(const struct dmi_system_id *d) acpi_dmi_osi_linux(1, d); /* enable */ return 0; } -static int __init dmi_disable_osi_linux(const struct dmi_system_id *d) -{ - acpi_dmi_osi_linux(0, d); /* disable */ - return 0; -} -static int __init dmi_unknown_osi_linux(const struct dmi_system_id *d) -{ - acpi_dmi_osi_linux(-1, d); /* unknown */ - return 0; -} static int __init dmi_disable_osi_vista(const struct dmi_system_id *d) { printk(KERN_NOTICE PREFIX "DMI detected: %s\n", d->ident); @@ -193,295 +183,21 @@ static int __init dmi_disable_osi_vista(const struct dmi_system_id *d) return 0; } -/* - * Most BIOS that invoke OSI(Linux) do nothing with it. - * But some cause Linux to break. - * Only a couple use it to make Linux run better. - * - * Thus, Linux should continue to disable OSI(Linux) by default, - * should continue to discourage BIOS writers from using it, and - * should whitelist the few existing systems that require it. - * - * If it appears clear a vendor isn't using OSI(Linux) - * for anything constructive, blacklist them by name to disable - * unnecessary dmesg warnings on all of their products. - */ - static struct dmi_system_id acpi_osi_dmi_table[] __initdata = { - /* - * Disable OSI(Linux) warnings on all "Acer, inc." - * - * _OSI(Linux) disables the latest Windows BIOS code: - * DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 3100"), - * DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 5050"), - * DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 5100"), - * DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 5580"), - * DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 3010"), - * _OSI(Linux) effect unknown: - * DMI_MATCH(DMI_PRODUCT_NAME, "Ferrari 5000"), - */ - /* - * note that dmi_check_system() uses strstr() - * to match sub-strings rather than !strcmp(), - * so "Acer" below matches "Acer, inc." above. - */ - /* - * Disable OSI(Linux) warnings on all "Acer" - * - * _OSI(Linux) effect unknown: - * DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 5610"), - * DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 7720Z"), - * DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 5520"), - * DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 6460"), - * DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 7510"), - * - * _OSI(Linux) is a NOP: - * DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 5315"), - * DMI_MATCH(DMI_PRODUCT_NAME, "Extensa 5220"), - */ - { - .callback = dmi_disable_osi_linux, - .ident = "Acer", - .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "Acer"), - }, - }, - /* - * Disable OSI(Linux) warnings on all "Apple Computer, Inc." - * Disable OSI(Linux) warnings on all "Apple Inc." - * - * _OSI(Linux) confirmed to be a NOP: - * DMI_MATCH(DMI_PRODUCT_NAME, "MacBook1,1"), - * DMI_MATCH(DMI_PRODUCT_NAME, "MacBook2,1"), - * DMI_MATCH(DMI_PRODUCT_NAME, "MacBookPro2,2"), - * DMI_MATCH(DMI_PRODUCT_NAME, "MacBookPro3,1"), - * _OSI(Linux) effect unknown: - * DMI_MATCH(DMI_PRODUCT_NAME, "MacPro2,1"), - * DMI_MATCH(DMI_PRODUCT_NAME, "MacBookPro1,1"), - */ - { - .callback = dmi_disable_osi_linux, - .ident = "Apple", - .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "Apple"), - }, - }, - /* - * Disable OSI(Linux) warnings on all "BenQ" - * - * _OSI(Linux) confirmed to be a NOP: - * DMI_MATCH(DMI_PRODUCT_NAME, "Joybook S31"), - */ - { - .callback = dmi_disable_osi_linux, - .ident = "BenQ", - .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "BenQ"), - }, - }, - /* - * Disable OSI(Linux) warnings on all "Clevo Co." - * - * _OSI(Linux) confirmed to be a NOP: - * DMI_MATCH(DMI_PRODUCT_NAME, "M570RU"), - */ - { - .callback = dmi_disable_osi_linux, - .ident = "Clevo", - .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "Clevo Co."), - }, - }, - /* - * Disable OSI(Linux) warnings on all "COMPAL" - * - * _OSI(Linux) confirmed to be a NOP: - * DMI_MATCH(DMI_BOARD_NAME, "HEL8X"), - * _OSI(Linux) unknown effect: - * DMI_MATCH(DMI_BOARD_NAME, "IFL91"), - */ - { - .callback = dmi_disable_osi_linux, - .ident = "Compal", - .matches = { - DMI_MATCH(DMI_BIOS_VENDOR, "COMPAL"), - }, - }, - { /* OSI(Linux) touches USB, unknown side-effect */ - .callback = dmi_disable_osi_linux, - .ident = "Dell Dimension 5150", - .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), - DMI_MATCH(DMI_PRODUCT_NAME, "Dell DM051"), - }, - }, - { /* OSI(Linux) is a NOP */ - .callback = dmi_disable_osi_linux, - .ident = "Dell i1501", - .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), - DMI_MATCH(DMI_PRODUCT_NAME, "Inspiron 1501"), - }, - }, - { /* OSI(Linux) effect unknown */ - .callback = dmi_unknown_osi_linux, - .ident = "Dell Latitude D830", - .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), - DMI_MATCH(DMI_PRODUCT_NAME, "Latitude D830"), - }, - }, - { /* OSI(Linux) effect unknown */ - .callback = dmi_unknown_osi_linux, - .ident = "Dell OptiPlex GX620", - .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), - DMI_MATCH(DMI_PRODUCT_NAME, "OptiPlex GX620"), - }, - }, - { /* OSI(Linux) causes some USB initialization to not run */ - .callback = dmi_unknown_osi_linux, - .ident = "Dell OptiPlex 755", - .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), - DMI_MATCH(DMI_PRODUCT_NAME, "OptiPlex 755"), - }, - }, - { /* OSI(Linux) effect unknown */ - .callback = dmi_unknown_osi_linux, - .ident = "Dell PE 1900", - .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), - DMI_MATCH(DMI_PRODUCT_NAME, "PowerEdge 1900"), - }, - }, - { /* OSI(Linux) is a NOP */ - .callback = dmi_unknown_osi_linux, - .ident = "Dell PE 1950", - .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), - DMI_MATCH(DMI_PRODUCT_NAME, "PowerEdge 1950"), - }, - }, - { /* OSI(Linux) is a NOP */ - .callback = dmi_disable_osi_linux, - .ident = "Dell PE R200", - .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), - DMI_MATCH(DMI_PRODUCT_NAME, "PowerEdge R200"), - }, - }, - { /* OSI(Linux) touches USB */ - .callback = dmi_disable_osi_linux, - .ident = "Dell PR 390", - .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), - DMI_MATCH(DMI_PRODUCT_NAME, "Precision WorkStation 390"), - }, - }, - { /* OSI(Linux) touches USB */ - .callback = dmi_unknown_osi_linux, - .ident = "Dell PR 390", - .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), - DMI_MATCH(DMI_PRODUCT_NAME, "Precision WorkStation 690"), - }, - }, - { /* OSI(Linux) unknown - ASL looks benign, but may effect dock/SMM */ - .callback = dmi_unknown_osi_linux, - .ident = "Dell PR M4300", - .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), - DMI_MATCH(DMI_PRODUCT_NAME, "Precision M4300"), - }, - }, - { /* OSI(Linux) is a NOP */ - .callback = dmi_disable_osi_linux, - .ident = "Dell Vostro 1000", - .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), - DMI_MATCH(DMI_PRODUCT_NAME, "Vostro 1000"), - }, - }, - { /* OSI(Linux) effect unknown */ - .callback = dmi_unknown_osi_linux, - .ident = "Dell PE SC440", - .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), - DMI_MATCH(DMI_PRODUCT_NAME, "PowerEdge SC440"), - }, - }, - { /* OSI(Linux) effect unknown */ - .callback = dmi_unknown_osi_linux, - .ident = "Dialogue Flybook V5", - .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "Dialogue Technology Corporation"), - DMI_MATCH(DMI_PRODUCT_NAME, "Flybook V5"), - }, - }, - /* - * Disable OSI(Linux) warnings on all "FUJITSU SIEMENS" - * - * _OSI(Linux) disables latest Windows BIOS code: - * DMI_MATCH(DMI_PRODUCT_NAME, "AMILO Pa 2510"), - * _OSI(Linux) confirmed to be a NOP: - * DMI_MATCH(DMI_PRODUCT_NAME, "AMILO Pi 1536"), - * DMI_MATCH(DMI_PRODUCT_NAME, "AMILO Pi 1556"), - * DMI_MATCH(DMI_PRODUCT_NAME, "AMILO Xi 1546"), - * DMI_MATCH(DMI_PRODUCT_NAME, "ESPRIMO Mobile V5505"), - * _OSI(Linux) unknown effect: - * DMI_MATCH(DMI_PRODUCT_NAME, "Amilo M1425"), - * DMI_MATCH(DMI_PRODUCT_NAME, "Amilo Si 1520"), - */ - { - .callback = dmi_disable_osi_linux, - .ident = "Fujitsu Siemens", - .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU SIEMENS"), - }, - }, { .callback = dmi_disable_osi_vista, .ident = "Fujitsu Siemens", .matches = { DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU SIEMENS"), - DMI_MATCH(DMI_PRODUCT_NAME, "ESPRIMO Mobile V5505"), + DMI_MATCH(DMI_PRODUCT_NAME, "ESPRIMO Mobile V5505"), }, }, + /* - * Disable OSI(Linux) warnings on all "Hewlett-Packard" - * - * _OSI(Linux) confirmed to be a NOP: - * .ident = "HP Pavilion tx 1000" - * DMI_MATCH(DMI_BOARD_NAME, "30BF"), - * .ident = "HP Pavilion dv2000" - * DMI_MATCH(DMI_BOARD_NAME, "30B5"), - * .ident = "HP Pavilion dv5000", - * DMI_MATCH(DMI_BOARD_NAME, "30A7"), - * .ident = "HP Pavilion dv6300 30BC", - * DMI_MATCH(DMI_BOARD_NAME, "30BC"), - * .ident = "HP Pavilion dv6000", - * DMI_MATCH(DMI_BOARD_NAME, "30B7"), - * DMI_MATCH(DMI_BOARD_NAME, "30B8"), - * .ident = "HP Pavilion dv9000", - * DMI_MATCH(DMI_BOARD_NAME, "30B9"), - * .ident = "HP Pavilion dv9500", - * DMI_MATCH(DMI_BOARD_NAME, "30CB"), - * .ident = "HP/Compaq Presario C500", - * DMI_MATCH(DMI_BOARD_NAME, "30C6"), - * .ident = "HP/Compaq Presario F500", - * DMI_MATCH(DMI_BOARD_NAME, "30D3"), - * _OSI(Linux) unknown effect: - * .ident = "HP Pavilion dv6500", - * DMI_MATCH(DMI_BOARD_NAME, "30D0"), + * BIOS invocation of _OSI(Linux) is almost always a BIOS bug. + * Linux ignores it, except for the machines enumerated below. */ - { - .callback = dmi_disable_osi_linux, - .ident = "Hewlett-Packard", - .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"), - }, - }, + /* * Lenovo has a mix of systems OSI(Linux) situations * and thus we can not wildcard the vendor. @@ -519,113 +235,6 @@ static struct dmi_system_id acpi_osi_dmi_table[] __initdata = { DMI_MATCH(DMI_PRODUCT_VERSION, "ThinkPad X61"), }, }, - { - .callback = dmi_disable_osi_linux, - .ident = "Lenovo 3000 V100", - .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"), - DMI_MATCH(DMI_PRODUCT_VERSION, "LENOVO3000 V100"), - }, - }, - { - .callback = dmi_disable_osi_linux, - .ident = "Lenovo 3000 N100", - .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"), - DMI_MATCH(DMI_PRODUCT_VERSION, "3000 N100"), - }, - }, - /* - * Disable OSI(Linux) warnings on all "LG Electronics" - * - * _OSI(Linux) confirmed to be a NOP: - * DMI_MATCH(DMI_PRODUCT_NAME, "P1-J150B"), - * with DMI_MATCH(DMI_BOARD_NAME, "ROCKY"), - * - * unknown: - * DMI_MATCH(DMI_PRODUCT_NAME, "S1-MDGDG"), - * with DMI_MATCH(DMI_BOARD_NAME, "ROCKY"), - */ - { - .callback = dmi_disable_osi_linux, - .ident = "LG", - .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "LG Electronics"), - }, - }, - /* NEC - OSI(Linux) effect unknown */ - { - .callback = dmi_unknown_osi_linux, - .ident = "NEC VERSA M360", - .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "NEC Computers SAS"), - DMI_MATCH(DMI_PRODUCT_NAME, "NEC VERSA M360"), - }, - }, - /* Panasonic */ - { - .callback = dmi_unknown_osi_linux, - .ident = "Panasonic", - .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "Matsushita"), - /* Toughbook CF-52 */ - DMI_MATCH(DMI_PRODUCT_NAME, "CF-52CCABVBG"), - }, - }, - /* - * Disable OSI(Linux) warnings on all "Samsung Electronics" - * - * OSI(Linux) disables PNP0C32 and other BIOS code for Windows: - * DMI_MATCH(DMI_PRODUCT_NAME, "R40P/R41P"), - * DMI_MATCH(DMI_PRODUCT_NAME, "R59P/R60P/R61P"), - */ - { - .callback = dmi_disable_osi_linux, - .ident = "Samsung", - .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "SAMSUNG ELECTRONICS CO., LTD."), - }, - }, - /* - * Disable OSI(Linux) warnings on all "Sony Corporation" - * - * _OSI(Linux) is a NOP: - * DMI_MATCH(DMI_PRODUCT_NAME, "VGN-NR11S_S"), - * DMI_MATCH(DMI_PRODUCT_NAME, "VGN-SZ38GP_C"), - * DMI_MATCH(DMI_PRODUCT_NAME, "VGN-SZ650N"), - * DMI_MATCH(DMI_PRODUCT_NAME, "VGN-TZ21MN_N"), - * _OSI(Linux) unknown effect: - * DMI_MATCH(DMI_PRODUCT_NAME, "VGN-FZ11M"), - */ - { - .callback = dmi_disable_osi_linux, - .ident = "Sony", - .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "Sony Corporation"), - }, - }, - /* - * Disable OSI(Linux) warnings on all "TOSHIBA" - * - * _OSI(Linux) breaks sound (bugzilla 7787): - * DMI_MATCH(DMI_PRODUCT_NAME, "Satellite P100"), - * DMI_MATCH(DMI_PRODUCT_NAME, "Satellite P105"), - * _OSI(Linux) is a NOP: - * DMI_MATCH(DMI_PRODUCT_NAME, "Satellite A100"), - * DMI_MATCH(DMI_PRODUCT_NAME, "Satellite A210"), - * _OSI(Linux) unknown effect: - * DMI_MATCH(DMI_PRODUCT_NAME, "Satellite A135"), - * DMI_MATCH(DMI_PRODUCT_NAME, "Satellite A200"), - * DMI_MATCH(DMI_PRODUCT_NAME, "Satellite P205"), - * DMI_MATCH(DMI_PRODUCT_NAME, "Satellite U305"), - */ - { - .callback = dmi_disable_osi_linux, - .ident = "Toshiba", - .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "TOSHIBA"), - }, - }, {} }; diff --git a/drivers/acpi/osl.c b/drivers/acpi/osl.c index 4be252145cb..c8111424dcb 100644 --- a/drivers/acpi/osl.c +++ b/drivers/acpi/osl.c @@ -35,7 +35,6 @@ #include #include #include -#include #include #include #include @@ -97,54 +96,44 @@ static DEFINE_SPINLOCK(acpi_res_lock); static char osi_additional_string[OSI_STRING_LENGTH_MAX]; /* - * "Ode to _OSI(Linux)" + * The story of _OSI(Linux) * - * osi_linux -- Control response to BIOS _OSI(Linux) query. + * From pre-history through Linux-2.6.22, + * Linux responded TRUE upon a BIOS OSI(Linux) query. * - * As Linux evolves, the features that it supports change. - * So an OSI string such as "Linux" is not specific enough - * to be useful across multiple versions of Linux. It - * doesn't identify any particular feature, interface, - * or even any particular version of Linux... + * Unfortunately, reference BIOS writers got wind of this + * and put OSI(Linux) in their example code, quickly exposing + * this string as ill-conceived and opening the door to + * an un-bounded number of BIOS incompatibilities. * - * Unfortunately, Linux-2.6.22 and earlier responded "yes" - * to a BIOS _OSI(Linux) query. When - * a reference mobile BIOS started using it, its use - * started to spread to many vendor platforms. - * As it is not supportable, we need to halt that spread. + * For example, OSI(Linux) was used on resume to re-POST a + * video card on one system, because Linux at that time + * could not do a speedy restore in its native driver. + * But then upon gaining quick native restore capability, + * Linux has no way to tell the BIOS to skip the time-consuming + * POST -- putting Linux at a permanent performance disadvantage. + * On another system, the BIOS writer used OSI(Linux) + * to infer native OS support for IPMI! On other systems, + * OSI(Linux) simply got in the way of Linux claiming to + * be compatible with other operating systems, exposing + * BIOS issues such as skipped device initialization. * - * Today, most BIOS references to _OSI(Linux) are noise -- - * they have no functional effect and are just dead code - * carried over from the reference BIOS. - * - * The next most common case is that _OSI(Linux) harms Linux, - * usually by causing the BIOS to follow paths that are - * not tested during Windows validation. - * - * Finally, there is a short list of platforms - * where OSI(Linux) benefits Linux. - * - * In Linux-2.6.23, OSI(Linux) is first disabled by default. - * DMI is used to disable the dmesg warning about OSI(Linux) - * on platforms where it is known to have no effect. - * But a dmesg warning remains for systems where - * we do not know if OSI(Linux) is good or bad for the system. - * DMI is also used to enable OSI(Linux) for the machines - * that are known to need it. + * So "Linux" turned out to be a really poor chose of + * OSI string, and from Linux-2.6.23 onward we respond FALSE. * * BIOS writers should NOT query _OSI(Linux) on future systems. - * It will be ignored by default, and to get Linux to - * not ignore it will require a kernel source update to - * add a DMI entry, or a boot-time "acpi_osi=Linux" invocation. + * Linux will complain on the console when it sees it, and return FALSE. + * To get Linux to return TRUE for your system will require + * a kernel source update to add a DMI entry, + * or boot with "acpi_osi=Linux" */ -#define OSI_LINUX_ENABLE 0 static struct osi_linux { unsigned int enable:1; unsigned int dmi:1; unsigned int cmdline:1; unsigned int known:1; -} osi_linux = { OSI_LINUX_ENABLE, 0, 0, 0}; +} osi_linux = { 0, 0, 0, 0}; static void __init acpi_request_region (struct acpi_generic_address *addr, unsigned int length, char *desc) @@ -1296,34 +1285,6 @@ acpi_status acpi_os_release_object(acpi_cache_t * cache, void *object) return (AE_OK); } -/** - * acpi_dmi_dump - dump DMI slots needed for blacklist entry - * - * Returns 0 on success - */ -static int acpi_dmi_dump(void) -{ - - if (!dmi_available) - return -1; - - printk(KERN_NOTICE PREFIX "DMI System Vendor: %s\n", - dmi_get_system_info(DMI_SYS_VENDOR)); - printk(KERN_NOTICE PREFIX "DMI Product Name: %s\n", - dmi_get_system_info(DMI_PRODUCT_NAME)); - printk(KERN_NOTICE PREFIX "DMI Product Version: %s\n", - dmi_get_system_info(DMI_PRODUCT_VERSION)); - printk(KERN_NOTICE PREFIX "DMI Board Name: %s\n", - dmi_get_system_info(DMI_BOARD_NAME)); - printk(KERN_NOTICE PREFIX "DMI BIOS Vendor: %s\n", - dmi_get_system_info(DMI_BIOS_VENDOR)); - printk(KERN_NOTICE PREFIX "DMI BIOS Date: %s\n", - dmi_get_system_info(DMI_BIOS_DATE)); - - return 0; -} - - /****************************************************************************** * * FUNCTION: acpi_os_validate_interface @@ -1350,21 +1311,6 @@ acpi_os_validate_interface (char *interface) osi_linux.cmdline ? " via cmdline" : osi_linux.dmi ? " via DMI" : ""); - if (!osi_linux.dmi) { - if (acpi_dmi_dump()) - printk(KERN_NOTICE PREFIX - "[please extract dmidecode output]\n"); - printk(KERN_NOTICE PREFIX - "Please send DMI info above to " - "linux-acpi@vger.kernel.org\n"); - } - if (!osi_linux.known && !osi_linux.cmdline) { - printk(KERN_NOTICE PREFIX - "If \"acpi_osi=%sLinux\" works better, " - "please notify linux-acpi@vger.kernel.org\n", - osi_linux.enable ? "!" : ""); - } - if (osi_linux.enable) return AE_OK; } -- cgit v1.2.3 From 23d0a65cf229acd273b6f5a325c34d758a90d592 Mon Sep 17 00:00:00 2001 From: Arjan van de Ven Date: Fri, 28 Nov 2008 08:19:09 -0800 Subject: toshiba_acpi: close race in toshiba_acpi driver the toshiba ACPI driver will, in a failure case, free the rfkill state before stopping the polling timer that would use this state. More interesting, in the same failure case handling, it calls the exit function, which also frees the rfkill state, but after stopping the polling. If the race happens, a NULL pointer is passed to rfkill_force_state() which then causes a nice dereference. Fix the race by just not doing the too-early freeing of the rfkill state. This appears to be the cause of a hot issue on kerneloops.org; while I have no solid evidence of that this patch will fix the issue, the race appears rather real. Signed-off-by: Arjan van de Ven Signed-off-by: Len Brown --- drivers/acpi/toshiba_acpi.c | 2 -- 1 file changed, 2 deletions(-) (limited to 'drivers/acpi') diff --git a/drivers/acpi/toshiba_acpi.c b/drivers/acpi/toshiba_acpi.c index 66aac06f2ac..25f531d892d 100644 --- a/drivers/acpi/toshiba_acpi.c +++ b/drivers/acpi/toshiba_acpi.c @@ -848,8 +848,6 @@ static int __init toshiba_acpi_init(void) ret = input_register_polled_device(toshiba_acpi.poll_dev); if (ret) { printk(MY_ERR "unable to register kill-switch input device\n"); - rfkill_free(toshiba_acpi.rfk_dev); - toshiba_acpi.rfk_dev = NULL; toshiba_acpi_exit(); return ret; } -- cgit v1.2.3 From aaad077638be1a25871bcae5e43952d6b63abfca Mon Sep 17 00:00:00 2001 From: "Rafael J. Wysocki" Date: Fri, 5 Dec 2008 01:07:51 +0100 Subject: ACPI: Fix ACPI battery regression introduced by commit 558073 Commit 558073dd56707864f09d563b64e7c37c021e89d2 ("ACPI: battery: Convert discharge energy rate to current properly") caused the battery subsystem to report wrong values of the remaining time on battery power and the time until fully charged on Toshiba Portege R500 (and presumably on other boxes too). Fix the issue by correcting the conversion from mW to mA. Signed-off-by: Rafael J. Wysocki Signed-off-by: Linus Torvalds --- drivers/acpi/battery.c | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) (limited to 'drivers/acpi') diff --git a/drivers/acpi/battery.c b/drivers/acpi/battery.c index a0a178dd189..4fb3c12ac1d 100644 --- a/drivers/acpi/battery.c +++ b/drivers/acpi/battery.c @@ -173,14 +173,17 @@ static int acpi_battery_get_property(struct power_supply *psy, val->intval = battery->voltage_now * 1000; break; case POWER_SUPPLY_PROP_CURRENT_NOW: - val->intval = battery->current_now * 1000; - /* if power units are mW, convert to mA by - dividing by current voltage (mV/1000) */ - if (!battery->power_unit) { - if (battery->voltage_now) { + val->intval = battery->current_now; + if (battery->power_unit) { + val->intval *= 1000; + } else { + /* + * If power units are mW, convert to mA by dividing by + * current voltage. + */ + if (battery->voltage_now) val->intval /= battery->voltage_now; - val->intval *= 1000; - } else + else val->intval = -1; } break; -- cgit v1.2.3 From f10a3a32ae2edbe94920ce6827f4c2550eb6ed48 Mon Sep 17 00:00:00 2001 From: Linus Torvalds Date: Fri, 5 Dec 2008 13:30:03 -0800 Subject: Revert "ACPI: battery: Convert discharge energy rate to current properly" This reverts commit 558073dd56707864f09d563b64e7c37c021e89d2, along with the failed try to fix the regression it caused ("ACPI: Fix ACPI battery regression introduced by commit 558073"), which just made things worse. Commit aaad077638be1a25871bcae5e43952d6b63abfca (that failed "Fix ACPI battery regression") got the voltage conversion confused, and fixed the problem with Rafael's battery monitor apparently just by mistake. So revert them both, getting us back to the 2.6.27 state in this, and let's revisit it when people understand what's going on. Noted-by: Paul Martin Requested-by: Rafael J. Wysocki Cc: Len Brown Cc: Alexey Starikovskiy Signed-off-by: Linus Torvalds --- drivers/acpi/battery.c | 14 +------------- 1 file changed, 1 insertion(+), 13 deletions(-) (limited to 'drivers/acpi') diff --git a/drivers/acpi/battery.c b/drivers/acpi/battery.c index 4fb3c12ac1d..1423b0c0cd2 100644 --- a/drivers/acpi/battery.c +++ b/drivers/acpi/battery.c @@ -173,19 +173,7 @@ static int acpi_battery_get_property(struct power_supply *psy, val->intval = battery->voltage_now * 1000; break; case POWER_SUPPLY_PROP_CURRENT_NOW: - val->intval = battery->current_now; - if (battery->power_unit) { - val->intval *= 1000; - } else { - /* - * If power units are mW, convert to mA by dividing by - * current voltage. - */ - if (battery->voltage_now) - val->intval /= battery->voltage_now; - else - val->intval = -1; - } + val->intval = battery->current_now * 1000; break; case POWER_SUPPLY_PROP_CHARGE_FULL_DESIGN: case POWER_SUPPLY_PROP_ENERGY_FULL_DESIGN: -- cgit v1.2.3