From 8fec62b2d9d0c80b594d0d85678bfdf57a70df1b Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Tue, 29 Jun 2010 10:07:09 +0200 Subject: acpi: use queue_work_on() instead of binding workqueue worker to cpu0 ACPI works need to be executed on cpu0 and acpi/osl.c achieves this by creating singlethread workqueue and then binding it to cpu0 from a work which is quite unorthodox. Make it create regular workqueues and use queue_work_on() instead. This is in preparation of concurrency managed workqueue and the extra workers won't be a problem after it's implemented. Signed-off-by: Tejun Heo --- drivers/acpi/osl.c | 40 +++++++++++----------------------------- 1 file changed, 11 insertions(+), 29 deletions(-) (limited to 'drivers/acpi') diff --git a/drivers/acpi/osl.c b/drivers/acpi/osl.c index 78418ce4fc78..46cce391fa46 100644 --- a/drivers/acpi/osl.c +++ b/drivers/acpi/osl.c @@ -191,36 +191,11 @@ acpi_status __init acpi_os_initialize(void) return AE_OK; } -static void bind_to_cpu0(struct work_struct *work) -{ - set_cpus_allowed_ptr(current, cpumask_of(0)); - kfree(work); -} - -static void bind_workqueue(struct workqueue_struct *wq) -{ - struct work_struct *work; - - work = kzalloc(sizeof(struct work_struct), GFP_KERNEL); - INIT_WORK(work, bind_to_cpu0); - queue_work(wq, work); -} - acpi_status acpi_os_initialize1(void) { - /* - * On some machines, a software-initiated SMI causes corruption unless - * the SMI runs on CPU 0. An SMI can be initiated by any AML, but - * typically it's done in GPE-related methods that are run via - * workqueues, so we can avoid the known corruption cases by binding - * the workqueues to CPU 0. - */ - kacpid_wq = create_singlethread_workqueue("kacpid"); - bind_workqueue(kacpid_wq); - kacpi_notify_wq = create_singlethread_workqueue("kacpi_notify"); - bind_workqueue(kacpi_notify_wq); - kacpi_hotplug_wq = create_singlethread_workqueue("kacpi_hotplug"); - bind_workqueue(kacpi_hotplug_wq); + kacpid_wq = create_workqueue("kacpid"); + kacpi_notify_wq = create_workqueue("kacpi_notify"); + kacpi_hotplug_wq = create_workqueue("kacpi_hotplug"); BUG_ON(!kacpid_wq); BUG_ON(!kacpi_notify_wq); BUG_ON(!kacpi_hotplug_wq); @@ -766,7 +741,14 @@ static acpi_status __acpi_os_execute(acpi_execute_type type, else INIT_WORK(&dpc->work, acpi_os_execute_deferred); - ret = queue_work(queue, &dpc->work); + /* + * On some machines, a software-initiated SMI causes corruption unless + * the SMI runs on CPU 0. An SMI can be initiated by any AML, but + * typically it's done in GPE-related methods that are run via + * workqueues, so we can avoid the known corruption cases by always + * queueing on CPU 0. + */ + ret = queue_work_on(0, queue, &dpc->work); if (!ret) { printk(KERN_ERR PREFIX -- cgit v1.2.1 From e96c4b081df0991a57b244f68c3955a9ea00bd0a Mon Sep 17 00:00:00 2001 From: "Rafael J. Wysocki" Date: Tue, 6 Jul 2010 18:28:35 -0400 Subject: ACPI / Sleep: Free NVS copy if suspending of devices fails If suspending of devices fails or system suspend is tested in the "devices" mode, the memory allocated for storing a copy of the ACPI NVS area will not be freed, because acpi_pm_finish() is not called in that case. Fix this by moving the suspend_nvs_free() call to acpi_pm_end(). Signed-off-by: Rafael J. Wysocki Signed-off-by: Len Brown --- drivers/acpi/sleep.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/acpi') diff --git a/drivers/acpi/sleep.c b/drivers/acpi/sleep.c index 5b7c52e4a00f..da68ed24f4c5 100644 --- a/drivers/acpi/sleep.c +++ b/drivers/acpi/sleep.c @@ -145,7 +145,6 @@ static void acpi_pm_finish(void) { u32 acpi_state = acpi_target_sleep_state; - suspend_nvs_free(); acpi_ec_unblock_transactions(); if (acpi_state == ACPI_STATE_S0) @@ -167,6 +166,7 @@ static void acpi_pm_finish(void) */ static void acpi_pm_end(void) { + suspend_nvs_free(); /* * This is necessary in case acpi_pm_finish() is not called during a * failing transition to a sleep state. -- cgit v1.2.1 From 25bed55753b8cf243406e8837990b55946c5278d Mon Sep 17 00:00:00 2001 From: "Rafael J. Wysocki" Date: Fri, 2 Jul 2010 00:12:26 +0200 Subject: ACPI / Sleep: Rework enabling wakeup devices There is no reason why acpi_enable_wakeup_device() should be called with interrupts disabled, because it doesn't access hardware. Thus it is possible to move it next to acpi_enable_wakeup_device_prep() and make the ACPI suspend, hibernate and poweroff code more straightforward. Signed-off-by: Rafael J. Wysocki Signed-off-by: Len Brown --- drivers/acpi/sleep.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) (limited to 'drivers/acpi') diff --git a/drivers/acpi/sleep.c b/drivers/acpi/sleep.c index da68ed24f4c5..8704ca78a8c4 100644 --- a/drivers/acpi/sleep.c +++ b/drivers/acpi/sleep.c @@ -70,10 +70,11 @@ static int acpi_sleep_prepare(u32 acpi_state) } ACPI_FLUSH_CPU_CACHE(); - acpi_enable_wakeup_device_prep(acpi_state); #endif printk(KERN_INFO PREFIX "Preparing to enter system sleep state S%d\n", acpi_state); + acpi_enable_wakeup_device_prep(acpi_state); + acpi_enable_wakeup_device(acpi_state); acpi_enter_sleep_state_prep(acpi_state); return 0; } @@ -238,7 +239,6 @@ static int acpi_suspend_enter(suspend_state_t pm_state) } local_irq_save(flags); - acpi_enable_wakeup_device(acpi_state); switch (acpi_state) { case ACPI_STATE_S1: barrier(); @@ -442,7 +442,6 @@ static int acpi_hibernation_enter(void) ACPI_FLUSH_CPU_CACHE(); local_irq_save(flags); - acpi_enable_wakeup_device(ACPI_STATE_S4); /* This shouldn't return. If it returns, we have a problem */ status = acpi_enter_sleep_state(ACPI_STATE_S4); /* Reprogram control registers and execute _BFS */ @@ -696,7 +695,6 @@ static void acpi_power_off(void) /* acpi_sleep_prepare(ACPI_STATE_S5) should have already been called */ printk(KERN_DEBUG "%s called\n", __func__); local_irq_disable(); - acpi_enable_wakeup_device(ACPI_STATE_S5); acpi_enter_sleep_state(ACPI_STATE_S5); } -- cgit v1.2.1 From 78f5f023167813130d2cf657d1b9eadc32f0e992 Mon Sep 17 00:00:00 2001 From: "Rafael J. Wysocki" Date: Tue, 6 Jul 2010 22:09:38 -0400 Subject: ACPI / Wakeup: Simplify enabling of wakeup devices To simplify the enabling of wakeup devices during system suspend and hibernation, merge acpi_enable_wakeup_device_prep() with acpi_disable_wakeup_device() and remove unnecessary (and no longer valid) comments from the latter. Rename acpi_enable_wakeup_device() to acpi_enable_wakeup_devices() and acpi_disable_wakeup_device() to acpi_disable_wakeup_devices(), because these functions usually operate on multiple device objects. Signed-off-by: Rafael J. Wysocki Signed-off-by: Len Brown --- drivers/acpi/sleep.c | 5 ++--- drivers/acpi/sleep.h | 5 ++--- drivers/acpi/wakeup.c | 48 ++++++++++-------------------------------------- 3 files changed, 14 insertions(+), 44 deletions(-) (limited to 'drivers/acpi') diff --git a/drivers/acpi/sleep.c b/drivers/acpi/sleep.c index 8704ca78a8c4..93441c95c53b 100644 --- a/drivers/acpi/sleep.c +++ b/drivers/acpi/sleep.c @@ -73,8 +73,7 @@ static int acpi_sleep_prepare(u32 acpi_state) #endif printk(KERN_INFO PREFIX "Preparing to enter system sleep state S%d\n", acpi_state); - acpi_enable_wakeup_device_prep(acpi_state); - acpi_enable_wakeup_device(acpi_state); + acpi_enable_wakeup_devices(acpi_state); acpi_enter_sleep_state_prep(acpi_state); return 0; } @@ -153,7 +152,7 @@ static void acpi_pm_finish(void) printk(KERN_INFO PREFIX "Waking up from system sleep state S%d\n", acpi_state); - acpi_disable_wakeup_device(acpi_state); + acpi_disable_wakeup_devices(acpi_state); acpi_leave_sleep_state(acpi_state); /* reset firmware waking vector */ diff --git a/drivers/acpi/sleep.h b/drivers/acpi/sleep.h index 25b8bd149284..d8821805c3bc 100644 --- a/drivers/acpi/sleep.h +++ b/drivers/acpi/sleep.h @@ -2,9 +2,8 @@ extern u8 sleep_states[]; extern int acpi_suspend(u32 state); -extern void acpi_enable_wakeup_device_prep(u8 sleep_state); -extern void acpi_enable_wakeup_device(u8 sleep_state); -extern void acpi_disable_wakeup_device(u8 sleep_state); +extern void acpi_enable_wakeup_devices(u8 sleep_state); +extern void acpi_disable_wakeup_devices(u8 sleep_state); extern struct list_head acpi_wakeup_device_list; extern struct mutex acpi_device_lock; diff --git a/drivers/acpi/wakeup.c b/drivers/acpi/wakeup.c index 388747a7ef4f..dc6d1d9112fb 100644 --- a/drivers/acpi/wakeup.c +++ b/drivers/acpi/wakeup.c @@ -21,45 +21,17 @@ ACPI_MODULE_NAME("wakeup_devices") /** - * acpi_enable_wakeup_device_prep - Prepare wake-up devices. + * acpi_enable_wakeup_devices - Enable wake-up device GPEs. * @sleep_state: ACPI system sleep state. * - * Enable all wake-up devices' power, unless the requested system sleep state is - * too deep. + * Enable wakeup device power of devices with the state.enable flag set and set + * the wakeup enable mask bits in the GPE registers that correspond to wakeup + * devices. */ -void acpi_enable_wakeup_device_prep(u8 sleep_state) +void acpi_enable_wakeup_devices(u8 sleep_state) { struct list_head *node, *next; - list_for_each_safe(node, next, &acpi_wakeup_device_list) { - struct acpi_device *dev = container_of(node, - struct acpi_device, - wakeup_list); - - if (!dev->wakeup.flags.valid || !dev->wakeup.state.enabled - || (sleep_state > (u32) dev->wakeup.sleep_state)) - continue; - - acpi_enable_wakeup_device_power(dev, sleep_state); - } -} - -/** - * acpi_enable_wakeup_device - Enable wake-up device GPEs. - * @sleep_state: ACPI system sleep state. - * - * Enable all wake-up devices' GPEs, with the assumption that - * acpi_disable_all_gpes() was executed before, so we don't need to disable any - * GPEs here. - */ -void acpi_enable_wakeup_device(u8 sleep_state) -{ - struct list_head *node, *next; - - /* - * Caution: this routine must be invoked when interrupt is disabled - * Refer ACPI2.0: P212 - */ list_for_each_safe(node, next, &acpi_wakeup_device_list) { struct acpi_device *dev = container_of(node, struct acpi_device, wakeup_list); @@ -68,6 +40,9 @@ void acpi_enable_wakeup_device(u8 sleep_state) || sleep_state > (u32) dev->wakeup.sleep_state) continue; + if (dev->wakeup.state.enabled) + acpi_enable_wakeup_device_power(dev, sleep_state); + /* The wake-up power should have been enabled already. */ acpi_enable_gpe(dev->wakeup.gpe_device, dev->wakeup.gpe_number, ACPI_GPE_TYPE_WAKE); @@ -75,13 +50,10 @@ void acpi_enable_wakeup_device(u8 sleep_state) } /** - * acpi_disable_wakeup_device - Disable devices' wakeup capability. + * acpi_disable_wakeup_devices - Disable devices' wakeup capability. * @sleep_state: ACPI system sleep state. - * - * This function only affects devices with wakeup.state.enabled set, which means - * that it reverses the changes made by acpi_enable_wakeup_device_prep(). */ -void acpi_disable_wakeup_device(u8 sleep_state) +void acpi_disable_wakeup_devices(u8 sleep_state) { struct list_head *node, *next; -- cgit v1.2.1 From c5f7a1bb65bca03253c189e946b3ca79669f08af Mon Sep 17 00:00:00 2001 From: "Rafael J. Wysocki" Date: Fri, 2 Jul 2010 00:14:09 +0200 Subject: ACPI / Sleep: Consolidate suspend and hibernation routines Some hibernation and suspend routines can be merged, which reduces the complexity of code a bit. Signed-off-by: Rafael J. Wysocki Signed-off-by: Len Brown --- drivers/acpi/sleep.c | 42 ++++++++++++++++-------------------------- 1 file changed, 16 insertions(+), 26 deletions(-) (limited to 'drivers/acpi') diff --git a/drivers/acpi/sleep.c b/drivers/acpi/sleep.c index 93441c95c53b..61c5bd03f733 100644 --- a/drivers/acpi/sleep.c +++ b/drivers/acpi/sleep.c @@ -104,6 +104,16 @@ static int acpi_pm_freeze(void) return 0; } +/** + * acpi_pre_suspend - Enable wakeup devices, "freeze" EC and save NVS. + */ +static int acpi_pm_pre_suspend(void) +{ + acpi_pm_freeze(); + suspend_nvs_save(); + return 0; +} + /** * __acpi_pm_prepare - Prepare the platform to enter the target state. * @@ -113,11 +123,9 @@ static int acpi_pm_freeze(void) static int __acpi_pm_prepare(void) { int error = acpi_sleep_prepare(acpi_target_sleep_state); - - suspend_nvs_save(); - if (error) acpi_target_sleep_state = ACPI_STATE_S0; + return error; } @@ -128,9 +136,8 @@ static int __acpi_pm_prepare(void) static int acpi_pm_prepare(void) { int error = __acpi_pm_prepare(); - if (!error) - acpi_pm_freeze(); + acpi_pm_pre_suspend(); return error; } @@ -322,9 +329,9 @@ static struct platform_suspend_ops acpi_suspend_ops = { static int acpi_suspend_begin_old(suspend_state_t pm_state) { int error = acpi_suspend_begin(pm_state); - if (!error) error = __acpi_pm_prepare(); + return error; } @@ -335,7 +342,7 @@ static int acpi_suspend_begin_old(suspend_state_t pm_state) static struct platform_suspend_ops acpi_suspend_ops_old = { .valid = acpi_suspend_state_valid, .begin = acpi_suspend_begin_old, - .prepare_late = acpi_pm_freeze, + .prepare_late = acpi_pm_pre_suspend, .enter = acpi_suspend_enter, .wake = acpi_suspend_finish, .end = acpi_pm_end, @@ -423,16 +430,6 @@ static int acpi_hibernation_begin(void) return error; } -static int acpi_hibernation_pre_snapshot(void) -{ - int error = acpi_pm_prepare(); - - if (!error) - suspend_nvs_save(); - - return error; -} - static int acpi_hibernation_enter(void) { acpi_status status = AE_OK; @@ -480,7 +477,7 @@ static void acpi_pm_thaw(void) static struct platform_hibernation_ops acpi_hibernation_ops = { .begin = acpi_hibernation_begin, .end = acpi_pm_end, - .pre_snapshot = acpi_hibernation_pre_snapshot, + .pre_snapshot = acpi_pm_prepare, .finish = acpi_pm_finish, .prepare = acpi_pm_prepare, .enter = acpi_hibernation_enter, @@ -516,13 +513,6 @@ static int acpi_hibernation_begin_old(void) return error; } -static int acpi_hibernation_pre_snapshot_old(void) -{ - acpi_pm_freeze(); - suspend_nvs_save(); - return 0; -} - /* * The following callbacks are used if the pre-ACPI 2.0 suspend ordering has * been requested. @@ -530,7 +520,7 @@ static int acpi_hibernation_pre_snapshot_old(void) static struct platform_hibernation_ops acpi_hibernation_ops_old = { .begin = acpi_hibernation_begin_old, .end = acpi_pm_end, - .pre_snapshot = acpi_hibernation_pre_snapshot_old, + .pre_snapshot = acpi_pm_pre_suspend, .prepare = acpi_pm_freeze, .finish = acpi_pm_finish, .enter = acpi_hibernation_enter, -- cgit v1.2.1 From 618d7fd0d4e51a45d25d9bc6097a0cb1e5a2f226 Mon Sep 17 00:00:00 2001 From: "Rafael J. Wysocki" Date: Fri, 2 Jul 2010 00:14:57 +0200 Subject: ACPI / Sleep: Drop acpi_suspend_finish() The function acpi_suspend_finish() is not necessary any more, because acpi_pm_finish() can be used instead of it just fine. Remove it. Signed-off-by: Rafael J. Wysocki Signed-off-by: Len Brown --- drivers/acpi/sleep.c | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) (limited to 'drivers/acpi') diff --git a/drivers/acpi/sleep.c b/drivers/acpi/sleep.c index 61c5bd03f733..5529c7023956 100644 --- a/drivers/acpi/sleep.c +++ b/drivers/acpi/sleep.c @@ -290,11 +290,6 @@ static int acpi_suspend_enter(suspend_state_t pm_state) return ACPI_SUCCESS(status) ? 0 : -EFAULT; } -static void acpi_suspend_finish(void) -{ - acpi_pm_finish(); -} - static int acpi_suspend_state_valid(suspend_state_t pm_state) { u32 acpi_state; @@ -316,7 +311,7 @@ static struct platform_suspend_ops acpi_suspend_ops = { .begin = acpi_suspend_begin, .prepare_late = acpi_pm_prepare, .enter = acpi_suspend_enter, - .wake = acpi_suspend_finish, + .wake = acpi_pm_finish, .end = acpi_pm_end, }; @@ -344,7 +339,7 @@ static struct platform_suspend_ops acpi_suspend_ops_old = { .begin = acpi_suspend_begin_old, .prepare_late = acpi_pm_pre_suspend, .enter = acpi_suspend_enter, - .wake = acpi_suspend_finish, + .wake = acpi_pm_finish, .end = acpi_pm_end, .recover = acpi_pm_finish, }; -- cgit v1.2.1 From aa9d36060fb7480a5907660b7ba61c3fda20fc61 Mon Sep 17 00:00:00 2001 From: Bob Moore Date: Wed, 26 May 2010 11:03:56 +0800 Subject: ACPICA: Add comment: _BCL cannot be sorted on the fly Because of package index values used for _BQC and _BCM. Signed-off-by: Bob Moore Signed-off-by: Lin Ming Signed-off-by: Len Brown --- drivers/acpi/acpica/nsrepair2.c | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'drivers/acpi') diff --git a/drivers/acpi/acpica/nsrepair2.c b/drivers/acpi/acpica/nsrepair2.c index 61bd0f6755d2..4009498fbabd 100644 --- a/drivers/acpi/acpica/nsrepair2.c +++ b/drivers/acpi/acpica/nsrepair2.c @@ -112,6 +112,13 @@ acpi_ns_sort_list(union acpi_operand_object **elements, * _GTM: Convert Buffer of BYTEs to a Buffer of DWORDs * _PSS: Sort the list descending by Power * _TSS: Sort the list descending by Power + * + * Names that must be packages, but cannot be sorted: + * + * _BCL: Values are tied to the Package index where they appear, and cannot + * be moved or sorted. These index values are used for _BQC and _BCM. + * However, we can fix the case where a buffer is returned, by converting + * it to a Package of integers. */ static const struct acpi_repair_info acpi_ns_repairable_names[] = { {"_ALR", acpi_ns_repair_ALR}, -- cgit v1.2.1 From 507f7d5e27015be1e5dda5c56bb5e10315b76f71 Mon Sep 17 00:00:00 2001 From: Bob Moore Date: Wed, 26 May 2010 11:18:35 +0800 Subject: ACPICA: iASL/Core: Add support for _WDG/_WED MS methods These objects are defined by "Windows Instrumentation", and are not part of the ACPI spec. Adds compiler support and runtime typechecking support in the ACPICA core. ACPICA BZ 860. http://www.acpica.org/bugzilla/show_bug.cgi?id=860 Signed-off-by: Bob Moore Signed-off-by: Lin Ming Signed-off-by: Len Brown --- drivers/acpi/acpica/acpredef.h | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) (limited to 'drivers/acpi') diff --git a/drivers/acpi/acpica/acpredef.h b/drivers/acpi/acpica/acpredef.h index 97116082cb6c..10998d369ad0 100644 --- a/drivers/acpi/acpica/acpredef.h +++ b/drivers/acpi/acpica/acpredef.h @@ -503,15 +503,16 @@ static const union acpi_predefined_info predefined_names[] = {{"_WAK", 1, ACPI_RTYPE_NONE | ACPI_RTYPE_INTEGER | ACPI_RTYPE_PACKAGE}}, {{{ACPI_PTYPE1_FIXED, ACPI_RTYPE_INTEGER, 2,0}, 0,0}}, /* Fixed-length (2 Int), but is optional */ - {{{0,0,0,0}, 0,0}} /* Table terminator */ -}; + /* _WDG/_WED are MS extensions defined by "Windows Instrumentation" */ -#if 0 - /* Not implemented */ + {{"_WDG", 0, ACPI_RTYPE_BUFFER}}, + {{"_WED", 1, + ACPI_RTYPE_INTEGER | ACPI_RTYPE_STRING | ACPI_RTYPE_BUFFER}}, - {{"_WDG", 0, ACPI_RTYPE_BUFFER}}, /* MS Extension */ - {{"_WED", 1, ACPI_RTYPE_PACKAGE}}, /* MS Extension */ + {{{0, 0, 0, 0}, 0, 0}} /* Table terminator */ +}; +#if 0 /* This is an internally implemented control method, no need to check */ {{"_OSI", 1, ACPI_RTYPE_INTEGER}}, -- cgit v1.2.1 From 96b7b7ad79e4bd8a0ae67dd201f7532ef4abf1c1 Mon Sep 17 00:00:00 2001 From: Alexey Starikovskiy Date: Wed, 26 May 2010 11:20:47 +0800 Subject: ACPICA: Expand initialization counters to 32 bits Expand the various initialization counters from 16-bit to 32-bit. Allows for very large namespaces. Signed-off-by: Alexey Starikovskiy Signed-off-by: Bob Moore Signed-off-by: Lin Ming Signed-off-by: Len Brown --- drivers/acpi/acpica/acstruct.h | 26 +++++++++++++------------- drivers/acpi/acpica/dsinit.c | 14 +++++++------- drivers/acpi/acpica/nsinit.c | 8 ++++---- 3 files changed, 24 insertions(+), 24 deletions(-) (limited to 'drivers/acpi') diff --git a/drivers/acpi/acpica/acstruct.h b/drivers/acpi/acpica/acstruct.h index 161bc0e3d70a..0e2c66af3c9d 100644 --- a/drivers/acpi/acpica/acstruct.h +++ b/drivers/acpi/acpica/acstruct.h @@ -127,22 +127,22 @@ struct acpi_walk_state { acpi_parse_upwards ascending_callback; }; -/* Info used by acpi_ps_init_objects */ +/* Info used by acpi_ns_initialize_objects and acpi_ds_initialize_objects */ struct acpi_init_walk_info { - u16 method_count; - u16 device_count; - u16 op_region_count; - u16 field_count; - u16 buffer_count; - u16 package_count; - u16 op_region_init; - u16 field_init; - u16 buffer_init; - u16 package_init; - u16 object_count; - acpi_owner_id owner_id; u32 table_index; + u32 object_count; + u32 method_count; + u32 device_count; + u32 op_region_count; + u32 field_count; + u32 buffer_count; + u32 package_count; + u32 op_region_init; + u32 field_init; + u32 buffer_init; + u32 package_init; + acpi_owner_id owner_id; }; struct acpi_get_devices_info { diff --git a/drivers/acpi/acpica/dsinit.c b/drivers/acpi/acpica/dsinit.c index abe140318a74..cc4a38c57558 100644 --- a/drivers/acpi/acpica/dsinit.c +++ b/drivers/acpi/acpica/dsinit.c @@ -171,12 +171,12 @@ acpi_ds_initialize_objects(u32 table_index, "**** Starting initialization of namespace objects ****\n")); ACPI_DEBUG_PRINT_RAW((ACPI_DB_INIT, "Parsing all Control Methods:")); - info.method_count = 0; - info.op_region_count = 0; - info.object_count = 0; - info.device_count = 0; - info.table_index = table_index; + /* Set all init info to zero */ + + ACPI_MEMSET(&info, 0, sizeof(struct acpi_init_walk_info)); + info.owner_id = owner_id; + info.table_index = table_index; /* Walk entire namespace from the supplied root */ @@ -204,13 +204,13 @@ acpi_ds_initialize_objects(u32 table_index, } ACPI_DEBUG_PRINT_RAW((ACPI_DB_INIT, - "\nTable [%4.4s](id %4.4X) - %hd Objects with %hd Devices %hd Methods %hd Regions\n", + "\nTable [%4.4s](id %4.4X) - %u Objects with %u Devices %u Methods %u Regions\n", table->signature, owner_id, info.object_count, info.device_count, info.method_count, info.op_region_count)); ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH, - "%hd Methods, %hd Regions\n", info.method_count, + "%u Methods, %u Regions\n", info.method_count, info.op_region_count)); return_ACPI_STATUS(AE_OK); diff --git a/drivers/acpi/acpica/nsinit.c b/drivers/acpi/acpica/nsinit.c index 4e5272c313e0..88145820d887 100644 --- a/drivers/acpi/acpica/nsinit.c +++ b/drivers/acpi/acpica/nsinit.c @@ -103,8 +103,8 @@ acpi_status acpi_ns_initialize_objects(void) } ACPI_DEBUG_PRINT_RAW((ACPI_DB_INIT, - "\nInitialized %hd/%hd Regions %hd/%hd Fields %hd/%hd " - "Buffers %hd/%hd Packages (%hd nodes)\n", + "\nInitialized %u/%u Regions %u/%u Fields %u/%u " + "Buffers %u/%u Packages (%u nodes)\n", info.op_region_init, info.op_region_count, info.field_init, info.field_count, info.buffer_init, info.buffer_count, @@ -112,9 +112,9 @@ acpi_status acpi_ns_initialize_objects(void) info.object_count)); ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH, - "%hd Control Methods found\n", info.method_count)); + "%u Control Methods found\n", info.method_count)); ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH, - "%hd Op Regions found\n", info.op_region_count)); + "%u Op Regions found\n", info.op_region_count)); return_ACPI_STATUS(AE_OK); } -- cgit v1.2.1 From b27d65975c252ff774edff8e01f0a9fd46d8ab62 Mon Sep 17 00:00:00 2001 From: Bob Moore Date: Wed, 26 May 2010 11:47:13 +0800 Subject: ACPICA: Core: Replace all %d format specifiers with %u (unsigned) With only a few exceptions, ACPICA does not use signed integers. Therefore, %d is incorrect. Signed-off-by: Bob Moore Signed-off-by: Lin Ming Signed-off-by: Len Brown --- drivers/acpi/acpica/dsmethod.c | 2 +- drivers/acpi/acpica/dsmthdat.c | 10 +++++----- drivers/acpi/acpica/dsutils.c | 4 ++-- drivers/acpi/acpica/exdump.c | 4 ++-- drivers/acpi/acpica/exfldio.c | 4 ++-- drivers/acpi/acpica/exprep.c | 14 +++++++------- drivers/acpi/acpica/exregion.c | 6 +++--- drivers/acpi/acpica/hwsleep.c | 2 +- drivers/acpi/acpica/nsaccess.c | 4 ++-- drivers/acpi/acpica/nsdump.c | 2 +- drivers/acpi/acpica/nsparse.c | 4 ++-- 11 files changed, 28 insertions(+), 28 deletions(-) (limited to 'drivers/acpi') diff --git a/drivers/acpi/acpica/dsmethod.c b/drivers/acpi/acpica/dsmethod.c index 2a9a561c2f01..00846333773e 100644 --- a/drivers/acpi/acpica/dsmethod.c +++ b/drivers/acpi/acpica/dsmethod.c @@ -605,7 +605,7 @@ acpi_ds_terminate_control_method(union acpi_operand_object *method_desc, * we immediately reuse it for the next thread executing this method */ ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH, - "*** Completed execution of one thread, %d threads remaining\n", + "*** Completed execution of one thread, %u threads remaining\n", method_desc->method.thread_count)); } else { /* This is the only executing thread for this method */ diff --git a/drivers/acpi/acpica/dsmthdat.c b/drivers/acpi/acpica/dsmthdat.c index f3d52f59250b..d5e927f818a0 100644 --- a/drivers/acpi/acpica/dsmthdat.c +++ b/drivers/acpi/acpica/dsmthdat.c @@ -146,7 +146,7 @@ void acpi_ds_method_data_delete_all(struct acpi_walk_state *walk_state) for (index = 0; index < ACPI_METHOD_NUM_LOCALS; index++) { if (walk_state->local_variables[index].object) { - ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "Deleting Local%d=%p\n", + ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "Deleting Local%u=%p\n", index, walk_state->local_variables[index]. object)); @@ -162,7 +162,7 @@ void acpi_ds_method_data_delete_all(struct acpi_walk_state *walk_state) for (index = 0; index < ACPI_METHOD_NUM_ARGS; index++) { if (walk_state->arguments[index].object) { - ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "Deleting Arg%d=%p\n", + ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "Deleting Arg%u=%p\n", index, walk_state->arguments[index].object)); @@ -226,7 +226,7 @@ acpi_ds_method_data_init_args(union acpi_operand_object **params, index++; } - ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "%d args passed to method\n", index)); + ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "%u args passed to method\n", index)); return_ACPI_STATUS(AE_OK); } @@ -323,7 +323,7 @@ acpi_ds_method_data_set_value(u8 type, ACPI_FUNCTION_TRACE(ds_method_data_set_value); ACPI_DEBUG_PRINT((ACPI_DB_EXEC, - "NewObj %p Type %2.2X, Refs=%d [%s]\n", object, + "NewObj %p Type %2.2X, Refs=%u [%s]\n", object, type, object->common.reference_count, acpi_ut_get_type_name(object->common.type))); @@ -543,7 +543,7 @@ acpi_ds_store_object_to_local(u8 type, union acpi_operand_object *new_obj_desc; ACPI_FUNCTION_TRACE(ds_store_object_to_local); - ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "Type=%2.2X Index=%d Obj=%p\n", + ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "Type=%2.2X Index=%u Obj=%p\n", type, index, obj_desc)); /* Parameter validation */ diff --git a/drivers/acpi/acpica/dsutils.c b/drivers/acpi/acpica/dsutils.c index 306c62ab2e88..15135c25aa9b 100644 --- a/drivers/acpi/acpica/dsutils.c +++ b/drivers/acpi/acpica/dsutils.c @@ -746,7 +746,7 @@ acpi_ds_create_operands(struct acpi_walk_state *walk_state, index--; ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH, - "Arg #%d (%p) done, Arg1=%p\n", index, arg, + "Arg #%u (%p) done, Arg1=%p\n", index, arg, first_arg)); } @@ -760,7 +760,7 @@ acpi_ds_create_operands(struct acpi_walk_state *walk_state, */ acpi_ds_obj_stack_pop_and_delete(arg_count, walk_state); - ACPI_EXCEPTION((AE_INFO, status, "While creating Arg %d", index)); + ACPI_EXCEPTION((AE_INFO, status, "While creating Arg %u", index)); return_ACPI_STATUS(status); } diff --git a/drivers/acpi/acpica/exdump.c b/drivers/acpi/acpica/exdump.c index d39d438ba1e3..cdb66d1e3fde 100644 --- a/drivers/acpi/acpica/exdump.c +++ b/drivers/acpi/acpica/exdump.c @@ -742,7 +742,7 @@ acpi_ex_dump_operands(union acpi_operand_object **operands, } ACPI_DEBUG_PRINT((ACPI_DB_EXEC, - "**** Start operand dump for opcode [%s], %d operands\n", + "**** Start operand dump for opcode [%s], %u operands\n", opcode_name, num_operands)); if (num_operands == 0) { @@ -945,7 +945,7 @@ acpi_ex_dump_package_obj(union acpi_operand_object *obj_desc, case ACPI_TYPE_PACKAGE: - acpi_os_printf("[Package] Contains %d Elements:\n", + acpi_os_printf("[Package] Contains %u Elements:\n", obj_desc->package.count); for (i = 0; i < obj_desc->package.count; i++) { diff --git a/drivers/acpi/acpica/exfldio.c b/drivers/acpi/acpica/exfldio.c index a6dc26f0b3be..047217303a4b 100644 --- a/drivers/acpi/acpica/exfldio.c +++ b/drivers/acpi/acpica/exfldio.c @@ -534,13 +534,13 @@ acpi_ex_field_datum_io(union acpi_operand_object *obj_desc, if (ACPI_SUCCESS(status)) { if (read_write == ACPI_READ) { ACPI_DEBUG_PRINT((ACPI_DB_BFIELD, - "Value Read %8.8X%8.8X, Width %d\n", + "Value Read %8.8X%8.8X, Width %u\n", ACPI_FORMAT_UINT64(*value), obj_desc->common_field. access_byte_width)); } else { ACPI_DEBUG_PRINT((ACPI_DB_BFIELD, - "Value Written %8.8X%8.8X, Width %d\n", + "Value Written %8.8X%8.8X, Width %u\n", ACPI_FORMAT_UINT64(*value), obj_desc->common_field. access_byte_width)); diff --git a/drivers/acpi/acpica/exprep.c b/drivers/acpi/acpica/exprep.c index 25059dace0ad..0686f271c61e 100644 --- a/drivers/acpi/acpica/exprep.c +++ b/drivers/acpi/acpica/exprep.c @@ -108,11 +108,11 @@ acpi_ex_generate_access(u32 field_bit_offset, field_byte_length = field_byte_end_offset - field_byte_offset; ACPI_DEBUG_PRINT((ACPI_DB_BFIELD, - "Bit length %d, Bit offset %d\n", + "Bit length %u, Bit offset %u\n", field_bit_length, field_bit_offset)); ACPI_DEBUG_PRINT((ACPI_DB_BFIELD, - "Byte Length %d, Byte Offset %d, End Offset %d\n", + "Byte Length %u, Byte Offset %u, End Offset %u\n", field_byte_length, field_byte_offset, field_byte_end_offset)); @@ -147,11 +147,11 @@ acpi_ex_generate_access(u32 field_bit_offset, accesses = field_end_offset - field_start_offset; ACPI_DEBUG_PRINT((ACPI_DB_BFIELD, - "AccessWidth %d end is within region\n", + "AccessWidth %u end is within region\n", access_byte_width)); ACPI_DEBUG_PRINT((ACPI_DB_BFIELD, - "Field Start %d, Field End %d -- requires %d accesses\n", + "Field Start %u, Field End %u -- requires %u accesses\n", field_start_offset, field_end_offset, accesses)); @@ -159,7 +159,7 @@ acpi_ex_generate_access(u32 field_bit_offset, if (accesses <= 1) { ACPI_DEBUG_PRINT((ACPI_DB_BFIELD, - "Entire field can be accessed with one operation of size %d\n", + "Entire field can be accessed with one operation of size %u\n", access_byte_width)); return_VALUE(access_byte_width); } @@ -174,7 +174,7 @@ acpi_ex_generate_access(u32 field_bit_offset, } } else { ACPI_DEBUG_PRINT((ACPI_DB_BFIELD, - "AccessWidth %d end is NOT within region\n", + "AccessWidth %u end is NOT within region\n", access_byte_width)); if (access_byte_width == 1) { ACPI_DEBUG_PRINT((ACPI_DB_BFIELD, @@ -190,7 +190,7 @@ acpi_ex_generate_access(u32 field_bit_offset, * previous access */ ACPI_DEBUG_PRINT((ACPI_DB_BFIELD, - "Backing off to previous optimal access width of %d\n", + "Backing off to previous optimal access width of %u\n", minimum_access_width)); return_VALUE(minimum_access_width); } diff --git a/drivers/acpi/acpica/exregion.c b/drivers/acpi/acpica/exregion.c index 531000fc77d2..8819d2ac5aee 100644 --- a/drivers/acpi/acpica/exregion.c +++ b/drivers/acpi/acpica/exregion.c @@ -194,7 +194,7 @@ acpi_ex_system_memory_space_handler(u32 function, ((u64) address - (u64) mem_info->mapped_physical_address); ACPI_DEBUG_PRINT((ACPI_DB_INFO, - "System-Memory (width %d) R/W %d Address=%8.8X%8.8X\n", + "System-Memory (width %u) R/W %u Address=%8.8X%8.8X\n", bit_width, function, ACPI_FORMAT_NATIVE_UINT(address))); @@ -297,7 +297,7 @@ acpi_ex_system_io_space_handler(u32 function, ACPI_FUNCTION_TRACE(ex_system_io_space_handler); ACPI_DEBUG_PRINT((ACPI_DB_INFO, - "System-IO (width %d) R/W %d Address=%8.8X%8.8X\n", + "System-IO (width %u) R/W %u Address=%8.8X%8.8X\n", bit_width, function, ACPI_FORMAT_NATIVE_UINT(address))); @@ -373,7 +373,7 @@ acpi_ex_pci_config_space_handler(u32 function, pci_register = (u16) (u32) address; ACPI_DEBUG_PRINT((ACPI_DB_INFO, - "Pci-Config %d (%d) Seg(%04x) Bus(%04x) Dev(%04x) Func(%04x) Reg(%04x)\n", + "Pci-Config %u (%u) Seg(%04x) Bus(%04x) Dev(%04x) Func(%04x) Reg(%04x)\n", function, bit_width, pci_id->segment, pci_id->bus, pci_id->device, pci_id->function, pci_register)); diff --git a/drivers/acpi/acpica/hwsleep.c b/drivers/acpi/acpica/hwsleep.c index 36eb803dd9d0..3796811276ac 100644 --- a/drivers/acpi/acpica/hwsleep.c +++ b/drivers/acpi/acpica/hwsleep.c @@ -307,7 +307,7 @@ acpi_status asmlinkage acpi_enter_sleep_state(u8 sleep_state) return_ACPI_STATUS(status); } ACPI_DEBUG_PRINT((ACPI_DB_INIT, - "Entering sleep state [S%d]\n", sleep_state)); + "Entering sleep state [S%u]\n", sleep_state)); /* Clear the SLP_EN and SLP_TYP fields */ diff --git a/drivers/acpi/acpica/nsaccess.c b/drivers/acpi/acpica/nsaccess.c index 3a2814676ac3..2cebfa94b79a 100644 --- a/drivers/acpi/acpica/nsaccess.c +++ b/drivers/acpi/acpica/nsaccess.c @@ -433,7 +433,7 @@ acpi_ns_lookup(union acpi_generic_state *scope_info, if (search_parent_flag == ACPI_NS_NO_UPSEARCH) { ACPI_DEBUG_PRINT((ACPI_DB_NAMES, - "Search scope is [%4.4s], path has %d carat(s)\n", + "Search scope is [%4.4s], path has %u carat(s)\n", acpi_ut_get_node_name (this_node), num_carats)); } @@ -495,7 +495,7 @@ acpi_ns_lookup(union acpi_generic_state *scope_info, path++; ACPI_DEBUG_PRINT((ACPI_DB_NAMES, - "Multi Pathname (%d Segments, Flags=%X)\n", + "Multi Pathname (%u Segments, Flags=%X)\n", num_segments, flags)); break; diff --git a/drivers/acpi/acpica/nsdump.c b/drivers/acpi/acpica/nsdump.c index 2110cc2360f0..a54dc39e304b 100644 --- a/drivers/acpi/acpica/nsdump.c +++ b/drivers/acpi/acpica/nsdump.c @@ -441,7 +441,7 @@ acpi_ns_dump_one_object(acpi_handle obj_handle, return (AE_OK); } - acpi_os_printf("(R%d)", obj_desc->common.reference_count); + acpi_os_printf("(R%u)", obj_desc->common.reference_count); switch (type) { case ACPI_TYPE_METHOD: diff --git a/drivers/acpi/acpica/nsparse.c b/drivers/acpi/acpica/nsparse.c index 27cda52c76bc..5808c89e9fac 100644 --- a/drivers/acpi/acpica/nsparse.c +++ b/drivers/acpi/acpica/nsparse.c @@ -136,8 +136,8 @@ acpi_ns_one_complete_parse(u32 pass_number, /* Parse the AML */ - ACPI_DEBUG_PRINT((ACPI_DB_PARSE, "*PARSE* pass %d parse\n", - (unsigned)pass_number)); + ACPI_DEBUG_PRINT((ACPI_DB_PARSE, "*PARSE* pass %u parse\n", + pass_number)); status = acpi_ps_parse_aml(walk_state); cleanup: -- cgit v1.2.1 From 5821f75421aa7c7bafdec291223153597f649934 Mon Sep 17 00:00:00 2001 From: Bob Moore Date: Wed, 26 May 2010 11:48:22 +0800 Subject: ACPICA: Expand device initialization counters to 32 bits Expand the various device initialization counters from 16-bit to 32-bit. Allows for very large namespaces. Signed-off-by: Bob Moore Signed-off-by: Lin Ming Signed-off-by: Len Brown --- drivers/acpi/acpica/acstruct.h | 6 +++--- drivers/acpi/acpica/nsinit.c | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) (limited to 'drivers/acpi') diff --git a/drivers/acpi/acpica/acstruct.h b/drivers/acpi/acpica/acstruct.h index 0e2c66af3c9d..6e5dd97949fe 100644 --- a/drivers/acpi/acpica/acstruct.h +++ b/drivers/acpi/acpica/acstruct.h @@ -201,11 +201,11 @@ struct acpi_evaluate_info { /* Info used by acpi_ns_initialize_devices */ struct acpi_device_walk_info { - u16 device_count; - u16 num_STA; - u16 num_INI; struct acpi_table_desc *table_desc; struct acpi_evaluate_info *evaluate_info; + u32 device_count; + u32 num_STA; + u32 num_INI; }; /* TBD: [Restructure] Merge with struct above */ diff --git a/drivers/acpi/acpica/nsinit.c b/drivers/acpi/acpica/nsinit.c index 88145820d887..f0e49df7c13b 100644 --- a/drivers/acpi/acpica/nsinit.c +++ b/drivers/acpi/acpica/nsinit.c @@ -208,8 +208,8 @@ acpi_status acpi_ns_initialize_devices(void) } ACPI_DEBUG_PRINT_RAW((ACPI_DB_INIT, - "\nExecuted %hd _INI methods requiring %hd _STA executions " - "(examined %hd objects)\n", + "\nExecuted %u _INI methods requiring %u _STA executions " + "(examined %u objects)\n", info.num_INI, info.num_STA, info.device_count)); return_ACPI_STATUS(status); -- cgit v1.2.1 From c45b5c097001480e66d4c523eb715ad317a4ef77 Mon Sep 17 00:00:00 2001 From: Alexey Starikovskiy Date: Wed, 26 May 2010 11:53:07 +0800 Subject: ACPICA: Performance enhancement for namespace search and access This change enhances the performance of namespace searches and walks by adding a backpointer to the parent in each namespace node. On large namespaces, this change can improve overall ACPI performance by up to 9X. Adding a pointer to each namespace node increases the overall size of the internal namespace by about 5%, since each namespace entry usually consists of both a namespace node and an ACPI operand object. Signed-off-by: Alexey Starikovskiy Signed-off-by: Bob Moore Signed-off-by: Lin Ming Signed-off-by: Len Brown --- drivers/acpi/acpica/aclocal.h | 5 +- drivers/acpi/acpica/acnamesp.h | 7 --- drivers/acpi/acpica/dsmthdat.c | 6 +-- drivers/acpi/acpica/dsopcode.c | 6 +-- drivers/acpi/acpica/evrgnini.c | 10 ++-- drivers/acpi/acpica/exdump.c | 2 +- drivers/acpi/acpica/nsaccess.c | 5 +- drivers/acpi/acpica/nsalloc.c | 74 +++++++++------------------ drivers/acpi/acpica/nsinit.c | 4 +- drivers/acpi/acpica/nsnames.c | 4 +- drivers/acpi/acpica/nssearch.c | 15 +----- drivers/acpi/acpica/nsutils.c | 113 ----------------------------------------- drivers/acpi/acpica/nswalk.c | 15 ++---- drivers/acpi/acpica/nsxfobj.c | 2 +- drivers/acpi/acpica/utglobal.c | 2 +- 15 files changed, 52 insertions(+), 218 deletions(-) (limited to 'drivers/acpi') diff --git a/drivers/acpi/acpica/aclocal.h b/drivers/acpi/acpica/aclocal.h index 147a7e6bd38f..eb2d420b39ec 100644 --- a/drivers/acpi/acpica/aclocal.h +++ b/drivers/acpi/acpica/aclocal.h @@ -184,8 +184,9 @@ struct acpi_namespace_node { u8 flags; /* Miscellaneous flags */ acpi_owner_id owner_id; /* Node creator */ union acpi_name_union name; /* ACPI Name, always 4 chars per ACPI spec */ + struct acpi_namespace_node *parent; /* Parent node */ struct acpi_namespace_node *child; /* First child */ - struct acpi_namespace_node *peer; /* Peer. Parent if ANOBJ_END_OF_PEER_LIST set */ + struct acpi_namespace_node *peer; /* First peer */ /* * The following fields are used by the ASL compiler and disassembler only @@ -199,7 +200,7 @@ struct acpi_namespace_node { /* Namespace Node flags */ -#define ANOBJ_END_OF_PEER_LIST 0x01 /* End-of-list, Peer field points to parent */ +#define ANOBJ_RESERVED 0x01 /* Available for use */ #define ANOBJ_TEMPORARY 0x02 /* Node is create by a method and is temporary */ #define ANOBJ_METHOD_ARG 0x04 /* Node is a method argument */ #define ANOBJ_METHOD_LOCAL 0x08 /* Node is a method local */ diff --git a/drivers/acpi/acpica/acnamesp.h b/drivers/acpi/acpica/acnamesp.h index 258159cfcdfa..9f60ff002203 100644 --- a/drivers/acpi/acpica/acnamesp.h +++ b/drivers/acpi/acpica/acnamesp.h @@ -369,11 +369,4 @@ struct acpi_namespace_node *acpi_ns_validate_handle(acpi_handle handle); void acpi_ns_terminate(void); -struct acpi_namespace_node *acpi_ns_get_parent_node(struct acpi_namespace_node - *node); - -struct acpi_namespace_node *acpi_ns_get_next_valid_node(struct - acpi_namespace_node - *node); - #endif /* __ACNAMESP_H__ */ diff --git a/drivers/acpi/acpica/dsmthdat.c b/drivers/acpi/acpica/dsmthdat.c index d5e927f818a0..8095306fcd8c 100644 --- a/drivers/acpi/acpica/dsmthdat.c +++ b/drivers/acpi/acpica/dsmthdat.c @@ -102,8 +102,7 @@ void acpi_ds_method_data_init(struct acpi_walk_state *walk_state) walk_state->arguments[i].name.integer |= (i << 24); walk_state->arguments[i].descriptor_type = ACPI_DESC_TYPE_NAMED; walk_state->arguments[i].type = ACPI_TYPE_ANY; - walk_state->arguments[i].flags = - ANOBJ_END_OF_PEER_LIST | ANOBJ_METHOD_ARG; + walk_state->arguments[i].flags = ANOBJ_METHOD_ARG; } /* Init the method locals */ @@ -116,8 +115,7 @@ void acpi_ds_method_data_init(struct acpi_walk_state *walk_state) walk_state->local_variables[i].descriptor_type = ACPI_DESC_TYPE_NAMED; walk_state->local_variables[i].type = ACPI_TYPE_ANY; - walk_state->local_variables[i].flags = - ANOBJ_END_OF_PEER_LIST | ANOBJ_METHOD_LOCAL; + walk_state->local_variables[i].flags = ANOBJ_METHOD_LOCAL; } return_VOID; diff --git a/drivers/acpi/acpica/dsopcode.c b/drivers/acpi/acpica/dsopcode.c index 53a7e416f33e..7c0e74227171 100644 --- a/drivers/acpi/acpica/dsopcode.c +++ b/drivers/acpi/acpica/dsopcode.c @@ -213,7 +213,7 @@ acpi_ds_get_buffer_field_arguments(union acpi_operand_object *obj_desc) /* Execute the AML code for the term_arg arguments */ - status = acpi_ds_execute_arguments(node, acpi_ns_get_parent_node(node), + status = acpi_ds_execute_arguments(node, node->parent, extra_desc->extra.aml_length, extra_desc->extra.aml_start); return_ACPI_STATUS(status); @@ -257,7 +257,7 @@ acpi_ds_get_bank_field_arguments(union acpi_operand_object *obj_desc) /* Execute the AML code for the term_arg arguments */ - status = acpi_ds_execute_arguments(node, acpi_ns_get_parent_node(node), + status = acpi_ds_execute_arguments(node, node->parent, extra_desc->extra.aml_length, extra_desc->extra.aml_start); return_ACPI_STATUS(status); @@ -394,7 +394,7 @@ acpi_status acpi_ds_get_region_arguments(union acpi_operand_object *obj_desc) /* Execute the argument AML */ - status = acpi_ds_execute_arguments(node, acpi_ns_get_parent_node(node), + status = acpi_ds_execute_arguments(node, node->parent, extra_desc->extra.aml_length, extra_desc->extra.aml_start); if (ACPI_FAILURE(status)) { diff --git a/drivers/acpi/acpica/evrgnini.c b/drivers/acpi/acpica/evrgnini.c index 2e3b0334072f..f40d271bf568 100644 --- a/drivers/acpi/acpica/evrgnini.c +++ b/drivers/acpi/acpica/evrgnini.c @@ -199,7 +199,7 @@ acpi_ev_pci_config_region_setup(acpi_handle handle, return_ACPI_STATUS(status); } - parent_node = acpi_ns_get_parent_node(region_obj->region.node); + parent_node = region_obj->region.node->parent; /* * Get the _SEG and _BBN values from the device upon which the handler @@ -248,7 +248,7 @@ acpi_ev_pci_config_region_setup(acpi_handle handle, break; } - pci_root_node = acpi_ns_get_parent_node(pci_root_node); + pci_root_node = pci_root_node->parent; } /* PCI root bridge not found, use namespace root node */ @@ -280,7 +280,7 @@ acpi_ev_pci_config_region_setup(acpi_handle handle, */ pci_device_node = region_obj->region.node; while (pci_device_node && (pci_device_node->type != ACPI_TYPE_DEVICE)) { - pci_device_node = acpi_ns_get_parent_node(pci_device_node); + pci_device_node = pci_device_node->parent; } if (!pci_device_node) { @@ -521,7 +521,7 @@ acpi_ev_initialize_region(union acpi_operand_object *region_obj, return_ACPI_STATUS(AE_NOT_EXIST); } - node = acpi_ns_get_parent_node(region_obj->region.node); + node = region_obj->region.node->parent; space_id = region_obj->region.space_id; /* Setup defaults */ @@ -654,7 +654,7 @@ acpi_ev_initialize_region(union acpi_operand_object *region_obj, /* This node does not have the handler we need; Pop up one level */ - node = acpi_ns_get_parent_node(node); + node = node->parent; } /* If we get here, there is no handler for this region */ diff --git a/drivers/acpi/acpica/exdump.c b/drivers/acpi/acpica/exdump.c index cdb66d1e3fde..f067bbb0d961 100644 --- a/drivers/acpi/acpica/exdump.c +++ b/drivers/acpi/acpica/exdump.c @@ -812,7 +812,7 @@ void acpi_ex_dump_namespace_node(struct acpi_namespace_node *node, u32 flags) acpi_ex_out_string("Type", acpi_ut_get_type_name(node->type)); acpi_ex_out_pointer("Attached Object", acpi_ns_get_attached_object(node)); - acpi_ex_out_pointer("Parent", acpi_ns_get_parent_node(node)); + acpi_ex_out_pointer("Parent", node->parent); acpi_ex_dump_object(ACPI_CAST_PTR(union acpi_operand_object, node), acpi_ex_dump_node); diff --git a/drivers/acpi/acpica/nsaccess.c b/drivers/acpi/acpica/nsaccess.c index 2cebfa94b79a..0cd925be5fc1 100644 --- a/drivers/acpi/acpica/nsaccess.c +++ b/drivers/acpi/acpica/nsaccess.c @@ -338,8 +338,7 @@ acpi_ns_lookup(union acpi_generic_state *scope_info, */ while (!acpi_ns_opens_scope(prefix_node->type) && prefix_node->type != ACPI_TYPE_ANY) { - prefix_node = - acpi_ns_get_parent_node(prefix_node); + prefix_node = prefix_node->parent; } } } @@ -419,7 +418,7 @@ acpi_ns_lookup(union acpi_generic_state *scope_info, /* Backup to the parent node */ num_carats++; - this_node = acpi_ns_get_parent_node(this_node); + this_node = this_node->parent; if (!this_node) { /* Current scope has no parent scope */ diff --git a/drivers/acpi/acpica/nsalloc.c b/drivers/acpi/acpica/nsalloc.c index 982269c1fa48..8d3a43a061ab 100644 --- a/drivers/acpi/acpica/nsalloc.c +++ b/drivers/acpi/acpica/nsalloc.c @@ -159,7 +159,7 @@ void acpi_ns_remove_node(struct acpi_namespace_node *node) ACPI_FUNCTION_TRACE_PTR(ns_remove_node, node); - parent_node = acpi_ns_get_parent_node(node); + parent_node = node->parent; prev_node = NULL; next_node = parent_node->child; @@ -168,29 +168,20 @@ void acpi_ns_remove_node(struct acpi_namespace_node *node) while (next_node != node) { prev_node = next_node; - next_node = prev_node->peer; + next_node = next_node->peer; } if (prev_node) { /* Node is not first child, unlink it */ - prev_node->peer = next_node->peer; - if (next_node->flags & ANOBJ_END_OF_PEER_LIST) { - prev_node->flags |= ANOBJ_END_OF_PEER_LIST; - } + prev_node->peer = node->peer; } else { - /* Node is first child (has no previous peer) */ - - if (next_node->flags & ANOBJ_END_OF_PEER_LIST) { - - /* No peers at all */ - - parent_node->child = NULL; - } else { /* Link peer list to parent */ - - parent_node->child = next_node->peer; - } + /* + * Node is first child (has no previous peer). + * Link peer list to parent + */ + parent_node->child = node->peer; } /* Delete the node and any attached objects */ @@ -238,23 +229,20 @@ void acpi_ns_install_node(struct acpi_walk_state *walk_state, struct acpi_namesp /* Link the new entry into the parent and existing children */ + node->peer = NULL; + node->parent = parent_node; child_node = parent_node->child; + if (!child_node) { parent_node->child = node; - node->flags |= ANOBJ_END_OF_PEER_LIST; - node->peer = parent_node; } else { - while (!(child_node->flags & ANOBJ_END_OF_PEER_LIST)) { + /* Add node to the end of the peer list */ + + while (child_node->peer) { child_node = child_node->peer; } child_node->peer = node; - - /* Clear end-of-list flag */ - - child_node->flags &= ~ANOBJ_END_OF_PEER_LIST; - node->flags |= ANOBJ_END_OF_PEER_LIST; - node->peer = parent_node; } /* Init the new entry */ @@ -288,9 +276,8 @@ void acpi_ns_install_node(struct acpi_walk_state *walk_state, struct acpi_namesp void acpi_ns_delete_children(struct acpi_namespace_node *parent_node) { - struct acpi_namespace_node *child_node; struct acpi_namespace_node *next_node; - u8 flags; + struct acpi_namespace_node *node_to_delete; ACPI_FUNCTION_TRACE_PTR(ns_delete_children, parent_node); @@ -298,37 +285,26 @@ void acpi_ns_delete_children(struct acpi_namespace_node *parent_node) return_VOID; } - /* If no children, all done! */ - - child_node = parent_node->child; - if (!child_node) { - return_VOID; - } - /* Deallocate all children at this level */ - do { - - /* Get the things we need */ - - next_node = child_node->peer; - flags = child_node->flags; + next_node = parent_node->child; + while (next_node) { /* Grandchildren should have all been deleted already */ - if (child_node->child) { + if (next_node->child) { ACPI_ERROR((AE_INFO, "Found a grandchild! P=%p C=%p", - parent_node, child_node)); + parent_node, next_node)); } /* * Delete this child node and move on to the next child in the list. * No need to unlink the node since we are deleting the entire branch. */ - acpi_ns_delete_node(child_node); - child_node = next_node; - - } while (!(flags & ANOBJ_END_OF_PEER_LIST)); + node_to_delete = next_node; + next_node = next_node->peer; + acpi_ns_delete_node(node_to_delete); + }; /* Clear the parent's child pointer */ @@ -405,7 +381,7 @@ void acpi_ns_delete_namespace_subtree(struct acpi_namespace_node *parent_node) /* Move up the tree to the grandparent */ - parent_node = acpi_ns_get_parent_node(parent_node); + parent_node = parent_node->parent; } } @@ -510,7 +486,7 @@ void acpi_ns_delete_namespace_by_owner(acpi_owner_id owner_id) /* Move up the tree to the grandparent */ - parent_node = acpi_ns_get_parent_node(parent_node); + parent_node = parent_node->parent; } } diff --git a/drivers/acpi/acpica/nsinit.c b/drivers/acpi/acpica/nsinit.c index f0e49df7c13b..660a2728908d 100644 --- a/drivers/acpi/acpica/nsinit.c +++ b/drivers/acpi/acpica/nsinit.c @@ -410,7 +410,7 @@ acpi_ns_find_ini_methods(acpi_handle obj_handle, * The only _INI methods that we care about are those that are * present under Device, Processor, and Thermal objects. */ - parent_node = acpi_ns_get_parent_node(node); + parent_node = node->parent; switch (parent_node->type) { case ACPI_TYPE_DEVICE: case ACPI_TYPE_PROCESSOR: @@ -420,7 +420,7 @@ acpi_ns_find_ini_methods(acpi_handle obj_handle, while (parent_node) { parent_node->flags |= ANOBJ_SUBTREE_HAS_INI; - parent_node = acpi_ns_get_parent_node(parent_node); + parent_node = parent_node->parent; } break; diff --git a/drivers/acpi/acpica/nsnames.c b/drivers/acpi/acpica/nsnames.c index 7dea0031605c..d3104af57e13 100644 --- a/drivers/acpi/acpica/nsnames.c +++ b/drivers/acpi/acpica/nsnames.c @@ -93,7 +93,7 @@ acpi_ns_build_external_path(struct acpi_namespace_node *node, /* Put the name into the buffer */ ACPI_MOVE_32_TO_32((name_buffer + index), &parent_node->name); - parent_node = acpi_ns_get_parent_node(parent_node); + parent_node = parent_node->parent; /* Prefix name with the path separator */ @@ -198,7 +198,7 @@ acpi_size acpi_ns_get_pathname_length(struct acpi_namespace_node *node) return 0; } size += ACPI_PATH_SEGMENT_LENGTH; - next_node = acpi_ns_get_parent_node(next_node); + next_node = next_node->parent; } if (!size) { diff --git a/drivers/acpi/acpica/nssearch.c b/drivers/acpi/acpica/nssearch.c index a8e42b5e9463..41102a84272f 100644 --- a/drivers/acpi/acpica/nssearch.c +++ b/drivers/acpi/acpica/nssearch.c @@ -152,17 +152,6 @@ acpi_ns_search_one_scope(u32 target_name, return_ACPI_STATUS(AE_OK); } - /* - * The last entry in the list points back to the parent, - * so a flag is used to indicate the end-of-list - */ - if (node->flags & ANOBJ_END_OF_PEER_LIST) { - - /* Searched entire list, we are done */ - - break; - } - /* Didn't match name, move on to the next peer object */ node = node->peer; @@ -217,7 +206,7 @@ acpi_ns_search_parent_tree(u32 target_name, ACPI_FUNCTION_TRACE(ns_search_parent_tree); - parent_node = acpi_ns_get_parent_node(node); + parent_node = node->parent; /* * If there is no parent (i.e., we are at the root) or type is "local", @@ -261,7 +250,7 @@ acpi_ns_search_parent_tree(u32 target_name, /* Not found here, go up another level (until we reach the root) */ - parent_node = acpi_ns_get_parent_node(parent_node); + parent_node = parent_node->parent; } /* Not found in parent tree */ diff --git a/drivers/acpi/acpica/nsutils.c b/drivers/acpi/acpica/nsutils.c index bab559712da1..e1add3491b04 100644 --- a/drivers/acpi/acpica/nsutils.c +++ b/drivers/acpi/acpica/nsutils.c @@ -847,116 +847,3 @@ acpi_ns_get_node(struct acpi_namespace_node *prefix_node, ACPI_FREE(internal_path); return_ACPI_STATUS(status); } - -/******************************************************************************* - * - * FUNCTION: acpi_ns_get_parent_node - * - * PARAMETERS: Node - Current table entry - * - * RETURN: Parent entry of the given entry - * - * DESCRIPTION: Obtain the parent entry for a given entry in the namespace. - * - ******************************************************************************/ - -struct acpi_namespace_node *acpi_ns_get_parent_node(struct acpi_namespace_node - *node) -{ - ACPI_FUNCTION_ENTRY(); - - if (!node) { - return (NULL); - } - - /* - * Walk to the end of this peer list. The last entry is marked with a flag - * and the peer pointer is really a pointer back to the parent. This saves - * putting a parent back pointer in each and every named object! - */ - while (!(node->flags & ANOBJ_END_OF_PEER_LIST)) { - node = node->peer; - } - - return (node->peer); -} - -/******************************************************************************* - * - * FUNCTION: acpi_ns_get_next_valid_node - * - * PARAMETERS: Node - Current table entry - * - * RETURN: Next valid Node in the linked node list. NULL if no more valid - * nodes. - * - * DESCRIPTION: Find the next valid node within a name table. - * Useful for implementing NULL-end-of-list loops. - * - ******************************************************************************/ - -struct acpi_namespace_node *acpi_ns_get_next_valid_node(struct - acpi_namespace_node - *node) -{ - - /* If we are at the end of this peer list, return NULL */ - - if (node->flags & ANOBJ_END_OF_PEER_LIST) { - return NULL; - } - - /* Otherwise just return the next peer */ - - return (node->peer); -} - -#ifdef ACPI_OBSOLETE_FUNCTIONS -/******************************************************************************* - * - * FUNCTION: acpi_ns_find_parent_name - * - * PARAMETERS: *child_node - Named Obj whose name is to be found - * - * RETURN: The ACPI name - * - * DESCRIPTION: Search for the given obj in its parent scope and return the - * name segment, or "????" if the parent name can't be found - * (which "should not happen"). - * - ******************************************************************************/ - -acpi_name acpi_ns_find_parent_name(struct acpi_namespace_node * child_node) -{ - struct acpi_namespace_node *parent_node; - - ACPI_FUNCTION_TRACE(ns_find_parent_name); - - if (child_node) { - - /* Valid entry. Get the parent Node */ - - parent_node = acpi_ns_get_parent_node(child_node); - if (parent_node) { - ACPI_DEBUG_PRINT((ACPI_DB_EXEC, - "Parent of %p [%4.4s] is %p [%4.4s]\n", - child_node, - acpi_ut_get_node_name(child_node), - parent_node, - acpi_ut_get_node_name(parent_node))); - - if (parent_node->name.integer) { - return_VALUE((acpi_name) parent_node->name. - integer); - } - } - - ACPI_DEBUG_PRINT((ACPI_DB_EXEC, - "Unable to find parent of %p (%4.4s)\n", - child_node, - acpi_ut_get_node_name(child_node))); - } - - return_VALUE(ACPI_UNKNOWN_NAME); -} -#endif diff --git a/drivers/acpi/acpica/nswalk.c b/drivers/acpi/acpica/nswalk.c index 00e79fb26029..2cd5be8fe10f 100644 --- a/drivers/acpi/acpica/nswalk.c +++ b/drivers/acpi/acpica/nswalk.c @@ -79,15 +79,6 @@ struct acpi_namespace_node *acpi_ns_get_next_node(struct acpi_namespace_node return parent_node->child; } - /* - * Get the next node. - * - * If we are at the end of this peer list, return NULL - */ - if (child_node->flags & ANOBJ_END_OF_PEER_LIST) { - return NULL; - } - /* Otherwise just return the next peer */ return child_node->peer; @@ -146,9 +137,9 @@ struct acpi_namespace_node *acpi_ns_get_next_node_typed(acpi_object_type type, return (next_node); } - /* Otherwise, move on to the next node */ + /* Otherwise, move on to the next peer node */ - next_node = acpi_ns_get_next_valid_node(next_node); + next_node = next_node->peer; } /* Not found */ @@ -355,7 +346,7 @@ acpi_ns_walk_namespace(acpi_object_type type, */ level--; child_node = parent_node; - parent_node = acpi_ns_get_parent_node(parent_node); + parent_node = parent_node->parent; node_previously_visited = TRUE; } diff --git a/drivers/acpi/acpica/nsxfobj.c b/drivers/acpi/acpica/nsxfobj.c index eafef24ea448..a1f04e9b8030 100644 --- a/drivers/acpi/acpica/nsxfobj.c +++ b/drivers/acpi/acpica/nsxfobj.c @@ -190,7 +190,7 @@ acpi_status acpi_get_parent(acpi_handle handle, acpi_handle * ret_handle) /* Get the parent entry */ - parent_node = acpi_ns_get_parent_node(node); + parent_node = node->parent; *ret_handle = ACPI_CAST_PTR(acpi_handle, parent_node); /* Return exception if parent is null */ diff --git a/drivers/acpi/acpica/utglobal.c b/drivers/acpi/acpica/utglobal.c index 66116750a0f9..0558747579ef 100644 --- a/drivers/acpi/acpica/utglobal.c +++ b/drivers/acpi/acpica/utglobal.c @@ -813,10 +813,10 @@ acpi_status acpi_ut_init_globals(void) acpi_gbl_root_node_struct.name.integer = ACPI_ROOT_NAME; acpi_gbl_root_node_struct.descriptor_type = ACPI_DESC_TYPE_NAMED; acpi_gbl_root_node_struct.type = ACPI_TYPE_DEVICE; + acpi_gbl_root_node_struct.parent = NULL; acpi_gbl_root_node_struct.child = NULL; acpi_gbl_root_node_struct.peer = NULL; acpi_gbl_root_node_struct.object = NULL; - acpi_gbl_root_node_struct.flags = ANOBJ_END_OF_PEER_LIST; #ifdef ACPI_DEBUG_OUTPUT acpi_gbl_lowest_stack_pointer = ACPI_CAST_PTR(acpi_size, ACPI_SIZE_MAX); -- cgit v1.2.1 From 20d33aea7ae7ad858f3f91c834d9043cd8122d38 Mon Sep 17 00:00:00 2001 From: Bob Moore Date: Thu, 27 May 2010 09:27:34 +0800 Subject: ACPICA: Update flags for operand object Remove obsolete AOPOBJ_SINGLE_DATUM. Add AOPOBJ_INVALID for use if the host OS rejects the address of an operation region (currently only used by Linux.) Signed-off-by: Bob Moore Signed-off-by: Lin Ming Signed-off-by: Len Brown --- drivers/acpi/acpica/acobject.h | 16 ++++++++-------- drivers/acpi/acpica/exprep.c | 9 --------- 2 files changed, 8 insertions(+), 17 deletions(-) (limited to 'drivers/acpi') diff --git a/drivers/acpi/acpica/acobject.h b/drivers/acpi/acpica/acobject.h index cde18ea82656..54857fa87aaf 100644 --- a/drivers/acpi/acpica/acobject.h +++ b/drivers/acpi/acpica/acobject.h @@ -91,14 +91,14 @@ /* Values for Flag byte above */ -#define AOPOBJ_AML_CONSTANT 0x01 -#define AOPOBJ_STATIC_POINTER 0x02 -#define AOPOBJ_DATA_VALID 0x04 -#define AOPOBJ_OBJECT_INITIALIZED 0x08 -#define AOPOBJ_SETUP_COMPLETE 0x10 -#define AOPOBJ_SINGLE_DATUM 0x20 -#define AOPOBJ_INVALID 0x40 /* Used if host OS won't allow an op_region address */ -#define AOPOBJ_MODULE_LEVEL 0x80 +#define AOPOBJ_AML_CONSTANT 0x01 /* Integer is an AML constant */ +#define AOPOBJ_STATIC_POINTER 0x02 /* Data is part of an ACPI table, don't delete */ +#define AOPOBJ_DATA_VALID 0x04 /* Object is intialized and data is valid */ +#define AOPOBJ_OBJECT_INITIALIZED 0x08 /* Region is initialized, _REG was run */ +#define AOPOBJ_SETUP_COMPLETE 0x10 /* Region setup is complete */ +#define AOPOBJ_INVALID 0x20 /* Host OS won't allow a Region address */ +#define AOPOBJ_MODULE_LEVEL 0x40 /* Method is actually module-level code */ +#define AOPOBJ_MODIFIED_NAMESPACE 0x80 /* Method modified the namespace */ /****************************************************************************** * diff --git a/drivers/acpi/acpica/exprep.c b/drivers/acpi/acpica/exprep.c index 0686f271c61e..98a331d2249b 100644 --- a/drivers/acpi/acpica/exprep.c +++ b/drivers/acpi/acpica/exprep.c @@ -385,15 +385,6 @@ acpi_ex_prep_common_field_object(union acpi_operand_object *obj_desc, (field_bit_position - ACPI_MUL_8(obj_desc->common_field.base_byte_offset)); - /* - * Does the entire field fit within a single field access element? (datum) - * (i.e., without crossing a datum boundary) - */ - if ((obj_desc->common_field.start_field_bit_offset + - field_bit_length) <= (u16) access_bit_width) { - obj_desc->common.flags |= AOPOBJ_SINGLE_DATUM; - } - return_ACPI_STATUS(AE_OK); } -- cgit v1.2.1 From a9fc03125ea0001ff18bc29da9539b587fdbd1d7 Mon Sep 17 00:00:00 2001 From: Alexey Starikovskiy Date: Wed, 26 May 2010 13:59:51 +0800 Subject: ACPICA: Optimization: Reduce the number of namespace walks On control method exit, only walk the namespace if the method is known to have created namespace objects outside of its local scope. Signed-off-by: Alexey Starikovskiy Signed-off-by: Bob Moore Signed-off-by: Lin Ming Signed-off-by: Len Brown --- drivers/acpi/acpica/dsmethod.c | 18 ++++++++++++++++-- drivers/acpi/acpica/nsalloc.c | 20 ++++++++++++++++---- 2 files changed, 32 insertions(+), 6 deletions(-) (limited to 'drivers/acpi') diff --git a/drivers/acpi/acpica/dsmethod.c b/drivers/acpi/acpica/dsmethod.c index 00846333773e..64750ee96e20 100644 --- a/drivers/acpi/acpica/dsmethod.c +++ b/drivers/acpi/acpica/dsmethod.c @@ -584,8 +584,22 @@ acpi_ds_terminate_control_method(union acpi_operand_object *method_desc, * want make the objects permanent. */ if (!(method_desc->method.flags & AOPOBJ_MODULE_LEVEL)) { - acpi_ns_delete_namespace_by_owner(method_desc->method. - owner_id); + + /* Delete any direct children of (created by) this method */ + + acpi_ns_delete_namespace_subtree(walk_state-> + method_node); + + /* + * Delete any objects that were created by this method + * elsewhere in the namespace (if any were created). + */ + if (method_desc->method. + flags & AOPOBJ_MODIFIED_NAMESPACE) { + acpi_ns_delete_namespace_by_owner(method_desc-> + method. + owner_id); + } } } diff --git a/drivers/acpi/acpica/nsalloc.c b/drivers/acpi/acpica/nsalloc.c index 8d3a43a061ab..1e5ff803d9ad 100644 --- a/drivers/acpi/acpica/nsalloc.c +++ b/drivers/acpi/acpica/nsalloc.c @@ -219,12 +219,24 @@ void acpi_ns_install_node(struct acpi_walk_state *walk_state, struct acpi_namesp ACPI_FUNCTION_TRACE(ns_install_node); - /* - * Get the owner ID from the Walk state. The owner ID is used to track - * table deletion and deletion of objects created by methods. - */ if (walk_state) { + /* + * Get the owner ID from the Walk state. The owner ID is used to + * track table deletion and deletion of objects created by methods. + */ owner_id = walk_state->owner_id; + + if ((walk_state->method_desc) && + (parent_node != walk_state->method_node)) { + /* + * A method is creating a new node that is not a child of the + * method (it is non-local). Mark the executing method as having + * modified the namespace. This is used for cleanup when the + * method exits. + */ + walk_state->method_desc->method.flags |= + AOPOBJ_MODIFIED_NAMESPACE; + } } /* Link the new entry into the parent and existing children */ -- cgit v1.2.1 From b76df673522d94e3eafcf16935b3d7e5dded3078 Mon Sep 17 00:00:00 2001 From: Lin Ming Date: Thu, 1 Jul 2010 10:07:17 +0800 Subject: ACPICA: Rename acpi_hw_gpe_register_bit Rename acpi_hw_gpe_register_bit to acpi_hw_get_gpe_register_bit in order to be same with ACPICA code base. Signed-off-by: Lin Ming Signed-off-by: Len Brown --- drivers/acpi/acpica/achware.h | 2 +- drivers/acpi/acpica/evgpe.c | 2 +- drivers/acpi/acpica/hwgpe.c | 10 +++++----- 3 files changed, 7 insertions(+), 7 deletions(-) (limited to 'drivers/acpi') diff --git a/drivers/acpi/acpica/achware.h b/drivers/acpi/acpica/achware.h index 32391588e163..c73144c9a395 100644 --- a/drivers/acpi/acpica/achware.h +++ b/drivers/acpi/acpica/achware.h @@ -90,7 +90,7 @@ acpi_status acpi_hw_write_port(acpi_io_address address, u32 value, u32 width); /* * hwgpe - GPE support */ -u32 acpi_hw_gpe_register_bit(struct acpi_gpe_event_info *gpe_event_info, +u32 acpi_hw_get_gpe_register_bit(struct acpi_gpe_event_info *gpe_event_info, struct acpi_gpe_register_info *gpe_register_info); acpi_status diff --git a/drivers/acpi/acpica/evgpe.c b/drivers/acpi/acpica/evgpe.c index 7c2c336006a1..d24d7d31f40c 100644 --- a/drivers/acpi/acpica/evgpe.c +++ b/drivers/acpi/acpica/evgpe.c @@ -78,7 +78,7 @@ acpi_ev_update_gpe_enable_masks(struct acpi_gpe_event_info *gpe_event_info) return_ACPI_STATUS(AE_NOT_EXIST); } - register_bit = acpi_hw_gpe_register_bit(gpe_event_info, + register_bit = acpi_hw_get_gpe_register_bit(gpe_event_info, gpe_register_info); /* Clear the wake/run bits up front */ diff --git a/drivers/acpi/acpica/hwgpe.c b/drivers/acpi/acpica/hwgpe.c index 3450309c2786..12d70fdadc2b 100644 --- a/drivers/acpi/acpica/hwgpe.c +++ b/drivers/acpi/acpica/hwgpe.c @@ -57,7 +57,7 @@ acpi_hw_enable_wakeup_gpe_block(struct acpi_gpe_xrupt_info *gpe_xrupt_info, /****************************************************************************** * - * FUNCTION: acpi_hw_gpe_register_bit + * FUNCTION: acpi_hw_get_gpe_register_bit * * PARAMETERS: gpe_event_info - Info block for the GPE * gpe_register_info - Info block for the GPE register @@ -69,7 +69,7 @@ acpi_hw_enable_wakeup_gpe_block(struct acpi_gpe_xrupt_info *gpe_xrupt_info, * ******************************************************************************/ -u32 acpi_hw_gpe_register_bit(struct acpi_gpe_event_info *gpe_event_info, +u32 acpi_hw_get_gpe_register_bit(struct acpi_gpe_event_info *gpe_event_info, struct acpi_gpe_register_info *gpe_register_info) { return (u32)1 << (gpe_event_info->gpe_number - @@ -115,7 +115,7 @@ acpi_hw_low_set_gpe(struct acpi_gpe_event_info *gpe_event_info, u8 action) /* Set ot clear just the bit that corresponds to this GPE */ - register_bit = acpi_hw_gpe_register_bit(gpe_event_info, + register_bit = acpi_hw_get_gpe_register_bit(gpe_event_info, gpe_register_info); switch (action) { case ACPI_GPE_COND_ENABLE: @@ -193,7 +193,7 @@ acpi_status acpi_hw_clear_gpe(struct acpi_gpe_event_info * gpe_event_info) return (AE_NOT_EXIST); } - register_bit = acpi_hw_gpe_register_bit(gpe_event_info, + register_bit = acpi_hw_get_gpe_register_bit(gpe_event_info, gpe_register_info); /* @@ -241,7 +241,7 @@ acpi_hw_get_gpe_status(struct acpi_gpe_event_info * gpe_event_info, /* Get the register bitmask for this GPE */ - register_bit = acpi_hw_gpe_register_bit(gpe_event_info, + register_bit = acpi_hw_get_gpe_register_bit(gpe_event_info, gpe_register_info); /* GPE currently enabled? (enabled for runtime?) */ -- cgit v1.2.1 From e8b6f970107cfc9c00cdcdb12ec6c7e135cf379f Mon Sep 17 00:00:00 2001 From: "Rafael J. Wysocki" Date: Fri, 25 Jun 2010 01:18:39 +0200 Subject: ACPICA: Introduce acpi_gpe_wakeup() ACPICA uses reference counters to avoid disabling GPEs too early in case they have been enabled for many times. This is done separately for runtime and for wakeup, but the wakeup GPE reference counter is not really necessary, because GPEs are only enabled to wake up the system at the hardware level by acpi_enter_sleep_state(). Thus it only is necessary to set the corresponding bits in the wakeup enable masks of these GPEs' registers right before the system enters a sleep state. Moreover, the GPE wakeup enable bits can only be set when the target sleep state of the system is known and they need to be cleared immediately after wakeup regardless of how many wakeup devices are associated with a given GPE. On the basis of the above observations, introduce function acpi_gpe_wakeup() to be used for setting or clearing the enable bit corresponding to a given GPE in its enable register's enable_for_wake mask. Modify the ACPI suspend and wakeup code the use acpi_gpe_wakeup() instead of acpi_{enable|disable}_gpe() to set and clear GPE enable bits in their registers' enable_for_wake masks during system transitions to a sleep state and back to the working state, respectively. [This will allow us to drop the third argument of acpi_{enable|disable}_gpe() and simplify the GPE handling code.] Signed-off-by: Rafael J. Wysocki Signed-off-by: Len Brown Signed-off-by: Bob Moore Signed-off-by: Lin Ming Signed-off-by: Len Brown --- drivers/acpi/acpica/evxfevnt.c | 67 ++++++++++++++++++++++++++++++++++++++++++ drivers/acpi/sleep.c | 15 ++-------- drivers/acpi/wakeup.c | 18 +++++++----- 3 files changed, 81 insertions(+), 19 deletions(-) (limited to 'drivers/acpi') diff --git a/drivers/acpi/acpica/evxfevnt.c b/drivers/acpi/acpica/evxfevnt.c index d97b8dce1668..d6a6d4a76592 100644 --- a/drivers/acpi/acpica/evxfevnt.c +++ b/drivers/acpi/acpica/evxfevnt.c @@ -306,6 +306,73 @@ acpi_status acpi_set_gpe(acpi_handle gpe_device, u32 gpe_number, u8 action) ACPI_EXPORT_SYMBOL(acpi_set_gpe) +/******************************************************************************* + * + * FUNCTION: acpi_gpe_wakeup + * + * PARAMETERS: gpe_device - Parent GPE Device. NULL for GPE0/GPE1 + * gpe_number - GPE level within the GPE block + * Action - Enable or Disable + * + * RETURN: Status + * + * DESCRIPTION: Set or clear the GPE's wakeup enable mask bit. + * + ******************************************************************************/ +acpi_status acpi_gpe_wakeup(acpi_handle gpe_device, u32 gpe_number, u8 action) +{ + acpi_status status = AE_OK; + struct acpi_gpe_event_info *gpe_event_info; + struct acpi_gpe_register_info *gpe_register_info; + acpi_cpu_flags flags; + u32 register_bit; + + ACPI_FUNCTION_TRACE(acpi_gpe_wakeup); + + 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); + if (!gpe_event_info) { + status = AE_BAD_PARAMETER; + goto unlock_and_exit; + } + + gpe_register_info = gpe_event_info->register_info; + if (!gpe_register_info) { + status = AE_NOT_EXIST; + goto unlock_and_exit; + } + + register_bit = + acpi_hw_get_gpe_register_bit(gpe_event_info, gpe_register_info); + + /* Perform the action */ + + switch (action) { + case ACPI_GPE_ENABLE: + ACPI_SET_BIT(gpe_register_info->enable_for_wake, register_bit); + break; + + case ACPI_GPE_DISABLE: + ACPI_CLEAR_BIT(gpe_register_info->enable_for_wake, + register_bit); + break; + + default: + ACPI_ERROR((AE_INFO, "%u, Invalid action", action)); + status = AE_BAD_PARAMETER; + break; + } + +unlock_and_exit: + acpi_os_release_lock(acpi_gbl_gpe_lock, flags); + return_ACPI_STATUS(status); +} + +ACPI_EXPORT_SYMBOL(acpi_gpe_wakeup) + /******************************************************************************* * * FUNCTION: acpi_enable_gpe diff --git a/drivers/acpi/sleep.c b/drivers/acpi/sleep.c index 5b7c52e4a00f..aaa1af55e280 100644 --- a/drivers/acpi/sleep.c +++ b/drivers/acpi/sleep.c @@ -664,18 +664,9 @@ int acpi_pm_device_sleep_wake(struct device *dev, bool enable) return -ENODEV; } - if (enable) { - error = acpi_enable_wakeup_device_power(adev, - acpi_target_sleep_state); - if (!error) - acpi_enable_gpe(adev->wakeup.gpe_device, - adev->wakeup.gpe_number, - ACPI_GPE_TYPE_WAKE); - } else { - acpi_disable_gpe(adev->wakeup.gpe_device, adev->wakeup.gpe_number, - ACPI_GPE_TYPE_WAKE); - error = acpi_disable_wakeup_device_power(adev); - } + error = enable ? + acpi_enable_wakeup_device_power(adev, acpi_target_sleep_state) : + acpi_disable_wakeup_device_power(adev); if (!error) dev_info(dev, "wake-up capability %s by ACPI\n", enable ? "enabled" : "disabled"); diff --git a/drivers/acpi/wakeup.c b/drivers/acpi/wakeup.c index 388747a7ef4f..c80537bc3234 100644 --- a/drivers/acpi/wakeup.c +++ b/drivers/acpi/wakeup.c @@ -64,13 +64,14 @@ void acpi_enable_wakeup_device(u8 sleep_state) struct acpi_device *dev = container_of(node, struct acpi_device, wakeup_list); - if (!dev->wakeup.flags.valid || !dev->wakeup.state.enabled + if (!dev->wakeup.flags.valid + || !(dev->wakeup.state.enabled || dev->wakeup.prepare_count) || sleep_state > (u32) dev->wakeup.sleep_state) continue; /* The wake-up power should have been enabled already. */ - acpi_enable_gpe(dev->wakeup.gpe_device, dev->wakeup.gpe_number, - ACPI_GPE_TYPE_WAKE); + acpi_gpe_wakeup(dev->wakeup.gpe_device, dev->wakeup.gpe_number, + ACPI_GPE_ENABLE); } } @@ -89,13 +90,16 @@ void acpi_disable_wakeup_device(u8 sleep_state) struct acpi_device *dev = container_of(node, struct acpi_device, wakeup_list); - if (!dev->wakeup.flags.valid || !dev->wakeup.state.enabled + if (!dev->wakeup.flags.valid + || !(dev->wakeup.state.enabled || dev->wakeup.prepare_count) || (sleep_state > (u32) dev->wakeup.sleep_state)) continue; - acpi_disable_gpe(dev->wakeup.gpe_device, dev->wakeup.gpe_number, - ACPI_GPE_TYPE_WAKE); - acpi_disable_wakeup_device_power(dev); + acpi_gpe_wakeup(dev->wakeup.gpe_device, dev->wakeup.gpe_number, + ACPI_GPE_DISABLE); + + if (dev->wakeup.state.enabled) + acpi_disable_wakeup_device_power(dev); } } -- cgit v1.2.1 From a44061aa8b5d58b2729faca4c155a94a5bea2a09 Mon Sep 17 00:00:00 2001 From: "Rafael J. Wysocki" Date: Thu, 1 Jul 2010 10:11:45 +0800 Subject: ACPICA: Remove wakeup GPE reference counting which is not used After the previous patch that introduced acpi_gpe_wakeup() and modified the ACPI suspend and wakeup code to use it, the third argument of acpi_{enable|disable}_gpe() and the GPE wakeup reference counter are not necessary any more. Remove them and modify all of the users of acpi_{enable|disable}_gpe() accordingly. Also drop GPE type constants that aren't used any more. Signed-off-by: Rafael J. Wysocki Signed-off-by: Len Brown Signed-off-by: Bob Moore Signed-off-by: Lin Ming Signed-off-by: Len Brown --- drivers/acpi/acpica/acevents.h | 2 +- drivers/acpi/acpica/aclocal.h | 1 - drivers/acpi/acpica/evgpe.c | 21 +++---- drivers/acpi/acpica/evgpeblk.c | 3 +- drivers/acpi/acpica/evgpeinit.c | 3 +- drivers/acpi/acpica/evxfevnt.c | 119 ++++++++++------------------------------ drivers/acpi/button.c | 6 +- drivers/acpi/ec.c | 6 +- drivers/acpi/system.c | 6 +- 9 files changed, 46 insertions(+), 121 deletions(-) (limited to 'drivers/acpi') diff --git a/drivers/acpi/acpica/acevents.h b/drivers/acpi/acpica/acevents.h index c3f43daa8be3..a561944fbaf9 100644 --- a/drivers/acpi/acpica/acevents.h +++ b/drivers/acpi/acpica/acevents.h @@ -78,7 +78,7 @@ acpi_ev_queue_notify_request(struct acpi_namespace_node *node, u32 acpi_ev_gpe_detect(struct acpi_gpe_xrupt_info *gpe_xrupt_list); acpi_status -acpi_ev_update_gpe_enable_masks(struct acpi_gpe_event_info *gpe_event_info); +acpi_ev_update_gpe_enable_mask(struct acpi_gpe_event_info *gpe_event_info); struct acpi_gpe_event_info *acpi_ev_get_gpe_event_info(acpi_handle gpe_device, u32 gpe_number); diff --git a/drivers/acpi/acpica/aclocal.h b/drivers/acpi/acpica/aclocal.h index eb2d420b39ec..1ee0bcf399aa 100644 --- a/drivers/acpi/acpica/aclocal.h +++ b/drivers/acpi/acpica/aclocal.h @@ -429,7 +429,6 @@ struct acpi_gpe_event_info { u8 flags; /* Misc info about this GPE */ u8 gpe_number; /* This GPE */ u8 runtime_count; /* References to a run GPE */ - u8 wakeup_count; /* References to a wake GPE */ }; /* Information about a GPE register pair, one per each status/enable pair in an array */ diff --git a/drivers/acpi/acpica/evgpe.c b/drivers/acpi/acpica/evgpe.c index d24d7d31f40c..9413ac61e440 100644 --- a/drivers/acpi/acpica/evgpe.c +++ b/drivers/acpi/acpica/evgpe.c @@ -54,24 +54,24 @@ static void ACPI_SYSTEM_XFACE acpi_ev_asynch_execute_gpe_method(void *context); /******************************************************************************* * - * FUNCTION: acpi_ev_update_gpe_enable_masks + * FUNCTION: acpi_ev_update_gpe_enable_mask * * PARAMETERS: gpe_event_info - GPE to update * * RETURN: Status * - * DESCRIPTION: Updates GPE register enable masks based upon whether there are - * references (either wake or run) to this GPE + * DESCRIPTION: Updates GPE register enable mask based upon whether there are + * runtime references to this GPE * ******************************************************************************/ acpi_status -acpi_ev_update_gpe_enable_masks(struct acpi_gpe_event_info *gpe_event_info) +acpi_ev_update_gpe_enable_mask(struct acpi_gpe_event_info *gpe_event_info) { struct acpi_gpe_register_info *gpe_register_info; u32 register_bit; - ACPI_FUNCTION_TRACE(ev_update_gpe_enable_masks); + ACPI_FUNCTION_TRACE(ev_update_gpe_enable_mask); gpe_register_info = gpe_event_info->register_info; if (!gpe_register_info) { @@ -81,19 +81,14 @@ acpi_ev_update_gpe_enable_masks(struct acpi_gpe_event_info *gpe_event_info) register_bit = acpi_hw_get_gpe_register_bit(gpe_event_info, gpe_register_info); - /* Clear the wake/run bits up front */ + /* Clear the run bit up front */ - ACPI_CLEAR_BIT(gpe_register_info->enable_for_wake, register_bit); ACPI_CLEAR_BIT(gpe_register_info->enable_for_run, register_bit); - /* Set the mask bits only if there are references to this GPE */ + /* Set the mask bit only if there are references to this GPE */ if (gpe_event_info->runtime_count) { - ACPI_SET_BIT(gpe_register_info->enable_for_run, register_bit); - } - - if (gpe_event_info->wakeup_count) { - ACPI_SET_BIT(gpe_register_info->enable_for_wake, register_bit); + ACPI_SET_BIT(gpe_register_info->enable_for_run, (u8)register_bit); } return_ACPI_STATUS(AE_OK); diff --git a/drivers/acpi/acpica/evgpeblk.c b/drivers/acpi/acpica/evgpeblk.c index 341a38ce8aa6..77e8630043f8 100644 --- a/drivers/acpi/acpica/evgpeblk.c +++ b/drivers/acpi/acpica/evgpeblk.c @@ -529,8 +529,7 @@ acpi_ev_initialize_gpe_block(struct acpi_namespace_node *gpe_device, /* Enable this GPE */ - status = acpi_enable_gpe(gpe_device, gpe_number, - ACPI_GPE_TYPE_RUNTIME); + status = acpi_enable_gpe(gpe_device, gpe_number); if (ACPI_FAILURE(status)) { ACPI_EXCEPTION((AE_INFO, status, "Could not enable GPE 0x%02X", diff --git a/drivers/acpi/acpica/evgpeinit.c b/drivers/acpi/acpica/evgpeinit.c index 3f6c2d26410d..8db9e076a53b 100644 --- a/drivers/acpi/acpica/evgpeinit.c +++ b/drivers/acpi/acpica/evgpeinit.c @@ -482,8 +482,7 @@ acpi_ev_match_gpe_method(acpi_handle obj_handle, gpe_device = NULL; } - status = acpi_enable_gpe(gpe_device, gpe_number, - ACPI_GPE_TYPE_RUNTIME); + status = acpi_enable_gpe(gpe_device, gpe_number); if (ACPI_FAILURE(status)) { ACPI_EXCEPTION((AE_INFO, status, "Could not enable GPE 0x%02X", diff --git a/drivers/acpi/acpica/evxfevnt.c b/drivers/acpi/acpica/evxfevnt.c index d6a6d4a76592..467fde961aef 100644 --- a/drivers/acpi/acpica/evxfevnt.c +++ b/drivers/acpi/acpica/evxfevnt.c @@ -352,12 +352,13 @@ acpi_status acpi_gpe_wakeup(acpi_handle gpe_device, u32 gpe_number, u8 action) switch (action) { case ACPI_GPE_ENABLE: - ACPI_SET_BIT(gpe_register_info->enable_for_wake, register_bit); + ACPI_SET_BIT(gpe_register_info->enable_for_wake, + (u8)register_bit); break; case ACPI_GPE_DISABLE: ACPI_CLEAR_BIT(gpe_register_info->enable_for_wake, - register_bit); + (u8)register_bit); break; default: @@ -379,17 +380,14 @@ ACPI_EXPORT_SYMBOL(acpi_gpe_wakeup) * * PARAMETERS: gpe_device - Parent GPE Device. NULL for GPE0/GPE1 * gpe_number - GPE level within the GPE block - * gpe_type - ACPI_GPE_TYPE_RUNTIME or ACPI_GPE_TYPE_WAKE - * or both * * RETURN: Status * * DESCRIPTION: Add a reference to a GPE. On the first reference, the GPE is - * hardware-enabled (for runtime GPEs), or the GPE register mask - * is updated (for wake GPEs). + * hardware-enabled. * ******************************************************************************/ -acpi_status acpi_enable_gpe(acpi_handle gpe_device, u32 gpe_number, u8 gpe_type) +acpi_status acpi_enable_gpe(acpi_handle gpe_device, u32 gpe_number) { acpi_status status = AE_OK; struct acpi_gpe_event_info *gpe_event_info; @@ -397,12 +395,6 @@ acpi_status acpi_enable_gpe(acpi_handle gpe_device, u32 gpe_number, u8 gpe_type) ACPI_FUNCTION_TRACE(acpi_enable_gpe); - /* Parameter validation */ - - if (!gpe_type || (gpe_type & ~ACPI_GPE_TYPE_WAKE_RUN)) { - return_ACPI_STATUS(AE_BAD_PARAMETER); - } - flags = acpi_os_acquire_lock(acpi_gbl_gpe_lock); /* Ensure that we have a valid GPE number */ @@ -413,46 +405,19 @@ acpi_status acpi_enable_gpe(acpi_handle gpe_device, u32 gpe_number, u8 gpe_type) goto unlock_and_exit; } - if (gpe_type & ACPI_GPE_TYPE_RUNTIME) { - if (gpe_event_info->runtime_count == ACPI_UINT8_MAX) { - status = AE_LIMIT; /* Too many references */ - goto unlock_and_exit; - } - - gpe_event_info->runtime_count++; - if (gpe_event_info->runtime_count == 1) { - status = acpi_ev_update_gpe_enable_masks(gpe_event_info); - if (ACPI_SUCCESS(status)) { - status = acpi_clear_and_enable_gpe(gpe_event_info); - } - - if (ACPI_FAILURE(status)) { - gpe_event_info->runtime_count--; - goto unlock_and_exit; - } - } + if (gpe_event_info->runtime_count == ACPI_UINT8_MAX) { + status = AE_LIMIT; /* Too many references */ + goto unlock_and_exit; } - if (gpe_type & ACPI_GPE_TYPE_WAKE) { - /* The GPE must have the ability to wake the system */ - - if (!(gpe_event_info->flags & ACPI_GPE_CAN_WAKE)) { - status = AE_TYPE; - goto unlock_and_exit; - } - - if (gpe_event_info->wakeup_count == ACPI_UINT8_MAX) { - status = AE_LIMIT; /* Too many references */ - goto unlock_and_exit; + gpe_event_info->runtime_count++; + if (gpe_event_info->runtime_count == 1) { + status = acpi_ev_update_gpe_enable_mask(gpe_event_info); + if (ACPI_SUCCESS(status)) { + status = acpi_clear_and_enable_gpe(gpe_event_info); } - - /* - * Update the enable mask on the first wakeup reference. Wake GPEs - * are only hardware-enabled just before sleeping. - */ - gpe_event_info->wakeup_count++; - if (gpe_event_info->wakeup_count == 1) { - status = acpi_ev_update_gpe_enable_masks(gpe_event_info); + if (ACPI_FAILURE(status)) { + gpe_event_info->runtime_count--; } } @@ -468,8 +433,6 @@ ACPI_EXPORT_SYMBOL(acpi_enable_gpe) * * PARAMETERS: gpe_device - Parent GPE Device. NULL for GPE0/GPE1 * gpe_number - GPE level within the GPE block - * gpe_type - ACPI_GPE_TYPE_RUNTIME or ACPI_GPE_TYPE_WAKE - * or both * * RETURN: Status * @@ -478,7 +441,7 @@ ACPI_EXPORT_SYMBOL(acpi_enable_gpe) * the GPE mask bit disabled (for wake GPEs) * ******************************************************************************/ -acpi_status acpi_disable_gpe(acpi_handle gpe_device, u32 gpe_number, u8 gpe_type) +acpi_status acpi_disable_gpe(acpi_handle gpe_device, u32 gpe_number) { acpi_status status = AE_OK; struct acpi_gpe_event_info *gpe_event_info; @@ -486,12 +449,6 @@ acpi_status acpi_disable_gpe(acpi_handle gpe_device, u32 gpe_number, u8 gpe_type ACPI_FUNCTION_TRACE(acpi_disable_gpe); - /* Parameter validation */ - - if (!gpe_type || (gpe_type & ~ACPI_GPE_TYPE_WAKE_RUN)) { - return_ACPI_STATUS(AE_BAD_PARAMETER); - } - flags = acpi_os_acquire_lock(acpi_gbl_gpe_lock); /* Ensure that we have a valid GPE number */ @@ -504,41 +461,21 @@ acpi_status acpi_disable_gpe(acpi_handle gpe_device, u32 gpe_number, u8 gpe_type /* Hardware-disable a runtime GPE on removal of the last reference */ - if (gpe_type & ACPI_GPE_TYPE_RUNTIME) { - if (!gpe_event_info->runtime_count) { - status = AE_LIMIT; /* There are no references to remove */ - goto unlock_and_exit; - } - - gpe_event_info->runtime_count--; - if (!gpe_event_info->runtime_count) { - status = acpi_ev_update_gpe_enable_masks(gpe_event_info); - if (ACPI_SUCCESS(status)) { - status = acpi_hw_low_set_gpe(gpe_event_info, - ACPI_GPE_DISABLE); - } - - if (ACPI_FAILURE(status)) { - gpe_event_info->runtime_count++; - goto unlock_and_exit; - } - } + if (!gpe_event_info->runtime_count) { + status = AE_LIMIT; /* There are no references to remove */ + goto unlock_and_exit; } - /* - * Update masks for wake GPE on removal of the last reference. - * No need to hardware-disable wake GPEs here, they are not currently - * enabled. - */ - if (gpe_type & ACPI_GPE_TYPE_WAKE) { - if (!gpe_event_info->wakeup_count) { - status = AE_LIMIT; /* There are no references to remove */ - goto unlock_and_exit; + gpe_event_info->runtime_count--; + if (!gpe_event_info->runtime_count) { + status = acpi_ev_update_gpe_enable_mask(gpe_event_info); + if (ACPI_SUCCESS(status)) { + status = + acpi_hw_low_set_gpe(gpe_event_info, + ACPI_GPE_DISABLE); } - - gpe_event_info->wakeup_count--; - if (!gpe_event_info->wakeup_count) { - status = acpi_ev_update_gpe_enable_masks(gpe_event_info); + if (ACPI_FAILURE(status)) { + gpe_event_info->runtime_count++; } } diff --git a/drivers/acpi/button.c b/drivers/acpi/button.c index 7d857dabdde4..1575a9b51f1d 100644 --- a/drivers/acpi/button.c +++ b/drivers/acpi/button.c @@ -424,8 +424,7 @@ static int acpi_button_add(struct acpi_device *device) if (device->wakeup.flags.valid) { /* Button's GPE is run-wake GPE */ acpi_enable_gpe(device->wakeup.gpe_device, - device->wakeup.gpe_number, - ACPI_GPE_TYPE_RUNTIME); + device->wakeup.gpe_number); device->wakeup.run_wake_count++; device->wakeup.state.enabled = 1; } @@ -448,8 +447,7 @@ static int acpi_button_remove(struct acpi_device *device, int type) if (device->wakeup.flags.valid) { acpi_disable_gpe(device->wakeup.gpe_device, - device->wakeup.gpe_number, - ACPI_GPE_TYPE_RUNTIME); + device->wakeup.gpe_number); device->wakeup.run_wake_count--; device->wakeup.state.enabled = 0; } diff --git a/drivers/acpi/ec.c b/drivers/acpi/ec.c index 5f2027d782e8..bf5045416575 100644 --- a/drivers/acpi/ec.c +++ b/drivers/acpi/ec.c @@ -822,7 +822,7 @@ static int ec_install_handlers(struct acpi_ec *ec) if (ACPI_FAILURE(status)) return -ENODEV; - acpi_enable_gpe(NULL, ec->gpe, ACPI_GPE_TYPE_RUNTIME); + acpi_enable_gpe(NULL, ec->gpe); status = acpi_install_address_space_handler(ec->handle, ACPI_ADR_SPACE_EC, &acpi_ec_space_handler, @@ -839,7 +839,7 @@ static int ec_install_handlers(struct acpi_ec *ec) } else { acpi_remove_gpe_handler(NULL, ec->gpe, &acpi_ec_gpe_handler); - acpi_disable_gpe(NULL, ec->gpe, ACPI_GPE_TYPE_RUNTIME); + acpi_disable_gpe(NULL, ec->gpe); return -ENODEV; } } @@ -850,7 +850,7 @@ static int ec_install_handlers(struct acpi_ec *ec) static void ec_remove_handlers(struct acpi_ec *ec) { - acpi_disable_gpe(NULL, ec->gpe, ACPI_GPE_TYPE_RUNTIME); + acpi_disable_gpe(NULL, ec->gpe); if (ACPI_FAILURE(acpi_remove_address_space_handler(ec->handle, ACPI_ADR_SPACE_EC, &acpi_ec_space_handler))) pr_err(PREFIX "failed to remove space handler\n"); diff --git a/drivers/acpi/system.c b/drivers/acpi/system.c index f8db50a0941c..5981bd07e20e 100644 --- a/drivers/acpi/system.c +++ b/drivers/acpi/system.c @@ -388,12 +388,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_GPE_TYPE_RUNTIME); + result = acpi_disable_gpe(handle, index); else if (!strcmp(buf, "enable\n") && !(status & ACPI_EVENT_FLAG_ENABLED)) - result = acpi_enable_gpe(handle, index, - ACPI_GPE_TYPE_RUNTIME); + result = acpi_enable_gpe(handle, index); else if (!strcmp(buf, "clear\n") && (status & ACPI_EVENT_FLAG_SET)) result = acpi_clear_gpe(handle, index); -- cgit v1.2.1 From b63559f5ce08bc8f94ce144a8d06f7af607ecc53 Mon Sep 17 00:00:00 2001 From: "Rafael J. Wysocki" Date: Fri, 25 Jun 2010 01:20:38 +0200 Subject: ACPI / EC: Drop suspend and resume routines The suspend and resume routines provided by the EC driver are not really necessary, because the handler of the GPE disabled by them is not going to be executed after suspend_device_irqs() and before resume_device_irqs() anyway. Signed-off-by: Rafael J. Wysocki Signed-off-by: Len Brown --- drivers/acpi/ec.c | 18 ------------------ 1 file changed, 18 deletions(-) (limited to 'drivers/acpi') diff --git a/drivers/acpi/ec.c b/drivers/acpi/ec.c index bf5045416575..9bf7a7546bd4 100644 --- a/drivers/acpi/ec.c +++ b/drivers/acpi/ec.c @@ -1088,22 +1088,6 @@ error: return -ENODEV; } -static int acpi_ec_suspend(struct acpi_device *device, pm_message_t state) -{ - struct acpi_ec *ec = acpi_driver_data(device); - /* Stop using the GPE, but keep it reference counted. */ - acpi_set_gpe(NULL, ec->gpe, ACPI_GPE_DISABLE); - return 0; -} - -static int acpi_ec_resume(struct acpi_device *device) -{ - struct acpi_ec *ec = acpi_driver_data(device); - /* Enable the GPE again, but don't reference count it once more. */ - acpi_set_gpe(NULL, ec->gpe, ACPI_GPE_ENABLE); - return 0; -} - static struct acpi_driver acpi_ec_driver = { .name = "ec", .class = ACPI_EC_CLASS, @@ -1111,8 +1095,6 @@ static struct acpi_driver acpi_ec_driver = { .ops = { .add = acpi_ec_add, .remove = acpi_ec_remove, - .suspend = acpi_ec_suspend, - .resume = acpi_ec_resume, }, }; -- cgit v1.2.1 From 3784730b02b9f147a55b0e4623fcad671273e6e6 Mon Sep 17 00:00:00 2001 From: "Rafael J. Wysocki" Date: Fri, 25 Jun 2010 01:21:42 +0200 Subject: ACPI / EC: Do not use acpi_set_gpe The EC driver is the last user of acpi_set_gpe() and since it is guaranteed that the EC GPE will not be shared, acpi_disable_gpe() and acpi_enable_gpe() may be used for disabling the GPE temporarilty if a GPE storm is detected and re-enabling it during EC transactions. Signed-off-by: Rafael J. Wysocki Signed-off-by: Len Brown --- drivers/acpi/ec.c | 15 ++++----------- 1 file changed, 4 insertions(+), 11 deletions(-) (limited to 'drivers/acpi') diff --git a/drivers/acpi/ec.c b/drivers/acpi/ec.c index 9bf7a7546bd4..1e6d4184f0ea 100644 --- a/drivers/acpi/ec.c +++ b/drivers/acpi/ec.c @@ -313,11 +313,8 @@ static int acpi_ec_transaction(struct acpi_ec *ec, struct transaction *t) pr_debug(PREFIX "transaction start\n"); /* disable GPE during transaction if storm is detected */ if (test_bit(EC_FLAGS_GPE_STORM, &ec->flags)) { - /* - * It has to be disabled at the hardware level regardless of the - * GPE reference counting, so that it doesn't trigger. - */ - acpi_set_gpe(NULL, ec->gpe, ACPI_GPE_DISABLE); + /* It has to be disabled, so that it doesn't trigger. */ + acpi_disable_gpe(NULL, ec->gpe); } status = acpi_ec_transaction_unlocked(ec, t); @@ -326,12 +323,8 @@ static int acpi_ec_transaction(struct acpi_ec *ec, struct transaction *t) ec_check_sci_sync(ec, acpi_ec_read_status(ec)); if (test_bit(EC_FLAGS_GPE_STORM, &ec->flags)) { msleep(1); - /* - * It is safe to enable the GPE outside of the transaction. Use - * acpi_set_gpe() for that, since we used it to disable the GPE - * above. - */ - acpi_set_gpe(NULL, ec->gpe, ACPI_GPE_ENABLE); + /* It is safe to enable the GPE outside of the transaction. */ + acpi_enable_gpe(NULL, ec->gpe); } else if (t->irq_count > ACPI_EC_STORM_THRESHOLD) { pr_info(PREFIX "GPE storm detected, " "transactions will use polling mode\n"); -- cgit v1.2.1 From 3bd741bd0dfcc1845ae6892baa5192c91addc84c Mon Sep 17 00:00:00 2001 From: "Rafael J. Wysocki" Date: Thu, 1 Jul 2010 11:01:12 +0800 Subject: ACPICA: Use low-level GPE enable during GPE block initialization The GPE block initialization code in acpi_ev_initialize_gpe_block() uses acpi_set_gpe() to make sure that the GPEs with nonzero runtime counter will remain enabled, but since it already has a struct acpi_gpe_event_info object for each GPE, it might use the low-level GPE enabling function, acpi_clear_and_enable_gpe(), for this purpose. To make that happen, move acpi_clear_and_enable_gpe() to drivers/acpi/acpica/evgpe.c and rename it to acpi_ev_enable_gpe(), modify the two existing users of it accordingly and modify acpi_ev_initialize_gpe_block() to use it instead of acpi_set_gpe() and to check its return value. Signed-off-by: Rafael J. Wysocki Signed-off-by: Len Brown Signed-off-by: Bob Moore Signed-off-by: Lin Ming Signed-off-by: Len Brown --- drivers/acpi/acpica/acevents.h | 2 ++ drivers/acpi/acpica/evgpe.c | 40 ++++++++++++++++++++++++++++++++++++++++ drivers/acpi/acpica/evgpeblk.c | 7 +++---- drivers/acpi/acpica/evxfevnt.c | 42 ++---------------------------------------- 4 files changed, 47 insertions(+), 44 deletions(-) (limited to 'drivers/acpi') diff --git a/drivers/acpi/acpica/acevents.h b/drivers/acpi/acpica/acevents.h index a561944fbaf9..e0e6affb0d80 100644 --- a/drivers/acpi/acpica/acevents.h +++ b/drivers/acpi/acpica/acevents.h @@ -80,6 +80,8 @@ u32 acpi_ev_gpe_detect(struct acpi_gpe_xrupt_info *gpe_xrupt_list); acpi_status acpi_ev_update_gpe_enable_mask(struct acpi_gpe_event_info *gpe_event_info); +acpi_status acpi_ev_enable_gpe(struct acpi_gpe_event_info *gpe_event_info); + struct acpi_gpe_event_info *acpi_ev_get_gpe_event_info(acpi_handle gpe_device, u32 gpe_number); diff --git a/drivers/acpi/acpica/evgpe.c b/drivers/acpi/acpica/evgpe.c index 9413ac61e440..56de460570d6 100644 --- a/drivers/acpi/acpica/evgpe.c +++ b/drivers/acpi/acpica/evgpe.c @@ -94,6 +94,46 @@ acpi_ev_update_gpe_enable_mask(struct acpi_gpe_event_info *gpe_event_info) return_ACPI_STATUS(AE_OK); } +/******************************************************************************* + * + * FUNCTION: acpi_ev_enable_gpe + * + * PARAMETERS: gpe_event_info - GPE to enable + * + * RETURN: Status + * + * DESCRIPTION: Clear the given GPE from stale events and enable it. + * + ******************************************************************************/ +acpi_status +acpi_ev_enable_gpe(struct acpi_gpe_event_info *gpe_event_info) +{ + acpi_status status; + + ACPI_FUNCTION_TRACE(ev_enable_gpe); + + /* + * We will only allow a GPE to be enabled if it has either an + * associated method (_Lxx/_Exx) or a handler. Otherwise, the + * GPE will be immediately disabled by acpi_ev_gpe_dispatch the + * first time it fires. + */ + if (!(gpe_event_info->flags & ACPI_GPE_DISPATCH_MASK)) { + return_ACPI_STATUS(AE_NO_HANDLER); + } + + /* Clear the GPE (of stale events) */ + status = acpi_hw_clear_gpe(gpe_event_info); + if (ACPI_FAILURE(status)) { + return_ACPI_STATUS(status); + } + + /* Enable the requested GPE */ + status = acpi_hw_low_set_gpe(gpe_event_info, ACPI_GPE_ENABLE); + + return_ACPI_STATUS(status); +} + /******************************************************************************* * diff --git a/drivers/acpi/acpica/evgpeblk.c b/drivers/acpi/acpica/evgpeblk.c index 77e8630043f8..0c6f3f878eb5 100644 --- a/drivers/acpi/acpica/evgpeblk.c +++ b/drivers/acpi/acpica/evgpeblk.c @@ -508,10 +508,8 @@ acpi_ev_initialize_gpe_block(struct acpi_namespace_node *gpe_device, * increment its reference counter. */ if (gpe_event_info->runtime_count) { - acpi_set_gpe(gpe_device, gpe_number, - ACPI_GPE_ENABLE); - gpe_enabled_count++; - continue; + status = acpi_ev_enable_gpe(gpe_event_info); + goto enabled; } if (gpe_event_info->flags & ACPI_GPE_CAN_WAKE) { @@ -530,6 +528,7 @@ acpi_ev_initialize_gpe_block(struct acpi_namespace_node *gpe_device, /* Enable this GPE */ status = acpi_enable_gpe(gpe_device, gpe_number); + enabled: if (ACPI_FAILURE(status)) { ACPI_EXCEPTION((AE_INFO, status, "Could not enable GPE 0x%02X", diff --git a/drivers/acpi/acpica/evxfevnt.c b/drivers/acpi/acpica/evxfevnt.c index 467fde961aef..b094cc0183d7 100644 --- a/drivers/acpi/acpica/evxfevnt.c +++ b/drivers/acpi/acpica/evxfevnt.c @@ -208,44 +208,6 @@ acpi_status acpi_enable_event(u32 event, u32 flags) ACPI_EXPORT_SYMBOL(acpi_enable_event) -/******************************************************************************* - * - * FUNCTION: acpi_clear_and_enable_gpe - * - * PARAMETERS: gpe_event_info - GPE to enable - * - * RETURN: Status - * - * DESCRIPTION: Clear the given GPE from stale events and enable it. - * - ******************************************************************************/ -static acpi_status -acpi_clear_and_enable_gpe(struct acpi_gpe_event_info *gpe_event_info) -{ - acpi_status status; - - /* - * We will only allow a GPE to be enabled if it has either an - * associated method (_Lxx/_Exx) or a handler. Otherwise, the - * GPE will be immediately disabled by acpi_ev_gpe_dispatch the - * first time it fires. - */ - if (!(gpe_event_info->flags & ACPI_GPE_DISPATCH_MASK)) { - return_ACPI_STATUS(AE_NO_HANDLER); - } - - /* Clear the GPE (of stale events) */ - status = acpi_hw_clear_gpe(gpe_event_info); - if (ACPI_FAILURE(status)) { - return_ACPI_STATUS(status); - } - - /* Enable the requested GPE */ - status = acpi_hw_low_set_gpe(gpe_event_info, ACPI_GPE_ENABLE); - - return_ACPI_STATUS(status); -} - /******************************************************************************* * * FUNCTION: acpi_set_gpe @@ -287,7 +249,7 @@ acpi_status acpi_set_gpe(acpi_handle gpe_device, u32 gpe_number, u8 action) switch (action) { case ACPI_GPE_ENABLE: - status = acpi_clear_and_enable_gpe(gpe_event_info); + status = acpi_ev_enable_gpe(gpe_event_info); break; case ACPI_GPE_DISABLE: @@ -414,7 +376,7 @@ acpi_status acpi_enable_gpe(acpi_handle gpe_device, u32 gpe_number) if (gpe_event_info->runtime_count == 1) { status = acpi_ev_update_gpe_enable_mask(gpe_event_info); if (ACPI_SUCCESS(status)) { - status = acpi_clear_and_enable_gpe(gpe_event_info); + status = acpi_ev_enable_gpe(gpe_event_info); } if (ACPI_FAILURE(status)) { gpe_event_info->runtime_count--; -- cgit v1.2.1 From 546eb57695875712f676e5f729159b0779f1c0af Mon Sep 17 00:00:00 2001 From: "Rafael J. Wysocki" Date: Thu, 1 Jul 2010 11:07:20 +0800 Subject: ACPICA: Drop acpi_set_gpe The acpi_set_gpe() function is a little awkward, because it doesn't really work as advertised in the "disable" case. Namely, if a GPE has been enabled with acpi_enable_gpe() and triggered a notification to occur, and if acpi_set_gpe() is used to disable it before acpi_ev_asynch_enable_gpe() runs, the GPE will be immediately enabled by the latter as though the acpi_set_gpe() had no effect. Thus, since it's been possible to make all of its callers use alternative operations to disable or enable GPEs, acpi_set_gpe() can be dropped. Signed-off-by: Rafael J. Wysocki Signed-off-by: Len Brown --- drivers/acpi/acpica/evxfevnt.c | 60 ------------------------------------------ 1 file changed, 60 deletions(-) (limited to 'drivers/acpi') diff --git a/drivers/acpi/acpica/evxfevnt.c b/drivers/acpi/acpica/evxfevnt.c index b094cc0183d7..fda5b44a5567 100644 --- a/drivers/acpi/acpica/evxfevnt.c +++ b/drivers/acpi/acpica/evxfevnt.c @@ -208,66 +208,6 @@ acpi_status acpi_enable_event(u32 event, u32 flags) ACPI_EXPORT_SYMBOL(acpi_enable_event) -/******************************************************************************* - * - * FUNCTION: acpi_set_gpe - * - * PARAMETERS: gpe_device - Parent GPE Device. NULL for GPE0/GPE1 - * gpe_number - GPE level within the GPE block - * action - ACPI_GPE_ENABLE or ACPI_GPE_DISABLE - * - * RETURN: Status - * - * DESCRIPTION: Enable or disable an individual GPE. This function bypasses - * the reference count mechanism used in the acpi_enable_gpe and - * acpi_disable_gpe interfaces -- and should be used with care. - * - * Note: Typically used to disable a runtime GPE for short period of time, - * then re-enable it, without disturbing the existing reference counts. This - * is useful, for example, in the Embedded Controller (EC) driver. - * - ******************************************************************************/ -acpi_status acpi_set_gpe(acpi_handle gpe_device, u32 gpe_number, u8 action) -{ - struct acpi_gpe_event_info *gpe_event_info; - acpi_status status; - acpi_cpu_flags flags; - - ACPI_FUNCTION_TRACE(acpi_set_gpe); - - 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); - if (!gpe_event_info) { - status = AE_BAD_PARAMETER; - goto unlock_and_exit; - } - - /* Perform the action */ - - switch (action) { - case ACPI_GPE_ENABLE: - status = acpi_ev_enable_gpe(gpe_event_info); - break; - - case ACPI_GPE_DISABLE: - status = acpi_hw_low_set_gpe(gpe_event_info, ACPI_GPE_DISABLE); - break; - - default: - status = AE_BAD_PARAMETER; - break; - } - - unlock_and_exit: - acpi_os_release_lock(acpi_gbl_gpe_lock, flags); - return_ACPI_STATUS(status); -} - -ACPI_EXPORT_SYMBOL(acpi_set_gpe) - /******************************************************************************* * * FUNCTION: acpi_gpe_wakeup -- cgit v1.2.1 From de5668fe7549c0586c6f64fa5661604cf7029a99 Mon Sep 17 00:00:00 2001 From: Bob Moore Date: Tue, 6 Jul 2010 10:30:37 +0800 Subject: ACPICA: Remove obsolete GPE function Remove acpi_hw_write_gpe_enable_reg, it had been reduced down to a single line of code, and called from only one place. Signed-off-by: Bob Moore Signed-off-by: Lin Ming Signed-off-by: Len Brown --- drivers/acpi/acpica/achware.h | 3 --- drivers/acpi/acpica/evgpe.c | 8 ++++++-- drivers/acpi/acpica/hwgpe.c | 25 ------------------------- 3 files changed, 6 insertions(+), 30 deletions(-) (limited to 'drivers/acpi') diff --git a/drivers/acpi/acpica/achware.h b/drivers/acpi/acpica/achware.h index c73144c9a395..120b3af56596 100644 --- a/drivers/acpi/acpica/achware.h +++ b/drivers/acpi/acpica/achware.h @@ -96,9 +96,6 @@ u32 acpi_hw_get_gpe_register_bit(struct acpi_gpe_event_info *gpe_event_info, acpi_status acpi_hw_low_set_gpe(struct acpi_gpe_event_info *gpe_event_info, u8 action); -acpi_status -acpi_hw_write_gpe_enable_reg(struct acpi_gpe_event_info *gpe_event_info); - acpi_status acpi_hw_disable_gpe_block(struct acpi_gpe_xrupt_info *gpe_xrupt_info, struct acpi_gpe_block_info *gpe_block, void *context); diff --git a/drivers/acpi/acpica/evgpe.c b/drivers/acpi/acpica/evgpe.c index 56de460570d6..7a6a3e6f4be0 100644 --- a/drivers/acpi/acpica/evgpe.c +++ b/drivers/acpi/acpica/evgpe.c @@ -452,8 +452,12 @@ static void acpi_ev_asynch_enable_gpe(void *context) } } - /* Enable this GPE */ - (void)acpi_hw_write_gpe_enable_reg(gpe_event_info); + /* + * Enable this GPE, conditionally. This means that the GPE will only be + * physically enabled if the enable_for_run bit is set in the event_info + */ + (void)acpi_hw_low_set_gpe(gpe_event_info, ACPI_GPE_COND_ENABLE); + return_VOID; } diff --git a/drivers/acpi/acpica/hwgpe.c b/drivers/acpi/acpica/hwgpe.c index 12d70fdadc2b..14750db2a1b8 100644 --- a/drivers/acpi/acpica/hwgpe.c +++ b/drivers/acpi/acpica/hwgpe.c @@ -141,31 +141,6 @@ acpi_hw_low_set_gpe(struct acpi_gpe_event_info *gpe_event_info, u8 action) return (status); } -/****************************************************************************** - * - * FUNCTION: acpi_hw_write_gpe_enable_reg - * - * PARAMETERS: gpe_event_info - Info block for the GPE to be enabled - * - * RETURN: Status - * - * DESCRIPTION: Write a GPE enable register. Note: The bit for this GPE must - * already be cleared or set in the parent register - * enable_for_run mask. - * - ******************************************************************************/ - -acpi_status -acpi_hw_write_gpe_enable_reg(struct acpi_gpe_event_info * gpe_event_info) -{ - acpi_status status; - - ACPI_FUNCTION_ENTRY(); - - status = acpi_hw_low_set_gpe(gpe_event_info, ACPI_GPE_COND_ENABLE); - return (status); -} - /****************************************************************************** * * FUNCTION: acpi_hw_clear_gpe -- cgit v1.2.1 From 150dba38f0c3d2d5f5edc58145d202de08ed623c Mon Sep 17 00:00:00 2001 From: Bob Moore Date: Tue, 6 Jul 2010 10:35:55 +0800 Subject: ACPICA: Fix lint warning for 64-bit constant cast to u64. Signed-off-by: Bob Moore Signed-off-by: Lin Ming Signed-off-by: Len Brown --- drivers/acpi/acpica/nsrepair.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/acpi') diff --git a/drivers/acpi/acpica/nsrepair.c b/drivers/acpi/acpica/nsrepair.c index d4be37751be4..d1c136692667 100644 --- a/drivers/acpi/acpica/nsrepair.c +++ b/drivers/acpi/acpica/nsrepair.c @@ -556,7 +556,7 @@ acpi_ns_repair_null_element(struct acpi_predefined_data *data, /* Need an Integer - create a zero-value integer */ - new_object = acpi_ut_create_integer_object(0); + new_object = acpi_ut_create_integer_object((u64)0); } else if (expected_btypes & ACPI_RTYPE_STRING) { /* Need a String - create a NULL string */ -- cgit v1.2.1 From 09079250db4d470f75eddcce31e0229c92d6c3bf Mon Sep 17 00:00:00 2001 From: Bob Moore Date: Tue, 6 Jul 2010 10:37:13 +0800 Subject: ACPICA: Fix for Alias references within Package objects This fixes a problem where a reference to an Alias within the definition of a Package was not always resolved properly. Aliases to objects like Processors, ThermalZones, etc. were resolved to the actual object instead of a reference to the object as it should be. Package objects are only allowed to contain integer, string, buffer, package, and reference objects. https://bugzilla.redhat.com/show_bug.cgi?id=608648 Signed-off-by: Bob Moore Signed-off-by: Lin Ming Signed-off-by: Len Brown --- drivers/acpi/acpica/dsobject.c | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) (limited to 'drivers/acpi') diff --git a/drivers/acpi/acpica/dsobject.c b/drivers/acpi/acpica/dsobject.c index 3607adcaf085..8e85f54a8e0e 100644 --- a/drivers/acpi/acpica/dsobject.c +++ b/drivers/acpi/acpica/dsobject.c @@ -81,6 +81,7 @@ acpi_ds_build_internal_object(struct acpi_walk_state *walk_state, { union acpi_operand_object *obj_desc; acpi_status status; + acpi_object_type type; ACPI_FUNCTION_TRACE(ds_build_internal_object); @@ -172,7 +173,20 @@ acpi_ds_build_internal_object(struct acpi_walk_state *walk_state, return_ACPI_STATUS(status); } - switch (op->common.node->type) { + /* + * Special handling for Alias objects. We need to setup the type + * and the Op->Common.Node to point to the Alias target. Note, + * Alias has at most one level of indirection internally. + */ + type = op->common.node->type; + if (type == ACPI_TYPE_LOCAL_ALIAS) { + type = obj_desc->common.type; + op->common.node = + ACPI_CAST_PTR(struct acpi_namespace_node, + op->common.node->object); + } + + switch (type) { /* * For these types, we need the actual node, not the subobject. * However, the subobject did not get an extra reference count above. -- cgit v1.2.1 From e8e18c956152ec9c26c94c6401c174691a8f04e7 Mon Sep 17 00:00:00 2001 From: "Rafael J. Wysocki" Date: Thu, 8 Jul 2010 00:42:51 +0200 Subject: ACPI: Fix bogus GPE test in acpi_bus_set_run_wake_flags() When we check if a GPE can be used for runtime signaling, we only search the FADT GPE blocks, which is incorrect, becuase the GPE may be located elsewhere. We really should be using the GPE device information previously returned by _PRW here, so make that happen. Signed-off-by: Rafael J. Wysocki Signed-off-by: Len Brown --- drivers/acpi/scan.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'drivers/acpi') diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c index 7f2e051ed4f1..449ada016d81 100644 --- a/drivers/acpi/scan.c +++ b/drivers/acpi/scan.c @@ -764,8 +764,9 @@ static void acpi_bus_set_run_wake_flags(struct acpi_device *device) return; } - status = acpi_get_gpe_status(NULL, device->wakeup.gpe_number, - &event_status); + status = acpi_get_gpe_status(device->wakeup.gpe_device, + device->wakeup.gpe_number, + &event_status); if (status == AE_OK) device->wakeup.flags.run_wake = !!(event_status & ACPI_EVENT_FLAG_HANDLE); -- cgit v1.2.1 From 9874647ba1bdf3e1af25e079070a00676f60f2f0 Mon Sep 17 00:00:00 2001 From: "Rafael J. Wysocki" Date: Thu, 8 Jul 2010 00:43:36 +0200 Subject: ACPI / ACPICA: Do not execute _PRW methods during initialization Currently, during initialization ACPICA walks the entire ACPI namespace in search of any device objects with assciated _PRW methods. All of the _PRW methods found are executed in the process to extract the GPE information returned by them, so that the GPEs in question can be marked as "able to wakeup" (more precisely, the ACPI_GPE_CAN_WAKE flag is set for them). The only purpose of this exercise is to avoid enabling the CAN_WAKE GPEs automatically, even if there are _Lxx/_Exx methods associated with them. However, it is both costly and unnecessary, because the host OS has to execute the _PRW methods anyway to check which devices can wake up the system from sleep states. Moreover, it then uses full information returned by _PRW, including the GPE information, so it can take care of disabling the GPEs if necessary. Remove the code that walks the namespace and executes _PRW from ACPICA and modify comments to reflect that change. Make acpi_bus_set_run_wake_flags() disable GPEs for wakeup devices so that they don't cause spurious wakeup events to be signaled. This not only reduces the complexity of the ACPICA initialization code, but in some cases it should reduce the kernel boot time as well. Unfortunately, for this purpose we need a new ACPICA function, acpi_gpe_can_wake(), to be called by the host OS in order to disable the GPEs that can wake up the system and were previously enabled by acpi_ev_initialize_gpe_block() or acpi_ev_update_gpes() (such a GPE should be disabled only once, because the initialization code enables it only once, but it may be pointed to by _PRW for multiple devices and that's why the additional function is necessary). Signed-off-by: Rafael J. Wysocki Signed-off-by: Len Brown --- drivers/acpi/acpica/acglobal.h | 7 -- drivers/acpi/acpica/evevent.c | 5 +- drivers/acpi/acpica/evgpeblk.c | 47 +------- drivers/acpi/acpica/evgpeinit.c | 235 +++------------------------------------- drivers/acpi/acpica/evxfevnt.c | 55 +++++++++- drivers/acpi/acpica/exconfig.c | 2 +- drivers/acpi/acpica/utxface.c | 8 +- drivers/acpi/osl.c | 20 ---- drivers/acpi/scan.c | 2 + 9 files changed, 83 insertions(+), 298 deletions(-) (limited to 'drivers/acpi') diff --git a/drivers/acpi/acpica/acglobal.h b/drivers/acpi/acpica/acglobal.h index 899d68afc3c5..18e796fe4295 100644 --- a/drivers/acpi/acpica/acglobal.h +++ b/drivers/acpi/acpica/acglobal.h @@ -99,13 +99,6 @@ u8 ACPI_INIT_GLOBAL(acpi_gbl_all_methods_serialized, FALSE); */ u8 ACPI_INIT_GLOBAL(acpi_gbl_create_osi_method, TRUE); -/* - * Disable wakeup GPEs during runtime? Default is TRUE because WAKE and - * RUNTIME GPEs should never be shared, and WAKE GPEs should typically only - * be enabled just before going to sleep. - */ -u8 ACPI_INIT_GLOBAL(acpi_gbl_leave_wake_gpes_disabled, TRUE); - /* * Optionally use default values for the ACPI register widths. Set this to * TRUE to use the defaults, if an FADT contains incorrect widths/lengths. diff --git a/drivers/acpi/acpica/evevent.c b/drivers/acpi/acpica/evevent.c index f5795915a2e9..303618889da0 100644 --- a/drivers/acpi/acpica/evevent.c +++ b/drivers/acpi/acpica/evevent.c @@ -102,9 +102,8 @@ acpi_status acpi_ev_initialize_events(void) * RETURN: Status * * DESCRIPTION: Completes initialization of the FADT-defined GPE blocks - * (0 and 1). This causes the _PRW methods to be run, so the HW - * must be fully initialized at this point, including global lock - * support. + * (0 and 1). The HW must be fully initialized at this point, + * including global lock support. * ******************************************************************************/ diff --git a/drivers/acpi/acpica/evgpeblk.c b/drivers/acpi/acpica/evgpeblk.c index 0c6f3f878eb5..12ca1bc5f1fd 100644 --- a/drivers/acpi/acpica/evgpeblk.c +++ b/drivers/acpi/acpica/evgpeblk.c @@ -439,8 +439,6 @@ acpi_ev_initialize_gpe_block(struct acpi_namespace_node *gpe_device, { acpi_status status; struct acpi_gpe_event_info *gpe_event_info; - struct acpi_gpe_walk_info walk_info; - u32 wake_gpe_count; u32 gpe_enabled_count; u32 gpe_index; u32 gpe_number; @@ -456,37 +454,9 @@ acpi_ev_initialize_gpe_block(struct acpi_namespace_node *gpe_device, } /* - * Runtime option: Should wake GPEs be enabled at runtime? The default - * is no, they should only be enabled just as the machine goes to sleep. + * Enable all GPEs that have a corresponding method. Any other GPEs + * within this block must be enabled via the acpi_enable_gpe interface. */ - if (acpi_gbl_leave_wake_gpes_disabled) { - /* - * Differentiate runtime vs wake GPEs, via the _PRW control methods. - * Each GPE that has one or more _PRWs that reference it is by - * definition a wake GPE and will not be enabled while the machine - * is running. - */ - walk_info.gpe_block = gpe_block; - walk_info.gpe_device = gpe_device; - walk_info.execute_by_owner_id = FALSE; - - status = - acpi_ns_walk_namespace(ACPI_TYPE_DEVICE, ACPI_ROOT_OBJECT, - ACPI_UINT32_MAX, ACPI_NS_WALK_UNLOCK, - acpi_ev_match_prw_and_gpe, NULL, - &walk_info, NULL); - if (ACPI_FAILURE(status)) { - ACPI_EXCEPTION((AE_INFO, status, - "While executing _PRW methods")); - } - } - - /* - * Enable all GPEs that have a corresponding method and are not - * capable of generating wakeups. Any other GPEs within this block - * must be enabled via the acpi_enable_gpe interface. - */ - wake_gpe_count = 0; gpe_enabled_count = 0; if (gpe_device == acpi_gbl_fadt_gpe_device) { @@ -512,13 +482,6 @@ acpi_ev_initialize_gpe_block(struct acpi_namespace_node *gpe_device, goto enabled; } - if (gpe_event_info->flags & ACPI_GPE_CAN_WAKE) { - wake_gpe_count++; - if (acpi_gbl_leave_wake_gpes_disabled) { - continue; - } - } - /* Ignore GPEs that have no corresponding _Lxx/_Exx method */ if (!(gpe_event_info->flags & ACPI_GPE_DISPATCH_METHOD)) { @@ -540,10 +503,10 @@ acpi_ev_initialize_gpe_block(struct acpi_namespace_node *gpe_device, } } - if (gpe_enabled_count || wake_gpe_count) { + if (gpe_enabled_count) { ACPI_DEBUG_PRINT((ACPI_DB_INIT, - "Enabled %u Runtime GPEs, added %u Wake GPEs in this block\n", - gpe_enabled_count, wake_gpe_count)); + "Enabled %u GPEs in this block\n", + gpe_enabled_count)); } return_ACPI_STATUS(AE_OK); diff --git a/drivers/acpi/acpica/evgpeinit.c b/drivers/acpi/acpica/evgpeinit.c index 8db9e076a53b..3084c5de1bba 100644 --- a/drivers/acpi/acpica/evgpeinit.c +++ b/drivers/acpi/acpica/evgpeinit.c @@ -211,9 +211,7 @@ acpi_status acpi_ev_gpe_initialize(void) * DESCRIPTION: Check for new GPE methods (_Lxx/_Exx) made available as a * result of a Load() or load_table() operation. If new GPE * methods have been installed, register the new methods and - * enable and runtime GPEs that are associated with them. Also, - * run any newly loaded _PRW methods in order to discover any - * new CAN_WAKE GPEs. + * enable and runtime GPEs that are associated with them. * ******************************************************************************/ @@ -223,49 +221,12 @@ void acpi_ev_update_gpes(acpi_owner_id table_owner_id) struct acpi_gpe_block_info *gpe_block; struct acpi_gpe_walk_info walk_info; acpi_status status = AE_OK; - u32 new_wake_gpe_count = 0; - - /* We will examine only _PRW/_Lxx/_Exx methods owned by this table */ - - walk_info.owner_id = table_owner_id; - walk_info.execute_by_owner_id = TRUE; - walk_info.count = 0; - - if (acpi_gbl_leave_wake_gpes_disabled) { - /* - * 1) Run any newly-loaded _PRW methods to find any GPEs that - * can now be marked as CAN_WAKE GPEs. Note: We must run the - * _PRW methods before we process the _Lxx/_Exx methods because - * we will enable all runtime GPEs associated with the new - * _Lxx/_Exx methods at the time we process those methods. - * - * Unlock interpreter so that we can run the _PRW methods. - */ - walk_info.gpe_block = NULL; - walk_info.gpe_device = NULL; - - acpi_ex_exit_interpreter(); - - status = - acpi_ns_walk_namespace(ACPI_TYPE_DEVICE, ACPI_ROOT_OBJECT, - ACPI_UINT32_MAX, - ACPI_NS_WALK_NO_UNLOCK, - acpi_ev_match_prw_and_gpe, NULL, - &walk_info, NULL); - if (ACPI_FAILURE(status)) { - ACPI_EXCEPTION((AE_INFO, status, - "While executing _PRW methods")); - } - - acpi_ex_enter_interpreter(); - new_wake_gpe_count = walk_info.count; - } /* * 2) Find any _Lxx/_Exx GPE methods that have just been loaded. * - * Any GPEs that correspond to new _Lxx/_Exx methods and are not - * marked as CAN_WAKE are immediately enabled. + * Any GPEs that correspond to new _Lxx/_Exx methods are immediately + * enabled. * * Examine the namespace underneath each gpe_device within the * gpe_block lists. @@ -275,6 +236,8 @@ void acpi_ev_update_gpes(acpi_owner_id table_owner_id) return; } + walk_info.owner_id = table_owner_id; + walk_info.execute_by_owner_id = TRUE; walk_info.count = 0; walk_info.enable_this_gpe = TRUE; @@ -307,10 +270,8 @@ void acpi_ev_update_gpes(acpi_owner_id table_owner_id) gpe_xrupt_info = gpe_xrupt_info->next; } - if (walk_info.count || new_wake_gpe_count) { - ACPI_INFO((AE_INFO, - "Enabled %u new runtime GPEs, added %u new wakeup GPEs", - walk_info.count, new_wake_gpe_count)); + if (walk_info.count) { + ACPI_INFO((AE_INFO, "Enabled %u new GPEs", walk_info.count)); } (void)acpi_ut_release_mutex(ACPI_MTX_EVENTS); @@ -386,9 +347,6 @@ acpi_ev_match_gpe_method(acpi_handle obj_handle, /* * 3) Edge/Level determination is based on the 2nd character * of the method name - * - * NOTE: Default GPE type is RUNTIME only. Later, if a _PRW object is - * found that points to this GPE, the ACPI_GPE_CAN_WAKE flag is set. */ switch (name[1]) { case 'L': @@ -471,23 +429,18 @@ acpi_ev_match_gpe_method(acpi_handle obj_handle, */ if (walk_info->enable_this_gpe) { - /* Ignore GPEs that can wake the system */ + walk_info->count++; + gpe_device = walk_info->gpe_device; - if (!(gpe_event_info->flags & ACPI_GPE_CAN_WAKE) || - !acpi_gbl_leave_wake_gpes_disabled) { - walk_info->count++; - gpe_device = walk_info->gpe_device; - - if (gpe_device == acpi_gbl_fadt_gpe_device) { - gpe_device = NULL; - } + if (gpe_device == acpi_gbl_fadt_gpe_device) { + gpe_device = NULL; + } - status = acpi_enable_gpe(gpe_device, gpe_number); - if (ACPI_FAILURE(status)) { - ACPI_EXCEPTION((AE_INFO, status, - "Could not enable GPE 0x%02X", - gpe_number)); - } + status = acpi_enable_gpe(gpe_device, gpe_number); + if (ACPI_FAILURE(status)) { + ACPI_EXCEPTION((AE_INFO, status, + "Could not enable GPE 0x%02X", + gpe_number)); } } @@ -496,157 +449,3 @@ acpi_ev_match_gpe_method(acpi_handle obj_handle, name, gpe_number)); return_ACPI_STATUS(AE_OK); } - -/******************************************************************************* - * - * FUNCTION: acpi_ev_match_prw_and_gpe - * - * PARAMETERS: Callback from walk_namespace - * - * RETURN: Status. NOTE: We ignore errors so that the _PRW walk is - * not aborted on a single _PRW failure. - * - * DESCRIPTION: Called from acpi_walk_namespace. Expects each object to be a - * Device. Run the _PRW method. If present, extract the GPE - * number and mark the GPE as a CAN_WAKE GPE. Allows a - * per-owner_id execution if execute_by_owner_id is TRUE in the - * walk_info parameter block. - * - * If walk_info->execute_by_owner_id is TRUE, we only execute _PRWs with that - * owner. - * If walk_info->gpe_device is NULL, we execute every _PRW found. Otherwise, - * we only execute _PRWs that refer to the input gpe_device. - * - ******************************************************************************/ - -acpi_status -acpi_ev_match_prw_and_gpe(acpi_handle obj_handle, - u32 level, void *context, void **return_value) -{ - struct acpi_gpe_walk_info *walk_info = - ACPI_CAST_PTR(struct acpi_gpe_walk_info, context); - struct acpi_namespace_node *gpe_device; - struct acpi_gpe_block_info *gpe_block; - struct acpi_namespace_node *target_gpe_device; - struct acpi_namespace_node *prw_node; - struct acpi_gpe_event_info *gpe_event_info; - union acpi_operand_object *pkg_desc; - union acpi_operand_object *obj_desc; - u32 gpe_number; - acpi_status status; - - ACPI_FUNCTION_TRACE(ev_match_prw_and_gpe); - - /* Check for a _PRW method under this device */ - - status = acpi_ns_get_node(obj_handle, METHOD_NAME__PRW, - ACPI_NS_NO_UPSEARCH, &prw_node); - if (ACPI_FAILURE(status)) { - return_ACPI_STATUS(AE_OK); - } - - /* Check if requested owner_id matches this owner_id */ - - if ((walk_info->execute_by_owner_id) && - (prw_node->owner_id != walk_info->owner_id)) { - return_ACPI_STATUS(AE_OK); - } - - /* Execute the _PRW */ - - status = acpi_ut_evaluate_object(prw_node, NULL, - ACPI_BTYPE_PACKAGE, &pkg_desc); - if (ACPI_FAILURE(status)) { - return_ACPI_STATUS(AE_OK); - } - - /* The returned _PRW package must have at least two elements */ - - if (pkg_desc->package.count < 2) { - goto cleanup; - } - - /* Extract pointers from the input context */ - - gpe_device = walk_info->gpe_device; - gpe_block = walk_info->gpe_block; - - /* - * The _PRW object must return a package, we are only interested - * in the first element - */ - obj_desc = pkg_desc->package.elements[0]; - - if (obj_desc->common.type == ACPI_TYPE_INTEGER) { - - /* Use FADT-defined GPE device (from definition of _PRW) */ - - target_gpe_device = NULL; - if (gpe_device) { - target_gpe_device = acpi_gbl_fadt_gpe_device; - } - - /* Integer is the GPE number in the FADT described GPE blocks */ - - gpe_number = (u32)obj_desc->integer.value; - } else if (obj_desc->common.type == ACPI_TYPE_PACKAGE) { - - /* Package contains a GPE reference and GPE number within a GPE block */ - - if ((obj_desc->package.count < 2) || - ((obj_desc->package.elements[0])->common.type != - ACPI_TYPE_LOCAL_REFERENCE) || - ((obj_desc->package.elements[1])->common.type != - ACPI_TYPE_INTEGER)) { - goto cleanup; - } - - /* Get GPE block reference and decode */ - - target_gpe_device = - obj_desc->package.elements[0]->reference.node; - gpe_number = (u32)obj_desc->package.elements[1]->integer.value; - } else { - /* Unknown type, just ignore it */ - - goto cleanup; - } - - /* Get the gpe_event_info for this GPE */ - - if (gpe_device) { - /* - * Is this GPE within this block? - * - * TRUE if and only if these conditions are true: - * 1) The GPE devices match. - * 2) The GPE index(number) is within the range of the Gpe Block - * associated with the GPE device. - */ - if (gpe_device != target_gpe_device) { - goto cleanup; - } - - gpe_event_info = - acpi_ev_low_get_gpe_info(gpe_number, gpe_block); - } else { - /* gpe_device is NULL, just match the target_device and gpe_number */ - - gpe_event_info = - acpi_ev_get_gpe_event_info(target_gpe_device, gpe_number); - } - - if (gpe_event_info) { - if (!(gpe_event_info->flags & ACPI_GPE_CAN_WAKE)) { - - /* This GPE can wake the system */ - - gpe_event_info->flags |= ACPI_GPE_CAN_WAKE; - walk_info->count++; - } - } - - cleanup: - acpi_ut_remove_reference(pkg_desc); - return_ACPI_STATUS(AE_OK); -} diff --git a/drivers/acpi/acpica/evxfevnt.c b/drivers/acpi/acpica/evxfevnt.c index fda5b44a5567..bd06fad83e7a 100644 --- a/drivers/acpi/acpica/evxfevnt.c +++ b/drivers/acpi/acpica/evxfevnt.c @@ -387,6 +387,59 @@ unlock_and_exit: } ACPI_EXPORT_SYMBOL(acpi_disable_gpe) +/******************************************************************************* + * + * FUNCTION: acpi_gpe_can_wake + * + * PARAMETERS: gpe_device - Parent GPE Device. NULL for GPE0/GPE1 + * gpe_number - GPE level within the GPE block + * + * RETURN: Status + * + * DESCRIPTION: Set the ACPI_GPE_CAN_WAKE flag for the given GPE. If the GPE + * has a corresponding method and is currently enabled, disable it + * (GPEs with corresponding methods are enabled unconditionally + * during initialization, but GPEs that can wake up are expected + * to be initially disabled). + * + ******************************************************************************/ +acpi_status acpi_gpe_can_wake(acpi_handle gpe_device, u32 gpe_number) +{ + acpi_status status = AE_OK; + struct acpi_gpe_event_info *gpe_event_info; + acpi_cpu_flags flags; + u8 disable = 0; + + ACPI_FUNCTION_TRACE(acpi_gpe_can_wake); + + 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); + if (!gpe_event_info) { + status = AE_BAD_PARAMETER; + goto unlock_and_exit; + } + + if (gpe_event_info->flags & ACPI_GPE_CAN_WAKE) { + goto unlock_and_exit; + } + + gpe_event_info->flags |= ACPI_GPE_CAN_WAKE; + disable = (gpe_event_info->flags & ACPI_GPE_DISPATCH_METHOD) + && gpe_event_info->runtime_count; + +unlock_and_exit: + acpi_os_release_lock(acpi_gbl_gpe_lock, flags); + + if (disable) + status = acpi_disable_gpe(gpe_device, gpe_number); + + return_ACPI_STATUS(status); +} +ACPI_EXPORT_SYMBOL(acpi_gpe_can_wake) + /******************************************************************************* * * FUNCTION: acpi_disable_event @@ -703,7 +756,7 @@ acpi_install_gpe_block(acpi_handle gpe_device, obj_desc->device.gpe_block = gpe_block; - /* Run the _PRW methods and enable the runtime GPEs in the new block */ + /* Enable the runtime GPEs in the new block */ status = acpi_ev_initialize_gpe_block(node, gpe_block); diff --git a/drivers/acpi/acpica/exconfig.c b/drivers/acpi/acpica/exconfig.c index 008621c5ad85..18832205b631 100644 --- a/drivers/acpi/acpica/exconfig.c +++ b/drivers/acpi/acpica/exconfig.c @@ -120,7 +120,7 @@ acpi_ex_add_table(u32 table_index, acpi_ns_exec_module_code_list(); acpi_ex_enter_interpreter(); - /* Update GPEs for any new _PRW or _Lxx/_Exx methods. Ignore errors */ + /* Update GPEs for any new _Lxx/_Exx methods. Ignore errors */ status = acpi_tb_get_owner_id(table_index, &owner_id); if (ACPI_SUCCESS(status)) { diff --git a/drivers/acpi/acpica/utxface.c b/drivers/acpi/acpica/utxface.c index db9d8ca57987..7f8cefcb2b32 100644 --- a/drivers/acpi/acpica/utxface.c +++ b/drivers/acpi/acpica/utxface.c @@ -293,12 +293,8 @@ acpi_status acpi_initialize_objects(u32 flags) * Complete the GPE initialization for the GPE blocks defined in the FADT * (GPE block 0 and 1). * - * Note1: This is where the _PRW methods are executed for the GPEs. These - * methods can only be executed after the SCI and Global Lock handlers are - * installed and initialized. - * - * Note2: Currently, there seems to be no need to run the _REG methods - * before execution of the _PRW methods and enabling of the GPEs. + * NOTE: Currently, there seems to be no need to run the _REG methods + * before enabling the GPEs. */ if (!(flags & ACPI_NO_EVENT_INIT)) { status = acpi_ev_install_fadt_gpes(); diff --git a/drivers/acpi/osl.c b/drivers/acpi/osl.c index 78418ce4fc78..44bddc5bc6ad 100644 --- a/drivers/acpi/osl.c +++ b/drivers/acpi/osl.c @@ -1064,26 +1064,6 @@ static int __init acpi_serialize_setup(char *str) __setup("acpi_serialize", acpi_serialize_setup); -/* - * Wake and Run-Time GPES are expected to be separate. - * We disable wake-GPEs at run-time to prevent spurious - * interrupts. - * - * However, if a system exists that shares Wake and - * Run-time events on the same GPE this flag is available - * to tell Linux to keep the wake-time GPEs enabled at run-time. - */ -static int __init acpi_wake_gpes_always_on_setup(char *str) -{ - printk(KERN_INFO PREFIX "wake GPEs not disabled\n"); - - acpi_gbl_leave_wake_gpes_disabled = FALSE; - - return 1; -} - -__setup("acpi_wake_gpes_always_on", acpi_wake_gpes_always_on_setup); - /* Check of resource interference between native drivers and ACPI * OperationRegions (SystemIO and System Memory only). * IO ports and memory declared in ACPI might be used by the ACPI subsystem diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c index 449ada016d81..b23825ecfa37 100644 --- a/drivers/acpi/scan.c +++ b/drivers/acpi/scan.c @@ -740,6 +740,8 @@ acpi_bus_extract_wakeup_device_power_package(struct acpi_device *device, device->wakeup.resources.handles[i] = element->reference.handle; } + acpi_gpe_can_wake(device->wakeup.gpe_device, device->wakeup.gpe_number); + return AE_OK; } -- cgit v1.2.1 From 9ce10df8d83d0528e80cd319b35ac5f6812b4f62 Mon Sep 17 00:00:00 2001 From: "Rafael J. Wysocki" Date: Thu, 8 Jul 2010 00:45:34 +0200 Subject: ACPI / ACPICA: Fail acpi_gpe_wakeup() if ACPI_GPE_CAN_WAKE is unset Make acpi_gpe_wakeup() return error code for GPEs whose ACPI_GPE_CAN_WAKE flag is not set. This way acpi_gpe_wakeup() will only wake for the GPEs reported by the host OS as "wakeup" ones with the help of acpi_gpe_can_wake(). Signed-off-by: Rafael J. Wysocki Signed-off-by: Len Brown --- drivers/acpi/acpica/evxfevnt.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/acpi') diff --git a/drivers/acpi/acpica/evxfevnt.c b/drivers/acpi/acpica/evxfevnt.c index bd06fad83e7a..53d591a11138 100644 --- a/drivers/acpi/acpica/evxfevnt.c +++ b/drivers/acpi/acpica/evxfevnt.c @@ -236,7 +236,7 @@ acpi_status acpi_gpe_wakeup(acpi_handle gpe_device, u32 gpe_number, u8 action) /* Ensure that we have a valid GPE number */ gpe_event_info = acpi_ev_get_gpe_event_info(gpe_device, gpe_number); - if (!gpe_event_info) { + if (!gpe_event_info || !(gpe_event_info->flags & ACPI_GPE_CAN_WAKE)) { status = AE_BAD_PARAMETER; goto unlock_and_exit; } -- cgit v1.2.1 From a0d468718b9049f7396d101075a129a2d683ad66 Mon Sep 17 00:00:00 2001 From: "Rafael J. Wysocki" Date: Thu, 8 Jul 2010 00:44:42 +0200 Subject: ACPI / ACPICA: Simplify acpi_ev_initialize_gpe_block() Simplify the main loop in acpi_ev_initialize_gpe_block() by rearranging code and removing the "enabled" label that is not necessary any more. Signed-off-by: Rafael J. Wysocki Signed-off-by: Len Brown --- drivers/acpi/acpica/evgpeblk.c | 21 ++++++++------------- 1 file changed, 8 insertions(+), 13 deletions(-) (limited to 'drivers/acpi') diff --git a/drivers/acpi/acpica/evgpeblk.c b/drivers/acpi/acpica/evgpeblk.c index 12ca1bc5f1fd..85445fb5844e 100644 --- a/drivers/acpi/acpica/evgpeblk.c +++ b/drivers/acpi/acpica/evgpeblk.c @@ -472,26 +472,21 @@ acpi_ev_initialize_gpe_block(struct acpi_namespace_node *gpe_device, gpe_event_info = &gpe_block->event_info[gpe_index]; gpe_number = gpe_index + gpe_block->block_base_number; - /* - * If the GPE has already been enabled for runtime - * signaling, make sure it remains enabled, but do not - * increment its reference counter. - */ - if (gpe_event_info->runtime_count) { - status = acpi_ev_enable_gpe(gpe_event_info); - goto enabled; - } - /* Ignore GPEs that have no corresponding _Lxx/_Exx method */ if (!(gpe_event_info->flags & ACPI_GPE_DISPATCH_METHOD)) { continue; } - /* Enable this GPE */ + /* + * If the GPE has already been enabled for runtime + * signaling, make sure it remains enabled, but do not + * increment its reference counter. + */ + status = gpe_event_info->runtime_count ? + acpi_ev_enable_gpe(gpe_event_info) : + acpi_enable_gpe(gpe_device, gpe_number); - status = acpi_enable_gpe(gpe_device, gpe_number); - enabled: if (ACPI_FAILURE(status)) { ACPI_EXCEPTION((AE_INFO, status, "Could not enable GPE 0x%02X", -- cgit v1.2.1 From 108029ff84fcad8f9199d2d2e2583ae2747d45a4 Mon Sep 17 00:00:00 2001 From: Zhao Yakui Date: Tue, 13 Jul 2010 03:36:08 +0000 Subject: ACPI: Add the check of ADR flag in course of finding ACPI handle for PCI device The _ADR object is used to provide OSPM with the address of one device on its parent bus. In course of finding ACPI handle for the corresponding PCI device, we will firstly evaluate the _ADR object and then compare the two addresses to see whether it is the target ACPI device. But for one PCI device(0000:00:00.0) under the PCI root bridge, the corresponding address will be constructed as zero.In such case maybe the ACPI device without _ADR object will be misdetected and then be used to create the relationship between PCI device and ACPI device. https://bugzilla.kernel.org/show_bug.cgi?id=16422 Signed-off-by: Zhao Yakui Signed-off-by: Len Brown --- drivers/acpi/glue.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'drivers/acpi') diff --git a/drivers/acpi/glue.c b/drivers/acpi/glue.c index 4af6301601e7..78b0164c35b2 100644 --- a/drivers/acpi/glue.c +++ b/drivers/acpi/glue.c @@ -100,7 +100,8 @@ do_acpi_find_child(acpi_handle handle, u32 lvl, void *context, void **rv) status = acpi_get_object_info(handle, &info); if (ACPI_SUCCESS(status)) { - if (info->address == find->address) + if ((info->address == find->address) + && (info->valid & ACPI_VALID_ADR)) find->handle = handle; kfree(info); } -- cgit v1.2.1 From 592913ecb87a9e06f98ddb55b298f1a66bf94c6b Mon Sep 17 00:00:00 2001 From: John Stultz Date: Tue, 13 Jul 2010 17:56:20 -0700 Subject: time: Kill off CONFIG_GENERIC_TIME Now that all arches have been converted over to use generic time via clocksources or arch_gettimeoffset(), we can remove the GENERIC_TIME config option and simplify the generic code. Signed-off-by: John Stultz LKML-Reference: <1279068988-21864-4-git-send-email-johnstul@us.ibm.com> Signed-off-by: Thomas Gleixner --- drivers/acpi/acpi_pad.c | 2 +- drivers/acpi/processor_idle.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers/acpi') diff --git a/drivers/acpi/acpi_pad.c b/drivers/acpi/acpi_pad.c index 446aced33aff..b76848c80be3 100644 --- a/drivers/acpi/acpi_pad.c +++ b/drivers/acpi/acpi_pad.c @@ -77,7 +77,7 @@ static void power_saving_mwait_init(void) power_saving_mwait_eax = (highest_cstate << MWAIT_SUBSTATE_SIZE) | (highest_subcstate - 1); -#if defined(CONFIG_GENERIC_TIME) && defined(CONFIG_X86) +#if defined(CONFIG_X86) switch (boot_cpu_data.x86_vendor) { case X86_VENDOR_AMD: case X86_VENDOR_INTEL: diff --git a/drivers/acpi/processor_idle.c b/drivers/acpi/processor_idle.c index e9a8026d39f0..294e10b5480a 100644 --- a/drivers/acpi/processor_idle.c +++ b/drivers/acpi/processor_idle.c @@ -264,7 +264,7 @@ int acpi_processor_resume(struct acpi_device * device) return 0; } -#if defined (CONFIG_GENERIC_TIME) && defined (CONFIG_X86) +#if defined(CONFIG_X86) static void tsc_check_state(int state) { switch (boot_cpu_data.x86_vendor) { -- cgit v1.2.1 From 852972acff8f10f3a15679be2059bb94916cba5d Mon Sep 17 00:00:00 2001 From: Matthew Garrett Date: Tue, 22 Jun 2010 11:25:43 -0400 Subject: ACPI: Disable ASPM if the platform won't provide _OSC control for PCIe The PCI SIG documentation for the _OSC OS/firmware handshaking interface states: "If the _OSC control method is absent from the scope of a host bridge device, then the operating system must not enable or attempt to use any features defined in this section for the hierarchy originated by the host bridge." The obvious interpretation of this is that the OS should not attempt to use PCIe hotplug, PME or AER - however, the specification also notes that an _OSC method is *required* for PCIe hierarchies, and experimental validation with An Alternative OS indicates that it doesn't use any PCIe functionality if the _OSC method is missing. That arguably means we shouldn't be using MSI or extended config space, but right now our problems seem to be limited to vendors being surprised when ASPM gets enabled on machines when other OSs refuse to do so. So, for now, let's just disable ASPM if the _OSC method doesn't exist or refuses to hand over PCIe capability control. Acked-by: Rafael J. Wysocki Signed-off-by: Matthew Garrett Signed-off-by: Jesse Barnes --- drivers/acpi/pci_root.c | 9 +++++++++ 1 file changed, 9 insertions(+) (limited to 'drivers/acpi') diff --git a/drivers/acpi/pci_root.c b/drivers/acpi/pci_root.c index 4eac59393edc..1f67057af2a5 100644 --- a/drivers/acpi/pci_root.c +++ b/drivers/acpi/pci_root.c @@ -33,6 +33,7 @@ #include #include #include +#include #include #include #include @@ -543,6 +544,14 @@ static int __devinit acpi_pci_root_add(struct acpi_device *device) if (flags != base_flags) acpi_pci_osc_support(root, flags); + status = acpi_pci_osc_control_set(root->device->handle, + OSC_PCI_EXPRESS_CAP_STRUCTURE_CONTROL); + + if (ACPI_FAILURE(status)) { + printk(KERN_INFO "Unable to assume PCIe control: Disabling ASPM\n"); + pcie_no_aspm(); + } + pci_acpi_add_bus_pm_notifier(device, root->bus); if (device->wakeup.flags.run_wake) device_set_run_wake(root->bus->bridge, true); -- cgit v1.2.1 From e8c534ec068af1a0845aceda373a9bfd2de62030 Mon Sep 17 00:00:00 2001 From: Michal Schmidt Date: Tue, 27 Jul 2010 18:53:35 +0200 Subject: x86: Fix keeping track of AMD C1E Accomodate the original C1E-aware idle routine to the different times during boot when the BIOS enables C1E. While at it, remove the synthetic CPUID flag in favor of a single global setting which denotes C1E status on the system. [ hpa: changed c1e_enabled to be a bool; clarified cpu bit 3:21 comment ] Signed-off-by: Michal Schmidt LKML-Reference: <20100727165335.GA11630@aftab> Signed-off-by: Borislav Petkov Signed-off-by: H. Peter Anvin Acked-by: Thomas Gleixner --- drivers/acpi/processor_idle.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/acpi') diff --git a/drivers/acpi/processor_idle.c b/drivers/acpi/processor_idle.c index e9a8026d39f0..eead3f581fb5 100644 --- a/drivers/acpi/processor_idle.c +++ b/drivers/acpi/processor_idle.c @@ -164,7 +164,7 @@ static void lapic_timer_check_state(int state, struct acpi_processor *pr, if (cpu_has(&cpu_data(pr->id), X86_FEATURE_ARAT)) return; - if (boot_cpu_has(X86_FEATURE_AMDC1E)) + if (c1e_detected) type = ACPI_STATE_C1; /* -- cgit v1.2.1 From 49c6c5ff924cecc0b6260109a510b7ed4c970dc5 Mon Sep 17 00:00:00 2001 From: Thomas Renninger Date: Fri, 16 Jul 2010 13:11:34 +0200 Subject: ACPI: Remove /proc/acpi/embedded_controller/.. Other patches in this series add the same info to /sys/... and /proc/ioports. The info removed should never have been used in an application, eventually someone read it manually. /proc/acpi is deprecated for more than a year anyway... Signed-off-by: Thomas Renninger CC: Alexey Starikovskiy CC: Len Brown CC: linux-kernel@vger.kernel.org CC: linux-acpi@vger.kernel.org CC: platform-driver-x86@vger.kernel.org Signed-off-by: Matthew Garrett --- drivers/acpi/ec.c | 81 +------------------------------------------------------ 1 file changed, 1 insertion(+), 80 deletions(-) (limited to 'drivers/acpi') diff --git a/drivers/acpi/ec.c b/drivers/acpi/ec.c index 5f2027d782e8..ce1f07fd7241 100644 --- a/drivers/acpi/ec.c +++ b/drivers/acpi/ec.c @@ -34,8 +34,6 @@ #include #include #include -#include -#include #include #include #include @@ -678,72 +676,6 @@ acpi_ec_space_handler(u32 function, acpi_physical_address address, } } -/* -------------------------------------------------------------------------- - FS Interface (/proc) - -------------------------------------------------------------------------- */ - -static struct proc_dir_entry *acpi_ec_dir; - -static int acpi_ec_read_info(struct seq_file *seq, void *offset) -{ - struct acpi_ec *ec = seq->private; - - if (!ec) - goto end; - - seq_printf(seq, "gpe:\t\t\t0x%02x\n", (u32) ec->gpe); - seq_printf(seq, "ports:\t\t\t0x%02x, 0x%02x\n", - (unsigned)ec->command_addr, (unsigned)ec->data_addr); - seq_printf(seq, "use global lock:\t%s\n", - ec->global_lock ? "yes" : "no"); - end: - return 0; -} - -static int acpi_ec_info_open_fs(struct inode *inode, struct file *file) -{ - return single_open(file, acpi_ec_read_info, PDE(inode)->data); -} - -static const struct file_operations acpi_ec_info_ops = { - .open = acpi_ec_info_open_fs, - .read = seq_read, - .llseek = seq_lseek, - .release = single_release, - .owner = THIS_MODULE, -}; - -static int acpi_ec_add_fs(struct acpi_device *device) -{ - struct proc_dir_entry *entry = NULL; - - if (!acpi_device_dir(device)) { - acpi_device_dir(device) = proc_mkdir(acpi_device_bid(device), - acpi_ec_dir); - if (!acpi_device_dir(device)) - return -ENODEV; - } - - entry = proc_create_data(ACPI_EC_FILE_INFO, S_IRUGO, - acpi_device_dir(device), - &acpi_ec_info_ops, acpi_driver_data(device)); - if (!entry) - return -ENODEV; - return 0; -} - -static int acpi_ec_remove_fs(struct acpi_device *device) -{ - - if (acpi_device_dir(device)) { - remove_proc_entry(ACPI_EC_FILE_INFO, acpi_device_dir(device)); - remove_proc_entry(acpi_device_bid(device), acpi_ec_dir); - acpi_device_dir(device) = NULL; - } - - return 0; -} - /* -------------------------------------------------------------------------- Driver Interface -------------------------------------------------------------------------- */ @@ -894,7 +826,6 @@ static int acpi_ec_add(struct acpi_device *device) if (!first_ec) first_ec = ec; device->driver_data = ec; - acpi_ec_add_fs(device); pr_info(PREFIX "GPE = 0x%lx, I/O: command/status = 0x%lx, data = 0x%lx\n", ec->gpe, ec->command_addr, ec->data_addr); @@ -921,7 +852,6 @@ static int acpi_ec_remove(struct acpi_device *device, int type) kfree(handler); } mutex_unlock(&ec->lock); - acpi_ec_remove_fs(device); device->driver_data = NULL; if (ec == first_ec) first_ec = NULL; @@ -1120,16 +1050,10 @@ int __init acpi_ec_init(void) { int result = 0; - acpi_ec_dir = proc_mkdir(ACPI_EC_CLASS, acpi_root_dir); - if (!acpi_ec_dir) - return -ENODEV; - /* Now register the driver for the EC */ result = acpi_bus_register_driver(&acpi_ec_driver); - if (result < 0) { - remove_proc_entry(ACPI_EC_CLASS, acpi_root_dir); + if (result < 0) return -ENODEV; - } return result; } @@ -1140,9 +1064,6 @@ static void __exit acpi_ec_exit(void) { acpi_bus_unregister_driver(&acpi_ec_driver); - - remove_proc_entry(ACPI_EC_CLASS, acpi_root_dir); - return; } #endif /* 0 */ -- cgit v1.2.1 From 1195a098168fcacfef1cd80d05358e52fb366bf6 Mon Sep 17 00:00:00 2001 From: Thomas Renninger Date: Fri, 16 Jul 2010 13:11:31 +0200 Subject: ACPI: Provide /sys/kernel/debug/ec/... This patch provides the same information through debugfs, which previously was provided through /proc/acpi/embedded_controller/*/info This is the gpe the EC is connected to and whether the global lock gets used. The io ports used are added to /proc/ioports in another patch. Beside the fact that /proc/acpi is deprecated for quite some time, this info is not needed for applications and thus can be moved to debugfs instead of a public interface like /sys. Signed-off-by: Thomas Renninger CC: Alexey Starikovskiy CC: Len Brown CC: linux-kernel@vger.kernel.org CC: linux-acpi@vger.kernel.org CC: Bjorn Helgaas CC: platform-driver-x86@vger.kernel.org Signed-off-by: Matthew Garrett --- drivers/acpi/Kconfig | 13 +++++++++++ drivers/acpi/Makefile | 1 + drivers/acpi/ec.c | 18 +++++----------- drivers/acpi/ec_sys.c | 57 +++++++++++++++++++++++++++++++++++++++++++++++++ drivers/acpi/internal.h | 24 +++++++++++++++++++++ 5 files changed, 100 insertions(+), 13 deletions(-) create mode 100644 drivers/acpi/ec_sys.c (limited to 'drivers/acpi') diff --git a/drivers/acpi/Kconfig b/drivers/acpi/Kconfig index 746411518802..f7226d1bc80e 100644 --- a/drivers/acpi/Kconfig +++ b/drivers/acpi/Kconfig @@ -104,6 +104,19 @@ config ACPI_SYSFS_POWER help Say N to disable power /sys interface +config ACPI_EC_DEBUGFS + tristate "EC read/write access through /sys/kernel/debug/ec" + default y + help + Say N to disable Embedded Controller /sys/kernel/debug interface + + An Embedded Controller typically is available on laptops and reads + sensor values like battery state and temperature. + The kernel access the EC through ACPI parsed code provided by BIOS + tables. + Thus this option is a debug option that helps to write ACPI drivers + and can be used to identify ACPI code or EC firmware bugs. + config ACPI_PROC_EVENT bool "Deprecated /proc/acpi/event support" depends on PROC_FS diff --git a/drivers/acpi/Makefile b/drivers/acpi/Makefile index 6ee33169e1dc..833b582d1762 100644 --- a/drivers/acpi/Makefile +++ b/drivers/acpi/Makefile @@ -60,6 +60,7 @@ obj-$(CONFIG_ACPI_SBS) += sbshc.o obj-$(CONFIG_ACPI_SBS) += sbs.o obj-$(CONFIG_ACPI_POWER_METER) += power_meter.o obj-$(CONFIG_ACPI_HED) += hed.o +obj-$(CONFIG_ACPI_EC_DEBUGFS) += ec_sys.o # processor has its own "processor." module_param namespace processor-y := processor_driver.o processor_throttling.o diff --git a/drivers/acpi/ec.c b/drivers/acpi/ec.c index ce1f07fd7241..a79e1b193e85 100644 --- a/drivers/acpi/ec.c +++ b/drivers/acpi/ec.c @@ -43,10 +43,13 @@ #include #include +#include "internal.h" + #define ACPI_EC_CLASS "embedded_controller" #define ACPI_EC_DEVICE_NAME "Embedded Controller" #define ACPI_EC_FILE_INFO "info" +#undef PREFIX #define PREFIX "ACPI: EC: " /* EC status register */ @@ -104,19 +107,8 @@ struct transaction { bool done; }; -static struct acpi_ec { - acpi_handle handle; - unsigned long gpe; - unsigned long command_addr; - unsigned long data_addr; - unsigned long global_lock; - unsigned long flags; - struct mutex lock; - wait_queue_head_t wait; - struct list_head list; - struct transaction *curr; - spinlock_t curr_lock; -} *boot_ec, *first_ec; +struct acpi_ec *boot_ec, *first_ec; +EXPORT_SYMBOL(first_ec); static int EC_FLAGS_MSI; /* Out-of-spec MSI controller */ static int EC_FLAGS_VALIDATE_ECDT; /* ASUStec ECDTs need to be validated */ diff --git a/drivers/acpi/ec_sys.c b/drivers/acpi/ec_sys.c new file mode 100644 index 000000000000..834c21a42d67 --- /dev/null +++ b/drivers/acpi/ec_sys.c @@ -0,0 +1,57 @@ +#include +#include +#include +#include "internal.h" + +MODULE_AUTHOR("Thomas Renninger "); +MODULE_DESCRIPTION("ACPI EC sysfs access driver"); +MODULE_LICENSE("GPL"); + +struct sysdev_class acpi_ec_sysdev_class = { + .name = "ec", +}; + +static struct dentry *acpi_ec_debugfs_dir; + +int acpi_ec_add_debugfs(struct acpi_ec *ec, unsigned int ec_device_count) +{ + struct dentry *dev_dir; + char name[64]; + if (ec_device_count == 0) { + acpi_ec_debugfs_dir = debugfs_create_dir("ec", NULL); + if (!acpi_ec_debugfs_dir) + return -ENOMEM; + } + + sprintf(name, "ec%u", ec_device_count); + dev_dir = debugfs_create_dir(name, acpi_ec_debugfs_dir); + if (!dev_dir) { + if (ec_device_count == 0) + debugfs_remove_recursive(acpi_ec_debugfs_dir); + /* TBD: Proper cleanup for multiple ECs */ + return -ENOMEM; + } + + debugfs_create_x32("gpe", 0444, dev_dir, (u32 *)&first_ec->gpe); + debugfs_create_bool("use_global_lock", 0444, dev_dir, + (u32 *)&first_ec->global_lock); + return 0; +} + +static int __init acpi_ec_sys_init(void) +{ + int err = 0; + if (first_ec) + err = acpi_ec_add_debugfs(first_ec, 0); + else + err = -ENODEV; + return err; +} + +static void __exit acpi_ec_sys_exit(void) +{ + debugfs_remove_recursive(acpi_ec_debugfs_dir); +} + +module_init(acpi_ec_sys_init); +module_exit(acpi_ec_sys_exit); diff --git a/drivers/acpi/internal.h b/drivers/acpi/internal.h index f8f190ec066e..8ae27264a00e 100644 --- a/drivers/acpi/internal.h +++ b/drivers/acpi/internal.h @@ -18,6 +18,11 @@ * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. */ +#ifndef _ACPI_INTERNAL_H_ +#define _ACPI_INTERNAL_H_ + +#include + #define PREFIX "ACPI: " int init_acpi_device_notify(void); @@ -46,6 +51,23 @@ void acpi_early_processor_set_pdc(void); /* -------------------------------------------------------------------------- Embedded Controller -------------------------------------------------------------------------- */ +struct acpi_ec { + acpi_handle handle; + unsigned long gpe; + unsigned long command_addr; + unsigned long data_addr; + unsigned long global_lock; + unsigned long flags; + struct mutex lock; + wait_queue_head_t wait; + struct list_head list; + struct transaction *curr; + spinlock_t curr_lock; + struct sys_device sysdev; +}; + +extern struct acpi_ec *first_ec; + int acpi_ec_init(void); int acpi_ec_ecdt_probe(void); int acpi_boot_ec_enable(void); @@ -63,3 +85,5 @@ int acpi_sleep_proc_init(void); #else static inline int acpi_sleep_proc_init(void) { return 0; } #endif + +#endif /* _ACPI_INTERNAL_H_ */ -- cgit v1.2.1 From 9827886dce77c47c378ce3154689cea2c45c731d Mon Sep 17 00:00:00 2001 From: Thomas Renninger Date: Fri, 16 Jul 2010 13:11:32 +0200 Subject: ACPI: Provide /sys/kernel/debug//ec/ec0/io for binary access to the EC A userspace app to easily read/write the EC can be found here: ftp://ftp.suse.com/pub/people/trenn/sources/ec/ec_access.c Multiple ECs are not supported, but shouldn't be hard to add as soon as the ec driver itself will support them. Signed-off-by: Thomas Renninger CC: Alexey Starikovskiy CC: Len Brown CC: linux-kernel@vger.kernel.org CC: linux-acpi@vger.kernel.org CC: platform-driver-x86@vger.kernel.org Signed-off-by: Matthew Garrett --- drivers/acpi/ec_sys.c | 86 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 86 insertions(+) (limited to 'drivers/acpi') diff --git a/drivers/acpi/ec_sys.c b/drivers/acpi/ec_sys.c index 834c21a42d67..3ef978185c73 100644 --- a/drivers/acpi/ec_sys.c +++ b/drivers/acpi/ec_sys.c @@ -1,3 +1,13 @@ +/* + * ec_sys.c + * + * Copyright (C) 2010 SUSE Products GmbH/Novell + * Author: + * Thomas Renninger + * + * This work is licensed under the terms of the GNU GPL, version 2. + */ + #include #include #include @@ -7,12 +17,87 @@ MODULE_AUTHOR("Thomas Renninger "); MODULE_DESCRIPTION("ACPI EC sysfs access driver"); MODULE_LICENSE("GPL"); +#define EC_SPACE_SIZE 256 + struct sysdev_class acpi_ec_sysdev_class = { .name = "ec", }; static struct dentry *acpi_ec_debugfs_dir; +static int acpi_ec_open_io(struct inode *i, struct file *f) +{ + f->private_data = i->i_private; + return 0; +} + +static ssize_t acpi_ec_read_io(struct file *f, char __user *buf, + size_t count, loff_t *off) +{ + /* Use this if support reading/writing multiple ECs exists in ec.c: + * struct acpi_ec *ec = ((struct seq_file *)f->private_data)->private; + */ + unsigned int size = EC_SPACE_SIZE; + u8 *data = (u8 *) buf; + loff_t init_off = *off; + int err = 0; + + if (*off >= size) + return 0; + if (*off + count >= size) { + size -= *off; + count = size; + } else + size = count; + + while (size) { + err = ec_read(*off, &data[*off - init_off]); + if (err) + return err; + *off += 1; + size--; + } + return count; +} + +static ssize_t acpi_ec_write_io(struct file *f, const char __user *buf, + size_t count, loff_t *off) +{ + /* Use this if support reading/writing multiple ECs exists in ec.c: + * struct acpi_ec *ec = ((struct seq_file *)f->private_data)->private; + */ + + unsigned int size = count; + loff_t init_off = *off; + u8 *data = (u8 *) buf; + int err = 0; + + if (*off >= EC_SPACE_SIZE) + return 0; + if (*off + count >= EC_SPACE_SIZE) { + size = EC_SPACE_SIZE - *off; + count = size; + } + + while (size) { + u8 byte_write = data[*off - init_off]; + err = ec_write(*off, byte_write); + if (err) + return err; + + *off += 1; + size--; + } + return count; +} + +static struct file_operations acpi_ec_io_ops = { + .owner = THIS_MODULE, + .open = acpi_ec_open_io, + .read = acpi_ec_read_io, + .write = acpi_ec_write_io, +}; + int acpi_ec_add_debugfs(struct acpi_ec *ec, unsigned int ec_device_count) { struct dentry *dev_dir; @@ -35,6 +120,7 @@ int acpi_ec_add_debugfs(struct acpi_ec *ec, unsigned int ec_device_count) debugfs_create_x32("gpe", 0444, dev_dir, (u32 *)&first_ec->gpe); debugfs_create_bool("use_global_lock", 0444, dev_dir, (u32 *)&first_ec->global_lock); + debugfs_create_file("io", 0666, dev_dir, ec, &acpi_ec_io_ops); return 0; } -- cgit v1.2.1 From b52e04216fcd86968c01ad0cfdb249375f19134d Mon Sep 17 00:00:00 2001 From: Thomas Renninger Date: Fri, 16 Jul 2010 13:11:33 +0200 Subject: ACPI: Register EC io ports in /proc/ioports Formerly these have been exposed through /proc/.. Better register them where all IO ports should get registered and scream loud if someone else claims to use them. EC data and command port typically should show up like this then: ... 0060-0060 : keyboard 0062-0062 : EC data 0064-0064 : keyboard 0066-0066 : EC command 0070-0071 : rtc0 ... Signed-off-by: Thomas Renninger CC: Alexey Starikovskiy CC: Len Brown CC: linux-kernel@vger.kernel.org CC: linux-acpi@vger.kernel.org CC: Bjorn Helgaas CC: platform-driver-x86@vger.kernel.org Signed-off-by: Matthew Garrett --- drivers/acpi/ec.c | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) (limited to 'drivers/acpi') diff --git a/drivers/acpi/ec.c b/drivers/acpi/ec.c index a79e1b193e85..265a99c1eb14 100644 --- a/drivers/acpi/ec.c +++ b/drivers/acpi/ec.c @@ -864,10 +864,18 @@ ec_parse_io_ports(struct acpi_resource *resource, void *context) * the second address region returned is the status/command * port. */ - if (ec->data_addr == 0) + if (ec->data_addr == 0) { ec->data_addr = resource->data.io.minimum; - else if (ec->command_addr == 0) + WARN(!request_region(ec->data_addr, 1, "EC data"), + "Could not request EC data io port %lu", + ec->data_addr); + } + else if (ec->command_addr == 0) { ec->command_addr = resource->data.io.minimum; + WARN(!request_region(ec->command_addr, 1, "EC command"), + "Could not request EC command io port %lu", + ec->command_addr); + } else return AE_CTRL_TERMINATE; -- cgit v1.2.1 From de4f10466e9347a2f1bfe39e501539557bed2c4b Mon Sep 17 00:00:00 2001 From: Thomas Renninger Date: Thu, 29 Jul 2010 22:08:44 +0200 Subject: acpi ec: Fix possible double io port registration which will result in a harmless but ugly WARN message on some machines. Signed-off-by: Thomas Renninger CC: mjg59@srcf.ucam.org CC: platform-driver-x86@vger.kernel.org CC: linux-acpi@vger.kernel.org CC: astarikovskiy@suse.de CC: akpm@linux-foundation.org Signed-off-by: Matthew Garrett --- drivers/acpi/ec.c | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) (limited to 'drivers/acpi') diff --git a/drivers/acpi/ec.c b/drivers/acpi/ec.c index 265a99c1eb14..1fa0aafebe2a 100644 --- a/drivers/acpi/ec.c +++ b/drivers/acpi/ec.c @@ -818,6 +818,12 @@ static int acpi_ec_add(struct acpi_device *device) if (!first_ec) first_ec = ec; device->driver_data = ec; + + WARN(!request_region(ec->data_addr, 1, "EC data"), + "Could not request EC data io port 0x%lx", ec->data_addr); + WARN(!request_region(ec->command_addr, 1, "EC cmd"), + "Could not request EC cmd io port 0x%lx", ec->command_addr); + pr_info(PREFIX "GPE = 0x%lx, I/O: command/status = 0x%lx, data = 0x%lx\n", ec->gpe, ec->command_addr, ec->data_addr); @@ -844,6 +850,8 @@ static int acpi_ec_remove(struct acpi_device *device, int type) kfree(handler); } mutex_unlock(&ec->lock); + release_region(ec->data_addr, 1); + release_region(ec->command_addr, 1); device->driver_data = NULL; if (ec == first_ec) first_ec = NULL; @@ -864,18 +872,10 @@ ec_parse_io_ports(struct acpi_resource *resource, void *context) * the second address region returned is the status/command * port. */ - if (ec->data_addr == 0) { + if (ec->data_addr == 0) ec->data_addr = resource->data.io.minimum; - WARN(!request_region(ec->data_addr, 1, "EC data"), - "Could not request EC data io port %lu", - ec->data_addr); - } - else if (ec->command_addr == 0) { + else if (ec->command_addr == 0) ec->command_addr = resource->data.io.minimum; - WARN(!request_region(ec->command_addr, 1, "EC command"), - "Could not request EC command io port %lu", - ec->command_addr); - } else return AE_CTRL_TERMINATE; -- cgit v1.2.1 From 500de3dd46ac9f9ae9d124634c68907b7d50d2cb Mon Sep 17 00:00:00 2001 From: Thomas Renninger Date: Thu, 29 Jul 2010 22:30:24 +0200 Subject: acpi ec_sys: Be more cautious about ec write access - Set Kconfig option default n - Only allow root to read/write io file (sever bug!) - Introduce write support module param -> default off - Properly clean up if any debugfs files cannot be created Signed-off-by: Thomas Renninger CC: mjg59@srcf.ucam.org CC: platform-driver-x86@vger.kernel.org CC: linux-acpi@vger.kernel.org CC: astarikovskiy@suse.de Signed-off-by: Matthew Garrett --- drivers/acpi/Kconfig | 11 ++++++++--- drivers/acpi/ec_sys.c | 31 ++++++++++++++++++++++++------- 2 files changed, 32 insertions(+), 10 deletions(-) (limited to 'drivers/acpi') diff --git a/drivers/acpi/Kconfig b/drivers/acpi/Kconfig index f7226d1bc80e..08e0140920e1 100644 --- a/drivers/acpi/Kconfig +++ b/drivers/acpi/Kconfig @@ -106,14 +106,19 @@ config ACPI_SYSFS_POWER config ACPI_EC_DEBUGFS tristate "EC read/write access through /sys/kernel/debug/ec" - default y + default n help Say N to disable Embedded Controller /sys/kernel/debug interface + Be aware that using this interface can confuse your Embedded + Controller in a way that a normal reboot is not enough. You then + have to power of your system, and remove the laptop battery for + some seconds. An Embedded Controller typically is available on laptops and reads sensor values like battery state and temperature. - The kernel access the EC through ACPI parsed code provided by BIOS - tables. + The kernel accesses the EC through ACPI parsed code provided by BIOS + tables. This option allows to access the EC directly without ACPI + code being involved. Thus this option is a debug option that helps to write ACPI drivers and can be used to identify ACPI code or EC firmware bugs. diff --git a/drivers/acpi/ec_sys.c b/drivers/acpi/ec_sys.c index 3ef978185c73..0e869b3f81ca 100644 --- a/drivers/acpi/ec_sys.c +++ b/drivers/acpi/ec_sys.c @@ -17,6 +17,11 @@ MODULE_AUTHOR("Thomas Renninger "); MODULE_DESCRIPTION("ACPI EC sysfs access driver"); MODULE_LICENSE("GPL"); +static bool write_support; +module_param(write_support, bool, 0644); +MODULE_PARM_DESC(write_support, "Dangerous, reboot and removal of battery may " + "be needed."); + #define EC_SPACE_SIZE 256 struct sysdev_class acpi_ec_sysdev_class = { @@ -102,6 +107,8 @@ int acpi_ec_add_debugfs(struct acpi_ec *ec, unsigned int ec_device_count) { struct dentry *dev_dir; char name[64]; + mode_t mode = 0400; + if (ec_device_count == 0) { acpi_ec_debugfs_dir = debugfs_create_dir("ec", NULL); if (!acpi_ec_debugfs_dir) @@ -111,17 +118,27 @@ int acpi_ec_add_debugfs(struct acpi_ec *ec, unsigned int ec_device_count) sprintf(name, "ec%u", ec_device_count); dev_dir = debugfs_create_dir(name, acpi_ec_debugfs_dir); if (!dev_dir) { - if (ec_device_count == 0) - debugfs_remove_recursive(acpi_ec_debugfs_dir); - /* TBD: Proper cleanup for multiple ECs */ + if (ec_device_count != 0) + goto error; return -ENOMEM; } - debugfs_create_x32("gpe", 0444, dev_dir, (u32 *)&first_ec->gpe); - debugfs_create_bool("use_global_lock", 0444, dev_dir, - (u32 *)&first_ec->global_lock); - debugfs_create_file("io", 0666, dev_dir, ec, &acpi_ec_io_ops); + if (!debugfs_create_x32("gpe", 0444, dev_dir, (u32 *)&first_ec->gpe)) + goto error; + if (!debugfs_create_bool("use_global_lock", 0444, dev_dir, + (u32 *)&first_ec->global_lock)) + goto error; + + if (write_support) + mode = 0600; + if (!debugfs_create_file("io", mode, dev_dir, ec, &acpi_ec_io_ops)) + goto error; + return 0; + +error: + debugfs_remove_recursive(acpi_ec_debugfs_dir); + return -ENOMEM; } static int __init acpi_ec_sys_init(void) -- cgit v1.2.1 From 28f4f8a9def2b1f3a6066bae791c77043ec49524 Mon Sep 17 00:00:00 2001 From: "Rafael J. Wysocki" Date: Tue, 3 Aug 2010 23:55:14 +0200 Subject: ACPI / ACPICA: Fix reference counting problems with GPE handlers If a handler is installed for a GPE associated with an AML method and such that it cannot wake up the system from sleep states, the GPE remains enabled after the handler has been installed, although it should be disabled in that case to avoid spurious execution of the handler. Fix this issue by making acpi_install_gpe_handler() disable GPEs that were previously associated with AML methods and cannot wake up the system from sleep states. Analogously, make acpi_remove_gpe_handler() enable the GPEs that are associated with AML methods after their handlers have been removed and cannot wake up the system from sleep states. In addition to that, fix a code ordering issue in acpi_remove_gpe_handler() that renders the locking ineffective (ACPI_MTX_EVENTS is released temporarily in the middle of the routine to wait for the completion of events already in progress). For this purpose introduce acpi_raw_disable_gpe() and acpi_raw_enable_gpe() to be called with acpi_gbl_gpe_lock held and rework acpi_disable_gpe() and acpi_enable_gpe(), respectively, to use them. Also rework acpi_gpe_can_wake() to use acpi_raw_disable_gpe() instead of calling acpi_disable_gpe() after releasing the lock to avoid the possible theoretical race with acpi_install_gpe_handler(). Signed-off-by: Rafael J. Wysocki Cc: "Moore, Robert" Cc: Lin Ming Signed-off-by: Len Brown --- drivers/acpi/acpica/acevents.h | 4 +++ drivers/acpi/acpica/aclocal.h | 1 + drivers/acpi/acpica/evgpe.c | 73 +++++++++++++++++++++++++++++++++++++++ drivers/acpi/acpica/evxface.c | 77 ++++++++++++++++++++++++++++-------------- drivers/acpi/acpica/evxfevnt.c | 62 +++++----------------------------- 5 files changed, 139 insertions(+), 78 deletions(-) (limited to 'drivers/acpi') diff --git a/drivers/acpi/acpica/acevents.h b/drivers/acpi/acpica/acevents.h index e0e6affb0d80..36867cd70eac 100644 --- a/drivers/acpi/acpica/acevents.h +++ b/drivers/acpi/acpica/acevents.h @@ -82,6 +82,10 @@ acpi_ev_update_gpe_enable_mask(struct acpi_gpe_event_info *gpe_event_info); acpi_status acpi_ev_enable_gpe(struct acpi_gpe_event_info *gpe_event_info); +acpi_status acpi_raw_enable_gpe(struct acpi_gpe_event_info *gpe_event_info); + +acpi_status acpi_raw_disable_gpe(struct acpi_gpe_event_info *gpe_event_info); + struct acpi_gpe_event_info *acpi_ev_get_gpe_event_info(acpi_handle gpe_device, u32 gpe_number); diff --git a/drivers/acpi/acpica/aclocal.h b/drivers/acpi/acpica/aclocal.h index 1ee0bcf399aa..df85b53a674f 100644 --- a/drivers/acpi/acpica/aclocal.h +++ b/drivers/acpi/acpica/aclocal.h @@ -412,6 +412,7 @@ struct acpi_handler_info { acpi_event_handler address; /* Address of handler, if any */ void *context; /* Context to be passed to handler */ struct acpi_namespace_node *method_node; /* Method node for this GPE level (saved) */ + u8 orig_flags; /* Original misc info about this GPE */ }; union acpi_gpe_dispatch_info { diff --git a/drivers/acpi/acpica/evgpe.c b/drivers/acpi/acpica/evgpe.c index 7a6a3e6f4be0..f226eac314db 100644 --- a/drivers/acpi/acpica/evgpe.c +++ b/drivers/acpi/acpica/evgpe.c @@ -135,6 +135,79 @@ acpi_ev_enable_gpe(struct acpi_gpe_event_info *gpe_event_info) } +/******************************************************************************* + * + * FUNCTION: acpi_raw_enable_gpe + * + * PARAMETERS: gpe_event_info - GPE to enable + * + * RETURN: Status + * + * DESCRIPTION: Add a reference to a GPE. On the first reference, the GPE is + * hardware-enabled. + * + ******************************************************************************/ + +acpi_status acpi_raw_enable_gpe(struct acpi_gpe_event_info *gpe_event_info) +{ + acpi_status status = AE_OK; + + if (gpe_event_info->runtime_count == ACPI_UINT8_MAX) { + return_ACPI_STATUS(AE_LIMIT); + } + + gpe_event_info->runtime_count++; + if (gpe_event_info->runtime_count == 1) { + status = acpi_ev_update_gpe_enable_mask(gpe_event_info); + if (ACPI_SUCCESS(status)) { + status = acpi_ev_enable_gpe(gpe_event_info); + } + + if (ACPI_FAILURE(status)) { + gpe_event_info->runtime_count--; + } + } + + return_ACPI_STATUS(status); +} + +/******************************************************************************* + * + * FUNCTION: acpi_raw_disable_gpe + * + * PARAMETERS: gpe_event_info - GPE to disable + * + * RETURN: Status + * + * DESCRIPTION: Remove a reference to a GPE. When the last reference is + * removed, the GPE is hardware-disabled. + * + ******************************************************************************/ + +acpi_status acpi_raw_disable_gpe(struct acpi_gpe_event_info *gpe_event_info) +{ + acpi_status status = AE_OK; + + if (!gpe_event_info->runtime_count) { + return_ACPI_STATUS(AE_LIMIT); + } + + gpe_event_info->runtime_count--; + if (!gpe_event_info->runtime_count) { + status = acpi_ev_update_gpe_enable_mask(gpe_event_info); + if (ACPI_SUCCESS(status)) { + status = acpi_hw_low_set_gpe(gpe_event_info, + ACPI_GPE_DISABLE); + } + + if (ACPI_FAILURE(status)) { + gpe_event_info->runtime_count++; + } + } + + return_ACPI_STATUS(status); +} + /******************************************************************************* * * FUNCTION: acpi_ev_low_get_gpe_info diff --git a/drivers/acpi/acpica/evxface.c b/drivers/acpi/acpica/evxface.c index 4a531cdf7942..14e48add32fa 100644 --- a/drivers/acpi/acpica/evxface.c +++ b/drivers/acpi/acpica/evxface.c @@ -691,12 +691,22 @@ acpi_install_gpe_handler(acpi_handle gpe_device, return_ACPI_STATUS(status); } + /* Allocate memory for the handler object */ + + handler = ACPI_ALLOCATE_ZEROED(sizeof(struct acpi_handler_info)); + if (!handler) { + status = AE_NO_MEMORY; + goto unlock_and_exit; + } + + 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); if (!gpe_event_info) { status = AE_BAD_PARAMETER; - goto unlock_and_exit; + goto free_and_exit; } /* Make sure that there isn't a handler there already */ @@ -704,24 +714,30 @@ acpi_install_gpe_handler(acpi_handle gpe_device, if ((gpe_event_info->flags & ACPI_GPE_DISPATCH_MASK) == ACPI_GPE_DISPATCH_HANDLER) { status = AE_ALREADY_EXISTS; - goto unlock_and_exit; + goto free_and_exit; } /* Allocate and init handler object */ - handler = ACPI_ALLOCATE_ZEROED(sizeof(struct acpi_handler_info)); - if (!handler) { - status = AE_NO_MEMORY; - goto unlock_and_exit; - } - handler->address = address; handler->context = context; handler->method_node = gpe_event_info->dispatch.method_node; + handler->orig_flags = gpe_event_info->flags & + (ACPI_GPE_XRUPT_TYPE_MASK | ACPI_GPE_DISPATCH_MASK); + + /* + * If the GPE is associated with a method and it cannot wake up the + * system from sleep states, it was enabled automatically during + * initialization, so it has to be disabled now to avoid spurious + * execution of the handler. + */ + + if ((handler->orig_flags & ACPI_GPE_DISPATCH_METHOD) + && !(gpe_event_info->flags & ACPI_GPE_CAN_WAKE)) + (void)acpi_raw_disable_gpe(gpe_event_info); /* Install the handler */ - flags = acpi_os_acquire_lock(acpi_gbl_gpe_lock); gpe_event_info->dispatch.handler = handler; /* Setup up dispatch flags to indicate handler (vs. method) */ @@ -735,6 +751,11 @@ acpi_install_gpe_handler(acpi_handle gpe_device, unlock_and_exit: (void)acpi_ut_release_mutex(ACPI_MTX_EVENTS); return_ACPI_STATUS(status); + +free_and_exit: + acpi_os_release_lock(acpi_gbl_gpe_lock, flags); + ACPI_FREE(handler); + goto unlock_and_exit; } ACPI_EXPORT_SYMBOL(acpi_install_gpe_handler) @@ -770,11 +791,17 @@ acpi_remove_gpe_handler(acpi_handle gpe_device, return_ACPI_STATUS(AE_BAD_PARAMETER); } + /* Make sure all deferred tasks are completed */ + + acpi_os_wait_events_complete(NULL); + 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); @@ -798,34 +825,34 @@ acpi_remove_gpe_handler(acpi_handle gpe_device, goto unlock_and_exit; } - /* Make sure all deferred tasks are completed */ - - (void)acpi_ut_release_mutex(ACPI_MTX_EVENTS); - acpi_os_wait_events_complete(NULL); - status = acpi_ut_acquire_mutex(ACPI_MTX_EVENTS); - if (ACPI_FAILURE(status)) { - return_ACPI_STATUS(status); - } - /* Remove the handler */ - flags = acpi_os_acquire_lock(acpi_gbl_gpe_lock); handler = gpe_event_info->dispatch.handler; /* Restore Method node (if any), set dispatch flags */ gpe_event_info->dispatch.method_node = handler->method_node; - gpe_event_info->flags &= ~ACPI_GPE_DISPATCH_MASK; /* Clear bits */ - if (handler->method_node) { - gpe_event_info->flags |= ACPI_GPE_DISPATCH_METHOD; - } - acpi_os_release_lock(acpi_gbl_gpe_lock, flags); + gpe_event_info->flags &= + ~(ACPI_GPE_XRUPT_TYPE_MASK | ACPI_GPE_DISPATCH_MASK); + gpe_event_info->flags |= handler->orig_flags; + + /* + * If the GPE was previously associated with a method and it cannot wake + * up the system from sleep states, it should be enabled at this point + * to restore the post-initialization configuration. + */ + + if ((handler->orig_flags & ACPI_GPE_DISPATCH_METHOD) + && !(gpe_event_info->flags & ACPI_GPE_CAN_WAKE)) + (void)acpi_raw_enable_gpe(gpe_event_info); /* Now we can free the handler object */ ACPI_FREE(handler); - unlock_and_exit: +unlock_and_exit: + acpi_os_release_lock(acpi_gbl_gpe_lock, flags); + (void)acpi_ut_release_mutex(ACPI_MTX_EVENTS); return_ACPI_STATUS(status); } diff --git a/drivers/acpi/acpica/evxfevnt.c b/drivers/acpi/acpica/evxfevnt.c index 53d591a11138..0fb9e94878d9 100644 --- a/drivers/acpi/acpica/evxfevnt.c +++ b/drivers/acpi/acpica/evxfevnt.c @@ -291,7 +291,7 @@ ACPI_EXPORT_SYMBOL(acpi_gpe_wakeup) ******************************************************************************/ acpi_status acpi_enable_gpe(acpi_handle gpe_device, u32 gpe_number) { - acpi_status status = AE_OK; + acpi_status status = AE_BAD_PARAMETER; struct acpi_gpe_event_info *gpe_event_info; acpi_cpu_flags flags; @@ -302,28 +302,10 @@ acpi_status acpi_enable_gpe(acpi_handle gpe_device, u32 gpe_number) /* Ensure that we have a valid GPE number */ gpe_event_info = acpi_ev_get_gpe_event_info(gpe_device, gpe_number); - if (!gpe_event_info) { - status = AE_BAD_PARAMETER; - goto unlock_and_exit; + if (gpe_event_info) { + status = acpi_raw_enable_gpe(gpe_event_info); } - if (gpe_event_info->runtime_count == ACPI_UINT8_MAX) { - status = AE_LIMIT; /* Too many references */ - goto unlock_and_exit; - } - - gpe_event_info->runtime_count++; - if (gpe_event_info->runtime_count == 1) { - status = acpi_ev_update_gpe_enable_mask(gpe_event_info); - if (ACPI_SUCCESS(status)) { - status = acpi_ev_enable_gpe(gpe_event_info); - } - if (ACPI_FAILURE(status)) { - gpe_event_info->runtime_count--; - } - } - -unlock_and_exit: acpi_os_release_lock(acpi_gbl_gpe_lock, flags); return_ACPI_STATUS(status); } @@ -345,7 +327,7 @@ ACPI_EXPORT_SYMBOL(acpi_enable_gpe) ******************************************************************************/ acpi_status acpi_disable_gpe(acpi_handle gpe_device, u32 gpe_number) { - acpi_status status = AE_OK; + acpi_status status = AE_BAD_PARAMETER; struct acpi_gpe_event_info *gpe_event_info; acpi_cpu_flags flags; @@ -356,32 +338,10 @@ acpi_status acpi_disable_gpe(acpi_handle gpe_device, u32 gpe_number) /* Ensure that we have a valid GPE number */ gpe_event_info = acpi_ev_get_gpe_event_info(gpe_device, gpe_number); - if (!gpe_event_info) { - status = AE_BAD_PARAMETER; - goto unlock_and_exit; - } - - /* Hardware-disable a runtime GPE on removal of the last reference */ - - if (!gpe_event_info->runtime_count) { - status = AE_LIMIT; /* There are no references to remove */ - goto unlock_and_exit; + if (gpe_event_info) { + status = acpi_raw_disable_gpe(gpe_event_info) ; } - gpe_event_info->runtime_count--; - if (!gpe_event_info->runtime_count) { - status = acpi_ev_update_gpe_enable_mask(gpe_event_info); - if (ACPI_SUCCESS(status)) { - status = - acpi_hw_low_set_gpe(gpe_event_info, - ACPI_GPE_DISABLE); - } - if (ACPI_FAILURE(status)) { - gpe_event_info->runtime_count++; - } - } - -unlock_and_exit: acpi_os_release_lock(acpi_gbl_gpe_lock, flags); return_ACPI_STATUS(status); } @@ -408,7 +368,6 @@ acpi_status acpi_gpe_can_wake(acpi_handle gpe_device, u32 gpe_number) acpi_status status = AE_OK; struct acpi_gpe_event_info *gpe_event_info; acpi_cpu_flags flags; - u8 disable = 0; ACPI_FUNCTION_TRACE(acpi_gpe_can_wake); @@ -427,15 +386,12 @@ acpi_status acpi_gpe_can_wake(acpi_handle gpe_device, u32 gpe_number) } gpe_event_info->flags |= ACPI_GPE_CAN_WAKE; - disable = (gpe_event_info->flags & ACPI_GPE_DISPATCH_METHOD) - && gpe_event_info->runtime_count; + if (gpe_event_info->flags & ACPI_GPE_DISPATCH_METHOD) { + (void)acpi_raw_disable_gpe(gpe_event_info); + } unlock_and_exit: acpi_os_release_lock(acpi_gbl_gpe_lock, flags); - - if (disable) - status = acpi_disable_gpe(gpe_device, gpe_number); - return_ACPI_STATUS(status); } ACPI_EXPORT_SYMBOL(acpi_gpe_can_wake) -- cgit v1.2.1 From 2663b3f23537618c0c286551b138353fe26b3df8 Mon Sep 17 00:00:00 2001 From: Huang Ying Date: Mon, 2 Aug 2010 15:48:22 +0800 Subject: ACPI, APEI, Fix a typo of error path of apei_resources_request Fix a typo of error path of apei_resources_request. release_mem_region and release_region should be interchange. Signed-off-by: Huang Ying Signed-off-by: Andi Kleen Signed-off-by: Len Brown --- drivers/acpi/apei/apei-base.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers/acpi') diff --git a/drivers/acpi/apei/apei-base.c b/drivers/acpi/apei/apei-base.c index 216e1e948ff6..73fd0c7487c1 100644 --- a/drivers/acpi/apei/apei-base.c +++ b/drivers/acpi/apei/apei-base.c @@ -482,14 +482,14 @@ err_unmap_ioport: list_for_each_entry(res, &resources->ioport, list) { if (res == res_bak) break; - release_mem_region(res->start, res->end - res->start); + release_region(res->start, res->end - res->start); } res_bak = NULL; err_unmap_iomem: list_for_each_entry(res, &resources->iomem, list) { if (res == res_bak) break; - release_region(res->start, res->end - res->start); + release_mem_region(res->start, res->end - res->start); } return -EINVAL; } -- cgit v1.2.1 From ad4ecef2f13c790f95b55320f2925c205d8f971f Mon Sep 17 00:00:00 2001 From: Huang Ying Date: Mon, 2 Aug 2010 15:48:23 +0800 Subject: ACPI, APEI, Rename CPER and GHES severity constants The abbreviation of severity should be SEV instead of SER, so the CPER severity constants are renamed accordingly. GHES severity constants are renamed in the same way too. Signed-off-by: Huang Ying Signed-off-by: Andi Kleen Signed-off-by: Len Brown --- drivers/acpi/apei/ghes.c | 32 ++++++++++++++++---------------- 1 file changed, 16 insertions(+), 16 deletions(-) (limited to 'drivers/acpi') diff --git a/drivers/acpi/apei/ghes.c b/drivers/acpi/apei/ghes.c index fd0cc016a099..c76aff6c861d 100644 --- a/drivers/acpi/apei/ghes.c +++ b/drivers/acpi/apei/ghes.c @@ -132,26 +132,26 @@ static void ghes_fini(struct ghes *ghes) } enum { - GHES_SER_NO = 0x0, - GHES_SER_CORRECTED = 0x1, - GHES_SER_RECOVERABLE = 0x2, - GHES_SER_PANIC = 0x3, + GHES_SEV_NO = 0x0, + GHES_SEV_CORRECTED = 0x1, + GHES_SEV_RECOVERABLE = 0x2, + GHES_SEV_PANIC = 0x3, }; static inline int ghes_severity(int severity) { switch (severity) { - case CPER_SER_INFORMATIONAL: - return GHES_SER_NO; - case CPER_SER_CORRECTED: - return GHES_SER_CORRECTED; - case CPER_SER_RECOVERABLE: - return GHES_SER_RECOVERABLE; - case CPER_SER_FATAL: - return GHES_SER_PANIC; + case CPER_SEV_INFORMATIONAL: + return GHES_SEV_NO; + case CPER_SEV_CORRECTED: + return GHES_SEV_CORRECTED; + case CPER_SEV_RECOVERABLE: + return GHES_SEV_RECOVERABLE; + case CPER_SEV_FATAL: + return GHES_SEV_PANIC; default: /* Unkown, go panic */ - return GHES_SER_PANIC; + return GHES_SEV_PANIC; } } @@ -237,16 +237,16 @@ static void ghes_clear_estatus(struct ghes *ghes) static void ghes_do_proc(struct ghes *ghes) { - int ser, processed = 0; + int sev, processed = 0; struct acpi_hest_generic_data *gdata; - ser = ghes_severity(ghes->estatus->error_severity); + sev = ghes_severity(ghes->estatus->error_severity); apei_estatus_for_each_section(ghes->estatus, gdata) { #ifdef CONFIG_X86_MCE if (!uuid_le_cmp(*(uuid_le *)gdata->section_type, CPER_SEC_PLATFORM_MEM)) { apei_mce_report_mem_error( - ser == GHES_SER_CORRECTED, + sev == GHES_SEV_CORRECTED, (struct cper_sec_mem_err *)(gdata+1)); processed = 1; } -- cgit v1.2.1 From 7ad6e9435596f692ff65f399da12816c94960185 Mon Sep 17 00:00:00 2001 From: Huang Ying Date: Mon, 2 Aug 2010 15:48:24 +0800 Subject: ACPI, APEI, Manage GHES as platform devices Register GHES during HEST initialization as platform devices. And make GHES driver into platform device driver. So that the GHES driver module can be loaded automatically when there are GHES available. Signed-off-by: Huang Ying Signed-off-by: Andi Kleen Signed-off-by: Len Brown --- drivers/acpi/apei/ghes.c | 140 +++++++++++++++++++++++++---------------------- drivers/acpi/apei/hest.c | 76 +++++++++++++++++++++++-- 2 files changed, 145 insertions(+), 71 deletions(-) (limited to 'drivers/acpi') diff --git a/drivers/acpi/apei/ghes.c b/drivers/acpi/apei/ghes.c index c76aff6c861d..385a6059714a 100644 --- a/drivers/acpi/apei/ghes.c +++ b/drivers/acpi/apei/ghes.c @@ -41,6 +41,8 @@ #include #include #include +#include +#include #include #include #include @@ -87,6 +89,7 @@ struct ghes { * used for that. */ static LIST_HEAD(ghes_sci); +static DEFINE_MUTEX(ghes_list_mutex); static struct ghes *ghes_new(struct acpi_hest_generic *generic) { @@ -293,18 +296,15 @@ static struct notifier_block ghes_notifier_sci = { .notifier_call = ghes_notify_sci, }; -static int hest_ghes_parse(struct acpi_hest_header *hest_hdr, void *data) +static int __devinit ghes_probe(struct platform_device *ghes_dev) { struct acpi_hest_generic *generic; struct ghes *ghes = NULL; - int rc = 0; + int rc = -EINVAL; - if (hest_hdr->type != ACPI_HEST_TYPE_GENERIC_ERROR) - return 0; - - generic = (struct acpi_hest_generic *)hest_hdr; + generic = ghes_dev->dev.platform_data; if (!generic->enabled) - return 0; + return -ENODEV; if (generic->error_block_length < sizeof(struct acpi_hest_generic_status)) { @@ -327,62 +327,91 @@ static int hest_ghes_parse(struct acpi_hest_header *hest_hdr, void *data) ghes = NULL; goto err; } - switch (generic->notify.type) { - case ACPI_HEST_NOTIFY_POLLED: - pr_warning(GHES_PFX -"Generic hardware error source: %d notified via POLL is not supported!\n", - generic->header.source_id); - break; - case ACPI_HEST_NOTIFY_EXTERNAL: - case ACPI_HEST_NOTIFY_LOCAL: - pr_warning(GHES_PFX -"Generic hardware error source: %d notified via IRQ is not supported!\n", - generic->header.source_id); - break; - case ACPI_HEST_NOTIFY_SCI: + if (generic->notify.type == ACPI_HEST_NOTIFY_SCI) { + mutex_lock(&ghes_list_mutex); if (list_empty(&ghes_sci)) register_acpi_hed_notifier(&ghes_notifier_sci); list_add_rcu(&ghes->list, &ghes_sci); - break; - case ACPI_HEST_NOTIFY_NMI: - pr_warning(GHES_PFX -"Generic hardware error source: %d notified via NMI is not supported!\n", - generic->header.source_id); - break; - default: - pr_warning(FW_WARN GHES_PFX - "Unknown notification type: %u for generic hardware error source: %d\n", - generic->notify.type, generic->header.source_id); - break; + mutex_unlock(&ghes_list_mutex); + } else { + unsigned char *notify = NULL; + + switch (generic->notify.type) { + case ACPI_HEST_NOTIFY_POLLED: + notify = "POLL"; + break; + case ACPI_HEST_NOTIFY_EXTERNAL: + case ACPI_HEST_NOTIFY_LOCAL: + notify = "IRQ"; + break; + case ACPI_HEST_NOTIFY_NMI: + notify = "NMI"; + break; + } + if (notify) { + pr_warning(GHES_PFX +"Generic hardware error source: %d notified via %s is not supported!\n", + generic->header.source_id, notify); + } else { + pr_warning(FW_WARN GHES_PFX +"Unknown notification type: %u for generic hardware error source: %d\n", + generic->notify.type, generic->header.source_id); + } + rc = -ENODEV; + goto err; } + platform_set_drvdata(ghes_dev, ghes); return 0; err: - if (ghes) + if (ghes) { ghes_fini(ghes); + kfree(ghes); + } return rc; } -static void ghes_cleanup(void) +static int __devexit ghes_remove(struct platform_device *ghes_dev) { - struct ghes *ghes, *nghes; + struct ghes *ghes; + struct acpi_hest_generic *generic; - if (!list_empty(&ghes_sci)) - unregister_acpi_hed_notifier(&ghes_notifier_sci); + ghes = platform_get_drvdata(ghes_dev); + generic = ghes->generic; + + switch (generic->notify.type) { + case ACPI_HEST_NOTIFY_SCI: + mutex_lock(&ghes_list_mutex); + list_del_rcu(&ghes->list); + if (list_empty(&ghes_sci)) + unregister_acpi_hed_notifier(&ghes_notifier_sci); + mutex_unlock(&ghes_list_mutex); + break; + default: + BUG(); + break; + } synchronize_rcu(); + ghes_fini(ghes); + kfree(ghes); - list_for_each_entry_safe(ghes, nghes, &ghes_sci, list) { - list_del(&ghes->list); - ghes_fini(ghes); - kfree(ghes); - } + platform_set_drvdata(ghes_dev, NULL); + + return 0; } +static struct platform_driver ghes_platform_driver = { + .driver = { + .name = "GHES", + .owner = THIS_MODULE, + }, + .probe = ghes_probe, + .remove = ghes_remove, +}; + static int __init ghes_init(void) { - int rc; - if (acpi_disabled) return -ENODEV; @@ -391,32 +420,12 @@ static int __init ghes_init(void) return -EINVAL; } - rc = apei_hest_parse(hest_ghes_parse, NULL); - if (rc) { - pr_err(GHES_PFX - "Error during parsing HEST generic hardware error sources.\n"); - goto err_cleanup; - } - - if (list_empty(&ghes_sci)) { - pr_info(GHES_PFX - "No functional generic hardware error sources.\n"); - rc = -ENODEV; - goto err_cleanup; - } - - pr_info(GHES_PFX - "Generic Hardware Error Source support is initialized.\n"); - - return 0; -err_cleanup: - ghes_cleanup(); - return rc; + return platform_driver_register(&ghes_platform_driver); } static void __exit ghes_exit(void) { - ghes_cleanup(); + platform_driver_unregister(&ghes_platform_driver); } module_init(ghes_init); @@ -425,3 +434,4 @@ module_exit(ghes_exit); MODULE_AUTHOR("Huang Ying"); MODULE_DESCRIPTION("APEI Generic Hardware Error Source support"); MODULE_LICENSE("GPL"); +MODULE_ALIAS("platform:GHES"); diff --git a/drivers/acpi/apei/hest.c b/drivers/acpi/apei/hest.c index e7f40d362cb3..343168d18266 100644 --- a/drivers/acpi/apei/hest.c +++ b/drivers/acpi/apei/hest.c @@ -34,6 +34,7 @@ #include #include #include +#include #include #include "apei-internal.h" @@ -47,11 +48,6 @@ EXPORT_SYMBOL_GPL(hest_disable); static struct acpi_table_hest *hest_tab; -static int hest_void_parse(struct acpi_hest_header *hest_hdr, void *data) -{ - return 0; -} - static int hest_esrc_len_tab[ACPI_HEST_TYPE_RESERVED] = { [ACPI_HEST_TYPE_IA32_CHECK] = -1, /* need further calculation */ [ACPI_HEST_TYPE_IA32_CORRECTED_CHECK] = -1, @@ -125,6 +121,69 @@ int apei_hest_parse(apei_hest_func_t func, void *data) } EXPORT_SYMBOL_GPL(apei_hest_parse); +struct ghes_arr { + struct platform_device **ghes_devs; + unsigned int count; +}; + +static int hest_parse_ghes_count(struct acpi_hest_header *hest_hdr, void *data) +{ + int *count = data; + + if (hest_hdr->type == ACPI_HEST_TYPE_GENERIC_ERROR) + (*count)++; + return 0; +} + +static int hest_parse_ghes(struct acpi_hest_header *hest_hdr, void *data) +{ + struct acpi_hest_generic *generic; + struct platform_device *ghes_dev; + struct ghes_arr *ghes_arr = data; + int rc; + + if (hest_hdr->type != ACPI_HEST_TYPE_GENERIC_ERROR) + return 0; + generic = (struct acpi_hest_generic *)hest_hdr; + if (!generic->enabled) + return 0; + ghes_dev = platform_device_alloc("GHES", hest_hdr->source_id); + if (!ghes_dev) + return -ENOMEM; + ghes_dev->dev.platform_data = generic; + rc = platform_device_add(ghes_dev); + if (rc) + goto err; + ghes_arr->ghes_devs[ghes_arr->count++] = ghes_dev; + + return 0; +err: + platform_device_put(ghes_dev); + return rc; +} + +static int hest_ghes_dev_register(unsigned int ghes_count) +{ + int rc, i; + struct ghes_arr ghes_arr; + + ghes_arr.count = 0; + ghes_arr.ghes_devs = kmalloc(sizeof(void *) * ghes_count, GFP_KERNEL); + if (!ghes_arr.ghes_devs) + return -ENOMEM; + + rc = apei_hest_parse(hest_parse_ghes, &ghes_arr); + if (rc) + goto err; +out: + kfree(ghes_arr.ghes_devs); + return rc; +err: + for (i = 0; i < ghes_arr.count; i++) + platform_device_unregister(ghes_arr.ghes_devs[i]); + goto out; +} + static int __init setup_hest_disable(char *str) { hest_disable = 1; @@ -137,6 +196,7 @@ static int __init hest_init(void) { acpi_status status; int rc = -ENODEV; + unsigned int ghes_count = 0; if (acpi_disabled) goto err; @@ -158,7 +218,11 @@ static int __init hest_init(void) goto err; } - rc = apei_hest_parse(hest_void_parse, NULL); + rc = apei_hest_parse(hest_parse_ghes_count, &ghes_count); + if (rc) + goto err; + + rc = hest_ghes_dev_register(ghes_count); if (rc) goto err; -- cgit v1.2.1 From 4ef2db016aab27af05a95aeab1c30ad3f2fed7b9 Mon Sep 17 00:00:00 2001 From: Rusty Russell Date: Wed, 11 Aug 2010 23:04:39 -0600 Subject: param: update drivers/acpi/debug.c to new scheme The new module_param_cb() uses an ops struct, and the ops take a const struct kernel_param pointer (it's in .rodata). Signed-off-by: Rusty Russell --- drivers/acpi/debug.c | 32 ++++++++++++++++++++++++-------- 1 file changed, 24 insertions(+), 8 deletions(-) (limited to 'drivers/acpi') diff --git a/drivers/acpi/debug.c b/drivers/acpi/debug.c index 146135e7a6a1..295dbfa2db9c 100644 --- a/drivers/acpi/debug.c +++ b/drivers/acpi/debug.c @@ -96,7 +96,8 @@ static const struct acpi_dlevel acpi_debug_levels[] = { /* -------------------------------------------------------------------------- FS Interface (/sys) -------------------------------------------------------------------------- */ -static int param_get_debug_layer(char *buffer, struct kernel_param *kp) { +static int param_get_debug_layer(char *buffer, const struct kernel_param *kp) +{ int result = 0; int i; @@ -118,7 +119,8 @@ static int param_get_debug_layer(char *buffer, struct kernel_param *kp) { return result; } -static int param_get_debug_level(char *buffer, struct kernel_param *kp) { +static int param_get_debug_level(char *buffer, const struct kernel_param *kp) +{ int result = 0; int i; @@ -137,8 +139,18 @@ static int param_get_debug_level(char *buffer, struct kernel_param *kp) { return result; } -module_param_call(debug_layer, param_set_uint, param_get_debug_layer, &acpi_dbg_layer, 0644); -module_param_call(debug_level, param_set_uint, param_get_debug_level, &acpi_dbg_level, 0644); +static struct kernel_param_ops acpi_debug_layer_ops = { + .set = param_set_uint, + .get = param_get_debug_layer, +}; + +static struct kernel_param_ops acpi_debug_level_ops = { + .set = param_set_uint, + .get = param_get_debug_level, +}; + +module_param_cb(debug_layer, &acpi_debug_layer_ops, &acpi_dbg_layer, 0644); +module_param_cb(debug_level, &acpi_debug_level_ops, &acpi_dbg_level, 0644); static char trace_method_name[6]; module_param_string(trace_method_name, trace_method_name, 6, 0644); @@ -147,7 +159,7 @@ module_param(trace_debug_layer, uint, 0644); static unsigned int trace_debug_level; module_param(trace_debug_level, uint, 0644); -static int param_set_trace_state(const char *val, struct kernel_param *kp) +static int param_set_trace_state(const char *val, const struct kernel_param *kp) { int result = 0; @@ -181,7 +193,7 @@ exit: return result; } -static int param_get_trace_state(char *buffer, struct kernel_param *kp) +static int param_get_trace_state(char *buffer, const struct kernel_param *kp) { if (!acpi_gbl_trace_method_name) return sprintf(buffer, "disable"); @@ -194,8 +206,12 @@ static int param_get_trace_state(char *buffer, struct kernel_param *kp) return 0; } -module_param_call(trace_state, param_set_trace_state, param_get_trace_state, - NULL, 0644); +static struct kernel_param_ops param_ops_trace_state = { + .set = param_set_trace_state, + .get = param_get_trace_state, +}; + +module_param_cb(trace_state, ¶m_ops_trace_state, NULL, 0644); /* -------------------------------------------------------------------------- DebugFS Interface -- cgit v1.2.1 From 0a7992c90828a65281c3c9cf180be3b432d277b2 Mon Sep 17 00:00:00 2001 From: Thomas Gleixner Date: Wed, 11 Aug 2010 14:17:29 -0700 Subject: acpi: fix bogus preemption logic The ACPI_PREEMPTION_POINT() logic was introduced in commit 8bd108d (ACPICA: add preemption point after each opcode parse). The follow up commits abe1dfab6, 138d15692, c084ca70 tried to fix the preemption logic back and forth, but nobody noticed that the usage of in_atomic_preempt_off() in that context is wrong. The check which guards the call of cond_resched() is: if (!in_atomic_preempt_off() && !irqs_disabled()) in_atomic_preempt_off() is not intended for general use as the comment above the macro definition clearly says: * Check whether we were atomic before we did preempt_disable(): * (used by the scheduler, *after* releasing the kernel lock) On a CONFIG_PREEMPT=n kernel the usage of in_atomic_preempt_off() works by accident, but with CONFIG_PREEMPT=y it's just broken. The whole purpose of the ACPI_PREEMPTION_POINT() is to reduce the latency on a CONFIG_PREEMPT=n kernel, so make ACPI_PREEMPTION_POINT() depend on CONFIG_PREEMPT=n and remove the in_atomic_preempt_off() check. Addresses https://bugzilla.kernel.org/show_bug.cgi?id=16210 [akpm@linux-foundation.org: fix build] Signed-off-by: Thomas Gleixner Cc: Len Brown Cc: Francois Valenduc Cc: Lin Ming Cc: Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/acpi/apei/erst.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers/acpi') diff --git a/drivers/acpi/apei/erst.c b/drivers/acpi/apei/erst.c index 864dd46c346f..18645f4e83cd 100644 --- a/drivers/acpi/apei/erst.c +++ b/drivers/acpi/apei/erst.c @@ -33,6 +33,7 @@ #include #include #include +#include #include #include "apei-internal.h" -- cgit v1.2.1 From 2ff729d506e8db82d76a93bc963df4d0a4d46b57 Mon Sep 17 00:00:00 2001 From: Huang Ying Date: Thu, 12 Aug 2010 11:55:17 +0800 Subject: ACPI, APEI, ERST debug support This patch adds debugging/testing support to ERST. A misc device is implemented to export raw ERST read/write/clear etc operations to user space. With this patch, we can add ERST testing support to linuxfirmwarekit ISO (linuxfirmwarekit.org) to verify the kernel support and the firmware implementation. Signed-off-by: Huang Ying Acked-by: Randy Dunlap Signed-off-by: Andi Kleen Signed-off-by: Len Brown --- drivers/acpi/apei/Kconfig | 9 ++ drivers/acpi/apei/Makefile | 1 + drivers/acpi/apei/erst-dbg.c | 207 +++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 217 insertions(+) create mode 100644 drivers/acpi/apei/erst-dbg.c (limited to 'drivers/acpi') diff --git a/drivers/acpi/apei/Kconfig b/drivers/acpi/apei/Kconfig index f8c668f27b5a..907e350f1c7d 100644 --- a/drivers/acpi/apei/Kconfig +++ b/drivers/acpi/apei/Kconfig @@ -28,3 +28,12 @@ config ACPI_APEI_EINJ EINJ provides a hardware error injection mechanism, it is mainly used for debugging and testing the other parts of APEI and some other RAS features. + +config ACPI_APEI_ERST_DEBUG + tristate "APEI Error Record Serialization Table (ERST) Debug Support" + depends on ACPI_APEI + help + ERST is a way provided by APEI to save and retrieve hardware + error infomation to and from a persistent store. Enable this + if you want to debugging and testing the ERST kernel support + and firmware implementation. diff --git a/drivers/acpi/apei/Makefile b/drivers/acpi/apei/Makefile index b13b03a17789..d1d1bc0a4ee1 100644 --- a/drivers/acpi/apei/Makefile +++ b/drivers/acpi/apei/Makefile @@ -1,5 +1,6 @@ obj-$(CONFIG_ACPI_APEI) += apei.o obj-$(CONFIG_ACPI_APEI_GHES) += ghes.o obj-$(CONFIG_ACPI_APEI_EINJ) += einj.o +obj-$(CONFIG_ACPI_APEI_ERST_DEBUG) += erst-dbg.o apei-y := apei-base.o hest.o cper.o erst.o diff --git a/drivers/acpi/apei/erst-dbg.c b/drivers/acpi/apei/erst-dbg.c new file mode 100644 index 000000000000..5281ddda2777 --- /dev/null +++ b/drivers/acpi/apei/erst-dbg.c @@ -0,0 +1,207 @@ +/* + * APEI Error Record Serialization Table debug support + * + * ERST is a way provided by APEI to save and retrieve hardware error + * infomation to and from a persistent store. This file provide the + * debugging/testing support for ERST kernel support and firmware + * implementation. + * + * Copyright 2010 Intel Corp. + * Author: Huang Ying + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License version + * 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include +#include +#include +#include +#include + +#include "apei-internal.h" + +#define ERST_DBG_PFX "ERST DBG: " + +#define ERST_DBG_RECORD_LEN_MAX 4096 + +static void *erst_dbg_buf; +static unsigned int erst_dbg_buf_len; + +/* Prevent erst_dbg_read/write from being invoked concurrently */ +static DEFINE_MUTEX(erst_dbg_mutex); + +static int erst_dbg_open(struct inode *inode, struct file *file) +{ + if (erst_disable) + return -ENODEV; + + return nonseekable_open(inode, file); +} + +static long erst_dbg_ioctl(struct file *f, unsigned int cmd, unsigned long arg) +{ + int rc; + u64 record_id; + u32 record_count; + + switch (cmd) { + case APEI_ERST_CLEAR_RECORD: + rc = copy_from_user(&record_id, (void __user *)arg, + sizeof(record_id)); + if (rc) + return -EFAULT; + return erst_clear(record_id); + case APEI_ERST_GET_RECORD_COUNT: + rc = erst_get_record_count(); + if (rc < 0) + return rc; + record_count = rc; + rc = put_user(record_count, (u32 __user *)arg); + if (rc) + return rc; + return 0; + default: + return -ENOTTY; + } +} + +static ssize_t erst_dbg_read(struct file *filp, char __user *ubuf, + size_t usize, loff_t *off) +{ + int rc; + ssize_t len = 0; + u64 id; + + if (*off != 0) + return -EINVAL; + + if (mutex_lock_interruptible(&erst_dbg_mutex) != 0) + return -EINTR; + +retry_next: + rc = erst_get_next_record_id(&id); + if (rc) + goto out; + /* no more record */ + if (id == APEI_ERST_INVALID_RECORD_ID) + goto out; +retry: + rc = len = erst_read(id, erst_dbg_buf, erst_dbg_buf_len); + /* The record may be cleared by others, try read next record */ + if (rc == -ENOENT) + goto retry_next; + if (rc < 0) + goto out; + if (len > ERST_DBG_RECORD_LEN_MAX) { + pr_warning(ERST_DBG_PFX + "Record (ID: 0x%llx) length is too long: %zd\n", + id, len); + rc = -EIO; + goto out; + } + if (len > erst_dbg_buf_len) { + kfree(erst_dbg_buf); + rc = -ENOMEM; + erst_dbg_buf = kmalloc(len, GFP_KERNEL); + if (!erst_dbg_buf) + goto out; + erst_dbg_buf_len = len; + goto retry; + } + + rc = -EINVAL; + if (len > usize) + goto out; + + rc = -EFAULT; + if (copy_to_user(ubuf, erst_dbg_buf, len)) + goto out; + rc = 0; +out: + mutex_unlock(&erst_dbg_mutex); + return rc ? rc : len; +} + +static ssize_t erst_dbg_write(struct file *filp, const char __user *ubuf, + size_t usize, loff_t *off) +{ + int rc; + struct cper_record_header *rcd; + + if (!capable(CAP_SYS_ADMIN)) + return -EPERM; + + if (usize > ERST_DBG_RECORD_LEN_MAX) { + pr_err(ERST_DBG_PFX "Too long record to be written\n"); + return -EINVAL; + } + + if (mutex_lock_interruptible(&erst_dbg_mutex)) + return -EINTR; + if (usize > erst_dbg_buf_len) { + kfree(erst_dbg_buf); + rc = -ENOMEM; + erst_dbg_buf = kmalloc(usize, GFP_KERNEL); + if (!erst_dbg_buf) + goto out; + erst_dbg_buf_len = usize; + } + rc = copy_from_user(erst_dbg_buf, ubuf, usize); + if (rc) { + rc = -EFAULT; + goto out; + } + rcd = erst_dbg_buf; + rc = -EINVAL; + if (rcd->record_length != usize) + goto out; + + rc = erst_write(erst_dbg_buf); + +out: + mutex_unlock(&erst_dbg_mutex); + return rc < 0 ? rc : usize; +} + +static const struct file_operations erst_dbg_ops = { + .owner = THIS_MODULE, + .open = erst_dbg_open, + .read = erst_dbg_read, + .write = erst_dbg_write, + .unlocked_ioctl = erst_dbg_ioctl, +}; + +static struct miscdevice erst_dbg_dev = { + .minor = MISC_DYNAMIC_MINOR, + .name = "erst_dbg", + .fops = &erst_dbg_ops, +}; + +static __init int erst_dbg_init(void) +{ + return misc_register(&erst_dbg_dev); +} + +static __exit void erst_dbg_exit(void) +{ + misc_deregister(&erst_dbg_dev); + kfree(erst_dbg_buf); +} + +module_init(erst_dbg_init); +module_exit(erst_dbg_exit); + +MODULE_AUTHOR("Huang Ying"); +MODULE_DESCRIPTION("APEI Error Record Serialization Table debug support"); +MODULE_LICENSE("GPL"); -- cgit v1.2.1 From a25ee9200eef07377e1703697afbb5d81f89e500 Mon Sep 17 00:00:00 2001 From: Zhang Rui Date: Thu, 15 Jul 2010 10:46:15 +0800 Subject: ACPI: introduce drivers/acpi/debugfs.c Introduce drivers/acpi/debugfs.c. Code for ACPI debugfs I/F, i.e. /sys/kernel/debug/acpi/custom_method, is moved to this file. And make ACPI debugfs always built in, even if CONFIG_ACPI_DEBUG is cleared. BTW:this adds about 400bytes code to ACPI, when CONFIG_ACPI_DEBUG is cleared. [uaccess.h build fix from Andrew Morton ] Signed-off-by: Zhang Rui Signed-off-by: Len Brown --- drivers/acpi/Makefile | 1 + drivers/acpi/bus.c | 1 + drivers/acpi/debug.c | 75 ------------------------------------------- drivers/acpi/debugfs.c | 85 +++++++++++++++++++++++++++++++++++++++++++++++++ drivers/acpi/internal.h | 6 ++++ 5 files changed, 93 insertions(+), 75 deletions(-) create mode 100644 drivers/acpi/debugfs.c (limited to 'drivers/acpi') diff --git a/drivers/acpi/Makefile b/drivers/acpi/Makefile index 6ee33169e1dc..7891904419fc 100644 --- a/drivers/acpi/Makefile +++ b/drivers/acpi/Makefile @@ -39,6 +39,7 @@ acpi-y += pci_root.o pci_link.o pci_irq.o pci_bind.o acpi-y += power.o acpi-y += system.o event.o acpi-$(CONFIG_ACPI_DEBUG) += debug.o +acpi-$(CONFIG_DEBUG_FS) += debugfs.o acpi-$(CONFIG_ACPI_NUMA) += numa.o acpi-$(CONFIG_ACPI_PROCFS_POWER) += cm_sbs.o ifdef CONFIG_ACPI_VIDEO diff --git a/drivers/acpi/bus.c b/drivers/acpi/bus.c index c1d23cd71652..7136f24e3002 100644 --- a/drivers/acpi/bus.c +++ b/drivers/acpi/bus.c @@ -1036,6 +1036,7 @@ static int __init acpi_init(void) acpi_power_init(); acpi_system_init(); acpi_debug_init(); + acpi_debugfs_init(); acpi_sleep_proc_init(); acpi_wakeup_device_init(); return result; diff --git a/drivers/acpi/debug.c b/drivers/acpi/debug.c index 146135e7a6a1..22476eab2b08 100644 --- a/drivers/acpi/debug.c +++ b/drivers/acpi/debug.c @@ -197,80 +197,6 @@ static int param_get_trace_state(char *buffer, struct kernel_param *kp) module_param_call(trace_state, param_set_trace_state, param_get_trace_state, NULL, 0644); -/* -------------------------------------------------------------------------- - DebugFS Interface - -------------------------------------------------------------------------- */ - -static ssize_t cm_write(struct file *file, const char __user *user_buf, - size_t count, loff_t *ppos) -{ - static char *buf; - static int uncopied_bytes; - struct acpi_table_header table; - acpi_status status; - - if (!(*ppos)) { - /* parse the table header to get the table length */ - if (count <= sizeof(struct acpi_table_header)) - return -EINVAL; - if (copy_from_user(&table, user_buf, - sizeof(struct acpi_table_header))) - return -EFAULT; - uncopied_bytes = table.length; - buf = kzalloc(uncopied_bytes, GFP_KERNEL); - if (!buf) - return -ENOMEM; - } - - if (uncopied_bytes < count) { - kfree(buf); - return -EINVAL; - } - - if (copy_from_user(buf + (*ppos), user_buf, count)) { - kfree(buf); - return -EFAULT; - } - - uncopied_bytes -= count; - *ppos += count; - - if (!uncopied_bytes) { - status = acpi_install_method(buf); - kfree(buf); - if (ACPI_FAILURE(status)) - return -EINVAL; - add_taint(TAINT_OVERRIDDEN_ACPI_TABLE); - } - - return count; -} - -static const struct file_operations cm_fops = { - .write = cm_write, -}; - -static int acpi_debugfs_init(void) -{ - struct dentry *acpi_dir, *cm_dentry; - - acpi_dir = debugfs_create_dir("acpi", NULL); - if (!acpi_dir) - goto err; - - cm_dentry = debugfs_create_file("custom_method", S_IWUGO, - acpi_dir, NULL, &cm_fops); - if (!cm_dentry) - goto err; - - return 0; - -err: - if (acpi_dir) - debugfs_remove(acpi_dir); - return -EINVAL; -} - /* -------------------------------------------------------------------------- FS Interface (/proc) -------------------------------------------------------------------------- */ @@ -400,7 +326,6 @@ int __init acpi_procfs_init(void) int __init acpi_debug_init(void) { - acpi_debugfs_init(); acpi_procfs_init(); return 0; } diff --git a/drivers/acpi/debugfs.c b/drivers/acpi/debugfs.c new file mode 100644 index 000000000000..abfcf9f6e766 --- /dev/null +++ b/drivers/acpi/debugfs.c @@ -0,0 +1,85 @@ +/* + * debugfs.c - ACPI debugfs interface to userspace. + */ + +#include +#include +#include +#include +#include +#include + +#define _COMPONENT ACPI_SYSTEM_COMPONENT +ACPI_MODULE_NAME("debugfs"); + +/* /sys/kernel/debug/acpi/custom_method */ + +static ssize_t cm_write(struct file *file, const char __user * user_buf, + size_t count, loff_t *ppos) +{ + static char *buf; + static int uncopied_bytes; + struct acpi_table_header table; + acpi_status status; + + if (!(*ppos)) { + /* parse the table header to get the table length */ + if (count <= sizeof(struct acpi_table_header)) + return -EINVAL; + if (copy_from_user(&table, user_buf, + sizeof(struct acpi_table_header))) + return -EFAULT; + uncopied_bytes = table.length; + buf = kzalloc(uncopied_bytes, GFP_KERNEL); + if (!buf) + return -ENOMEM; + } + + if (uncopied_bytes < count) { + kfree(buf); + return -EINVAL; + } + + if (copy_from_user(buf + (*ppos), user_buf, count)) { + kfree(buf); + return -EFAULT; + } + + uncopied_bytes -= count; + *ppos += count; + + if (!uncopied_bytes) { + status = acpi_install_method(buf); + kfree(buf); + if (ACPI_FAILURE(status)) + return -EINVAL; + add_taint(TAINT_OVERRIDDEN_ACPI_TABLE); + } + + return count; +} + +static const struct file_operations cm_fops = { + .write = cm_write, +}; + +int __init acpi_debugfs_init(void) +{ + struct dentry *acpi_dir, *cm_dentry; + + acpi_dir = debugfs_create_dir("acpi", NULL); + if (!acpi_dir) + goto err; + + cm_dentry = debugfs_create_file("custom_method", S_IWUGO, + acpi_dir, NULL, &cm_fops); + if (!cm_dentry) + goto err; + + return 0; + +err: + if (acpi_dir) + debugfs_remove(acpi_dir); + return -EINVAL; +} diff --git a/drivers/acpi/internal.h b/drivers/acpi/internal.h index f8f190ec066e..0650e343867e 100644 --- a/drivers/acpi/internal.h +++ b/drivers/acpi/internal.h @@ -30,6 +30,12 @@ int acpi_debug_init(void); static inline int acpi_debug_init(void) { return 0; } #endif +#ifdef CONFIG_DEBUG_FS +int acpi_debugfs_init(void); +#else +static inline int acpi_debugfs_init(void) { return 0; } +#endif + /* -------------------------------------------------------------------------- Power Resource -------------------------------------------------------------------------- */ -- cgit v1.2.1 From c637e4861c7db8165d0f438db3829e7878c96059 Mon Sep 17 00:00:00 2001 From: Zhang Rui Date: Thu, 15 Jul 2010 10:46:17 +0800 Subject: ACPI: introduce module parameter acpi.aml_debug_output Introduce module parameter acpi.aml_debug_output. With acpi.aml_debug_output set, we can get AML debug object output (Store (AAA, Debug)), even with CONFIG_ACPI_DEBUG cleared. Together with the runtime custom method mechanism, we can debug AML code problems without rebuilding the kernel. Signed-off-by: Zhang Rui Signed-off-by: Len Brown --- drivers/acpi/acpica/acglobal.h | 2 +- drivers/acpi/debugfs.c | 8 ++++++++ 2 files changed, 9 insertions(+), 1 deletion(-) (limited to 'drivers/acpi') diff --git a/drivers/acpi/acpica/acglobal.h b/drivers/acpi/acpica/acglobal.h index 899d68afc3c5..92122292ef1f 100644 --- a/drivers/acpi/acpica/acglobal.h +++ b/drivers/acpi/acpica/acglobal.h @@ -115,7 +115,7 @@ u8 ACPI_INIT_GLOBAL(acpi_gbl_use_default_register_widths, TRUE); /* * Optionally enable output from the AML Debug Object. */ -u8 ACPI_INIT_GLOBAL(acpi_gbl_enable_aml_debug_object, FALSE); +u32 ACPI_INIT_GLOBAL(acpi_gbl_enable_aml_debug_object, FALSE); /* * Optionally copy the entire DSDT to local memory (instead of simply diff --git a/drivers/acpi/debugfs.c b/drivers/acpi/debugfs.c index abfcf9f6e766..7de27d49c4b9 100644 --- a/drivers/acpi/debugfs.c +++ b/drivers/acpi/debugfs.c @@ -12,6 +12,14 @@ #define _COMPONENT ACPI_SYSTEM_COMPONENT ACPI_MODULE_NAME("debugfs"); + +/* /sys/modules/acpi/parameters/aml_debug_output */ + +module_param_named(aml_debug_output, acpi_gbl_enable_aml_debug_object, + bool, 0644); +MODULE_PARM_DESC(aml_debug_output, + "To enable/disable the ACPI Debug Object output."); + /* /sys/kernel/debug/acpi/custom_method */ static ssize_t cm_write(struct file *file, const char __user * user_buf, -- cgit v1.2.1 From 1c8fce27e275fd7c6b75bc6455745f02d3903ee6 Mon Sep 17 00:00:00 2001 From: Zhang Rui Date: Thu, 15 Jul 2010 10:46:30 +0800 Subject: ACPI: introduce drivers/acpi/sysfs.c Introduce drivers/acpi/sysfs.c. code for ACPI sysfs I/F, including #ifdef ACPI_DEBUG /sys/module/acpi/parameters/debug_layer /sys/module/acpi/parameters/debug_level /sys/module/acpi/parameters/trace_method_name /sys/module/acpi/parameters/trace_debug_layer /sys/module/acpi/parameters/trace_debug_level /sys/module/acpi/parameters/trace_state #endif /sys/module/acpi/parameters/acpica_version /sys/firmware/acpi/tables/ /sys/firmware/acpi/interrupts/ is moved to this file. No function change in this patch. Signed-off-by: Zhang Rui Signed-off-by: Len Brown --- drivers/acpi/Makefile | 1 + drivers/acpi/bus.c | 1 + drivers/acpi/debug.c | 104 -------- drivers/acpi/internal.h | 1 + drivers/acpi/sysfs.c | 685 ++++++++++++++++++++++++++++++++++++++++++++++++ drivers/acpi/system.c | 467 --------------------------------- 6 files changed, 688 insertions(+), 571 deletions(-) create mode 100644 drivers/acpi/sysfs.c (limited to 'drivers/acpi') diff --git a/drivers/acpi/Makefile b/drivers/acpi/Makefile index 7891904419fc..03a81a844d23 100644 --- a/drivers/acpi/Makefile +++ b/drivers/acpi/Makefile @@ -38,6 +38,7 @@ acpi-$(CONFIG_ACPI_DOCK) += dock.o acpi-y += pci_root.o pci_link.o pci_irq.o pci_bind.o acpi-y += power.o acpi-y += system.o event.o +acpi-y += sysfs.o acpi-$(CONFIG_ACPI_DEBUG) += debug.o acpi-$(CONFIG_DEBUG_FS) += debugfs.o acpi-$(CONFIG_ACPI_NUMA) += numa.o diff --git a/drivers/acpi/bus.c b/drivers/acpi/bus.c index 7136f24e3002..bd9708b0f3f3 100644 --- a/drivers/acpi/bus.c +++ b/drivers/acpi/bus.c @@ -1036,6 +1036,7 @@ static int __init acpi_init(void) acpi_power_init(); acpi_system_init(); acpi_debug_init(); + acpi_sysfs_init(); acpi_debugfs_init(); acpi_sleep_proc_init(); acpi_wakeup_device_init(); diff --git a/drivers/acpi/debug.c b/drivers/acpi/debug.c index 22476eab2b08..f82240dbbba3 100644 --- a/drivers/acpi/debug.c +++ b/drivers/acpi/debug.c @@ -93,110 +93,6 @@ static const struct acpi_dlevel acpi_debug_levels[] = { ACPI_DEBUG_INIT(ACPI_LV_EVENTS), }; -/* -------------------------------------------------------------------------- - FS Interface (/sys) - -------------------------------------------------------------------------- */ -static int param_get_debug_layer(char *buffer, struct kernel_param *kp) { - int result = 0; - int i; - - result = sprintf(buffer, "%-25s\tHex SET\n", "Description"); - - for(i = 0; i +#include +#include +#include + +#define _COMPONENT ACPI_SYSTEM_COMPONENT +ACPI_MODULE_NAME("sysfs"); + +#define PREFIX "ACPI: " + +#ifdef CONFIG_ACPI_DEBUG +/* + * ACPI debug sysfs I/F, including: + * /sys/modules/acpi/parameters/debug_layer + * /sys/modules/acpi/parameters/debug_level + * /sys/modules/acpi/parameters/trace_method_name + * /sys/modules/acpi/parameters/trace_state + * /sys/modules/acpi/parameters/trace_debug_layer + * /sys/modules/acpi/parameters/trace_debug_level + */ + +struct acpi_dlayer { + const char *name; + unsigned long value; +}; +struct acpi_dlevel { + const char *name; + unsigned long value; +}; +#define ACPI_DEBUG_INIT(v) { .name = #v, .value = v } + +static const struct acpi_dlayer acpi_debug_layers[] = { + ACPI_DEBUG_INIT(ACPI_UTILITIES), + ACPI_DEBUG_INIT(ACPI_HARDWARE), + ACPI_DEBUG_INIT(ACPI_EVENTS), + ACPI_DEBUG_INIT(ACPI_TABLES), + ACPI_DEBUG_INIT(ACPI_NAMESPACE), + ACPI_DEBUG_INIT(ACPI_PARSER), + ACPI_DEBUG_INIT(ACPI_DISPATCHER), + ACPI_DEBUG_INIT(ACPI_EXECUTER), + ACPI_DEBUG_INIT(ACPI_RESOURCES), + ACPI_DEBUG_INIT(ACPI_CA_DEBUGGER), + ACPI_DEBUG_INIT(ACPI_OS_SERVICES), + 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[] = { + ACPI_DEBUG_INIT(ACPI_LV_INIT), + ACPI_DEBUG_INIT(ACPI_LV_DEBUG_OBJECT), + ACPI_DEBUG_INIT(ACPI_LV_INFO), + + ACPI_DEBUG_INIT(ACPI_LV_INIT_NAMES), + ACPI_DEBUG_INIT(ACPI_LV_PARSE), + ACPI_DEBUG_INIT(ACPI_LV_LOAD), + ACPI_DEBUG_INIT(ACPI_LV_DISPATCH), + ACPI_DEBUG_INIT(ACPI_LV_EXEC), + ACPI_DEBUG_INIT(ACPI_LV_NAMES), + ACPI_DEBUG_INIT(ACPI_LV_OPREGION), + ACPI_DEBUG_INIT(ACPI_LV_BFIELD), + ACPI_DEBUG_INIT(ACPI_LV_TABLES), + ACPI_DEBUG_INIT(ACPI_LV_VALUES), + ACPI_DEBUG_INIT(ACPI_LV_OBJECTS), + ACPI_DEBUG_INIT(ACPI_LV_RESOURCES), + ACPI_DEBUG_INIT(ACPI_LV_USER_REQUESTS), + ACPI_DEBUG_INIT(ACPI_LV_PACKAGE), + + ACPI_DEBUG_INIT(ACPI_LV_ALLOCATIONS), + ACPI_DEBUG_INIT(ACPI_LV_FUNCTIONS), + ACPI_DEBUG_INIT(ACPI_LV_OPTIMIZATIONS), + + ACPI_DEBUG_INIT(ACPI_LV_MUTEX), + ACPI_DEBUG_INIT(ACPI_LV_THREADS), + ACPI_DEBUG_INIT(ACPI_LV_IO), + ACPI_DEBUG_INIT(ACPI_LV_INTERRUPTS), + + ACPI_DEBUG_INIT(ACPI_LV_AML_DISASSEMBLE), + ACPI_DEBUG_INIT(ACPI_LV_VERBOSE_INFO), + ACPI_DEBUG_INIT(ACPI_LV_FULL_TABLES), + ACPI_DEBUG_INIT(ACPI_LV_EVENTS), +}; + +static int param_get_debug_layer(char *buffer, struct kernel_param *kp) +{ + int result = 0; + int i; + + result = sprintf(buffer, "%-25s\tHex SET\n", "Description"); + + for (i = 0; i < ARRAY_SIZE(acpi_debug_layers); i++) { + result += sprintf(buffer + result, "%-25s\t0x%08lX [%c]\n", + acpi_debug_layers[i].name, + acpi_debug_layers[i].value, + (acpi_dbg_layer & acpi_debug_layers[i].value) + ? '*' : ' '); + } + result += + sprintf(buffer + result, "%-25s\t0x%08X [%c]\n", "ACPI_ALL_DRIVERS", + ACPI_ALL_DRIVERS, + (acpi_dbg_layer & ACPI_ALL_DRIVERS) == + ACPI_ALL_DRIVERS ? '*' : (acpi_dbg_layer & ACPI_ALL_DRIVERS) + == 0 ? ' ' : '-'); + result += + sprintf(buffer + result, + "--\ndebug_layer = 0x%08X ( * = enabled)\n", + acpi_dbg_layer); + + return result; +} + +static int param_get_debug_level(char *buffer, struct kernel_param *kp) +{ + int result = 0; + int i; + + result = sprintf(buffer, "%-25s\tHex SET\n", "Description"); + + for (i = 0; i < ARRAY_SIZE(acpi_debug_levels); i++) { + result += sprintf(buffer + result, "%-25s\t0x%08lX [%c]\n", + acpi_debug_levels[i].name, + acpi_debug_levels[i].value, + (acpi_dbg_level & acpi_debug_levels[i].value) + ? '*' : ' '); + } + result += + sprintf(buffer + result, "--\ndebug_level = 0x%08X (* = enabled)\n", + acpi_dbg_level); + + return result; +} + +module_param_call(debug_layer, param_set_uint, param_get_debug_layer, + &acpi_dbg_layer, 0644); +module_param_call(debug_level, param_set_uint, param_get_debug_level, + &acpi_dbg_level, 0644); + +static char trace_method_name[6]; +module_param_string(trace_method_name, trace_method_name, 6, 0644); +static unsigned int trace_debug_layer; +module_param(trace_debug_layer, uint, 0644); +static unsigned int trace_debug_level; +module_param(trace_debug_level, uint, 0644); + +static int param_set_trace_state(const char *val, struct kernel_param *kp) +{ + int result = 0; + + if (!strncmp(val, "enable", strlen("enable") - 1)) { + result = acpi_debug_trace(trace_method_name, trace_debug_level, + trace_debug_layer, 0); + if (result) + result = -EBUSY; + goto exit; + } + + if (!strncmp(val, "disable", strlen("disable") - 1)) { + int name = 0; + result = acpi_debug_trace((char *)&name, trace_debug_level, + trace_debug_layer, 0); + if (result) + result = -EBUSY; + goto exit; + } + + if (!strncmp(val, "1", 1)) { + result = acpi_debug_trace(trace_method_name, trace_debug_level, + trace_debug_layer, 1); + if (result) + result = -EBUSY; + goto exit; + } + + result = -EINVAL; +exit: + return result; +} + +static int param_get_trace_state(char *buffer, struct kernel_param *kp) +{ + if (!acpi_gbl_trace_method_name) + return sprintf(buffer, "disable"); + else { + if (acpi_gbl_trace_flags & 1) + return sprintf(buffer, "1"); + else + return sprintf(buffer, "enable"); + } + return 0; +} + +module_param_call(trace_state, param_set_trace_state, param_get_trace_state, + NULL, 0644); +#endif /* CONFIG_ACPI_DEBUG */ + +/* /sys/module/acpi/parameters/acpica_version */ +static int param_get_acpica_version(char *buffer, struct kernel_param *kp) +{ + int result; + + result = sprintf(buffer, "%x", ACPI_CA_VERSION); + + return result; +} + +module_param_call(acpica_version, NULL, param_get_acpica_version, NULL, 0444); + +/* + * ACPI table sysfs I/F: + * /sys/firmware/acpi/tables/ + * /sys/firmware/acpi/tables/dynamic/ + */ + +static LIST_HEAD(acpi_table_attr_list); +static struct kobject *tables_kobj; +static struct kobject *dynamic_tables_kobj; + +struct acpi_table_attr { + struct bin_attribute attr; + char name[8]; + int instance; + struct list_head node; +}; + +static ssize_t acpi_table_show(struct file *filp, struct kobject *kobj, + struct bin_attribute *bin_attr, char *buf, + loff_t offset, size_t count) +{ + struct acpi_table_attr *table_attr = + 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(name, table_attr->instance, &table_header); + if (ACPI_FAILURE(status)) + return -ENODEV; + + return memory_read_from_buffer(buf, count, &offset, + table_header, table_header->length); +} + +static void acpi_table_attr_init(struct acpi_table_attr *table_attr, + struct acpi_table_header *table_header) +{ + struct acpi_table_header *header = NULL; + struct acpi_table_attr *attr = NULL; + + sysfs_attr_init(&table_attr->attr.attr); + 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_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 + ACPI_NAME_SIZE, "%d", + table_attr->instance); + + table_attr->attr.size = 0; + table_attr->attr.read = acpi_table_show; + table_attr->attr.attr.name = table_attr->name; + table_attr->attr.attr.mode = 0400; + + return; +} + +static acpi_status +acpi_sysfs_table_handler(u32 event, void *table, void *context) +{ + struct acpi_table_attr *table_attr; + + switch (event) { + case ACPI_TABLE_EVENT_LOAD: + table_attr = + kzalloc(sizeof(struct acpi_table_attr), GFP_KERNEL); + if (!table_attr) + return AE_NO_MEMORY; + + acpi_table_attr_init(table_attr, table); + if (sysfs_create_bin_file(dynamic_tables_kobj, + &table_attr->attr)) { + kfree(table_attr); + return AE_ERROR; + } else + list_add_tail(&table_attr->node, &acpi_table_attr_list); + break; + case ACPI_TABLE_EVENT_UNLOAD: + /* + * we do not need to do anything right now + * because the table is not deleted from the + * global table list when unloading it. + */ + break; + default: + return AE_BAD_PARAMETER; + } + return AE_OK; +} + +static int acpi_tables_sysfs_init(void) +{ + struct acpi_table_attr *table_attr; + struct acpi_table_header *table_header = NULL; + int table_index = 0; + int result; + + tables_kobj = kobject_create_and_add("tables", acpi_kobj); + if (!tables_kobj) + goto err; + + dynamic_tables_kobj = kobject_create_and_add("dynamic", tables_kobj); + if (!dynamic_tables_kobj) + goto err_dynamic_tables; + + do { + result = acpi_get_table_by_index(table_index, &table_header); + if (!result) { + table_index++; + table_attr = NULL; + table_attr = + kzalloc(sizeof(struct acpi_table_attr), GFP_KERNEL); + if (!table_attr) + return -ENOMEM; + + acpi_table_attr_init(table_attr, table_header); + result = + sysfs_create_bin_file(tables_kobj, + &table_attr->attr); + if (result) { + kfree(table_attr); + return result; + } else + list_add_tail(&table_attr->node, + &acpi_table_attr_list); + } + } while (!result); + kobject_uevent(tables_kobj, KOBJ_ADD); + kobject_uevent(dynamic_tables_kobj, KOBJ_ADD); + result = acpi_install_table_handler(acpi_sysfs_table_handler, NULL); + + return result == AE_OK ? 0 : -EINVAL; +err_dynamic_tables: + kobject_put(tables_kobj); +err: + return -ENOMEM; +} + +/* + * Detailed ACPI IRQ counters: + * /sys/firmware/acpi/interrupts/ + */ + +u32 acpi_irq_handled; +u32 acpi_irq_not_handled; + +#define COUNT_GPE 0 +#define COUNT_SCI 1 /* acpi_irq_handled */ +#define COUNT_SCI_NOT 2 /* acpi_irq_not_handled */ +#define COUNT_ERROR 3 /* other */ +#define NUM_COUNTERS_EXTRA 4 + +struct event_counter { + u32 count; + u32 flags; +}; + +static struct event_counter *all_counters; +static u32 num_gpes; +static u32 num_counters; +static struct attribute **all_attrs; +static u32 acpi_gpe_count; + +static struct attribute_group interrupt_stats_attr_group = { + .name = "interrupts", +}; + +static struct kobj_attribute *counter_attrs; + +static void delete_gpe_attr_array(void) +{ + struct event_counter *tmp = all_counters; + + all_counters = NULL; + kfree(tmp); + + if (counter_attrs) { + int i; + + for (i = 0; i < num_gpes; i++) + kfree(counter_attrs[i].attr.name); + + kfree(counter_attrs); + } + kfree(all_attrs); + + return; +} + +void acpi_os_gpe_count(u32 gpe_number) +{ + acpi_gpe_count++; + + if (!all_counters) + return; + + if (gpe_number < num_gpes) + all_counters[gpe_number].count++; + else + all_counters[num_gpes + ACPI_NUM_FIXED_EVENTS + + COUNT_ERROR].count++; + + return; +} + +void acpi_os_fixed_event_count(u32 event_number) +{ + if (!all_counters) + return; + + if (event_number < ACPI_NUM_FIXED_EVENTS) + all_counters[num_gpes + event_number].count++; + else + all_counters[num_gpes + ACPI_NUM_FIXED_EVENTS + + COUNT_ERROR].count++; + + return; +} + +static int get_status(u32 index, acpi_event_status *status, + acpi_handle *handle) +{ + int result = 0; + + if (index >= num_gpes + ACPI_NUM_FIXED_EVENTS) + goto end; + + if (index < num_gpes) { + result = acpi_get_gpe_device(index, handle); + if (result) { + ACPI_EXCEPTION((AE_INFO, AE_NOT_FOUND, + "Invalid GPE 0x%x\n", index)); + goto end; + } + result = acpi_get_gpe_status(*handle, index, status); + } else if (index < (num_gpes + ACPI_NUM_FIXED_EVENTS)) + result = acpi_get_event_status(index - num_gpes, status); + +end: + return result; +} + +static ssize_t counter_show(struct kobject *kobj, + struct kobj_attribute *attr, char *buf) +{ + int index = attr - counter_attrs; + int size; + acpi_handle handle; + acpi_event_status status; + int result = 0; + + all_counters[num_gpes + ACPI_NUM_FIXED_EVENTS + COUNT_SCI].count = + acpi_irq_handled; + all_counters[num_gpes + ACPI_NUM_FIXED_EVENTS + COUNT_SCI_NOT].count = + acpi_irq_not_handled; + all_counters[num_gpes + ACPI_NUM_FIXED_EVENTS + COUNT_GPE].count = + acpi_gpe_count; + size = sprintf(buf, "%8d", all_counters[index].count); + + /* "gpe_all" or "sci" */ + if (index >= num_gpes + ACPI_NUM_FIXED_EVENTS) + goto end; + + result = get_status(index, &status, &handle); + if (result) + goto end; + + if (!(status & ACPI_EVENT_FLAG_HANDLE)) + size += sprintf(buf + size, " invalid"); + else if (status & ACPI_EVENT_FLAG_ENABLED) + size += sprintf(buf + size, " enabled"); + else if (status & ACPI_EVENT_FLAG_WAKE_ENABLED) + size += sprintf(buf + size, " wake_enabled"); + else + size += sprintf(buf + size, " disabled"); + +end: + size += sprintf(buf + size, "\n"); + return result ? result : size; +} + +/* + * counter_set() sets the specified counter. + * setting the total "sci" file to any value clears all counters. + * enable/disable/clear a gpe/fixed event in user space. + */ +static ssize_t counter_set(struct kobject *kobj, + struct kobj_attribute *attr, const char *buf, + size_t size) +{ + int index = attr - counter_attrs; + acpi_event_status status; + acpi_handle handle; + int result = 0; + + if (index == num_gpes + ACPI_NUM_FIXED_EVENTS + COUNT_SCI) { + int i; + for (i = 0; i < num_counters; ++i) + all_counters[i].count = 0; + acpi_gpe_count = 0; + acpi_irq_handled = 0; + acpi_irq_not_handled = 0; + goto end; + } + + /* show the event status for both GPEs and Fixed Events */ + result = get_status(index, &status, &handle); + if (result) + goto end; + + if (!(status & ACPI_EVENT_FLAG_HANDLE)) { + printk(KERN_WARNING PREFIX + "Can not change Invalid GPE/Fixed Event status\n"); + return -EINVAL; + } + + if (index < num_gpes) { + if (!strcmp(buf, "disable\n") && + (status & ACPI_EVENT_FLAG_ENABLED)) + result = acpi_disable_gpe(handle, index); + else if (!strcmp(buf, "enable\n") && + !(status & ACPI_EVENT_FLAG_ENABLED)) + result = acpi_enable_gpe(handle, index); + else if (!strcmp(buf, "clear\n") && + (status & ACPI_EVENT_FLAG_SET)) + result = acpi_clear_gpe(handle, index); + else + all_counters[index].count = strtoul(buf, NULL, 0); + } else if (index < num_gpes + ACPI_NUM_FIXED_EVENTS) { + int event = index - num_gpes; + if (!strcmp(buf, "disable\n") && + (status & ACPI_EVENT_FLAG_ENABLED)) + result = acpi_disable_event(event, ACPI_NOT_ISR); + else if (!strcmp(buf, "enable\n") && + !(status & ACPI_EVENT_FLAG_ENABLED)) + result = acpi_enable_event(event, ACPI_NOT_ISR); + else if (!strcmp(buf, "clear\n") && + (status & ACPI_EVENT_FLAG_SET)) + result = acpi_clear_event(event); + else + all_counters[index].count = strtoul(buf, NULL, 0); + } else + all_counters[index].count = strtoul(buf, NULL, 0); + + if (ACPI_FAILURE(result)) + result = -EINVAL; +end: + return result ? result : size; +} + +void acpi_irq_stats_init(void) +{ + int i; + + if (all_counters) + return; + + num_gpes = acpi_current_gpe_count; + num_counters = num_gpes + ACPI_NUM_FIXED_EVENTS + NUM_COUNTERS_EXTRA; + + all_attrs = kzalloc(sizeof(struct attribute *) * (num_counters + 1), + GFP_KERNEL); + if (all_attrs == NULL) + return; + + all_counters = kzalloc(sizeof(struct event_counter) * (num_counters), + GFP_KERNEL); + if (all_counters == NULL) + goto fail; + + counter_attrs = kzalloc(sizeof(struct kobj_attribute) * (num_counters), + GFP_KERNEL); + if (counter_attrs == NULL) + goto fail; + + for (i = 0; i < num_counters; ++i) { + char buffer[12]; + char *name; + + if (i < num_gpes) + sprintf(buffer, "gpe%02X", i); + else if (i == num_gpes + ACPI_EVENT_PMTIMER) + sprintf(buffer, "ff_pmtimer"); + else if (i == num_gpes + ACPI_EVENT_GLOBAL) + sprintf(buffer, "ff_gbl_lock"); + else if (i == num_gpes + ACPI_EVENT_POWER_BUTTON) + sprintf(buffer, "ff_pwr_btn"); + else if (i == num_gpes + ACPI_EVENT_SLEEP_BUTTON) + sprintf(buffer, "ff_slp_btn"); + else if (i == num_gpes + ACPI_EVENT_RTC) + sprintf(buffer, "ff_rt_clk"); + else if (i == num_gpes + ACPI_NUM_FIXED_EVENTS + COUNT_GPE) + sprintf(buffer, "gpe_all"); + else if (i == num_gpes + ACPI_NUM_FIXED_EVENTS + COUNT_SCI) + sprintf(buffer, "sci"); + else if (i == num_gpes + ACPI_NUM_FIXED_EVENTS + COUNT_SCI_NOT) + sprintf(buffer, "sci_not"); + else if (i == num_gpes + ACPI_NUM_FIXED_EVENTS + COUNT_ERROR) + sprintf(buffer, "error"); + else + sprintf(buffer, "bug%02X", i); + + name = kzalloc(strlen(buffer) + 1, GFP_KERNEL); + if (name == NULL) + goto fail; + strncpy(name, buffer, strlen(buffer) + 1); + + sysfs_attr_init(&counter_attrs[i].attr); + counter_attrs[i].attr.name = name; + counter_attrs[i].attr.mode = 0644; + counter_attrs[i].show = counter_show; + counter_attrs[i].store = counter_set; + + all_attrs[i] = &counter_attrs[i].attr; + } + + interrupt_stats_attr_group.attrs = all_attrs; + if (!sysfs_create_group(acpi_kobj, &interrupt_stats_attr_group)) + return; + +fail: + delete_gpe_attr_array(); + return; +} + +static void __exit interrupt_stats_exit(void) +{ + sysfs_remove_group(acpi_kobj, &interrupt_stats_attr_group); + + delete_gpe_attr_array(); + + return; +} + +int __init acpi_sysfs_init(void) +{ + int result; + + result = acpi_tables_sysfs_init(); + + return result; +} diff --git a/drivers/acpi/system.c b/drivers/acpi/system.c index 5981bd07e20e..d70481f32c89 100644 --- a/drivers/acpi/system.c +++ b/drivers/acpi/system.c @@ -40,469 +40,6 @@ ACPI_MODULE_NAME("system"); #define ACPI_SYSTEM_CLASS "system" #define ACPI_SYSTEM_DEVICE_NAME "System" -u32 acpi_irq_handled; -u32 acpi_irq_not_handled; - -/* - * Make ACPICA version work as module param - */ -static int param_get_acpica_version(char *buffer, struct kernel_param *kp) -{ - int result; - - result = sprintf(buffer, "%x", ACPI_CA_VERSION); - - return result; -} - -module_param_call(acpica_version, NULL, param_get_acpica_version, NULL, 0444); - -/* -------------------------------------------------------------------------- - FS Interface (/sys) - -------------------------------------------------------------------------- */ -static LIST_HEAD(acpi_table_attr_list); -static struct kobject *tables_kobj; -static struct kobject *dynamic_tables_kobj; - -struct acpi_table_attr { - struct bin_attribute attr; - char name[8]; - int instance; - struct list_head node; -}; - -static ssize_t acpi_table_show(struct file *filp, struct kobject *kobj, - struct bin_attribute *bin_attr, char *buf, - loff_t offset, size_t count) -{ - struct acpi_table_attr *table_attr = - 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(name, table_attr->instance, - &table_header); - if (ACPI_FAILURE(status)) - return -ENODEV; - - return memory_read_from_buffer(buf, count, &offset, - table_header, table_header->length); -} - -static void acpi_table_attr_init(struct acpi_table_attr *table_attr, - struct acpi_table_header *table_header) -{ - struct acpi_table_header *header = NULL; - struct acpi_table_attr *attr = NULL; - - sysfs_attr_init(&table_attr->attr.attr); - 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_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 + ACPI_NAME_SIZE, "%d", - table_attr->instance); - - table_attr->attr.size = 0; - table_attr->attr.read = acpi_table_show; - table_attr->attr.attr.name = table_attr->name; - table_attr->attr.attr.mode = 0400; - - return; -} - -static acpi_status -acpi_sysfs_table_handler(u32 event, void *table, void *context) -{ - struct acpi_table_attr *table_attr; - - switch (event) { - case ACPI_TABLE_EVENT_LOAD: - table_attr = - kzalloc(sizeof(struct acpi_table_attr), GFP_KERNEL); - if (!table_attr) - return AE_NO_MEMORY; - - acpi_table_attr_init(table_attr, table); - if (sysfs_create_bin_file(dynamic_tables_kobj, - &table_attr->attr)) { - kfree(table_attr); - return AE_ERROR; - } else - list_add_tail(&table_attr->node, - &acpi_table_attr_list); - break; - case ACPI_TABLE_EVENT_UNLOAD: - /* - * we do not need to do anything right now - * because the table is not deleted from the - * global table list when unloading it. - */ - break; - default: - return AE_BAD_PARAMETER; - } - return AE_OK; -} - -static int acpi_system_sysfs_init(void) -{ - struct acpi_table_attr *table_attr; - struct acpi_table_header *table_header = NULL; - int table_index = 0; - int result; - - tables_kobj = kobject_create_and_add("tables", acpi_kobj); - if (!tables_kobj) - goto err; - - dynamic_tables_kobj = kobject_create_and_add("dynamic", tables_kobj); - if (!dynamic_tables_kobj) - goto err_dynamic_tables; - - do { - result = acpi_get_table_by_index(table_index, &table_header); - if (!result) { - table_index++; - table_attr = NULL; - table_attr = - kzalloc(sizeof(struct acpi_table_attr), GFP_KERNEL); - if (!table_attr) - return -ENOMEM; - - acpi_table_attr_init(table_attr, table_header); - result = - sysfs_create_bin_file(tables_kobj, - &table_attr->attr); - if (result) { - kfree(table_attr); - return result; - } else - list_add_tail(&table_attr->node, - &acpi_table_attr_list); - } - } while (!result); - kobject_uevent(tables_kobj, KOBJ_ADD); - kobject_uevent(dynamic_tables_kobj, KOBJ_ADD); - result = acpi_install_table_handler(acpi_sysfs_table_handler, NULL); - - return result == AE_OK ? 0 : -EINVAL; -err_dynamic_tables: - kobject_put(tables_kobj); -err: - return -ENOMEM; -} - -/* - * Detailed ACPI IRQ counters in /sys/firmware/acpi/interrupts/ - * See Documentation/ABI/testing/sysfs-firmware-acpi - */ - -#define COUNT_GPE 0 -#define COUNT_SCI 1 /* acpi_irq_handled */ -#define COUNT_SCI_NOT 2 /* acpi_irq_not_handled */ -#define COUNT_ERROR 3 /* other */ -#define NUM_COUNTERS_EXTRA 4 - -struct event_counter { - u32 count; - u32 flags; -}; - -static struct event_counter *all_counters; -static u32 num_gpes; -static u32 num_counters; -static struct attribute **all_attrs; -static u32 acpi_gpe_count; - -static struct attribute_group interrupt_stats_attr_group = { - .name = "interrupts", -}; -static struct kobj_attribute *counter_attrs; - -static void delete_gpe_attr_array(void) -{ - struct event_counter *tmp = all_counters; - - all_counters = NULL; - kfree(tmp); - - if (counter_attrs) { - int i; - - for (i = 0; i < num_gpes; i++) - kfree(counter_attrs[i].attr.name); - - kfree(counter_attrs); - } - kfree(all_attrs); - - return; -} - -void acpi_os_gpe_count(u32 gpe_number) -{ - acpi_gpe_count++; - - if (!all_counters) - return; - - if (gpe_number < num_gpes) - all_counters[gpe_number].count++; - else - all_counters[num_gpes + ACPI_NUM_FIXED_EVENTS + COUNT_ERROR]. - count++; - - return; -} - -void acpi_os_fixed_event_count(u32 event_number) -{ - if (!all_counters) - return; - - if (event_number < ACPI_NUM_FIXED_EVENTS) - all_counters[num_gpes + event_number].count++; - else - all_counters[num_gpes + ACPI_NUM_FIXED_EVENTS + COUNT_ERROR]. - count++; - - return; -} - -static int get_status(u32 index, acpi_event_status *status, acpi_handle *handle) -{ - int result = 0; - - if (index >= num_gpes + ACPI_NUM_FIXED_EVENTS) - goto end; - - if (index < num_gpes) { - result = acpi_get_gpe_device(index, handle); - if (result) { - ACPI_EXCEPTION((AE_INFO, AE_NOT_FOUND, - "Invalid GPE 0x%x\n", index)); - goto end; - } - result = acpi_get_gpe_status(*handle, index, status); - } else if (index < (num_gpes + ACPI_NUM_FIXED_EVENTS)) - result = acpi_get_event_status(index - num_gpes, status); - -end: - return result; -} - -static ssize_t counter_show(struct kobject *kobj, - struct kobj_attribute *attr, char *buf) -{ - int index = attr - counter_attrs; - int size; - acpi_handle handle; - acpi_event_status status; - int result = 0; - - all_counters[num_gpes + ACPI_NUM_FIXED_EVENTS + COUNT_SCI].count = - acpi_irq_handled; - all_counters[num_gpes + ACPI_NUM_FIXED_EVENTS + COUNT_SCI_NOT].count = - acpi_irq_not_handled; - all_counters[num_gpes + ACPI_NUM_FIXED_EVENTS + COUNT_GPE].count = - acpi_gpe_count; - - size = sprintf(buf, "%8d", all_counters[index].count); - - /* "gpe_all" or "sci" */ - if (index >= num_gpes + ACPI_NUM_FIXED_EVENTS) - goto end; - - result = get_status(index, &status, &handle); - if (result) - goto end; - - if (!(status & ACPI_EVENT_FLAG_HANDLE)) - size += sprintf(buf + size, " invalid"); - else if (status & ACPI_EVENT_FLAG_ENABLED) - size += sprintf(buf + size, " enabled"); - else if (status & ACPI_EVENT_FLAG_WAKE_ENABLED) - size += sprintf(buf + size, " wake_enabled"); - else - size += sprintf(buf + size, " disabled"); - -end: - size += sprintf(buf + size, "\n"); - return result ? result : size; -} - -/* - * counter_set() sets the specified counter. - * setting the total "sci" file to any value clears all counters. - * enable/disable/clear a gpe/fixed event in user space. - */ -static ssize_t counter_set(struct kobject *kobj, - struct kobj_attribute *attr, const char *buf, size_t size) -{ - int index = attr - counter_attrs; - acpi_event_status status; - acpi_handle handle; - int result = 0; - - if (index == num_gpes + ACPI_NUM_FIXED_EVENTS + COUNT_SCI) { - int i; - for (i = 0; i < num_counters; ++i) - all_counters[i].count = 0; - acpi_gpe_count = 0; - acpi_irq_handled = 0; - acpi_irq_not_handled = 0; - goto end; - } - - /* show the event status for both GPEs and Fixed Events */ - result = get_status(index, &status, &handle); - if (result) - goto end; - - if (!(status & ACPI_EVENT_FLAG_HANDLE)) { - printk(KERN_WARNING PREFIX - "Can not change Invalid GPE/Fixed Event status\n"); - return -EINVAL; - } - - if (index < num_gpes) { - if (!strcmp(buf, "disable\n") && - (status & ACPI_EVENT_FLAG_ENABLED)) - result = acpi_disable_gpe(handle, index); - else if (!strcmp(buf, "enable\n") && - !(status & ACPI_EVENT_FLAG_ENABLED)) - result = acpi_enable_gpe(handle, index); - else if (!strcmp(buf, "clear\n") && - (status & ACPI_EVENT_FLAG_SET)) - result = acpi_clear_gpe(handle, index); - else - all_counters[index].count = strtoul(buf, NULL, 0); - } else if (index < num_gpes + ACPI_NUM_FIXED_EVENTS) { - int event = index - num_gpes; - if (!strcmp(buf, "disable\n") && - (status & ACPI_EVENT_FLAG_ENABLED)) - result = acpi_disable_event(event, ACPI_NOT_ISR); - else if (!strcmp(buf, "enable\n") && - !(status & ACPI_EVENT_FLAG_ENABLED)) - result = acpi_enable_event(event, ACPI_NOT_ISR); - else if (!strcmp(buf, "clear\n") && - (status & ACPI_EVENT_FLAG_SET)) - result = acpi_clear_event(event); - else - all_counters[index].count = strtoul(buf, NULL, 0); - } else - all_counters[index].count = strtoul(buf, NULL, 0); - - if (ACPI_FAILURE(result)) - result = -EINVAL; -end: - return result ? result : size; -} - -void acpi_irq_stats_init(void) -{ - int i; - - if (all_counters) - return; - - num_gpes = acpi_current_gpe_count; - num_counters = num_gpes + ACPI_NUM_FIXED_EVENTS + NUM_COUNTERS_EXTRA; - - all_attrs = kzalloc(sizeof(struct attribute *) * (num_counters + 1), - GFP_KERNEL); - if (all_attrs == NULL) - return; - - all_counters = kzalloc(sizeof(struct event_counter) * (num_counters), - GFP_KERNEL); - if (all_counters == NULL) - goto fail; - - counter_attrs = kzalloc(sizeof(struct kobj_attribute) * (num_counters), - GFP_KERNEL); - if (counter_attrs == NULL) - goto fail; - - for (i = 0; i < num_counters; ++i) { - char buffer[12]; - char *name; - - if (i < num_gpes) - sprintf(buffer, "gpe%02X", i); - else if (i == num_gpes + ACPI_EVENT_PMTIMER) - sprintf(buffer, "ff_pmtimer"); - else if (i == num_gpes + ACPI_EVENT_GLOBAL) - sprintf(buffer, "ff_gbl_lock"); - else if (i == num_gpes + ACPI_EVENT_POWER_BUTTON) - sprintf(buffer, "ff_pwr_btn"); - else if (i == num_gpes + ACPI_EVENT_SLEEP_BUTTON) - sprintf(buffer, "ff_slp_btn"); - else if (i == num_gpes + ACPI_EVENT_RTC) - sprintf(buffer, "ff_rt_clk"); - else if (i == num_gpes + ACPI_NUM_FIXED_EVENTS + COUNT_GPE) - sprintf(buffer, "gpe_all"); - else if (i == num_gpes + ACPI_NUM_FIXED_EVENTS + COUNT_SCI) - sprintf(buffer, "sci"); - else if (i == num_gpes + ACPI_NUM_FIXED_EVENTS + COUNT_SCI_NOT) - sprintf(buffer, "sci_not"); - else if (i == num_gpes + ACPI_NUM_FIXED_EVENTS + COUNT_ERROR) - sprintf(buffer, "error"); - else - sprintf(buffer, "bug%02X", i); - - name = kzalloc(strlen(buffer) + 1, GFP_KERNEL); - if (name == NULL) - goto fail; - strncpy(name, buffer, strlen(buffer) + 1); - - sysfs_attr_init(&counter_attrs[i].attr); - counter_attrs[i].attr.name = name; - counter_attrs[i].attr.mode = 0644; - counter_attrs[i].show = counter_show; - counter_attrs[i].store = counter_set; - - all_attrs[i] = &counter_attrs[i].attr; - } - - interrupt_stats_attr_group.attrs = all_attrs; - if (!sysfs_create_group(acpi_kobj, &interrupt_stats_attr_group)) - return; - -fail: - delete_gpe_attr_array(); - return; -} - -static void __exit interrupt_stats_exit(void) -{ - sysfs_remove_group(acpi_kobj, &interrupt_stats_attr_group); - - delete_gpe_attr_array(); - - return; -} - /* -------------------------------------------------------------------------- FS Interface (/proc) -------------------------------------------------------------------------- */ @@ -628,10 +165,6 @@ int __init acpi_system_init(void) int result; result = acpi_system_procfs_init(); - if (result) - return result; - - result = acpi_system_sysfs_init(); return result; } -- cgit v1.2.1 From 47f5c892b06797336a34f1096b4b617623aa1960 Mon Sep 17 00:00:00 2001 From: Zhang Rui Date: Thu, 15 Jul 2010 10:46:33 +0800 Subject: ACPI: remove deprecated ACPI procfs I/F Rmove deprecated ACPI procfs I/F, including /proc/acpi/debug_layer /proc/acpi/debug_level /proc/acpi/info /proc/acpi/dsdt /proc/acpi/fadt /proc/acpi/sleep because the sysfs I/F is already available and has been working well for years. Signed-off-by: Zhang Rui Signed-off-by: Len Brown --- drivers/acpi/Kconfig | 6 -- drivers/acpi/Makefile | 3 +- drivers/acpi/bus.c | 2 - drivers/acpi/debug.c | 227 ------------------------------------------------ drivers/acpi/internal.h | 7 -- drivers/acpi/proc.c | 70 --------------- drivers/acpi/system.c | 170 ------------------------------------ 7 files changed, 1 insertion(+), 484 deletions(-) delete mode 100644 drivers/acpi/debug.c delete mode 100644 drivers/acpi/system.c (limited to 'drivers/acpi') diff --git a/drivers/acpi/Kconfig b/drivers/acpi/Kconfig index 746411518802..d77d9c27c846 100644 --- a/drivers/acpi/Kconfig +++ b/drivers/acpi/Kconfig @@ -54,12 +54,6 @@ config ACPI_PROCFS they have been replaced by functions in /sys. The deprecated files (and their replacements) include: - /proc/acpi/sleep (/sys/power/state) - /proc/acpi/info (/sys/module/acpi/parameters/acpica_version) - /proc/acpi/dsdt (/sys/firmware/acpi/tables/DSDT) - /proc/acpi/fadt (/sys/firmware/acpi/tables/FACP) - /proc/acpi/debug_layer (/sys/module/acpi/parameters/debug_layer) - /proc/acpi/debug_level (/sys/module/acpi/parameters/debug_level) /proc/acpi/processor/*/power (/sys/devices/system/cpu/*/cpuidle/*) /proc/acpi/processor/*/performance (/sys/devices/system/cpu/*/ cpufreq/*) diff --git a/drivers/acpi/Makefile b/drivers/acpi/Makefile index 03a81a844d23..3f0449622e69 100644 --- a/drivers/acpi/Makefile +++ b/drivers/acpi/Makefile @@ -37,9 +37,8 @@ acpi-y += ec.o acpi-$(CONFIG_ACPI_DOCK) += dock.o acpi-y += pci_root.o pci_link.o pci_irq.o pci_bind.o acpi-y += power.o -acpi-y += system.o event.o +acpi-y += event.o acpi-y += sysfs.o -acpi-$(CONFIG_ACPI_DEBUG) += debug.o acpi-$(CONFIG_DEBUG_FS) += debugfs.o acpi-$(CONFIG_ACPI_NUMA) += numa.o acpi-$(CONFIG_ACPI_PROCFS_POWER) += cm_sbs.o diff --git a/drivers/acpi/bus.c b/drivers/acpi/bus.c index bd9708b0f3f3..5c221ab535d5 100644 --- a/drivers/acpi/bus.c +++ b/drivers/acpi/bus.c @@ -1034,8 +1034,6 @@ static int __init acpi_init(void) acpi_scan_init(); acpi_ec_init(); acpi_power_init(); - acpi_system_init(); - acpi_debug_init(); acpi_sysfs_init(); acpi_debugfs_init(); acpi_sleep_proc_init(); diff --git a/drivers/acpi/debug.c b/drivers/acpi/debug.c deleted file mode 100644 index f82240dbbba3..000000000000 --- a/drivers/acpi/debug.c +++ /dev/null @@ -1,227 +0,0 @@ -/* - * debug.c - ACPI debug interface to userspace. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#define _COMPONENT ACPI_SYSTEM_COMPONENT -ACPI_MODULE_NAME("debug"); - -struct acpi_dlayer { - const char *name; - unsigned long value; -}; -struct acpi_dlevel { - const char *name; - unsigned long value; -}; -#define ACPI_DEBUG_INIT(v) { .name = #v, .value = v } - -static const struct acpi_dlayer acpi_debug_layers[] = { - ACPI_DEBUG_INIT(ACPI_UTILITIES), - ACPI_DEBUG_INIT(ACPI_HARDWARE), - ACPI_DEBUG_INIT(ACPI_EVENTS), - ACPI_DEBUG_INIT(ACPI_TABLES), - ACPI_DEBUG_INIT(ACPI_NAMESPACE), - ACPI_DEBUG_INIT(ACPI_PARSER), - ACPI_DEBUG_INIT(ACPI_DISPATCHER), - ACPI_DEBUG_INIT(ACPI_EXECUTER), - ACPI_DEBUG_INIT(ACPI_RESOURCES), - ACPI_DEBUG_INIT(ACPI_CA_DEBUGGER), - ACPI_DEBUG_INIT(ACPI_OS_SERVICES), - 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[] = { - ACPI_DEBUG_INIT(ACPI_LV_INIT), - ACPI_DEBUG_INIT(ACPI_LV_DEBUG_OBJECT), - ACPI_DEBUG_INIT(ACPI_LV_INFO), - - ACPI_DEBUG_INIT(ACPI_LV_INIT_NAMES), - ACPI_DEBUG_INIT(ACPI_LV_PARSE), - ACPI_DEBUG_INIT(ACPI_LV_LOAD), - ACPI_DEBUG_INIT(ACPI_LV_DISPATCH), - ACPI_DEBUG_INIT(ACPI_LV_EXEC), - ACPI_DEBUG_INIT(ACPI_LV_NAMES), - ACPI_DEBUG_INIT(ACPI_LV_OPREGION), - ACPI_DEBUG_INIT(ACPI_LV_BFIELD), - ACPI_DEBUG_INIT(ACPI_LV_TABLES), - ACPI_DEBUG_INIT(ACPI_LV_VALUES), - ACPI_DEBUG_INIT(ACPI_LV_OBJECTS), - ACPI_DEBUG_INIT(ACPI_LV_RESOURCES), - ACPI_DEBUG_INIT(ACPI_LV_USER_REQUESTS), - ACPI_DEBUG_INIT(ACPI_LV_PACKAGE), - - ACPI_DEBUG_INIT(ACPI_LV_ALLOCATIONS), - ACPI_DEBUG_INIT(ACPI_LV_FUNCTIONS), - ACPI_DEBUG_INIT(ACPI_LV_OPTIMIZATIONS), - - ACPI_DEBUG_INIT(ACPI_LV_MUTEX), - ACPI_DEBUG_INIT(ACPI_LV_THREADS), - ACPI_DEBUG_INIT(ACPI_LV_IO), - ACPI_DEBUG_INIT(ACPI_LV_INTERRUPTS), - - ACPI_DEBUG_INIT(ACPI_LV_AML_DISASSEMBLE), - ACPI_DEBUG_INIT(ACPI_LV_VERBOSE_INFO), - ACPI_DEBUG_INIT(ACPI_LV_FULL_TABLES), - ACPI_DEBUG_INIT(ACPI_LV_EVENTS), -}; - -/* -------------------------------------------------------------------------- - FS Interface (/proc) - -------------------------------------------------------------------------- */ -#ifdef CONFIG_ACPI_PROCFS -#define ACPI_SYSTEM_FILE_DEBUG_LAYER "debug_layer" -#define ACPI_SYSTEM_FILE_DEBUG_LEVEL "debug_level" - -static int acpi_system_debug_proc_show(struct seq_file *m, void *v) -{ - unsigned int i; - - seq_printf(m, "%-25s\tHex SET\n", "Description"); - - switch ((unsigned long)m->private) { - case 0: - for (i = 0; i < ARRAY_SIZE(acpi_debug_layers); i++) { - seq_printf(m, "%-25s\t0x%08lX [%c]\n", - acpi_debug_layers[i].name, - acpi_debug_layers[i].value, - (acpi_dbg_layer & acpi_debug_layers[i]. - value) ? '*' : ' '); - } - seq_printf(m, "%-25s\t0x%08X [%c]\n", "ACPI_ALL_DRIVERS", - ACPI_ALL_DRIVERS, - (acpi_dbg_layer & ACPI_ALL_DRIVERS) == - ACPI_ALL_DRIVERS ? '*' : (acpi_dbg_layer & - ACPI_ALL_DRIVERS) == - 0 ? ' ' : '-'); - seq_printf(m, - "--\ndebug_layer = 0x%08X (* = enabled, - = partial)\n", - acpi_dbg_layer); - break; - case 1: - for (i = 0; i < ARRAY_SIZE(acpi_debug_levels); i++) { - seq_printf(m, "%-25s\t0x%08lX [%c]\n", - acpi_debug_levels[i].name, - acpi_debug_levels[i].value, - (acpi_dbg_level & acpi_debug_levels[i]. - value) ? '*' : ' '); - } - seq_printf(m, "--\ndebug_level = 0x%08X (* = enabled)\n", - acpi_dbg_level); - break; - } - return 0; -} - -static int acpi_system_debug_proc_open(struct inode *inode, struct file *file) -{ - return single_open(file, acpi_system_debug_proc_show, PDE(inode)->data); -} - -static ssize_t acpi_system_debug_proc_write(struct file *file, - const char __user * buffer, - size_t count, loff_t *pos) -{ - char debug_string[12] = { '\0' }; - - - if (count > sizeof(debug_string) - 1) - return -EINVAL; - - if (copy_from_user(debug_string, buffer, count)) - return -EFAULT; - - debug_string[count] = '\0'; - - switch ((unsigned long)PDE(file->f_path.dentry->d_inode)->data) { - case 0: - acpi_dbg_layer = simple_strtoul(debug_string, NULL, 0); - break; - case 1: - acpi_dbg_level = simple_strtoul(debug_string, NULL, 0); - break; - default: - return -EINVAL; - } - - return count; -} - -static const struct file_operations acpi_system_debug_proc_fops = { - .owner = THIS_MODULE, - .open = acpi_system_debug_proc_open, - .read = seq_read, - .llseek = seq_lseek, - .release = single_release, - .write = acpi_system_debug_proc_write, -}; -#endif - -int __init acpi_procfs_init(void) -{ -#ifdef CONFIG_ACPI_PROCFS - struct proc_dir_entry *entry; - int error = 0; - char *name; - - /* 'debug_layer' [R/W] */ - name = ACPI_SYSTEM_FILE_DEBUG_LAYER; - entry = proc_create_data(name, S_IFREG | S_IRUGO | S_IWUSR, - acpi_root_dir, &acpi_system_debug_proc_fops, - (void *)0); - if (!entry) - goto Error; - - /* 'debug_level' [R/W] */ - name = ACPI_SYSTEM_FILE_DEBUG_LEVEL; - entry = proc_create_data(name, S_IFREG | S_IRUGO | S_IWUSR, - acpi_root_dir, &acpi_system_debug_proc_fops, - (void *)1); - if (!entry) - goto Error; - - Done: - return error; - - Error: - remove_proc_entry(ACPI_SYSTEM_FILE_DEBUG_LEVEL, acpi_root_dir); - remove_proc_entry(ACPI_SYSTEM_FILE_DEBUG_LAYER, acpi_root_dir); - error = -ENODEV; - goto Done; -#else - return 0; -#endif -} - -int __init acpi_debug_init(void) -{ - acpi_procfs_init(); - return 0; -} diff --git a/drivers/acpi/internal.h b/drivers/acpi/internal.h index eed823418559..e37964439d66 100644 --- a/drivers/acpi/internal.h +++ b/drivers/acpi/internal.h @@ -22,15 +22,8 @@ int init_acpi_device_notify(void); int acpi_scan_init(void); -int acpi_system_init(void); int acpi_sysfs_init(void); -#ifdef CONFIG_ACPI_DEBUG -int acpi_debug_init(void); -#else -static inline int acpi_debug_init(void) { return 0; } -#endif - #ifdef CONFIG_DEBUG_FS int acpi_debugfs_init(void); #else diff --git a/drivers/acpi/proc.c b/drivers/acpi/proc.c index 1ac678d2c51c..afad67769db6 100644 --- a/drivers/acpi/proc.c +++ b/drivers/acpi/proc.c @@ -17,64 +17,11 @@ /* * this file provides support for: - * /proc/acpi/sleep * /proc/acpi/alarm * /proc/acpi/wakeup */ ACPI_MODULE_NAME("sleep") -#ifdef CONFIG_ACPI_PROCFS -static int acpi_system_sleep_seq_show(struct seq_file *seq, void *offset) -{ - int i; - - for (i = 0; i <= ACPI_STATE_S5; i++) { - if (sleep_states[i]) { - seq_printf(seq, "S%d ", i); - } - } - - seq_puts(seq, "\n"); - - return 0; -} - -static int acpi_system_sleep_open_fs(struct inode *inode, struct file *file) -{ - return single_open(file, acpi_system_sleep_seq_show, PDE(inode)->data); -} - -static ssize_t -acpi_system_write_sleep(struct file *file, - const char __user * buffer, size_t count, loff_t * ppos) -{ - char str[12]; - u32 state = 0; - int error = 0; - - if (count > sizeof(str) - 1) - goto Done; - memset(str, 0, sizeof(str)); - if (copy_from_user(str, buffer, count)) - return -EFAULT; - - /* Check for S4 bios request */ - if (!strcmp(str, "4b")) { - error = acpi_suspend(4); - goto Done; - } - state = simple_strtoul(str, NULL, 0); -#ifdef CONFIG_HIBERNATION - if (state == 4) { - error = hibernate(); - goto Done; - } -#endif - error = acpi_suspend(state); - Done: - return error ? error : count; -} -#endif /* CONFIG_ACPI_PROCFS */ #if defined(CONFIG_RTC_DRV_CMOS) || defined(CONFIG_RTC_DRV_CMOS_MODULE) || !defined(CONFIG_X86) /* use /sys/class/rtc/rtcX/wakealarm instead; it's not ACPI-specific */ @@ -463,17 +410,6 @@ static const struct file_operations acpi_system_wakeup_device_fops = { .release = single_release, }; -#ifdef CONFIG_ACPI_PROCFS -static const struct file_operations acpi_system_sleep_fops = { - .owner = THIS_MODULE, - .open = acpi_system_sleep_open_fs, - .read = seq_read, - .write = acpi_system_write_sleep, - .llseek = seq_lseek, - .release = single_release, -}; -#endif /* CONFIG_ACPI_PROCFS */ - #ifdef HAVE_ACPI_LEGACY_ALARM static const struct file_operations acpi_system_alarm_fops = { .owner = THIS_MODULE, @@ -495,12 +431,6 @@ static u32 rtc_handler(void *context) int __init acpi_sleep_proc_init(void) { -#ifdef CONFIG_ACPI_PROCFS - /* 'sleep' [R/W] */ - proc_create("sleep", S_IFREG | S_IRUGO | S_IWUSR, - acpi_root_dir, &acpi_system_sleep_fops); -#endif /* CONFIG_ACPI_PROCFS */ - #ifdef HAVE_ACPI_LEGACY_ALARM /* 'alarm' [R/W] */ proc_create("alarm", S_IFREG | S_IRUGO | S_IWUSR, diff --git a/drivers/acpi/system.c b/drivers/acpi/system.c deleted file mode 100644 index d70481f32c89..000000000000 --- a/drivers/acpi/system.c +++ /dev/null @@ -1,170 +0,0 @@ -/* - * acpi_system.c - ACPI System Driver ($Revision: 63 $) - * - * Copyright (C) 2001, 2002 Andy Grover - * Copyright (C) 2001, 2002 Paul Diefenbaugh - * - * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or (at - * your option) any later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. - * - * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - */ - -#include -#include -#include -#include -#include -#include - -#include - -#define PREFIX "ACPI: " - -#define _COMPONENT ACPI_SYSTEM_COMPONENT -ACPI_MODULE_NAME("system"); - -#define ACPI_SYSTEM_CLASS "system" -#define ACPI_SYSTEM_DEVICE_NAME "System" - -/* -------------------------------------------------------------------------- - FS Interface (/proc) - -------------------------------------------------------------------------- */ -#ifdef CONFIG_ACPI_PROCFS -#define ACPI_SYSTEM_FILE_INFO "info" -#define ACPI_SYSTEM_FILE_EVENT "event" -#define ACPI_SYSTEM_FILE_DSDT "dsdt" -#define ACPI_SYSTEM_FILE_FADT "fadt" - -static int acpi_system_read_info(struct seq_file *seq, void *offset) -{ - - seq_printf(seq, "version: %x\n", ACPI_CA_VERSION); - return 0; -} - -static int acpi_system_info_open_fs(struct inode *inode, struct file *file) -{ - return single_open(file, acpi_system_read_info, PDE(inode)->data); -} - -static const struct file_operations acpi_system_info_ops = { - .owner = THIS_MODULE, - .open = acpi_system_info_open_fs, - .read = seq_read, - .llseek = seq_lseek, - .release = single_release, -}; - -static ssize_t acpi_system_read_dsdt(struct file *, char __user *, size_t, - loff_t *); - -static const struct file_operations acpi_system_dsdt_ops = { - .owner = THIS_MODULE, - .read = acpi_system_read_dsdt, -}; - -static ssize_t -acpi_system_read_dsdt(struct file *file, - char __user * buffer, size_t count, loff_t * ppos) -{ - acpi_status status = AE_OK; - struct acpi_table_header *dsdt = NULL; - ssize_t res; - - status = acpi_get_table(ACPI_SIG_DSDT, 1, &dsdt); - if (ACPI_FAILURE(status)) - return -ENODEV; - - res = simple_read_from_buffer(buffer, count, ppos, dsdt, dsdt->length); - - return res; -} - -static ssize_t acpi_system_read_fadt(struct file *, char __user *, size_t, - loff_t *); - -static const struct file_operations acpi_system_fadt_ops = { - .owner = THIS_MODULE, - .read = acpi_system_read_fadt, -}; - -static ssize_t -acpi_system_read_fadt(struct file *file, - char __user * buffer, size_t count, loff_t * ppos) -{ - acpi_status status = AE_OK; - struct acpi_table_header *fadt = NULL; - ssize_t res; - - status = acpi_get_table(ACPI_SIG_FADT, 1, &fadt); - if (ACPI_FAILURE(status)) - return -ENODEV; - - res = simple_read_from_buffer(buffer, count, ppos, fadt, fadt->length); - - return res; -} - -static int acpi_system_procfs_init(void) -{ - struct proc_dir_entry *entry; - int error = 0; - - /* 'info' [R] */ - entry = proc_create(ACPI_SYSTEM_FILE_INFO, S_IRUGO, acpi_root_dir, - &acpi_system_info_ops); - if (!entry) - goto Error; - - /* 'dsdt' [R] */ - entry = proc_create(ACPI_SYSTEM_FILE_DSDT, S_IRUSR, acpi_root_dir, - &acpi_system_dsdt_ops); - if (!entry) - goto Error; - - /* 'fadt' [R] */ - entry = proc_create(ACPI_SYSTEM_FILE_FADT, S_IRUSR, acpi_root_dir, - &acpi_system_fadt_ops); - if (!entry) - goto Error; - - Done: - return error; - - Error: - remove_proc_entry(ACPI_SYSTEM_FILE_FADT, acpi_root_dir); - remove_proc_entry(ACPI_SYSTEM_FILE_DSDT, acpi_root_dir); - remove_proc_entry(ACPI_SYSTEM_FILE_INFO, acpi_root_dir); - - error = -EFAULT; - goto Done; -} -#else -static int acpi_system_procfs_init(void) -{ - return 0; -} -#endif - -int __init acpi_system_init(void) -{ - int result; - - result = acpi_system_procfs_init(); - - return result; -} -- cgit v1.2.1 From 06af7eb043c02822072cea862fce1b7c74115e8f Mon Sep 17 00:00:00 2001 From: Zhang Rui Date: Thu, 15 Jul 2010 10:46:38 +0800 Subject: ACPI power_resource: remove unused procfs I/F Remove unused ACPI power procfs I/F. Signed-off-by: Zhang Rui Signed-off-by: Len Brown --- drivers/acpi/power.c | 128 +-------------------------------------------------- 1 file changed, 1 insertion(+), 127 deletions(-) (limited to 'drivers/acpi') diff --git a/drivers/acpi/power.c b/drivers/acpi/power.c index f74d3b31e5c9..4fe5018fd6ab 100644 --- a/drivers/acpi/power.c +++ b/drivers/acpi/power.c @@ -40,8 +40,6 @@ #include #include #include -#include -#include #include #include #include "sleep.h" @@ -64,7 +62,6 @@ module_param_named(power_nocheck, acpi_power_nocheck, bool, 000); static int acpi_power_add(struct acpi_device *device); static int acpi_power_remove(struct acpi_device *device, int type); static int acpi_power_resume(struct acpi_device *device); -static int acpi_power_open_fs(struct inode *inode, struct file *file); static const struct acpi_device_id power_device_ids[] = { {ACPI_POWER_HID, 0}, @@ -99,14 +96,6 @@ struct acpi_power_resource { static struct list_head acpi_power_resource_list; -static const struct file_operations acpi_power_fops = { - .owner = THIS_MODULE, - .open = acpi_power_open_fs, - .read = seq_read, - .llseek = seq_lseek, - .release = single_release, -}; - /* -------------------------------------------------------------------------- Power Resource Management -------------------------------------------------------------------------- */ @@ -541,102 +530,6 @@ int acpi_power_transition(struct acpi_device *device, int state) return result; } -/* -------------------------------------------------------------------------- - FS Interface (/proc) - -------------------------------------------------------------------------- */ - -static struct proc_dir_entry *acpi_power_dir; - -static int acpi_power_seq_show(struct seq_file *seq, void *offset) -{ - int count = 0; - int result = 0, state; - struct acpi_power_resource *resource = NULL; - struct list_head *node, *next; - struct acpi_power_reference *ref; - - - resource = seq->private; - - if (!resource) - goto end; - - result = acpi_power_get_state(resource->device->handle, &state); - if (result) - goto end; - - seq_puts(seq, "state: "); - switch (state) { - case ACPI_POWER_RESOURCE_STATE_ON: - seq_puts(seq, "on\n"); - break; - case ACPI_POWER_RESOURCE_STATE_OFF: - seq_puts(seq, "off\n"); - break; - default: - seq_puts(seq, "unknown\n"); - break; - } - - mutex_lock(&resource->resource_lock); - list_for_each_safe(node, next, &resource->reference) { - ref = container_of(node, struct acpi_power_reference, node); - count++; - } - mutex_unlock(&resource->resource_lock); - - seq_printf(seq, "system level: S%d\n" - "order: %d\n" - "reference count: %d\n", - resource->system_level, - resource->order, count); - - end: - return 0; -} - -static int acpi_power_open_fs(struct inode *inode, struct file *file) -{ - return single_open(file, acpi_power_seq_show, PDE(inode)->data); -} - -static int acpi_power_add_fs(struct acpi_device *device) -{ - struct proc_dir_entry *entry = NULL; - - - if (!device) - return -EINVAL; - - if (!acpi_device_dir(device)) { - acpi_device_dir(device) = proc_mkdir(acpi_device_bid(device), - acpi_power_dir); - if (!acpi_device_dir(device)) - return -ENODEV; - } - - /* 'status' [R] */ - entry = proc_create_data(ACPI_POWER_FILE_STATUS, - S_IRUGO, acpi_device_dir(device), - &acpi_power_fops, acpi_driver_data(device)); - if (!entry) - return -EIO; - return 0; -} - -static int acpi_power_remove_fs(struct acpi_device *device) -{ - - if (acpi_device_dir(device)) { - remove_proc_entry(ACPI_POWER_FILE_STATUS, - acpi_device_dir(device)); - remove_proc_entry(acpi_device_bid(device), acpi_power_dir); - acpi_device_dir(device) = NULL; - } - - return 0; -} - /* -------------------------------------------------------------------------- Driver Interface -------------------------------------------------------------------------- */ @@ -690,10 +583,6 @@ static int acpi_power_add(struct acpi_device *device) break; } - result = acpi_power_add_fs(device); - if (result) - goto end; - printk(KERN_INFO PREFIX "%s [%s] (%s)\n", acpi_device_name(device), acpi_device_bid(device), state ? "on" : "off"); @@ -715,8 +604,6 @@ static int acpi_power_remove(struct acpi_device *device, int type) resource = acpi_driver_data(device); - acpi_power_remove_fs(device); - mutex_lock(&resource->resource_lock); list_for_each_safe(node, next, &resource->reference) { struct acpi_power_reference *ref = container_of(node, struct acpi_power_reference, node); @@ -760,19 +647,6 @@ static int acpi_power_resume(struct acpi_device *device) int __init acpi_power_init(void) { - int result = 0; - INIT_LIST_HEAD(&acpi_power_resource_list); - - acpi_power_dir = proc_mkdir(ACPI_POWER_CLASS, acpi_root_dir); - if (!acpi_power_dir) - return -ENODEV; - - result = acpi_bus_register_driver(&acpi_power_driver); - if (result < 0) { - remove_proc_entry(ACPI_POWER_CLASS, acpi_root_dir); - return -ENODEV; - } - - return 0; + return acpi_bus_register_driver(&acpi_power_driver); } -- cgit v1.2.1 From d09fe55510257f1acd21ea80a9bdd7c72b5895b3 Mon Sep 17 00:00:00 2001 From: Zhang Rui Date: Thu, 15 Jul 2010 10:46:41 +0800 Subject: ACPI processor: remove deprecated ACPI procfs I/F Remove deprecated ACPI processor procfs I/F, including: /proc/acpi/processor/CPUX/power /proc/acpi/processor/CPUX/limit /proc/acpi/processor/CPUX/info /proc/acpi/processor/CPUX/throttling still exists, as we don't have sysfs I/F available for now. Signed-off-by: Zhang Rui Signed-off-by: Len Brown --- drivers/acpi/Kconfig | 3 -- drivers/acpi/processor_driver.c | 85 ------------------------------- drivers/acpi/processor_idle.c | 99 ------------------------------------- drivers/acpi/processor_thermal.c | 83 ------------------------------- drivers/acpi/processor_throttling.c | 2 - 5 files changed, 272 deletions(-) (limited to 'drivers/acpi') diff --git a/drivers/acpi/Kconfig b/drivers/acpi/Kconfig index d77d9c27c846..6f66a937ba20 100644 --- a/drivers/acpi/Kconfig +++ b/drivers/acpi/Kconfig @@ -54,9 +54,6 @@ config ACPI_PROCFS they have been replaced by functions in /sys. The deprecated files (and their replacements) include: - /proc/acpi/processor/*/power (/sys/devices/system/cpu/*/cpuidle/*) - /proc/acpi/processor/*/performance (/sys/devices/system/cpu/*/ - cpufreq/*) /proc/acpi/processor/*/throttling (/sys/class/thermal/ cooling_device*/*) This option has no effect on /proc/acpi/ files diff --git a/drivers/acpi/processor_driver.c b/drivers/acpi/processor_driver.c index 38ea0cc6dc49..156021892389 100644 --- a/drivers/acpi/processor_driver.c +++ b/drivers/acpi/processor_driver.c @@ -83,9 +83,6 @@ MODULE_LICENSE("GPL"); static int acpi_processor_add(struct acpi_device *device); static int acpi_processor_remove(struct acpi_device *device, int type); -#ifdef CONFIG_ACPI_PROCFS -static int acpi_processor_info_open_fs(struct inode *inode, struct file *file); -#endif static void acpi_processor_notify(struct acpi_device *device, u32 event); static acpi_status acpi_processor_hotadd_init(acpi_handle handle, int *p_cpu); static int acpi_processor_handle_eject(struct acpi_processor *pr); @@ -113,15 +110,6 @@ static struct acpi_driver acpi_processor_driver = { #define INSTALL_NOTIFY_HANDLER 1 #define UNINSTALL_NOTIFY_HANDLER 2 -#ifdef CONFIG_ACPI_PROCFS -static const struct file_operations acpi_processor_info_fops = { - .owner = THIS_MODULE, - .open = acpi_processor_info_open_fs, - .read = seq_read, - .llseek = seq_lseek, - .release = single_release, -}; -#endif DEFINE_PER_CPU(struct acpi_processor *, processors); EXPORT_PER_CPU_SYMBOL(processors); @@ -256,44 +244,8 @@ static int acpi_processor_errata(struct acpi_processor *pr) return result; } -/* -------------------------------------------------------------------------- - FS Interface (/proc) - -------------------------------------------------------------------------- */ - -#ifdef CONFIG_ACPI_PROCFS static struct proc_dir_entry *acpi_processor_dir = NULL; -static int acpi_processor_info_seq_show(struct seq_file *seq, void *offset) -{ - struct acpi_processor *pr = seq->private; - - - if (!pr) - goto end; - - seq_printf(seq, "processor id: %d\n" - "acpi id: %d\n" - "bus mastering control: %s\n" - "power management: %s\n" - "throttling control: %s\n" - "limit interface: %s\n", - pr->id, - pr->acpi_id, - pr->flags.bm_control ? "yes" : "no", - pr->flags.power ? "yes" : "no", - pr->flags.throttling ? "yes" : "no", - pr->flags.limit ? "yes" : "no"); - - end: - return 0; -} - -static int acpi_processor_info_open_fs(struct inode *inode, struct file *file) -{ - return single_open(file, acpi_processor_info_seq_show, - PDE(inode)->data); -} - static int __cpuinit acpi_processor_add_fs(struct acpi_device *device) { struct proc_dir_entry *entry = NULL; @@ -306,14 +258,6 @@ static int __cpuinit acpi_processor_add_fs(struct acpi_device *device) return -ENODEV; } - /* 'info' [R] */ - entry = proc_create_data(ACPI_PROCESSOR_FILE_INFO, - S_IRUGO, acpi_device_dir(device), - &acpi_processor_info_fops, - acpi_driver_data(device)); - if (!entry) - return -EIO; - /* 'throttling' [R/W] */ entry = proc_create_data(ACPI_PROCESSOR_FILE_THROTTLING, S_IFREG | S_IRUGO | S_IWUSR, @@ -322,43 +266,20 @@ static int __cpuinit acpi_processor_add_fs(struct acpi_device *device) acpi_driver_data(device)); if (!entry) return -EIO; - - /* 'limit' [R/W] */ - entry = proc_create_data(ACPI_PROCESSOR_FILE_LIMIT, - S_IFREG | S_IRUGO | S_IWUSR, - acpi_device_dir(device), - &acpi_processor_limit_fops, - acpi_driver_data(device)); - if (!entry) - return -EIO; return 0; } static int acpi_processor_remove_fs(struct acpi_device *device) { if (acpi_device_dir(device)) { - remove_proc_entry(ACPI_PROCESSOR_FILE_INFO, - acpi_device_dir(device)); remove_proc_entry(ACPI_PROCESSOR_FILE_THROTTLING, acpi_device_dir(device)); - remove_proc_entry(ACPI_PROCESSOR_FILE_LIMIT, - acpi_device_dir(device)); remove_proc_entry(acpi_device_bid(device), acpi_processor_dir); acpi_device_dir(device) = NULL; } return 0; } -#else -static inline int acpi_processor_add_fs(struct acpi_device *device) -{ - return 0; -} -static inline int acpi_processor_remove_fs(struct acpi_device *device) -{ - return 0; -} -#endif /* -------------------------------------------------------------------------- Driver Interface @@ -921,11 +842,9 @@ static int __init acpi_processor_init(void) memset(&errata, 0, sizeof(errata)); -#ifdef CONFIG_ACPI_PROCFS acpi_processor_dir = proc_mkdir(ACPI_PROCESSOR_CLASS, acpi_root_dir); if (!acpi_processor_dir) return -ENOMEM; -#endif if (!cpuidle_register_driver(&acpi_idle_driver)) { printk(KERN_DEBUG "ACPI: %s registered with cpuidle\n", @@ -952,9 +871,7 @@ static int __init acpi_processor_init(void) out_cpuidle: cpuidle_unregister_driver(&acpi_idle_driver); -#ifdef CONFIG_ACPI_PROCFS remove_proc_entry(ACPI_PROCESSOR_CLASS, acpi_root_dir); -#endif return result; } @@ -974,9 +891,7 @@ static void __exit acpi_processor_exit(void) cpuidle_unregister_driver(&acpi_idle_driver); -#ifdef CONFIG_ACPI_PROCFS remove_proc_entry(ACPI_PROCESSOR_CLASS, acpi_root_dir); -#endif return; } diff --git a/drivers/acpi/processor_idle.c b/drivers/acpi/processor_idle.c index e9a8026d39f0..5cbc0cb73e2c 100644 --- a/drivers/acpi/processor_idle.c +++ b/drivers/acpi/processor_idle.c @@ -33,8 +33,6 @@ #include #include #include -#include -#include #include #include #include @@ -82,13 +80,6 @@ module_param(bm_check_disable, uint, 0000); static unsigned int latency_factor __read_mostly = 2; module_param(latency_factor, uint, 0644); -#ifdef CONFIG_ACPI_PROCFS -static u64 us_to_pm_timer_ticks(s64 t) -{ - return div64_u64(t * PM_TIMER_FREQUENCY, 1000000); -} -#endif - /* * IBM ThinkPad R40e crashes mysteriously when going into C2 or C3. * For now disable this. Probably a bug somewhere else. @@ -689,78 +680,6 @@ static int acpi_processor_get_power_info(struct acpi_processor *pr) return 0; } -#ifdef CONFIG_ACPI_PROCFS -static int acpi_processor_power_seq_show(struct seq_file *seq, void *offset) -{ - struct acpi_processor *pr = seq->private; - unsigned int i; - - - if (!pr) - goto end; - - seq_printf(seq, "active state: C%zd\n" - "max_cstate: C%d\n" - "maximum allowed latency: %d usec\n", - pr->power.state ? pr->power.state - pr->power.states : 0, - max_cstate, pm_qos_request(PM_QOS_CPU_DMA_LATENCY)); - - seq_puts(seq, "states:\n"); - - for (i = 1; i <= pr->power.count; i++) { - seq_printf(seq, " %cC%d: ", - (&pr->power.states[i] == - pr->power.state ? '*' : ' '), i); - - if (!pr->power.states[i].valid) { - seq_puts(seq, "\n"); - continue; - } - - switch (pr->power.states[i].type) { - case ACPI_STATE_C1: - seq_printf(seq, "type[C1] "); - break; - case ACPI_STATE_C2: - seq_printf(seq, "type[C2] "); - break; - case ACPI_STATE_C3: - seq_printf(seq, "type[C3] "); - break; - default: - seq_printf(seq, "type[--] "); - break; - } - - seq_puts(seq, "promotion[--] "); - - seq_puts(seq, "demotion[--] "); - - seq_printf(seq, "latency[%03d] usage[%08d] duration[%020Lu]\n", - pr->power.states[i].latency, - pr->power.states[i].usage, - us_to_pm_timer_ticks(pr->power.states[i].time)); - } - - end: - return 0; -} - -static int acpi_processor_power_open_fs(struct inode *inode, struct file *file) -{ - return single_open(file, acpi_processor_power_seq_show, - PDE(inode)->data); -} - -static const struct file_operations acpi_processor_power_fops = { - .owner = THIS_MODULE, - .open = acpi_processor_power_open_fs, - .read = seq_read, - .llseek = seq_lseek, - .release = single_release, -}; -#endif - /** * acpi_idle_bm_check - checks if bus master activity was detected */ @@ -1172,9 +1091,6 @@ int __cpuinit acpi_processor_power_init(struct acpi_processor *pr, { acpi_status status = 0; static int first_run; -#ifdef CONFIG_ACPI_PROCFS - struct proc_dir_entry *entry = NULL; -#endif if (boot_option_idle_override) return 0; @@ -1223,15 +1139,6 @@ int __cpuinit acpi_processor_power_init(struct acpi_processor *pr, if (cpuidle_register_device(&pr->power.dev)) return -EIO; } -#ifdef CONFIG_ACPI_PROCFS - /* 'power' [R] */ - entry = proc_create_data(ACPI_PROCESSOR_FILE_POWER, - S_IRUGO, acpi_device_dir(device), - &acpi_processor_power_fops, - acpi_driver_data(device)); - if (!entry) - return -EIO; -#endif return 0; } @@ -1244,11 +1151,5 @@ int acpi_processor_power_exit(struct acpi_processor *pr, cpuidle_unregister_device(&pr->power.dev); pr->flags.power_setup_done = 0; -#ifdef CONFIG_ACPI_PROCFS - if (acpi_device_dir(device)) - remove_proc_entry(ACPI_PROCESSOR_FILE_POWER, - acpi_device_dir(device)); -#endif - return 0; } diff --git a/drivers/acpi/processor_thermal.c b/drivers/acpi/processor_thermal.c index 6deafb4aa0da..953b25fb9869 100644 --- a/drivers/acpi/processor_thermal.c +++ b/drivers/acpi/processor_thermal.c @@ -30,8 +30,6 @@ #include #include #include -#include -#include #include #include @@ -438,84 +436,3 @@ struct thermal_cooling_device_ops processor_cooling_ops = { .get_cur_state = processor_get_cur_state, .set_cur_state = processor_set_cur_state, }; - -/* /proc interface */ -#ifdef CONFIG_ACPI_PROCFS -static int acpi_processor_limit_seq_show(struct seq_file *seq, void *offset) -{ - struct acpi_processor *pr = seq->private; - - if (!pr) - goto end; - - if (!pr->flags.limit) { - seq_puts(seq, "\n"); - goto end; - } - - seq_printf(seq, "active limit: P%d:T%d\n" - "user limit: P%d:T%d\n" - "thermal limit: P%d:T%d\n", - pr->limit.state.px, pr->limit.state.tx, - pr->limit.user.px, pr->limit.user.tx, - pr->limit.thermal.px, pr->limit.thermal.tx); - - end: - return 0; -} - -static int acpi_processor_limit_open_fs(struct inode *inode, struct file *file) -{ - return single_open(file, acpi_processor_limit_seq_show, - PDE(inode)->data); -} - -static ssize_t acpi_processor_write_limit(struct file * file, - const char __user * buffer, - size_t count, loff_t * data) -{ - int result = 0; - struct seq_file *m = file->private_data; - struct acpi_processor *pr = m->private; - char limit_string[25] = { '\0' }; - int px = 0; - int tx = 0; - - - if (!pr || (count > sizeof(limit_string) - 1)) { - return -EINVAL; - } - - if (copy_from_user(limit_string, buffer, count)) { - return -EFAULT; - } - - limit_string[count] = '\0'; - - if (sscanf(limit_string, "%d:%d", &px, &tx) != 2) { - printk(KERN_ERR PREFIX "Invalid data format\n"); - return -EINVAL; - } - - if (pr->flags.throttling) { - if ((tx < 0) || (tx > (pr->throttling.state_count - 1))) { - printk(KERN_ERR PREFIX "Invalid tx\n"); - return -EINVAL; - } - pr->limit.user.tx = tx; - } - - result = acpi_processor_apply_limit(pr); - - return count; -} - -const struct file_operations acpi_processor_limit_fops = { - .owner = THIS_MODULE, - .open = acpi_processor_limit_open_fs, - .read = seq_read, - .write = acpi_processor_write_limit, - .llseek = seq_lseek, - .release = single_release, -}; -#endif diff --git a/drivers/acpi/processor_throttling.c b/drivers/acpi/processor_throttling.c index 9ade1a5b32ed..730863855ed5 100644 --- a/drivers/acpi/processor_throttling.c +++ b/drivers/acpi/processor_throttling.c @@ -1215,7 +1215,6 @@ int acpi_processor_get_throttling_info(struct acpi_processor *pr) } /* proc interface */ -#ifdef CONFIG_ACPI_PROCFS static int acpi_processor_throttling_seq_show(struct seq_file *seq, void *offset) { @@ -1323,4 +1322,3 @@ const struct file_operations acpi_processor_throttling_fops = { .llseek = seq_lseek, .release = single_release, }; -#endif -- cgit v1.2.1 From 6e37c658aefa57c472b2dbf1de88dbd3c67cdb52 Mon Sep 17 00:00:00 2001 From: Zhang Rui Date: Thu, 15 Jul 2010 10:46:43 +0800 Subject: ACPI video: make procfs I/F depend on CONFIG_ACPI_PROCFS Mark ACPI video driver procfs I/F deprecated, including: /proc/acpi/video/*/info /proc/acpi/video/*/DOS /proc/acpi/video/*/ROM /proc/acpi/video/*/POST /proc/acpi/video/*/POST_info /proc/acpi/video/*/*/info /proc/acpi/video/*/*/state /proc/acpi/video/*/*/EDID and /proc/acpi/video/*/*/brightness, because 1. we already have the sysfs I/F /sysclass/backlight/ as the replacement of /proc/acpi/video/*/*/brightness. 2. the other procfs I/F is not useful for userspace. Signed-off-by: Zhang Rui Signed-off-by: Len Brown --- drivers/acpi/Kconfig | 1 + drivers/acpi/video.c | 131 +++++++++++++++++++++++++++++++-------------------- 2 files changed, 82 insertions(+), 50 deletions(-) (limited to 'drivers/acpi') diff --git a/drivers/acpi/Kconfig b/drivers/acpi/Kconfig index 6f66a937ba20..354e613f3ca4 100644 --- a/drivers/acpi/Kconfig +++ b/drivers/acpi/Kconfig @@ -56,6 +56,7 @@ config ACPI_PROCFS /proc/acpi/processor/*/throttling (/sys/class/thermal/ cooling_device*/*) + /proc/acpi/video/*/brightness (/sys/class/backlight/) This option has no effect on /proc/acpi/ files and functions which do not yet exist in /sys. diff --git a/drivers/acpi/video.c b/drivers/acpi/video.c index 9865d46f49a8..909ae7bf3b93 100644 --- a/drivers/acpi/video.c +++ b/drivers/acpi/video.c @@ -152,7 +152,9 @@ struct acpi_video_bus { struct acpi_video_bus_flags flags; struct list_head video_device_list; struct mutex device_list_lock; /* protects video_device_list */ +#ifdef CONFIG_ACPI_PROCFS struct proc_dir_entry *dir; +#endif struct input_dev *input; char phys[32]; /* for input device */ struct notifier_block pm_nb; @@ -208,6 +210,7 @@ struct acpi_video_device { struct output_device *output_dev; }; +#ifdef CONFIG_ACPI_PROCFS /* bus */ static int acpi_video_bus_info_open_fs(struct inode *inode, struct file *file); static const struct file_operations acpi_video_bus_info_fops = { @@ -307,6 +310,7 @@ static const struct file_operations acpi_video_device_EDID_fops = { .llseek = seq_lseek, .release = single_release, }; +#endif /* CONFIG_ACPI_PROCFS */ static const char device_decode[][30] = { "motherboard VGA device", @@ -449,16 +453,6 @@ static struct thermal_cooling_device_ops video_cooling_ops = { /* device */ -static int -acpi_video_device_query(struct acpi_video_device *device, unsigned long long *state) -{ - int status; - - status = acpi_evaluate_integer(device->dev->handle, "_DGS", NULL, state); - - return status; -} - static int acpi_video_device_get_state(struct acpi_video_device *device, unsigned long long *state) @@ -698,46 +692,6 @@ acpi_video_device_EDID(struct acpi_video_device *device, /* bus */ -static int -acpi_video_bus_set_POST(struct acpi_video_bus *video, unsigned long option) -{ - int status; - unsigned long long tmp; - union acpi_object arg0 = { ACPI_TYPE_INTEGER }; - struct acpi_object_list args = { 1, &arg0 }; - - - arg0.integer.value = option; - - status = acpi_evaluate_integer(video->device->handle, "_SPD", &args, &tmp); - if (ACPI_SUCCESS(status)) - status = tmp ? (-EINVAL) : (AE_OK); - - return status; -} - -static int -acpi_video_bus_get_POST(struct acpi_video_bus *video, unsigned long long *id) -{ - int status; - - status = acpi_evaluate_integer(video->device->handle, "_GPD", NULL, id); - - return status; -} - -static int -acpi_video_bus_POST_options(struct acpi_video_bus *video, - unsigned long long *options) -{ - int status; - - status = acpi_evaluate_integer(video->device->handle, "_VPO", NULL, options); - *options &= 3; - - return status; -} - /* * Arg: * video : video bus device pointer @@ -1159,6 +1113,7 @@ static int acpi_video_bus_check(struct acpi_video_bus *video) /* -------------------------------------------------------------------------- FS Interface (/proc) -------------------------------------------------------------------------- */ +#ifdef CONFIG_ACPI_PROCFS static struct proc_dir_entry *acpi_video_dir; @@ -1198,6 +1153,18 @@ acpi_video_device_info_open_fs(struct inode *inode, struct file *file) PDE(inode)->data); } +static int +acpi_video_device_query(struct acpi_video_device *device, + unsigned long long *state) +{ + int status; + + status = acpi_evaluate_integer(device->dev->handle, "_DGS", + NULL, state); + + return status; +} + static int acpi_video_device_state_seq_show(struct seq_file *seq, void *offset) { int status; @@ -1492,6 +1459,19 @@ static int acpi_video_bus_ROM_open_fs(struct inode *inode, struct file *file) return single_open(file, acpi_video_bus_ROM_seq_show, PDE(inode)->data); } +static int +acpi_video_bus_POST_options(struct acpi_video_bus *video, + unsigned long long *options) +{ + int status; + + status = acpi_evaluate_integer(video->device->handle, "_VPO", + NULL, options); + *options &= 3; + + return status; +} + static int acpi_video_bus_POST_info_seq_show(struct seq_file *seq, void *offset) { struct acpi_video_bus *video = seq->private; @@ -1530,6 +1510,16 @@ acpi_video_bus_POST_info_open_fs(struct inode *inode, struct file *file) PDE(inode)->data); } +static int +acpi_video_bus_get_POST(struct acpi_video_bus *video, unsigned long long *id) +{ + int status; + + status = acpi_evaluate_integer(video->device->handle, "_GPD", NULL, id); + + return status; +} + static int acpi_video_bus_POST_seq_show(struct seq_file *seq, void *offset) { struct acpi_video_bus *video = seq->private; @@ -1572,6 +1562,25 @@ static int acpi_video_bus_DOS_open_fs(struct inode *inode, struct file *file) return single_open(file, acpi_video_bus_DOS_seq_show, PDE(inode)->data); } +static int +acpi_video_bus_set_POST(struct acpi_video_bus *video, unsigned long option) +{ + int status; + unsigned long long tmp; + union acpi_object arg0 = { ACPI_TYPE_INTEGER }; + struct acpi_object_list args = { 1, &arg0 }; + + + arg0.integer.value = option; + + status = acpi_evaluate_integer(video->device->handle, "_SPD", + &args, &tmp); + if (ACPI_SUCCESS(status)) + status = tmp ? (-EINVAL) : (AE_OK); + + return status; +} + static ssize_t acpi_video_bus_write_POST(struct file *file, const char __user * buffer, @@ -1722,6 +1731,24 @@ static int acpi_video_bus_remove_fs(struct acpi_device *device) return 0; } +#else +static inline int acpi_video_device_add_fs(struct acpi_device *device) +{ + return 0; +} +static inline int acpi_video_device_remove_fs(struct acpi_device *device) +{ + return 0; +} +static inline int acpi_video_bus_add_fs(struct acpi_device *device) +{ + return 0; +} +static inline int acpi_video_bus_remove_fs(struct acpi_device *device) +{ + return 0; +} +#endif /* CONFIG_ACPI_PROCFS */ /* -------------------------------------------------------------------------- Driver Interface @@ -2557,9 +2584,11 @@ int acpi_video_register(void) return 0; } +#ifdef CONFIG_ACPI_PROCFS acpi_video_dir = proc_mkdir(ACPI_VIDEO_CLASS, acpi_root_dir); if (!acpi_video_dir) return -ENODEV; +#endif result = acpi_bus_register_driver(&acpi_video_bus); if (result < 0) { @@ -2588,7 +2617,9 @@ void acpi_video_unregister(void) } acpi_bus_unregister_driver(&acpi_video_bus); +#ifdef CONFIG_ACPI_PROCFS remove_proc_entry(ACPI_VIDEO_CLASS, acpi_root_dir); +#endif register_count = 0; -- cgit v1.2.1 From 43d9f87b79804f2d75d9d8a81c862b179f055a15 Mon Sep 17 00:00:00 2001 From: Zhang Rui Date: Thu, 15 Jul 2010 10:46:44 +0800 Subject: ACPI thermal: make procfs I/F depend on CONFIG_ACPI_PROCFS Mark the ACPI thermal procfs I/F deprecated, because /sys/class/thermal/ is already available and has been working for years w/o any problem. The ACPI thermal procfs I/F will be removed in 2.6.37. Signed-off-by: Zhang Rui Signed-off-by: Len Brown --- drivers/acpi/Kconfig | 1 + drivers/acpi/thermal.c | 86 +++++++++++++++++++++++++++++++------------------- 2 files changed, 54 insertions(+), 33 deletions(-) (limited to 'drivers/acpi') diff --git a/drivers/acpi/Kconfig b/drivers/acpi/Kconfig index 354e613f3ca4..5ed51b3d7522 100644 --- a/drivers/acpi/Kconfig +++ b/drivers/acpi/Kconfig @@ -57,6 +57,7 @@ config ACPI_PROCFS /proc/acpi/processor/*/throttling (/sys/class/thermal/ cooling_device*/*) /proc/acpi/video/*/brightness (/sys/class/backlight/) + /proc/acpi/thermal_zone/*/* (/sys/class/thermal/) This option has no effect on /proc/acpi/ files and functions which do not yet exist in /sys. diff --git a/drivers/acpi/thermal.c b/drivers/acpi/thermal.c index efad1f33aeb5..2f8f17131d9f 100644 --- a/drivers/acpi/thermal.c +++ b/drivers/acpi/thermal.c @@ -37,10 +37,14 @@ #include #include #include + +#ifdef CONFIG_ACPI_PROCFS #include +#include +#endif + #include #include -#include #include #include #include @@ -102,16 +106,6 @@ static int acpi_thermal_add(struct acpi_device *device); static int acpi_thermal_remove(struct acpi_device *device, int type); static int acpi_thermal_resume(struct acpi_device *device); static void acpi_thermal_notify(struct acpi_device *device, u32 event); -static int acpi_thermal_state_open_fs(struct inode *inode, struct file *file); -static int acpi_thermal_temp_open_fs(struct inode *inode, struct file *file); -static int acpi_thermal_trip_open_fs(struct inode *inode, struct file *file); -static int acpi_thermal_cooling_open_fs(struct inode *inode, struct file *file); -static ssize_t acpi_thermal_write_cooling_mode(struct file *, - const char __user *, size_t, - loff_t *); -static int acpi_thermal_polling_open_fs(struct inode *inode, struct file *file); -static ssize_t acpi_thermal_write_polling(struct file *, const char __user *, - size_t, loff_t *); static const struct acpi_device_id thermal_device_ids[] = { {ACPI_THERMAL_HID, 0}, @@ -201,6 +195,18 @@ struct acpi_thermal { struct mutex lock; }; +#ifdef CONFIG_ACPI_PROCFS +static int acpi_thermal_state_open_fs(struct inode *inode, struct file *file); +static int acpi_thermal_temp_open_fs(struct inode *inode, struct file *file); +static int acpi_thermal_trip_open_fs(struct inode *inode, struct file *file); +static int acpi_thermal_cooling_open_fs(struct inode *inode, struct file *file); +static ssize_t acpi_thermal_write_cooling_mode(struct file *, + const char __user *, size_t, + loff_t *); +static int acpi_thermal_polling_open_fs(struct inode *inode, struct file *file); +static ssize_t acpi_thermal_write_polling(struct file *, const char __user *, + size_t, loff_t *); + static const struct file_operations acpi_thermal_state_fops = { .owner = THIS_MODULE, .open = acpi_thermal_state_open_fs, @@ -242,6 +248,7 @@ static const struct file_operations acpi_thermal_polling_fops = { .llseek = seq_lseek, .release = single_release, }; +#endif /* CONFIG_ACPI_PROCFS*/ /* -------------------------------------------------------------------------- Thermal Zone Management @@ -287,26 +294,6 @@ static int acpi_thermal_get_polling_frequency(struct acpi_thermal *tz) return 0; } -static int acpi_thermal_set_polling(struct acpi_thermal *tz, int seconds) -{ - - if (!tz) - return -EINVAL; - - tz->polling_frequency = seconds * 10; /* Convert value to deci-seconds */ - - tz->thermal_zone->polling_delay = seconds * 1000; - - if (tz->tz_enabled) - thermal_zone_device_update(tz->thermal_zone); - - ACPI_DEBUG_PRINT((ACPI_DB_INFO, - "Polling frequency set to %lu seconds\n", - tz->polling_frequency/10)); - - return 0; -} - static int acpi_thermal_set_cooling_mode(struct acpi_thermal *tz, int mode) { acpi_status status = AE_OK; @@ -973,7 +960,7 @@ static void acpi_thermal_unregister_thermal_zone(struct acpi_thermal *tz) /* -------------------------------------------------------------------------- FS Interface (/proc) -------------------------------------------------------------------------- */ - +#ifdef CONFIG_ACPI_PROCFS static struct proc_dir_entry *acpi_thermal_dir; static int acpi_thermal_state_seq_show(struct seq_file *seq, void *offset) @@ -1187,6 +1174,26 @@ static int acpi_thermal_polling_open_fs(struct inode *inode, struct file *file) PDE(inode)->data); } +static int acpi_thermal_set_polling(struct acpi_thermal *tz, int seconds) +{ + if (!tz) + return -EINVAL; + + /* Convert value to deci-seconds */ + tz->polling_frequency = seconds * 10; + + tz->thermal_zone->polling_delay = seconds * 1000; + + if (tz->tz_enabled) + thermal_zone_device_update(tz->thermal_zone); + + ACPI_DEBUG_PRINT((ACPI_DB_INFO, + "Polling frequency set to %lu seconds\n", + tz->polling_frequency/10)); + + return 0; +} + static ssize_t acpi_thermal_write_polling(struct file *file, const char __user * buffer, @@ -1295,7 +1302,13 @@ static int acpi_thermal_remove_fs(struct acpi_device *device) return 0; } - +#else +static inline int acpi_thermal_add_fs(struct acpi_device *device) { return 0; } +static inline int acpi_thermal_remove_fs(struct acpi_device *device) +{ + return 0; +} +#endif /* CONFIG_ACPI_PROCFS */ /* -------------------------------------------------------------------------- Driver Interface -------------------------------------------------------------------------- */ @@ -1566,13 +1579,18 @@ static int __init acpi_thermal_init(void) printk(KERN_NOTICE "ACPI: thermal control disabled\n"); return -ENODEV; } + +#ifdef CONFIG_ACPI_PROCFS acpi_thermal_dir = proc_mkdir(ACPI_THERMAL_CLASS, acpi_root_dir); if (!acpi_thermal_dir) return -ENODEV; +#endif result = acpi_bus_register_driver(&acpi_thermal_driver); if (result < 0) { +#ifdef CONFIG_ACPI_PROCFS remove_proc_entry(ACPI_THERMAL_CLASS, acpi_root_dir); +#endif return -ENODEV; } @@ -1584,7 +1602,9 @@ static void __exit acpi_thermal_exit(void) acpi_bus_unregister_driver(&acpi_thermal_driver); +#ifdef CONFIG_ACPI_PROCFS remove_proc_entry(ACPI_THERMAL_CLASS, acpi_root_dir); +#endif return; } -- cgit v1.2.1 From cfa806f059801dbe7e435745eb2e187c8bfe1e7f Mon Sep 17 00:00:00 2001 From: Andi Kleen Date: Tue, 20 Jul 2010 15:18:36 -0700 Subject: gcc-4.6: ACPI: fix unused but set variables in ACPI Some minor improvements in error handling, but overall it was mostly dead code. Signed-off-by: Andi Kleen Signed-off-by: Andrew Morton Signed-off-by: Len Brown --- drivers/acpi/acpica/utmutex.c | 5 +---- drivers/acpi/numa.c | 4 +--- drivers/acpi/osl.c | 7 +++---- drivers/acpi/power.c | 2 -- drivers/acpi/processor_idle.c | 3 +-- drivers/acpi/video.c | 10 +++++----- 6 files changed, 11 insertions(+), 20 deletions(-) (limited to 'drivers/acpi') diff --git a/drivers/acpi/acpica/utmutex.c b/drivers/acpi/acpica/utmutex.c index 058b3df48271..f5cca3a1300c 100644 --- a/drivers/acpi/acpica/utmutex.c +++ b/drivers/acpi/acpica/utmutex.c @@ -279,13 +279,10 @@ acpi_status acpi_ut_acquire_mutex(acpi_mutex_handle mutex_id) acpi_status acpi_ut_release_mutex(acpi_mutex_handle mutex_id) { - acpi_thread_id this_thread_id; - ACPI_FUNCTION_NAME(ut_release_mutex); - this_thread_id = acpi_os_get_thread_id(); ACPI_DEBUG_PRINT((ACPI_DB_MUTEX, "Thread %p releasing Mutex [%s]\n", - ACPI_CAST_PTR(void, this_thread_id), + ACPI_CAST_PTR(void, acpi_os_get_thread_id()), acpi_ut_get_mutex_name(mutex_id))); if (mutex_id > ACPI_MAX_MUTEX) { diff --git a/drivers/acpi/numa.c b/drivers/acpi/numa.c index b0337d314604..5718566e00f9 100644 --- a/drivers/acpi/numa.c +++ b/drivers/acpi/numa.c @@ -255,12 +255,10 @@ acpi_parse_memory_affinity(struct acpi_subtable_header * header, static int __init acpi_parse_srat(struct acpi_table_header *table) { - struct acpi_table_srat *srat; - if (!table) return -EINVAL; - srat = (struct acpi_table_srat *)table; + /* Real work done in acpi_table_parse_srat below. */ return 0; } diff --git a/drivers/acpi/osl.c b/drivers/acpi/osl.c index 44bddc5bc6ad..03017b1eb38b 100644 --- a/drivers/acpi/osl.c +++ b/drivers/acpi/osl.c @@ -141,15 +141,14 @@ static struct osi_linux { static void __init acpi_request_region (struct acpi_generic_address *addr, unsigned int length, char *desc) { - struct resource *res; - if (!addr->address || !length) return; + /* Resources are never freed */ if (addr->space_id == ACPI_ADR_SPACE_SYSTEM_IO) - res = request_region(addr->address, length, desc); + request_region(addr->address, length, desc); else if (addr->space_id == ACPI_ADR_SPACE_SYSTEM_MEMORY) - res = request_mem_region(addr->address, length, desc); + request_mem_region(addr->address, length, desc); } static int __init acpi_reserve_resources(void) diff --git a/drivers/acpi/power.c b/drivers/acpi/power.c index 4fe5018fd6ab..cf073aa0709b 100644 --- a/drivers/acpi/power.c +++ b/drivers/acpi/power.c @@ -242,8 +242,6 @@ static int acpi_power_off_device(acpi_handle handle, struct acpi_device *dev) acpi_status status = AE_OK; struct acpi_power_resource *resource = NULL; struct list_head *node, *next; - struct acpi_power_reference *ref; - result = acpi_power_get_context(handle, &resource); if (result) diff --git a/drivers/acpi/processor_idle.c b/drivers/acpi/processor_idle.c index 5cbc0cb73e2c..07bc74d8356e 100644 --- a/drivers/acpi/processor_idle.c +++ b/drivers/acpi/processor_idle.c @@ -722,13 +722,12 @@ static inline void acpi_idle_do_entry(struct acpi_processor_cx *cx) } else if (cx->entry_method == ACPI_CSTATE_HALT) { acpi_safe_halt(); } else { - int unused; /* IO port based C-state */ inb(cx->address); /* Dummy wait op - must do something useless after P_LVL2 read because chipsets cannot guarantee that STPCLK# signal gets asserted in time to freeze execution properly. */ - unused = inl(acpi_gbl_FADT.xpm_timer_block.address); + inl(acpi_gbl_FADT.xpm_timer_block.address); } start_critical_timings(); } diff --git a/drivers/acpi/video.c b/drivers/acpi/video.c index 909ae7bf3b93..67dec0c675aa 100644 --- a/drivers/acpi/video.c +++ b/drivers/acpi/video.c @@ -2167,7 +2167,7 @@ acpi_video_bus_get_devices(struct acpi_video_bus *video, status = acpi_video_bus_get_one_device(dev, video); if (ACPI_FAILURE(status)) { printk(KERN_WARNING PREFIX - "Cant attach device"); + "Cant attach device\n"); continue; } } @@ -2177,19 +2177,19 @@ acpi_video_bus_get_devices(struct acpi_video_bus *video, static int acpi_video_bus_put_one_device(struct acpi_video_device *device) { acpi_status status; - struct acpi_video_bus *video; - if (!device || !device->video) return -ENOENT; - video = device->video; - acpi_video_device_remove_fs(device->dev); status = acpi_remove_notify_handler(device->dev->handle, ACPI_DEVICE_NOTIFY, acpi_video_device_notify); + if (ACPI_FAILURE(status)) { + printk(KERN_WARNING PREFIX + "Cant remove video notify handler\n"); + } if (device->backlight) { sysfs_remove_link(&device->backlight->dev.kobj, "device"); backlight_device_unregister(device->backlight); -- cgit v1.2.1