diff options
Diffstat (limited to 'drivers/acpi')
76 files changed, 1458 insertions, 2318 deletions
diff --git a/drivers/acpi/Kconfig b/drivers/acpi/Kconfig index 08e0140920e..b811f2173f6 100644 --- a/drivers/acpi/Kconfig +++ b/drivers/acpi/Kconfig @@ -54,17 +54,10 @@ 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/*) /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/Makefile b/drivers/acpi/Makefile index 833b582d176..3d031d02e54 100644 --- a/drivers/acpi/Makefile +++ b/drivers/acpi/Makefile @@ -37,8 +37,9 @@ 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-$(CONFIG_ACPI_DEBUG) += debug.o +acpi-y += event.o +acpi-y += sysfs.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/acpi_pad.c b/drivers/acpi/acpi_pad.c index 446aced33af..b76848c80be 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/acpica/acevents.h b/drivers/acpi/acpica/acevents.h index c3f43daa8be..36867cd70ea 100644 --- a/drivers/acpi/acpica/acevents.h +++ b/drivers/acpi/acpica/acevents.h @@ -78,7 +78,13 @@ 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); + +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/acglobal.h b/drivers/acpi/acpica/acglobal.h index 899d68afc3c..1d192142c69 100644 --- a/drivers/acpi/acpica/acglobal.h +++ b/drivers/acpi/acpica/acglobal.h @@ -100,13 +100,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. */ @@ -115,7 +108,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/acpica/achware.h b/drivers/acpi/acpica/achware.h index 32391588e16..120b3af5659 100644 --- a/drivers/acpi/acpica/achware.h +++ b/drivers/acpi/acpica/achware.h @@ -90,16 +90,13 @@ 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 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/aclocal.h b/drivers/acpi/acpica/aclocal.h index 147a7e6bd38..df85b53a674 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 */ @@ -411,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 { @@ -428,7 +430,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/acnamesp.h b/drivers/acpi/acpica/acnamesp.h index 258159cfcdf..9f60ff00220 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/acobject.h b/drivers/acpi/acpica/acobject.h index cde18ea8265..54857fa87aa 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/acpredef.h b/drivers/acpi/acpica/acpredef.h index 97116082cb6..10998d369ad 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}}, diff --git a/drivers/acpi/acpica/acstruct.h b/drivers/acpi/acpica/acstruct.h index 161bc0e3d70..6e5dd97949f 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 { @@ -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/dsinit.c b/drivers/acpi/acpica/dsinit.c index abe140318a7..cc4a38c5755 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/dsmethod.c b/drivers/acpi/acpica/dsmethod.c index 2a9a561c2f0..64750ee96e2 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); + } } } @@ -605,7 +619,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 f3d52f59250..8095306fcd8 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; @@ -146,7 +144,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 +160,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 +224,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 +321,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 +541,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/dsobject.c b/drivers/acpi/acpica/dsobject.c index 3607adcaf08..8e85f54a8e0 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. diff --git a/drivers/acpi/acpica/dsopcode.c b/drivers/acpi/acpica/dsopcode.c index 53a7e416f33..7c0e7422717 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/dsutils.c b/drivers/acpi/acpica/dsutils.c index 306c62ab2e8..15135c25aa9 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/evevent.c b/drivers/acpi/acpica/evevent.c index f5795915a2e..303618889da 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/evgpe.c b/drivers/acpi/acpica/evgpe.c index 7c2c336006a..f226eac314d 100644 --- a/drivers/acpi/acpica/evgpe.c +++ b/drivers/acpi/acpica/evgpe.c @@ -54,51 +54,159 @@ 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) { 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 */ + /* 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); + ACPI_SET_BIT(gpe_register_info->enable_for_run, (u8)register_bit); } - if (gpe_event_info->wakeup_count) { - ACPI_SET_BIT(gpe_register_info->enable_for_wake, register_bit); + 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); } - return_ACPI_STATUS(AE_OK); + /* 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_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); +} /******************************************************************************* * @@ -417,8 +525,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/evgpeblk.c b/drivers/acpi/acpica/evgpeblk.c index 341a38ce8aa..85445fb5844 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) { @@ -502,35 +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) { - acpi_set_gpe(gpe_device, gpe_number, - ACPI_GPE_ENABLE); - gpe_enabled_count++; - continue; - } - - 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)) { 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, - ACPI_GPE_TYPE_RUNTIME); if (ACPI_FAILURE(status)) { ACPI_EXCEPTION((AE_INFO, status, "Could not enable GPE 0x%02X", @@ -542,10 +498,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 3f6c2d26410..3084c5de1bb 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,24 +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, - ACPI_GPE_TYPE_RUNTIME); - 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)); } } @@ -497,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/evrgnini.c b/drivers/acpi/acpica/evrgnini.c index 2e3b0334072..f40d271bf56 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/evxface.c b/drivers/acpi/acpica/evxface.c index 4a531cdf794..14e48add32f 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 18b3f1468b7..304825528d4 100644 --- a/drivers/acpi/acpica/evxfevnt.c +++ b/drivers/acpi/acpica/evxfevnt.c @@ -213,101 +213,71 @@ 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 + * FUNCTION: acpi_gpe_wakeup * * 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 + * Action - Enable or 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. + * DESCRIPTION: Set or clear the GPE's wakeup enable mask bit. * ******************************************************************************/ -acpi_status acpi_set_gpe(acpi_handle gpe_device, u32 gpe_number, u8 action) +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; - acpi_status status; + struct acpi_gpe_register_info *gpe_register_info; acpi_cpu_flags flags; + u32 register_bit; - ACPI_FUNCTION_TRACE(acpi_set_gpe); + 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) { + if (!gpe_event_info || !(gpe_event_info->flags & ACPI_GPE_CAN_WAKE)) { 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: - status = acpi_clear_and_enable_gpe(gpe_event_info); + ACPI_SET_BIT(gpe_register_info->enable_for_wake, + (u8)register_bit); break; case ACPI_GPE_DISABLE: - status = acpi_hw_low_set_gpe(gpe_event_info, ACPI_GPE_DISABLE); + ACPI_CLEAR_BIT(gpe_register_info->enable_for_wake, + (u8)register_bit); break; default: + ACPI_ERROR((AE_INFO, "%u, Invalid action", action)); status = AE_BAD_PARAMETER; break; } - unlock_and_exit: +unlock_and_exit: acpi_os_release_lock(acpi_gbl_gpe_lock, flags); return_ACPI_STATUS(status); } -ACPI_EXPORT_SYMBOL(acpi_set_gpe) +ACPI_EXPORT_SYMBOL(acpi_gpe_wakeup) /******************************************************************************* * @@ -315,84 +285,30 @@ ACPI_EXPORT_SYMBOL(acpi_set_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 * * 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; + acpi_status status = AE_BAD_PARAMETER; struct acpi_gpe_event_info *gpe_event_info; acpi_cpu_flags flags; 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 */ 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_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_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; - } - - /* - * 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 (gpe_event_info) { + status = acpi_raw_enable_gpe(gpe_event_info); } -unlock_and_exit: acpi_os_release_lock(acpi_gbl_gpe_lock, flags); return_ACPI_STATUS(status); } @@ -404,8 +320,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 * @@ -414,20 +328,52 @@ 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; + acpi_status status = AE_BAD_PARAMETER; struct acpi_gpe_event_info *gpe_event_info; acpi_cpu_flags flags; ACPI_FUNCTION_TRACE(acpi_disable_gpe); - /* Parameter validation */ + flags = acpi_os_acquire_lock(acpi_gbl_gpe_lock); + + /* Ensure that we have a valid GPE number */ - if (!gpe_type || (gpe_type & ~ACPI_GPE_TYPE_WAKE_RUN)) { - return_ACPI_STATUS(AE_BAD_PARAMETER); + gpe_event_info = acpi_ev_get_gpe_event_info(gpe_device, gpe_number); + if (gpe_event_info) { + status = acpi_raw_disable_gpe(gpe_event_info) ; } + acpi_os_release_lock(acpi_gbl_gpe_lock, flags); + return_ACPI_STATUS(status); +} +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; + + ACPI_FUNCTION_TRACE(acpi_gpe_can_wake); + flags = acpi_os_acquire_lock(acpi_gbl_gpe_lock); /* Ensure that we have a valid GPE number */ @@ -438,51 +384,20 @@ acpi_status acpi_disable_gpe(acpi_handle gpe_device, u32 gpe_number, u8 gpe_type goto unlock_and_exit; } - /* 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->flags & ACPI_GPE_CAN_WAKE) { + 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->wakeup_count--; - if (!gpe_event_info->wakeup_count) { - status = acpi_ev_update_gpe_enable_masks(gpe_event_info); - } + gpe_event_info->flags |= ACPI_GPE_CAN_WAKE; + 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); return_ACPI_STATUS(status); } -ACPI_EXPORT_SYMBOL(acpi_disable_gpe) +ACPI_EXPORT_SYMBOL(acpi_gpe_can_wake) /******************************************************************************* * @@ -800,7 +715,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 008621c5ad8..18832205b63 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/exdump.c b/drivers/acpi/acpica/exdump.c index d39d438ba1e..f067bbb0d96 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) { @@ -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); @@ -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 a6dc26f0b3b..047217303a4 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 25059dace0a..98a331d2249 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); } @@ -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); } diff --git a/drivers/acpi/acpica/exregion.c b/drivers/acpi/acpica/exregion.c index 531000fc77d..8819d2ac5ae 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/hwgpe.c b/drivers/acpi/acpica/hwgpe.c index 3450309c278..14750db2a1b 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: @@ -143,31 +143,6 @@ acpi_hw_low_set_gpe(struct acpi_gpe_event_info *gpe_event_info, u8 action) /****************************************************************************** * - * 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 * * PARAMETERS: gpe_event_info - Info block for the GPE to be cleared @@ -193,7 +168,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 +216,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?) */ diff --git a/drivers/acpi/acpica/hwsleep.c b/drivers/acpi/acpica/hwsleep.c index 36eb803dd9d..3796811276a 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 3a2814676ac..0cd925be5fc 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 */ @@ -433,7 +432,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 +494,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/nsalloc.c b/drivers/acpi/acpica/nsalloc.c index 982269c1fa4..1e5ff803d9a 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 */ @@ -228,33 +219,42 @@ 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 */ + 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 +288,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 +297,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 +393,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 +498,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/nsdump.c b/drivers/acpi/acpica/nsdump.c index 2110cc2360f..a54dc39e304 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/nsinit.c b/drivers/acpi/acpica/nsinit.c index 4e5272c313e..660a2728908 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); } @@ -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); @@ -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 7dea0031605..d3104af57e1 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/nsparse.c b/drivers/acpi/acpica/nsparse.c index 27cda52c76b..5808c89e9fa 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: diff --git a/drivers/acpi/acpica/nsrepair.c b/drivers/acpi/acpica/nsrepair.c index d4be37751be..d1c13669266 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 */ diff --git a/drivers/acpi/acpica/nsrepair2.c b/drivers/acpi/acpica/nsrepair2.c index 61bd0f6755d..4009498fbab 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}, diff --git a/drivers/acpi/acpica/nssearch.c b/drivers/acpi/acpica/nssearch.c index a8e42b5e946..41102a84272 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 bab559712da..e1add3491b0 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 00e79fb2602..2cd5be8fe10 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 eafef24ea44..a1f04e9b803 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 66116750a0f..0558747579e 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); diff --git a/drivers/acpi/acpica/utmutex.c b/drivers/acpi/acpica/utmutex.c index 058b3df4827..f5cca3a1300 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/acpica/utxface.c b/drivers/acpi/acpica/utxface.c index db9d8ca5798..7f8cefcb2b3 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/apei/Kconfig b/drivers/acpi/apei/Kconfig index f8c668f27b5..907e350f1c7 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 b13b03a1778..d1d1bc0a4ee 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/apei-base.c b/drivers/acpi/apei/apei-base.c index 216e1e948ff..73fd0c7487c 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; } diff --git a/drivers/acpi/apei/erst-dbg.c b/drivers/acpi/apei/erst-dbg.c new file mode 100644 index 00000000000..5281ddda277 --- /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 <ying.huang@intel.com> + * + * 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 <linux/kernel.h> +#include <linux/module.h> +#include <linux/uaccess.h> +#include <acpi/apei.h> +#include <linux/miscdevice.h> + +#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"); diff --git a/drivers/acpi/apei/erst.c b/drivers/acpi/apei/erst.c index 864dd46c346..18645f4e83c 100644 --- a/drivers/acpi/apei/erst.c +++ b/drivers/acpi/apei/erst.c @@ -33,6 +33,7 @@ #include <linux/uaccess.h> #include <linux/cper.h> #include <linux/nmi.h> +#include <linux/hardirq.h> #include <acpi/apei.h> #include "apei-internal.h" diff --git a/drivers/acpi/apei/ghes.c b/drivers/acpi/apei/ghes.c index fd0cc016a09..385a6059714 100644 --- a/drivers/acpi/apei/ghes.c +++ b/drivers/acpi/apei/ghes.c @@ -41,6 +41,8 @@ #include <linux/interrupt.h> #include <linux/cper.h> #include <linux/kdebug.h> +#include <linux/platform_device.h> +#include <linux/mutex.h> #include <acpi/apei.h> #include <acpi/atomicio.h> #include <acpi/hed.h> @@ -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) { @@ -132,26 +135,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 +240,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; } @@ -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 e7f40d362cb..343168d1826 100644 --- a/drivers/acpi/apei/hest.c +++ b/drivers/acpi/apei/hest.c @@ -34,6 +34,7 @@ #include <linux/kdebug.h> #include <linux/highmem.h> #include <linux/io.h> +#include <linux/platform_device.h> #include <acpi/apei.h> #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; diff --git a/drivers/acpi/bus.c b/drivers/acpi/bus.c index c1d23cd7165..5c221ab535d 100644 --- a/drivers/acpi/bus.c +++ b/drivers/acpi/bus.c @@ -1034,8 +1034,8 @@ 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(); acpi_wakeup_device_init(); return result; diff --git a/drivers/acpi/button.c b/drivers/acpi/button.c index 7d857dabdde..1575a9b51f1 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/debug.c b/drivers/acpi/debug.c deleted file mode 100644 index 146135e7a6a..00000000000 --- a/drivers/acpi/debug.c +++ /dev/null @@ -1,406 +0,0 @@ -/* - * debug.c - ACPI debug interface to userspace. - */ - -#include <linux/proc_fs.h> -#include <linux/seq_file.h> -#include <linux/init.h> -#include <linux/module.h> -#include <linux/kernel.h> -#include <linux/moduleparam.h> -#include <linux/debugfs.h> -#include <linux/slab.h> -#include <asm/uaccess.h> -#include <acpi/acpi_drivers.h> - -#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 (/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 <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); - -/* -------------------------------------------------------------------------- - 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) - -------------------------------------------------------------------------- */ -#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_debugfs_init(); - acpi_procfs_init(); - return 0; -} diff --git a/drivers/acpi/debugfs.c b/drivers/acpi/debugfs.c new file mode 100644 index 00000000000..7de27d49c4b --- /dev/null +++ b/drivers/acpi/debugfs.c @@ -0,0 +1,93 @@ +/* + * debugfs.c - ACPI debugfs interface to userspace. + */ + +#include <linux/init.h> +#include <linux/module.h> +#include <linux/kernel.h> +#include <linux/uaccess.h> +#include <linux/debugfs.h> +#include <acpi/acpi_drivers.h> + +#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, + 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/ec.c b/drivers/acpi/ec.c index 1fa0aafebe2..f31291ba94d 100644 --- a/drivers/acpi/ec.c +++ b/drivers/acpi/ec.c @@ -303,11 +303,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); @@ -316,12 +313,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"); @@ -746,7 +739,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, @@ -763,7 +756,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; } } @@ -774,7 +767,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"); @@ -1018,22 +1011,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, @@ -1041,8 +1018,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, }, }; diff --git a/drivers/acpi/glue.c b/drivers/acpi/glue.c index 4af6301601e..78b0164c35b 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); } diff --git a/drivers/acpi/internal.h b/drivers/acpi/internal.h index 8ae27264a00..a212bfeddf8 100644 --- a/drivers/acpi/internal.h +++ b/drivers/acpi/internal.h @@ -27,12 +27,12 @@ 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); +#ifdef CONFIG_DEBUG_FS +int acpi_debugfs_init(void); #else -static inline int acpi_debug_init(void) { return 0; } +static inline int acpi_debugfs_init(void) { return 0; } #endif /* -------------------------------------------------------------------------- diff --git a/drivers/acpi/numa.c b/drivers/acpi/numa.c index b0337d31460..5718566e00f 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 78418ce4fc7..65b25a303b8 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) @@ -191,36 +190,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 +740,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 @@ -1064,26 +1045,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/pci_root.c b/drivers/acpi/pci_root.c index 4eac59393ed..1f67057af2a 100644 --- a/drivers/acpi/pci_root.c +++ b/drivers/acpi/pci_root.c @@ -33,6 +33,7 @@ #include <linux/pm_runtime.h> #include <linux/pci.h> #include <linux/pci-acpi.h> +#include <linux/pci-aspm.h> #include <linux/acpi.h> #include <linux/slab.h> #include <acpi/acpi_bus.h> @@ -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); diff --git a/drivers/acpi/power.c b/drivers/acpi/power.c index f74d3b31e5c..844c155aeb0 100644 --- a/drivers/acpi/power.c +++ b/drivers/acpi/power.c @@ -40,8 +40,6 @@ #include <linux/init.h> #include <linux/types.h> #include <linux/slab.h> -#include <linux/proc_fs.h> -#include <linux/seq_file.h> #include <acpi/acpi_bus.h> #include <acpi/acpi_drivers.h> #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 -------------------------------------------------------------------------- */ @@ -255,7 +244,6 @@ static int acpi_power_off_device(acpi_handle handle, struct acpi_device *dev) struct list_head *node, *next; struct acpi_power_reference *ref; - result = acpi_power_get_context(handle, &resource); if (result) return result; @@ -542,102 +530,6 @@ int acpi_power_transition(struct acpi_device *device, int state) } /* -------------------------------------------------------------------------- - 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 +582,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 +603,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 +646,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); } diff --git a/drivers/acpi/proc.c b/drivers/acpi/proc.c index 1ac678d2c51..afad67769db 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/processor_driver.c b/drivers/acpi/processor_driver.c index 38ea0cc6dc4..15602189238 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 e9a8026d39f..f4428e82b35 100644 --- a/drivers/acpi/processor_idle.c +++ b/drivers/acpi/processor_idle.c @@ -33,8 +33,6 @@ #include <linux/init.h> #include <linux/cpufreq.h> #include <linux/slab.h> -#include <linux/proc_fs.h> -#include <linux/seq_file.h> #include <linux/acpi.h> #include <linux/dmi.h> #include <linux/moduleparam.h> @@ -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. @@ -164,7 +155,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; /* @@ -264,7 +255,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) { @@ -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, "<not supported>\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 */ @@ -803,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(); } @@ -1172,9 +1090,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 +1138,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 +1150,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 6deafb4aa0d..953b25fb986 100644 --- a/drivers/acpi/processor_thermal.c +++ b/drivers/acpi/processor_thermal.c @@ -30,8 +30,6 @@ #include <linux/module.h> #include <linux/init.h> #include <linux/cpufreq.h> -#include <linux/proc_fs.h> -#include <linux/seq_file.h> #include <linux/sysdev.h> #include <asm/uaccess.h> @@ -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, "<not supported>\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 9ade1a5b32e..730863855ed 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 diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c index 7f2e051ed4f..b23825ecfa3 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; } @@ -764,8 +766,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); diff --git a/drivers/acpi/sleep.c b/drivers/acpi/sleep.c index 2862c781b37..cf82989ae75 100644 --- a/drivers/acpi/sleep.c +++ b/drivers/acpi/sleep.c @@ -70,10 +70,10 @@ 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_devices(acpi_state); acpi_enter_sleep_state_prep(acpi_state); return 0; } @@ -119,6 +119,16 @@ static int acpi_pm_freeze(void) } /** + * 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. * * If necessary, set the firmware waking vector and do arch-specific @@ -127,11 +137,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; } @@ -142,9 +150,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; } @@ -159,7 +166,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,7 +173,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 */ @@ -181,6 +187,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. @@ -251,7 +258,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(); @@ -297,11 +303,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; @@ -323,7 +324,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, }; @@ -336,9 +337,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; } @@ -349,9 +350,9 @@ 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, + .wake = acpi_pm_finish, .end = acpi_pm_end, .recover = acpi_pm_finish, }; @@ -423,16 +424,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; @@ -441,7 +432,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 */ @@ -481,7 +471,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, @@ -517,13 +507,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. @@ -531,7 +514,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, @@ -663,18 +646,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"); @@ -695,7 +669,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); } diff --git a/drivers/acpi/sleep.h b/drivers/acpi/sleep.h index 25b8bd14928..d8821805c3b 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/system.c b/drivers/acpi/sysfs.c index f8db50a0941..68e2e4582fa 100644 --- a/drivers/acpi/system.c +++ b/drivers/acpi/sysfs.c @@ -1,51 +1,218 @@ /* - * acpi_system.c - ACPI System Driver ($Revision: 63 $) - * - * Copyright (C) 2001, 2002 Andy Grover <andrew.grover@intel.com> - * Copyright (C) 2001, 2002 Paul Diefenbaugh <paul.s.diefenbaugh@intel.com> - * - * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - * - * 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. - * - * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + * sysfs.c - ACPI sysfs interface to userspace. */ -#include <linux/proc_fs.h> -#include <linux/seq_file.h> -#include <linux/slab.h> #include <linux/init.h> -#include <linux/string.h> -#include <asm/uaccess.h> - +#include <linux/kernel.h> +#include <linux/moduleparam.h> #include <acpi/acpi_drivers.h> -#define PREFIX "ACPI: " - #define _COMPONENT ACPI_SYSTEM_COMPONENT -ACPI_MODULE_NAME("system"); - -#define ACPI_SYSTEM_CLASS "system" -#define ACPI_SYSTEM_DEVICE_NAME "System" +ACPI_MODULE_NAME("sysfs"); -u32 acpi_irq_handled; -u32 acpi_irq_not_handled; +#define PREFIX "ACPI: " +#ifdef CONFIG_ACPI_DEBUG /* - * Make ACPICA version work as module param + * 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; @@ -57,9 +224,12 @@ static int param_get_acpica_version(char *buffer, struct kernel_param *kp) module_param_call(acpica_version, NULL, param_get_acpica_version, NULL, 0444); -/* -------------------------------------------------------------------------- - FS Interface (/sys) - -------------------------------------------------------------------------- */ +/* + * 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; @@ -86,14 +256,12 @@ static ssize_t acpi_table_show(struct file *filp, struct kobject *kobj, else memcpy(name, "\0\0\0\0", 4); - status = - acpi_get_table(name, table_attr->instance, - &table_header); + 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); + table_header, table_header->length); } static void acpi_table_attr_init(struct acpi_table_attr *table_attr, @@ -105,7 +273,7 @@ static void acpi_table_attr_init(struct acpi_table_attr *table_attr, sysfs_attr_init(&table_attr->attr.attr); if (table_header->signature[0] != '\0') memcpy(table_attr->name, table_header->signature, - ACPI_NAME_SIZE); + ACPI_NAME_SIZE); else memcpy(table_attr->name, "NULL", 4); @@ -117,8 +285,8 @@ static void acpi_table_attr_init(struct acpi_table_attr *table_attr, table_attr->instance++; if (table_attr->instance > 1 || (table_attr->instance == 1 && - !acpi_get_table - (table_header->signature, 2, &header))) + !acpi_get_table + (table_header->signature, 2, &header))) sprintf(table_attr->name + ACPI_NAME_SIZE, "%d", table_attr->instance); @@ -138,18 +306,17 @@ acpi_sysfs_table_handler(u32 event, void *table, void *context) switch (event) { case ACPI_TABLE_EVENT_LOAD: table_attr = - kzalloc(sizeof(struct acpi_table_attr), GFP_KERNEL); + 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)) { + &table_attr->attr)) { kfree(table_attr); return AE_ERROR; } else - list_add_tail(&table_attr->node, - &acpi_table_attr_list); + list_add_tail(&table_attr->node, &acpi_table_attr_list); break; case ACPI_TABLE_EVENT_UNLOAD: /* @@ -164,7 +331,7 @@ acpi_sysfs_table_handler(u32 event, void *table, void *context) return AE_OK; } -static int acpi_system_sysfs_init(void) +static int acpi_tables_sysfs_init(void) { struct acpi_table_attr *table_attr; struct acpi_table_header *table_header = NULL; @@ -213,14 +380,17 @@ err: } /* - * Detailed ACPI IRQ counters in /sys/firmware/acpi/interrupts/ - * See Documentation/ABI/testing/sysfs-firmware-acpi + * 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 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 { @@ -237,6 +407,7 @@ 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) @@ -269,8 +440,8 @@ void acpi_os_gpe_count(u32 gpe_number) if (gpe_number < num_gpes) all_counters[gpe_number].count++; else - all_counters[num_gpes + ACPI_NUM_FIXED_EVENTS + COUNT_ERROR]. - count++; + all_counters[num_gpes + ACPI_NUM_FIXED_EVENTS + + COUNT_ERROR].count++; return; } @@ -283,13 +454,14 @@ void acpi_os_fixed_event_count(u32 event_number) 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++; + 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) +static int get_status(u32 index, acpi_event_status *status, + acpi_handle *handle) { int result = 0; @@ -300,7 +472,7 @@ static int get_status(u32 index, acpi_event_status *status, acpi_handle *handle) result = acpi_get_gpe_device(index, handle); if (result) { ACPI_EXCEPTION((AE_INFO, AE_NOT_FOUND, - "Invalid GPE 0x%x\n", index)); + "Invalid GPE 0x%x\n", index)); goto end; } result = acpi_get_gpe_status(*handle, index, status); @@ -312,7 +484,7 @@ end: } static ssize_t counter_show(struct kobject *kobj, - struct kobj_attribute *attr, char *buf) + struct kobj_attribute *attr, char *buf) { int index = attr - counter_attrs; int size; @@ -321,12 +493,11 @@ static ssize_t counter_show(struct kobject *kobj, int result = 0; all_counters[num_gpes + ACPI_NUM_FIXED_EVENTS + COUNT_SCI].count = - acpi_irq_handled; + acpi_irq_handled; all_counters[num_gpes + ACPI_NUM_FIXED_EVENTS + COUNT_SCI_NOT].count = - acpi_irq_not_handled; + acpi_irq_not_handled; all_counters[num_gpes + ACPI_NUM_FIXED_EVENTS + COUNT_GPE].count = - acpi_gpe_count; - + acpi_gpe_count; size = sprintf(buf, "%8d", all_counters[index].count); /* "gpe_all" or "sci" */ @@ -338,13 +509,13 @@ static ssize_t counter_show(struct kobject *kobj, goto end; if (!(status & ACPI_EVENT_FLAG_HANDLE)) - size += sprintf(buf + size, " invalid"); + size += sprintf(buf + size, " invalid"); else if (status & ACPI_EVENT_FLAG_ENABLED) - size += sprintf(buf + size, " enabled"); + size += sprintf(buf + size, " enabled"); else if (status & ACPI_EVENT_FLAG_WAKE_ENABLED) - size += sprintf(buf + size, " wake_enabled"); + size += sprintf(buf + size, " wake_enabled"); else - size += sprintf(buf + size, " disabled"); + size += sprintf(buf + size, " disabled"); end: size += sprintf(buf + size, "\n"); @@ -357,7 +528,8 @@ end: * 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) + struct kobj_attribute *attr, const char *buf, + size_t size) { int index = attr - counter_attrs; acpi_event_status status; @@ -381,34 +553,32 @@ static ssize_t counter_set(struct kobject *kobj, if (!(status & ACPI_EVENT_FLAG_HANDLE)) { printk(KERN_WARNING PREFIX - "Can not change Invalid GPE/Fixed Event status\n"); + "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, - ACPI_GPE_TYPE_RUNTIME); + (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, - ACPI_GPE_TYPE_RUNTIME); + !(status & ACPI_EVENT_FLAG_ENABLED)) + result = acpi_enable_gpe(handle, index); else if (!strcmp(buf, "clear\n") && - (status & ACPI_EVENT_FLAG_SET)) + (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)) + (status & ACPI_EVENT_FLAG_ENABLED)) result = acpi_disable_event(event, ACPI_NOT_ISR); else if (!strcmp(buf, "enable\n") && - !(status & ACPI_EVENT_FLAG_ENABLED)) + !(status & ACPI_EVENT_FLAG_ENABLED)) result = acpi_enable_event(event, ACPI_NOT_ISR); else if (!strcmp(buf, "clear\n") && - (status & ACPI_EVENT_FLAG_SET)) + (status & ACPI_EVENT_FLAG_SET)) result = acpi_clear_event(event); else all_counters[index].count = strtoul(buf, NULL, 0); @@ -432,17 +602,17 @@ void acpi_irq_stats_init(void) num_counters = num_gpes + ACPI_NUM_FIXED_EVENTS + NUM_COUNTERS_EXTRA; all_attrs = kzalloc(sizeof(struct attribute *) * (num_counters + 1), - GFP_KERNEL); + GFP_KERNEL); if (all_attrs == NULL) return; all_counters = kzalloc(sizeof(struct event_counter) * (num_counters), - GFP_KERNEL); + GFP_KERNEL); if (all_counters == NULL) goto fail; counter_attrs = kzalloc(sizeof(struct kobj_attribute) * (num_counters), - GFP_KERNEL); + GFP_KERNEL); if (counter_attrs == NULL) goto fail; @@ -505,135 +675,11 @@ static void __exit interrupt_stats_exit(void) return; } -/* -------------------------------------------------------------------------- - 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 __init acpi_sysfs_init(void) { int result; - result = acpi_system_procfs_init(); - if (result) - return result; - - result = acpi_system_sysfs_init(); + result = acpi_tables_sysfs_init(); return result; } diff --git a/drivers/acpi/thermal.c b/drivers/acpi/thermal.c index efad1f33aeb..2f8f17131d9 100644 --- a/drivers/acpi/thermal.c +++ b/drivers/acpi/thermal.c @@ -37,10 +37,14 @@ #include <linux/init.h> #include <linux/slab.h> #include <linux/types.h> + +#ifdef CONFIG_ACPI_PROCFS #include <linux/proc_fs.h> +#include <linux/seq_file.h> +#endif + #include <linux/jiffies.h> #include <linux/kmod.h> -#include <linux/seq_file.h> #include <linux/reboot.h> #include <linux/device.h> #include <asm/uaccess.h> @@ -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; } diff --git a/drivers/acpi/video.c b/drivers/acpi/video.c index 9865d46f49a..67dec0c675a 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", @@ -450,16 +454,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 @@ -2140,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; } } @@ -2150,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); @@ -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; diff --git a/drivers/acpi/wakeup.c b/drivers/acpi/wakeup.c index 388747a7ef4..f62a50c3ed3 100644 --- a/drivers/acpi/wakeup.c +++ b/drivers/acpi/wakeup.c @@ -21,67 +21,40 @@ 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); - 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; + 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); + acpi_gpe_wakeup(dev->wakeup.gpe_device, dev->wakeup.gpe_number, + ACPI_GPE_ENABLE); } } /** - * 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; @@ -89,13 +62,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); } } |