summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--drivers/acpi/dispatcher/dsmethod.c16
-rw-r--r--drivers/acpi/dispatcher/dsopcode.c4
-rw-r--r--drivers/acpi/dispatcher/dswstate.c18
-rw-r--r--drivers/acpi/events/evevent.c12
-rw-r--r--drivers/acpi/events/evgpe.c368
-rw-r--r--drivers/acpi/events/evgpeblk.c150
-rw-r--r--drivers/acpi/events/evmisc.c4
-rw-r--r--drivers/acpi/events/evregion.c373
-rw-r--r--drivers/acpi/events/evxface.c83
-rw-r--r--drivers/acpi/events/evxfevnt.c176
-rw-r--r--drivers/acpi/events/evxfregn.c202
-rw-r--r--drivers/acpi/executer/exconfig.c47
-rw-r--r--drivers/acpi/executer/exmutex.c46
-rw-r--r--drivers/acpi/executer/exoparg2.c36
-rw-r--r--drivers/acpi/hardware/hwgpe.c304
-rw-r--r--drivers/acpi/hardware/hwregs.c31
-rw-r--r--drivers/acpi/hardware/hwsleep.c52
-rw-r--r--drivers/acpi/namespace/nsaccess.c2
-rw-r--r--drivers/acpi/namespace/nseval.c90
-rw-r--r--drivers/acpi/namespace/nsinit.c31
-rw-r--r--drivers/acpi/namespace/nsparse.c5
-rw-r--r--drivers/acpi/namespace/nsxfeval.c52
-rw-r--r--drivers/acpi/namespace/nsxfname.c4
-rw-r--r--drivers/acpi/parser/psxface.c52
-rw-r--r--drivers/acpi/resources/rsutils.c7
-rw-r--r--drivers/acpi/utilities/uteval.c18
-rw-r--r--drivers/acpi/utilities/utglobal.c52
-rw-r--r--drivers/acpi/utilities/utxface.c41
-rw-r--r--include/acpi/acconfig.h4
-rw-r--r--include/acpi/acdispat.h3
-rw-r--r--include/acpi/acevents.h51
-rw-r--r--include/acpi/acexcep.h6
-rw-r--r--include/acpi/acglobal.h1
-rw-r--r--include/acpi/achware.h21
-rw-r--r--include/acpi/aclocal.h39
-rw-r--r--include/acpi/acnamesp.h18
-rw-r--r--include/acpi/acobject.h13
-rw-r--r--include/acpi/acparser.h4
-rw-r--r--include/acpi/acpixf.h10
-rw-r--r--include/acpi/acstruct.h23
-rw-r--r--include/acpi/actbl.h29
-rw-r--r--include/acpi/actypes.h67
42 files changed, 1610 insertions, 955 deletions
diff --git a/drivers/acpi/dispatcher/dsmethod.c b/drivers/acpi/dispatcher/dsmethod.c
index 360fbe5e8bee..5af958fcea20 100644
--- a/drivers/acpi/dispatcher/dsmethod.c
+++ b/drivers/acpi/dispatcher/dsmethod.c
@@ -145,8 +145,9 @@ acpi_ds_parse_method (
return_ACPI_STATUS (AE_NO_MEMORY);
}
- status = acpi_ds_init_aml_walk (walk_state, op, node, obj_desc->method.aml_start,
- obj_desc->method.aml_length, NULL, NULL, 1);
+ status = acpi_ds_init_aml_walk (walk_state, op, node,
+ obj_desc->method.aml_start,
+ obj_desc->method.aml_length, NULL, 1);
if (ACPI_FAILURE (status)) {
acpi_ds_delete_walk_state (walk_state);
return_ACPI_STATUS (status);
@@ -267,8 +268,9 @@ acpi_ds_call_control_method (
{
acpi_status status;
struct acpi_namespace_node *method_node;
- union acpi_operand_object *obj_desc;
struct acpi_walk_state *next_walk_state;
+ union acpi_operand_object *obj_desc;
+ struct acpi_parameter_info info;
u32 i;
@@ -309,7 +311,6 @@ acpi_ds_call_control_method (
return_ACPI_STATUS (AE_NO_MEMORY);
}
-
/* Create and init a Root Node */
op = acpi_ps_create_scope_op ();
@@ -320,7 +321,7 @@ acpi_ds_call_control_method (
status = acpi_ds_init_aml_walk (next_walk_state, op, method_node,
obj_desc->method.aml_start, obj_desc->method.aml_length,
- NULL, NULL, 1);
+ NULL, 1);
if (ACPI_FAILURE (status)) {
acpi_ds_delete_walk_state (next_walk_state);
goto cleanup;
@@ -348,9 +349,12 @@ acpi_ds_call_control_method (
*/
this_walk_state->operands [this_walk_state->num_operands] = NULL;
+ info.parameters = &this_walk_state->operands[0];
+ info.parameter_type = ACPI_PARAM_ARGS;
+
status = acpi_ds_init_aml_walk (next_walk_state, NULL, method_node,
obj_desc->method.aml_start, obj_desc->method.aml_length,
- &this_walk_state->operands[0], NULL, 3);
+ &info, 3);
if (ACPI_FAILURE (status)) {
goto cleanup;
}
diff --git a/drivers/acpi/dispatcher/dsopcode.c b/drivers/acpi/dispatcher/dsopcode.c
index e0a313f57509..377edfae9440 100644
--- a/drivers/acpi/dispatcher/dsopcode.c
+++ b/drivers/acpi/dispatcher/dsopcode.c
@@ -105,7 +105,7 @@ acpi_ds_execute_arguments (
}
status = acpi_ds_init_aml_walk (walk_state, op, NULL, aml_start,
- aml_length, NULL, NULL, 1);
+ aml_length, NULL, 1);
if (ACPI_FAILURE (status)) {
acpi_ds_delete_walk_state (walk_state);
return_ACPI_STATUS (status);
@@ -150,7 +150,7 @@ acpi_ds_execute_arguments (
/* Execute the opcode and arguments */
status = acpi_ds_init_aml_walk (walk_state, op, NULL, aml_start,
- aml_length, NULL, NULL, 3);
+ aml_length, NULL, 3);
if (ACPI_FAILURE (status)) {
acpi_ds_delete_walk_state (walk_state);
return_ACPI_STATUS (status);
diff --git a/drivers/acpi/dispatcher/dswstate.c b/drivers/acpi/dispatcher/dswstate.c
index 2b39562264bf..81c6b46acda0 100644
--- a/drivers/acpi/dispatcher/dswstate.c
+++ b/drivers/acpi/dispatcher/dswstate.c
@@ -906,8 +906,7 @@ acpi_ds_init_aml_walk (
struct acpi_namespace_node *method_node,
u8 *aml_start,
u32 aml_length,
- union acpi_operand_object **params,
- union acpi_operand_object **return_obj_desc,
+ struct acpi_parameter_info *info,
u32 pass_number)
{
acpi_status status;
@@ -926,8 +925,17 @@ acpi_ds_init_aml_walk (
/* The next_op of the next_walk will be the beginning of the method */
walk_state->next_op = NULL;
- walk_state->params = params;
- walk_state->caller_return_desc = return_obj_desc;
+
+ if (info) {
+ if (info->parameter_type == ACPI_PARAM_GPE) {
+ walk_state->gpe_event_info = ACPI_CAST_PTR (struct acpi_gpe_event_info,
+ info->parameters);
+ }
+ else {
+ walk_state->params = info->parameters;
+ walk_state->caller_return_desc = &info->return_object;
+ }
+ }
status = acpi_ps_init_scope (&walk_state->parser_state, op);
if (ACPI_FAILURE (status)) {
@@ -949,7 +957,7 @@ acpi_ds_init_aml_walk (
/* Init the method arguments */
- status = acpi_ds_method_data_init_args (params, ACPI_METHOD_NUM_ARGS, walk_state);
+ status = acpi_ds_method_data_init_args (walk_state->params, ACPI_METHOD_NUM_ARGS, walk_state);
if (ACPI_FAILURE (status)) {
return_ACPI_STATUS (status);
}
diff --git a/drivers/acpi/events/evevent.c b/drivers/acpi/events/evevent.c
index abdb3a5a2ed8..558ec7b33756 100644
--- a/drivers/acpi/events/evevent.c
+++ b/drivers/acpi/events/evevent.c
@@ -50,7 +50,7 @@
/*******************************************************************************
*
- * FUNCTION: acpi_ev_initialize
+ * FUNCTION: acpi_ev_initialize_events
*
* PARAMETERS: None
*
@@ -61,13 +61,13 @@
******************************************************************************/
acpi_status
-acpi_ev_initialize (
+acpi_ev_initialize_events (
void)
{
acpi_status status;
- ACPI_FUNCTION_TRACE ("ev_initialize");
+ ACPI_FUNCTION_TRACE ("ev_initialize_events");
/* Make sure we have ACPI tables */
@@ -104,7 +104,7 @@ acpi_ev_initialize (
/*******************************************************************************
*
- * FUNCTION: acpi_ev_handler_initialize
+ * FUNCTION: acpi_ev_install_xrupt_handlers
*
* PARAMETERS: None
*
@@ -115,13 +115,13 @@ acpi_ev_initialize (
******************************************************************************/
acpi_status
-acpi_ev_handler_initialize (
+acpi_ev_install_xrupt_handlers (
void)
{
acpi_status status;
- ACPI_FUNCTION_TRACE ("ev_handler_initialize");
+ ACPI_FUNCTION_TRACE ("ev_install_xrupt_handlers");
/* Install the SCI handler */
diff --git a/drivers/acpi/events/evgpe.c b/drivers/acpi/events/evgpe.c
index 221dca54d799..dba66b50c347 100644
--- a/drivers/acpi/events/evgpe.c
+++ b/drivers/acpi/events/evgpe.c
@@ -51,6 +51,244 @@
/*******************************************************************************
*
+ * FUNCTION: acpi_ev_set_gpe_type
+ *
+ * PARAMETERS: gpe_event_info - GPE to set
+ * Type - New type
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Sets the new type for the GPE (wake, run, or wake/run)
+ *
+ ******************************************************************************/
+
+acpi_status
+acpi_ev_set_gpe_type (
+ struct acpi_gpe_event_info *gpe_event_info,
+ u8 type)
+{
+ ACPI_FUNCTION_TRACE ("ev_set_gpe_type");
+
+
+ /* Validate type and update register enable masks */
+
+ switch (type) {
+ case ACPI_GPE_TYPE_WAKE:
+ case ACPI_GPE_TYPE_RUNTIME:
+ case ACPI_GPE_TYPE_WAKE_RUN:
+ break;
+
+ default:
+ return_ACPI_STATUS (AE_BAD_PARAMETER);
+ }
+
+ /* Disable the GPE if currently enabled */
+
+ acpi_ev_disable_gpe (gpe_event_info);
+
+ /* Type was validated above */
+
+ gpe_event_info->flags &= ~ACPI_GPE_TYPE_MASK; /* Clear type bits */
+ gpe_event_info->flags |= type; /* Insert type */
+ return_ACPI_STATUS (AE_OK);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: acpi_ev_update_gpe_enable_masks
+ *
+ * PARAMETERS: gpe_event_info - GPE to update
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Updates GPE register enable masks based on the GPE type
+ *
+ ******************************************************************************/
+
+acpi_status
+acpi_ev_update_gpe_enable_masks (
+ struct acpi_gpe_event_info *gpe_event_info,
+ u8 type)
+{
+ struct acpi_gpe_register_info *gpe_register_info;
+ u8 register_bit;
+
+
+ ACPI_FUNCTION_TRACE ("ev_update_gpe_enable_masks");
+
+
+ gpe_register_info = gpe_event_info->register_info;
+ if (!gpe_register_info) {
+ return_ACPI_STATUS (AE_NOT_EXIST);
+ }
+ register_bit = gpe_event_info->register_bit;
+
+ /* 1) Disable case. Simply clear all enable bits */
+
+ if (type == ACPI_GPE_DISABLE) {
+ gpe_register_info->enable_for_wake &= ~register_bit;
+ gpe_register_info->enable_for_run &= ~register_bit;
+ return_ACPI_STATUS (AE_OK);
+ }
+
+ /* 2) Enable case. Set the appropriate enable bits */
+
+ switch (gpe_event_info->flags & ACPI_GPE_TYPE_MASK) {
+ case ACPI_GPE_TYPE_WAKE:
+ gpe_register_info->enable_for_wake |= register_bit;
+ gpe_register_info->enable_for_run &= ~register_bit;
+ break;
+
+ case ACPI_GPE_TYPE_RUNTIME:
+ gpe_register_info->enable_for_wake &= ~register_bit;
+ gpe_register_info->enable_for_run |= register_bit;
+ break;
+
+ case ACPI_GPE_TYPE_WAKE_RUN:
+ gpe_register_info->enable_for_wake |= register_bit;
+ gpe_register_info->enable_for_run |= register_bit;
+ break;
+
+ default:
+ return_ACPI_STATUS (AE_BAD_PARAMETER);
+ }
+
+ return_ACPI_STATUS (AE_OK);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: acpi_ev_enable_gpe
+ *
+ * PARAMETERS: gpe_event_info - GPE to enable
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Enable a GPE based on the GPE type
+ *
+ ******************************************************************************/
+
+acpi_status
+acpi_ev_enable_gpe (
+ struct acpi_gpe_event_info *gpe_event_info,
+ u8 write_to_hardware)
+{
+ acpi_status status;
+
+
+ ACPI_FUNCTION_TRACE ("ev_enable_gpe");
+
+
+ /* Make sure HW enable masks are updated */
+
+ status = acpi_ev_update_gpe_enable_masks (gpe_event_info, ACPI_GPE_ENABLE);
+ if (ACPI_FAILURE (status)) {
+ return_ACPI_STATUS (status);
+ }
+
+ /* Mark wake-enabled or HW enable, or both */
+
+ switch (gpe_event_info->flags & ACPI_GPE_TYPE_MASK) {
+ case ACPI_GPE_TYPE_WAKE:
+ gpe_event_info->flags |= ACPI_GPE_WAKE_ENABLED;
+ break;
+
+ case ACPI_GPE_TYPE_WAKE_RUN:
+ gpe_event_info->flags |= ACPI_GPE_WAKE_ENABLED;
+
+ /* Fallthrough */
+
+ case ACPI_GPE_TYPE_RUNTIME:
+
+ gpe_event_info->flags |= ACPI_GPE_RUN_ENABLED;
+
+ if (write_to_hardware) {
+ /* Clear the GPE (of stale events), then enable it */
+
+ status = acpi_hw_clear_gpe (gpe_event_info);
+ if (ACPI_FAILURE (status)) {
+ return_ACPI_STATUS (status);
+ }
+
+ /* Enable the requested runtime GPE */
+
+ status = acpi_hw_enable_gpe (gpe_event_info);
+ }
+ break;
+
+ default:
+ return_ACPI_STATUS (AE_BAD_PARAMETER);
+ }
+
+ return_ACPI_STATUS (AE_OK);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: acpi_ev_disable_gpe
+ *
+ * PARAMETERS: gpe_event_info - GPE to disable
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Disable a GPE based on the GPE type
+ *
+ ******************************************************************************/
+
+acpi_status
+acpi_ev_disable_gpe (
+ struct acpi_gpe_event_info *gpe_event_info)
+{
+ acpi_status status;
+
+
+ ACPI_FUNCTION_TRACE ("ev_disable_gpe");
+
+
+ if (!(gpe_event_info->flags & ACPI_GPE_ENABLE_MASK)) {
+ return_ACPI_STATUS (AE_OK);
+ }
+
+ /* Make sure HW enable masks are updated */
+
+ status = acpi_ev_update_gpe_enable_masks (gpe_event_info, ACPI_GPE_DISABLE);
+ if (ACPI_FAILURE (status)) {
+ return_ACPI_STATUS (status);
+ }
+
+ /* Mark wake-disabled or HW disable, or both */
+
+ switch (gpe_event_info->flags & ACPI_GPE_TYPE_MASK) {
+ case ACPI_GPE_TYPE_WAKE:
+ gpe_event_info->flags &= ~ACPI_GPE_WAKE_ENABLED;
+ break;
+
+ case ACPI_GPE_TYPE_WAKE_RUN:
+ gpe_event_info->flags &= ~ACPI_GPE_WAKE_ENABLED;
+
+ /* Fallthrough */
+
+ case ACPI_GPE_TYPE_RUNTIME:
+
+ /* Disable the requested runtime GPE */
+
+ gpe_event_info->flags &= ~ACPI_GPE_RUN_ENABLED;
+ status = acpi_hw_disable_gpe (gpe_event_info);
+ break;
+
+ default:
+ return_ACPI_STATUS (AE_BAD_PARAMETER);
+ }
+
+ return_ACPI_STATUS (AE_OK);
+}
+
+
+/*******************************************************************************
+ *
* FUNCTION: acpi_ev_get_gpe_event_info
*
* PARAMETERS: gpe_device - Device node. NULL for GPE0/GPE1
@@ -139,7 +377,8 @@ acpi_ev_gpe_detect (
u32 int_status = ACPI_INTERRUPT_NOT_HANDLED;
u8 enabled_status_byte;
struct acpi_gpe_register_info *gpe_register_info;
- u32 in_value;
+ u32 status_reg;
+ u32 enable_reg;
acpi_status status;
struct acpi_gpe_block_info *gpe_block;
u32 i;
@@ -171,33 +410,32 @@ acpi_ev_gpe_detect (
/* Read the Status Register */
- status = acpi_hw_low_level_read (ACPI_GPE_REGISTER_WIDTH, &in_value,
+ status = acpi_hw_low_level_read (ACPI_GPE_REGISTER_WIDTH, &status_reg,
&gpe_register_info->status_address);
- gpe_register_info->status = (u8) in_value;
if (ACPI_FAILURE (status)) {
goto unlock_and_exit;
}
/* Read the Enable Register */
- status = acpi_hw_low_level_read (ACPI_GPE_REGISTER_WIDTH, &in_value,
+ status = acpi_hw_low_level_read (ACPI_GPE_REGISTER_WIDTH, &enable_reg,
&gpe_register_info->enable_address);
- gpe_register_info->enable = (u8) in_value;
if (ACPI_FAILURE (status)) {
goto unlock_and_exit;
}
ACPI_DEBUG_PRINT ((ACPI_DB_INTERRUPTS,
"GPE pair: Status %8.8X%8.8X = %02X, Enable %8.8X%8.8X = %02X\n",
- ACPI_FORMAT_UINT64 (gpe_register_info->status_address.address),
- gpe_register_info->status,
- ACPI_FORMAT_UINT64 (gpe_register_info->enable_address.address),
- gpe_register_info->enable));
+ ACPI_FORMAT_UINT64 (
+ gpe_register_info->status_address.address),
+ status_reg,
+ ACPI_FORMAT_UINT64 (
+ gpe_register_info->enable_address.address),
+ enable_reg));
/* First check if there is anything active at all in this register */
- enabled_status_byte = (u8) (gpe_register_info->status &
- gpe_register_info->enable);
+ enabled_status_byte = (u8) (status_reg & enable_reg);
if (!enabled_status_byte) {
/* No active GPEs in this register, move on */
@@ -255,6 +493,7 @@ acpi_ev_asynch_execute_gpe_method (
u32 gpe_number = 0;
acpi_status status;
struct acpi_gpe_event_info local_gpe_event_info;
+ struct acpi_parameter_info info;
ACPI_FUNCTION_TRACE ("ev_asynch_execute_gpe_method");
@@ -283,23 +522,33 @@ acpi_ev_asynch_execute_gpe_method (
return_VOID;
}
- if (local_gpe_event_info.method_node) {
+ /*
+ * Must check for control method type dispatch one more
+ * time to avoid race with ev_gpe_install_handler
+ */
+ if ((local_gpe_event_info.flags & ACPI_GPE_DISPATCH_MASK) == ACPI_GPE_DISPATCH_METHOD) {
/*
- * Invoke the GPE Method (_Lxx, _Exx):
- * (Evaluate the _Lxx/_Exx control method that corresponds to this GPE.)
+ * Invoke the GPE Method (_Lxx, _Exx) i.e., evaluate the _Lxx/_Exx
+ * control method that corresponds to this GPE
*/
- status = acpi_ns_evaluate_by_handle (local_gpe_event_info.method_node, NULL, NULL);
+ info.node = local_gpe_event_info.dispatch.method_node;
+ info.parameters = ACPI_CAST_PTR (union acpi_operand_object *, gpe_event_info);
+ info.parameter_type = ACPI_PARAM_GPE;
+
+ status = acpi_ns_evaluate_by_handle (&info);
if (ACPI_FAILURE (status)) {
- ACPI_REPORT_ERROR (("%s while evaluating method [%4.4s] for GPE[%2X]\n",
+ ACPI_REPORT_ERROR ((
+ "%s while evaluating method [%4.4s] for GPE[%2X]\n",
acpi_format_exception (status),
- acpi_ut_get_node_name (local_gpe_event_info.method_node), gpe_number));
+ acpi_ut_get_node_name (local_gpe_event_info.dispatch.method_node),
+ gpe_number));
}
}
if ((local_gpe_event_info.flags & ACPI_GPE_XRUPT_TYPE_MASK) == ACPI_GPE_LEVEL_TRIGGERED) {
/*
- * GPE is level-triggered, we clear the GPE status bit after handling
- * the event.
+ * GPE is level-triggered, we clear the GPE status bit after
+ * handling the event.
*/
status = acpi_hw_clear_gpe (&local_gpe_event_info);
if (ACPI_FAILURE (status)) {
@@ -354,6 +603,15 @@ acpi_ev_gpe_dispatch (
}
}
+ /* Save current system state */
+
+ if (acpi_gbl_system_awake_and_running) {
+ gpe_event_info->flags |= ACPI_GPE_SYSTEM_RUNNING;
+ }
+ else {
+ gpe_event_info->flags &= ~ACPI_GPE_SYSTEM_RUNNING;
+ }
+
/*
* Dispatch the GPE to either an installed handler, or the control
* method associated with this GPE (_Lxx or _Exx).
@@ -361,10 +619,13 @@ acpi_ev_gpe_dispatch (
* If there is neither a handler nor a method, we disable the level to
* prevent further events from coming in here.
*/
- if (gpe_event_info->handler) {
+ switch (gpe_event_info->flags & ACPI_GPE_DISPATCH_MASK) {
+ case ACPI_GPE_DISPATCH_HANDLER:
+
/* Invoke the installed handler (at interrupt level) */
- gpe_event_info->handler (gpe_event_info->context);
+ gpe_event_info->dispatch.handler->address (
+ gpe_event_info->dispatch.handler->context);
/* It is now safe to clear level-triggered events. */
@@ -377,8 +638,10 @@ acpi_ev_gpe_dispatch (
return_VALUE (ACPI_INTERRUPT_NOT_HANDLED);
}
}
- }
- else if (gpe_event_info->method_node) {
+ break;
+
+ case ACPI_GPE_DISPATCH_METHOD:
+
/*
* Disable GPE, so it doesn't keep firing before the method has a
* chance to run.
@@ -402,8 +665,10 @@ acpi_ev_gpe_dispatch (
"acpi_ev_gpe_dispatch: Unable to queue handler for GPE[%2X], event is disabled\n",
gpe_number));
}
- }
- else {
+ break;
+
+ default:
+
/* No handler or method to run! */
ACPI_REPORT_ERROR ((
@@ -421,8 +686,61 @@ acpi_ev_gpe_dispatch (
gpe_number));
return_VALUE (ACPI_INTERRUPT_NOT_HANDLED);
}
+ break;
}
return_VALUE (ACPI_INTERRUPT_HANDLED);
}
+
+#ifdef ACPI_GPE_NOTIFY_CHECK
+
+/*******************************************************************************
+ * NOT USED, PROTOTYPE ONLY AND WILL PROBABLY BE REMOVED
+ *
+ * FUNCTION: acpi_ev_check_for_wake_only_gpe
+ *
+ * PARAMETERS: gpe_event_info - info for this GPE
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Determine if a a GPE is "wake-only".
+ *
+ * Called from Notify() code in interpreter when a "device_wake"
+ * Notify comes in.
+ *
+ ******************************************************************************/
+
+acpi_status
+acpi_ev_check_for_wake_only_gpe (
+ struct acpi_gpe_event_info *gpe_event_info)
+{
+ acpi_status status;
+
+
+ ACPI_FUNCTION_TRACE ("ev_check_for_wake_only_gpe");
+
+
+ if ((gpe_event_info) && /* Only >0 for _Lxx/_Exx */
+ ((gpe_event_info->flags & ACPI_GPE_SYSTEM_MASK) == ACPI_GPE_SYSTEM_RUNNING)) /* System state at GPE time */ {
+ /* This must be a wake-only GPE, disable it */
+
+ status = acpi_hw_disable_gpe (gpe_event_info);
+
+ /* Set GPE to wake-only. Do not change wake disabled/enabled status */
+
+ acpi_ev_set_gpe_type (gpe_event_info, ACPI_GPE_TYPE_WAKE);
+
+ ACPI_REPORT_INFO (("GPE %p was updated from wake/run to wake-only\n",
+ gpe_event_info));
+
+ /* This was a wake-only GPE */
+
+ return_ACPI_STATUS (AE_WAKE_ONLY_GPE);
+ }
+
+ return_ACPI_STATUS (AE_OK);
+}
+#endif
+
+
diff --git a/drivers/acpi/events/evgpeblk.c b/drivers/acpi/events/evgpeblk.c
index b6641e11cc28..9f756e0ed7ae 100644
--- a/drivers/acpi/events/evgpeblk.c
+++ b/drivers/acpi/events/evgpeblk.c
@@ -53,7 +53,7 @@
*
* FUNCTION: acpi_ev_valid_gpe_event
*
- * PARAMETERS: gpe_event_info - Info for this GPE
+ * PARAMETERS: gpe_event_info - Info for this GPE
*
* RETURN: TRUE if the gpe_event is valid
*
@@ -154,6 +154,50 @@ unlock_and_exit:
}
+/******************************************************************************
+ *
+ * FUNCTION: acpi_ev_delete_gpe_handlers
+ *
+ * PARAMETERS: gpe_xrupt_info - GPE Interrupt info
+ * gpe_block - Gpe Block info
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Delete all Handler objects found in the GPE data structs.
+ * Used only prior to termination.
+ *
+ ******************************************************************************/
+
+acpi_status
+acpi_ev_delete_gpe_handlers (
+ struct acpi_gpe_xrupt_info *gpe_xrupt_info,
+ struct acpi_gpe_block_info *gpe_block)
+{
+ struct acpi_gpe_event_info *gpe_event_info;
+ u32 i;
+ u32 j;
+
+
+ /* Examine each GPE Register within the block */
+
+ for (i = 0; i < gpe_block->register_count; i++) {
+ /* Now look at the individual GPEs in this byte register */
+
+ for (j = 0; j < ACPI_GPE_REGISTER_WIDTH; j++) {
+ gpe_event_info = &gpe_block->event_info[(i * ACPI_GPE_REGISTER_WIDTH) + j];
+
+ if ((gpe_event_info->flags & ACPI_GPE_DISPATCH_MASK) == ACPI_GPE_DISPATCH_HANDLER) {
+ ACPI_MEM_FREE (gpe_event_info->dispatch.handler);
+ gpe_event_info->dispatch.handler = NULL;
+ gpe_event_info->flags &= ~ACPI_GPE_DISPATCH_MASK;
+ }
+ }
+ }
+
+ return (AE_OK);
+}
+
+
/*******************************************************************************
*
* FUNCTION: acpi_ev_save_method_info
@@ -206,16 +250,16 @@ acpi_ev_save_method_info (
* 2) Edge/Level determination is based on the 2nd character
* of the method name
*
- * NOTE: Default GPE type is RUNTIME. May be changed later to WAKE if a
- * _PRW object is found that points to this GPE.
+ * NOTE: Default GPE type is RUNTIME. May be changed later to WAKE
+ * if a _PRW object is found that points to this GPE.
*/
switch (name[1]) {
case 'L':
- type = ACPI_GPE_LEVEL_TRIGGERED | ACPI_GPE_TYPE_RUNTIME;
+ type = ACPI_GPE_LEVEL_TRIGGERED;
break;
case 'E':
- type = ACPI_GPE_EDGE_TRIGGERED | ACPI_GPE_TYPE_RUNTIME;
+ type = ACPI_GPE_EDGE_TRIGGERED;
break;
default:
@@ -253,12 +297,19 @@ acpi_ev_save_method_info (
/*
* Now we can add this information to the gpe_event_info block
- * for use during dispatch of this GPE.
+ * for use during dispatch of this GPE. Default type is RUNTIME, although
+ * this may change when the _PRW methods are executed later.
*/
gpe_event_info = &gpe_block->event_info[gpe_number - gpe_block->block_base_number];
- gpe_event_info->flags = type;
- gpe_event_info->method_node = (struct acpi_namespace_node *) obj_handle;
+ gpe_event_info->flags = (u8) (type | ACPI_GPE_DISPATCH_METHOD |
+ ACPI_GPE_TYPE_RUNTIME);
+
+ gpe_event_info->dispatch.method_node = (struct acpi_namespace_node *) obj_handle;
+
+ /* Update enable mask, but don't enable the HW GPE as of yet */
+
+ acpi_ev_enable_gpe (gpe_event_info, FALSE);
ACPI_DEBUG_PRINT ((ACPI_DB_LOAD,
"Registered GPE method %s as GPE number 0x%.2X\n",
@@ -269,7 +320,7 @@ acpi_ev_save_method_info (
/*******************************************************************************
*
- * FUNCTION: acpi_ev_get_gpe_type
+ * FUNCTION: acpi_ev_match_prw_and_gpe
*
* PARAMETERS: Callback from walk_namespace
*
@@ -282,7 +333,7 @@ acpi_ev_save_method_info (
******************************************************************************/
static acpi_status
-acpi_ev_get_gpe_type (
+acpi_ev_match_prw_and_gpe (
acpi_handle obj_handle,
u32 level,
void *info,
@@ -299,7 +350,7 @@ acpi_ev_get_gpe_type (
acpi_status status;
- ACPI_FUNCTION_TRACE ("ev_get_gpe_type");
+ ACPI_FUNCTION_TRACE ("ev_match_prw_and_gpe");
/* Check for a _PRW method under this device */
@@ -369,10 +420,13 @@ acpi_ev_get_gpe_type (
if ((gpe_device == target_gpe_device) &&
(gpe_number >= gpe_block->block_base_number) &&
(gpe_number < gpe_block->block_base_number + (gpe_block->register_count * 8))) {
- /* Mark GPE for WAKE but DISABLED (even for wake) */
-
gpe_event_info = &gpe_block->event_info[gpe_number - gpe_block->block_base_number];
- gpe_event_info->flags |= ACPI_GPE_TYPE_WAKE;
+
+ /* Mark GPE for WAKE-ONLY but WAKE_DISABLED */
+
+ gpe_event_info->flags &= ~(ACPI_GPE_WAKE_ENABLED | ACPI_GPE_RUN_ENABLED);
+ acpi_ev_set_gpe_type (gpe_event_info, ACPI_GPE_TYPE_WAKE);
+ acpi_ev_update_gpe_enable_masks (gpe_event_info, ACPI_GPE_DISABLE);
}
cleanup:
@@ -740,7 +794,7 @@ acpi_ev_create_gpe_info_blocks (
/* Init the event_info for each GPE within this register */
for (j = 0; j < ACPI_GPE_REGISTER_WIDTH; j++) {
- this_event->bit_mask = acpi_gbl_decode_to8bit[j];
+ this_event->register_bit = acpi_gbl_decode_to8bit[j];
this_event->register_info = this_register;
this_event++;
}
@@ -815,6 +869,7 @@ acpi_ev_create_gpe_block (
acpi_status status;
struct acpi_gpe_walk_info gpe_info;
+
ACPI_FUNCTION_TRACE ("ev_create_gpe_block");
@@ -833,6 +888,7 @@ acpi_ev_create_gpe_block (
gpe_block->register_count = register_count;
gpe_block->block_base_number = gpe_block_base_number;
+ gpe_block->node = gpe_device;
ACPI_MEMCPY (&gpe_block->block_address, gpe_block_address, sizeof (struct acpi_generic_address));
@@ -852,18 +908,6 @@ acpi_ev_create_gpe_block (
return_ACPI_STATUS (status);
}
- /* Dump info about this GPE block */
-
- ACPI_DEBUG_PRINT ((ACPI_DB_INIT,
- "GPE %02d to %02d [%4.4s] %d regs at %8.8X%8.8X on int %d\n",
- gpe_block->block_base_number,
- (u32) (gpe_block->block_base_number +
- ((gpe_block->register_count * ACPI_GPE_REGISTER_WIDTH) -1)),
- gpe_device->name.ascii,
- gpe_block->register_count,
- ACPI_FORMAT_UINT64 (gpe_block->block_address.address),
- interrupt_level));
-
/* Find all GPE methods (_Lxx, _Exx) for this block */
status = acpi_ns_walk_namespace (ACPI_TYPE_METHOD, gpe_device,
@@ -871,27 +915,28 @@ acpi_ev_create_gpe_block (
gpe_block, NULL);
/*
- * 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.
+ * 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.
*/
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.)
+ * 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.)
*/
gpe_info.gpe_block = gpe_block;
gpe_info.gpe_device = gpe_device;
status = acpi_ns_walk_namespace (ACPI_TYPE_DEVICE, ACPI_ROOT_OBJECT,
- ACPI_UINT32_MAX, ACPI_NS_WALK_UNLOCK, acpi_ev_get_gpe_type,
+ ACPI_UINT32_MAX, ACPI_NS_WALK_UNLOCK, acpi_ev_match_prw_and_gpe,
&gpe_info, NULL);
}
/*
- * Enable all GPEs in this block that are 1) "runtime" GPEs, and 2) have
- * a corresponding _Lxx or _Exx method. All other GPEs must be enabled via
- * the acpi_enable_gpe() external interface.
+ * Enable all GPEs in this block that are 1) "runtime" or "run/wake" GPEs,
+ * and 2) have a corresponding _Lxx or _Exx method. All other GPEs must
+ * be enabled via the acpi_enable_gpe() external interface.
*/
wake_gpe_count = 0;
gpe_enabled_count = 0;
@@ -901,23 +946,35 @@ acpi_ev_create_gpe_block (
/* Get the info block for this particular GPE */
gpe_event_info = &gpe_block->event_info[(i * ACPI_GPE_REGISTER_WIDTH) + j];
- if ((gpe_event_info->method_node) &&
- ((gpe_event_info->flags & ACPI_GPE_TYPE_MASK) == ACPI_GPE_TYPE_RUNTIME)) {
- /* Enable this GPE, it is 1) RUNTIME and 2) has an _Lxx or _Exx method */
-
- status = acpi_hw_enable_gpe (gpe_event_info);
- if (ACPI_FAILURE (status)) {
- return_ACPI_STATUS (status);
- }
+
+ if (((gpe_event_info->flags & ACPI_GPE_DISPATCH_MASK) == ACPI_GPE_DISPATCH_METHOD) &&
+ (gpe_event_info->flags & ACPI_GPE_TYPE_RUNTIME)) {
gpe_enabled_count++;
}
- if ((gpe_event_info->flags & ACPI_GPE_TYPE_MASK) == ACPI_GPE_TYPE_WAKE) {
+ if (gpe_event_info->flags & ACPI_GPE_TYPE_WAKE) {
wake_gpe_count++;
}
}
}
+ /* Dump info about this GPE block */
+
+ ACPI_DEBUG_PRINT ((ACPI_DB_INIT,
+ "GPE %02d to %02d [%4.4s] %d regs at %8.8X%8.8X on int %d\n",
+ gpe_block->block_base_number,
+ (u32) (gpe_block->block_base_number +
+ ((gpe_block->register_count * ACPI_GPE_REGISTER_WIDTH) -1)),
+ gpe_device->name.ascii,
+ gpe_block->register_count,
+ ACPI_FORMAT_UINT64 (gpe_block->block_address.address),
+ interrupt_level));
+
+
+ /* Enable all valid GPEs found above */
+
+ status = acpi_hw_enable_runtime_gpe_block (NULL, gpe_block);
+
ACPI_DEBUG_PRINT ((ACPI_DB_INIT,
"Found %u Wake, Enabled %u Runtime GPEs in this block\n",
wake_gpe_count, gpe_enabled_count));
@@ -1054,7 +1111,8 @@ acpi_ev_gpe_initialize (
if ((register_count0 + register_count1) == 0) {
/* GPEs are not required by ACPI, this is OK */
- ACPI_REPORT_INFO (("There are no GPE blocks defined in the FADT\n"));
+ ACPI_DEBUG_PRINT ((ACPI_DB_INIT,
+ "There are no GPE blocks defined in the FADT\n"));
status = AE_OK;
goto cleanup;
}
diff --git a/drivers/acpi/events/evmisc.c b/drivers/acpi/events/evmisc.c
index caafe802c303..de0a6fa24c50 100644
--- a/drivers/acpi/events/evmisc.c
+++ b/drivers/acpi/events/evmisc.c
@@ -557,6 +557,10 @@ acpi_ev_terminate (void)
}
}
+ /* Deallocate all handler objects installed within GPE info structs */
+
+ status = acpi_ev_walk_gpe_list (acpi_ev_delete_gpe_handlers);
+
/* Return to original mode if necessary */
if (acpi_gbl_original_mode == ACPI_SYS_MODE_LEGACY) {
diff --git a/drivers/acpi/events/evregion.c b/drivers/acpi/events/evregion.c
index ec81e587f6d7..1a98937586da 100644
--- a/drivers/acpi/events/evregion.c
+++ b/drivers/acpi/events/evregion.c
@@ -61,7 +61,7 @@ static u8 acpi_gbl_default_address_spaces[ACPI_NUM_DEFAULT_SPA
/*******************************************************************************
*
- * FUNCTION: acpi_ev_init_address_spaces
+ * FUNCTION: acpi_ev_install_region_handlers
*
* PARAMETERS: None
*
@@ -72,15 +72,20 @@ static u8 acpi_gbl_default_address_spaces[ACPI_NUM_DEFAULT_SPA
******************************************************************************/
acpi_status
-acpi_ev_init_address_spaces (
+acpi_ev_install_region_handlers (
void) {
acpi_status status;
acpi_native_uint i;
- ACPI_FUNCTION_TRACE ("ev_init_address_spaces");
+ ACPI_FUNCTION_TRACE ("ev_install_region_handlers");
+ status = acpi_ut_acquire_mutex (ACPI_MTX_NAMESPACE);
+ if (ACPI_FAILURE (status)) {
+ return_ACPI_STATUS (status);
+ }
+
/*
* All address spaces (PCI Config, EC, SMBus) are scope dependent
* and registration must occur for a specific device.
@@ -99,9 +104,8 @@ acpi_ev_init_address_spaces (
* has already been installed (via acpi_install_address_space_handler).
* Similar for AE_SAME_HANDLER.
*/
-
for (i = 0; i < ACPI_NUM_DEFAULT_SPACES; i++) {
- status = acpi_install_address_space_handler ((acpi_handle) acpi_gbl_root_node,
+ status = acpi_ev_install_space_handler (acpi_gbl_root_node,
acpi_gbl_default_address_spaces[i],
ACPI_DEFAULT_HANDLER, NULL, NULL);
switch (status) {
@@ -111,15 +115,63 @@ acpi_ev_init_address_spaces (
/* These exceptions are all OK */
+ status = AE_OK;
break;
default:
- return_ACPI_STATUS (status);
+ goto unlock_and_exit;
}
}
- return_ACPI_STATUS (AE_OK);
+unlock_and_exit:
+ (void) acpi_ut_release_mutex (ACPI_MTX_NAMESPACE);
+ return_ACPI_STATUS (status);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: acpi_ev_initialize_op_regions
+ *
+ * PARAMETERS: None
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Execute _REG methods for all Operation Regions that have
+ * an installed default region handler.
+ *
+ ******************************************************************************/
+
+acpi_status
+acpi_ev_initialize_op_regions (
+ void)
+{
+ acpi_status status;
+ acpi_native_uint i;
+
+
+ ACPI_FUNCTION_TRACE ("ev_initialize_op_regions");
+
+
+ status = acpi_ut_acquire_mutex (ACPI_MTX_NAMESPACE);
+ if (ACPI_FAILURE (status)) {
+ return_ACPI_STATUS (status);
+ }
+
+ /*
+ * Run the _REG methods for op_regions in each default address space
+ */
+ for (i = 0; i < ACPI_NUM_DEFAULT_SPACES; i++) {
+ /* TBD: Make sure handler is the DEFAULT handler, otherwise
+ * _REG will have already been run.
+ */
+ status = acpi_ev_execute_reg_methods (acpi_gbl_root_node,
+ acpi_gbl_default_address_spaces[i]);
+ }
+
+ (void) acpi_ut_release_mutex (ACPI_MTX_NAMESPACE);
+ return_ACPI_STATUS (status);
}
@@ -138,11 +190,12 @@ acpi_ev_init_address_spaces (
acpi_status
acpi_ev_execute_reg_method (
- union acpi_operand_object *region_obj,
+ union acpi_operand_object *region_obj,
u32 function)
{
- union acpi_operand_object *params[3];
- union acpi_operand_object *region_obj2;
+ struct acpi_parameter_info info;
+ union acpi_operand_object *params[3];
+ union acpi_operand_object *region_obj2;
acpi_status status;
@@ -159,10 +212,11 @@ acpi_ev_execute_reg_method (
}
/*
- * _REG method has two arguments
- * Arg0: Integer: Operation region space ID
+ * The _REG method has two arguments:
+ *
+ * Arg0, Integer: Operation region space ID
* Same value as region_obj->Region.space_id
- * Arg1: Integer: connection status
+ * Arg1, Integer: connection status
* 1 for connecting the handler,
* 0 for disconnecting the handler
* Passed as a parameter
@@ -184,10 +238,15 @@ acpi_ev_execute_reg_method (
params[1]->integer.value = function;
params[2] = NULL;
+ info.node = region_obj2->extra.method_REG;
+ info.parameters = params;
+ info.parameter_type = ACPI_PARAM_ARGS;
+
/* Execute the method, no return value */
- ACPI_DEBUG_EXEC(acpi_ut_display_init_pathname (ACPI_TYPE_METHOD, region_obj2->extra.method_REG, NULL));
- status = acpi_ns_evaluate_by_handle (region_obj2->extra.method_REG, params, NULL);
+ ACPI_DEBUG_EXEC (acpi_ut_display_init_pathname (
+ ACPI_TYPE_METHOD, info.node, NULL));
+ status = acpi_ns_evaluate_by_handle (&info);
acpi_ut_remove_reference (params[1]);
@@ -326,7 +385,7 @@ acpi_ev_address_space_dispatch (
ACPI_FORMAT_UINT64 (address),
acpi_ut_get_region_name (region_obj->region.space_id)));
- if (!(handler_desc->address_space.flags & ACPI_ADDR_HANDLER_DEFAULT_INSTALLED)) {
+ if (!(handler_desc->address_space.hflags & ACPI_ADDR_HANDLER_DEFAULT_INSTALLED)) {
/*
* For handlers other than the default (supplied) handlers, we must
* exit the interpreter because the handler *might* block -- we don't
@@ -347,7 +406,7 @@ acpi_ev_address_space_dispatch (
acpi_format_exception (status)));
}
- if (!(handler_desc->address_space.flags & ACPI_ADDR_HANDLER_DEFAULT_INSTALLED)) {
+ if (!(handler_desc->address_space.hflags & ACPI_ADDR_HANDLER_DEFAULT_INSTALLED)) {
/*
* We just returned from a non-default handler, we must re-enter the
* interpreter
@@ -676,6 +735,273 @@ acpi_ev_install_handler (
return (status);
}
+
+/*******************************************************************************
+ *
+ * FUNCTION: acpi_ev_install_space_handler
+ *
+ * PARAMETERS: Node - Namespace node for the device
+ * space_id - The address space ID
+ * Handler - Address of the handler
+ * Setup - Address of the setup function
+ * Context - Value passed to the handler on each access
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Install a handler for all op_regions of a given space_id.
+ * Assumes namespace is locked
+ *
+ ******************************************************************************/
+
+acpi_status
+acpi_ev_install_space_handler (
+ struct acpi_namespace_node *node,
+ acpi_adr_space_type space_id,
+ acpi_adr_space_handler handler,
+ acpi_adr_space_setup setup,
+ void *context)
+{
+ union acpi_operand_object *obj_desc;
+ union acpi_operand_object *handler_obj;
+ acpi_status status;
+ acpi_object_type type;
+ u16 flags = 0;
+
+
+ ACPI_FUNCTION_TRACE ("ev_install_space_handler");
+
+
+ /*
+ * This registration is valid for only the types below
+ * and the root. This is where the default handlers
+ * get placed.
+ */
+ if ((node->type != ACPI_TYPE_DEVICE) &&
+ (node->type != ACPI_TYPE_PROCESSOR) &&
+ (node->type != ACPI_TYPE_THERMAL) &&
+ (node != acpi_gbl_root_node)) {
+ status = AE_BAD_PARAMETER;
+ goto unlock_and_exit;
+ }
+
+ if (handler == ACPI_DEFAULT_HANDLER) {
+ flags = ACPI_ADDR_HANDLER_DEFAULT_INSTALLED;
+
+ switch (space_id) {
+ case ACPI_ADR_SPACE_SYSTEM_MEMORY:
+ handler = acpi_ex_system_memory_space_handler;
+ setup = acpi_ev_system_memory_region_setup;
+ break;
+
+ case ACPI_ADR_SPACE_SYSTEM_IO:
+ handler = acpi_ex_system_io_space_handler;
+ setup = acpi_ev_io_space_region_setup;
+ break;
+
+ case ACPI_ADR_SPACE_PCI_CONFIG:
+ handler = acpi_ex_pci_config_space_handler;
+ setup = acpi_ev_pci_config_region_setup;
+ break;
+
+ case ACPI_ADR_SPACE_CMOS:
+ handler = acpi_ex_cmos_space_handler;
+ setup = acpi_ev_cmos_region_setup;
+ break;
+
+ case ACPI_ADR_SPACE_PCI_BAR_TARGET:
+ handler = acpi_ex_pci_bar_space_handler;
+ setup = acpi_ev_pci_bar_region_setup;
+ break;
+
+ case ACPI_ADR_SPACE_DATA_TABLE:
+ handler = acpi_ex_data_table_space_handler;
+ setup = NULL;
+ break;
+
+ default:
+ status = AE_BAD_PARAMETER;
+ goto unlock_and_exit;
+ }
+ }
+
+ /* If the caller hasn't specified a setup routine, use the default */
+
+ if (!setup) {
+ setup = acpi_ev_default_region_setup;
+ }
+
+ /* Check for an existing internal object */
+
+ obj_desc = acpi_ns_get_attached_object (node);
+ if (obj_desc) {
+ /*
+ * The attached device object already exists.
+ * Make sure the handler is not already installed.
+ */
+ handler_obj = obj_desc->device.handler;
+
+ /* Walk the handler list for this device */
+
+ while (handler_obj) {
+ /* Same space_id indicates a handler already installed */
+
+ if (handler_obj->address_space.space_id == space_id) {
+ if (handler_obj->address_space.handler == handler) {
+ /*
+ * It is (relatively) OK to attempt to install the SAME
+ * handler twice. This can easily happen with PCI_Config space.
+ */
+ status = AE_SAME_HANDLER;
+ goto unlock_and_exit;
+ }
+ else {
+ /* A handler is already installed */
+
+ status = AE_ALREADY_EXISTS;
+ }
+ goto unlock_and_exit;
+ }
+
+ /* Walk the linked list of handlers */
+
+ handler_obj = handler_obj->address_space.next;
+ }
+ }
+ else {
+ ACPI_DEBUG_PRINT ((ACPI_DB_OPREGION,
+ "Creating object on Device %p while installing handler\n", node));
+
+ /* obj_desc does not exist, create one */
+
+ if (node->type == ACPI_TYPE_ANY) {
+ type = ACPI_TYPE_DEVICE;
+ }
+ else {
+ type = node->type;
+ }
+
+ obj_desc = acpi_ut_create_internal_object (type);
+ if (!obj_desc) {
+ status = AE_NO_MEMORY;
+ goto unlock_and_exit;
+ }
+
+ /* Init new descriptor */
+
+ obj_desc->common.type = (u8) type;
+
+ /* Attach the new object to the Node */
+
+ status = acpi_ns_attach_object (node, obj_desc, type);
+
+ /* Remove local reference to the object */
+
+ acpi_ut_remove_reference (obj_desc);
+
+ if (ACPI_FAILURE (status)) {
+ goto unlock_and_exit;
+ }
+ }
+
+ ACPI_DEBUG_PRINT ((ACPI_DB_OPREGION,
+ "Installing address handler for region %s(%X) on Device %4.4s %p(%p)\n",
+ acpi_ut_get_region_name (space_id), space_id,
+ acpi_ut_get_node_name (node), node, obj_desc));
+
+ /*
+ * Install the handler
+ *
+ * At this point there is no existing handler.
+ * Just allocate the object for the handler and link it
+ * into the list.
+ */
+ handler_obj = acpi_ut_create_internal_object (ACPI_TYPE_LOCAL_ADDRESS_HANDLER);
+ if (!handler_obj) {
+ status = AE_NO_MEMORY;
+ goto unlock_and_exit;
+ }
+
+ /* Init handler obj */
+
+ handler_obj->address_space.space_id = (u8) space_id;
+ handler_obj->address_space.hflags = flags;
+ handler_obj->address_space.region_list = NULL;
+ handler_obj->address_space.node = node;
+ handler_obj->address_space.handler = handler;
+ handler_obj->address_space.context = context;
+ handler_obj->address_space.setup = setup;
+
+ /* Install at head of Device.address_space list */
+
+ handler_obj->address_space.next = obj_desc->device.handler;
+
+ /*
+ * The Device object is the first reference on the handler_obj.
+ * Each region that uses the handler adds a reference.
+ */
+ obj_desc->device.handler = handler_obj;
+
+ /*
+ * Walk the namespace finding all of the regions this
+ * handler will manage.
+ *
+ * Start at the device and search the branch toward
+ * the leaf nodes until either the leaf is encountered or
+ * a device is detected that has an address handler of the
+ * same type.
+ *
+ * In either case, back up and search down the remainder
+ * of the branch
+ */
+ status = acpi_ns_walk_namespace (ACPI_TYPE_ANY, node, ACPI_UINT32_MAX,
+ ACPI_NS_WALK_UNLOCK, acpi_ev_install_handler,
+ handler_obj, NULL);
+
+unlock_and_exit:
+ return_ACPI_STATUS (status);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: acpi_ev_execute_reg_methods
+ *
+ * PARAMETERS: Node - Namespace node for the device
+ * space_id - The address space ID
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Run _REG methods for the Space ID;
+ * Note: assumes namespace is locked, or system init time.
+ *
+ ******************************************************************************/
+
+acpi_status
+acpi_ev_execute_reg_methods (
+ struct acpi_namespace_node *node,
+ acpi_adr_space_type space_id)
+{
+ acpi_status status;
+
+
+ ACPI_FUNCTION_TRACE ("ev_execute_reg_methods");
+
+
+ /*
+ * Run all _REG methods for all Operation Regions for this
+ * space ID. This is a separate walk in order to handle any
+ * interdependencies between regions and _REG methods. (i.e. handlers
+ * must be installed for all regions of this Space ID before we
+ * can run any _REG methods)
+ */
+ status = acpi_ns_walk_namespace (ACPI_TYPE_ANY, node, ACPI_UINT32_MAX,
+ ACPI_NS_WALK_UNLOCK, acpi_ev_reg_run,
+ &space_id, NULL);
+
+ return_ACPI_STATUS (status);
+}
+
+
/*******************************************************************************
*
* FUNCTION: acpi_ev_reg_run
@@ -693,19 +1019,13 @@ acpi_ev_reg_run (
void *context,
void **return_value)
{
- union acpi_operand_object *handler_obj;
union acpi_operand_object *obj_desc;
struct acpi_namespace_node *node;
+ acpi_adr_space_type space_id;
acpi_status status;
- handler_obj = (union acpi_operand_object *) context;
-
- /* Parameter validation */
-
- if (!handler_obj) {
- return (AE_OK);
- }
+ space_id = *ACPI_CAST_PTR (acpi_adr_space_type, context);
/* Convert and validate the device handle */
@@ -732,10 +1052,9 @@ acpi_ev_reg_run (
return (AE_OK);
}
-
/* Object is a Region */
- if (obj_desc->region.space_id != handler_obj->address_space.space_id) {
+ if (obj_desc->region.space_id != space_id) {
/*
* This region is for a different address space
* -- just ignore it
diff --git a/drivers/acpi/events/evxface.c b/drivers/acpi/events/evxface.c
index d2fe466e7748..1d2bf4e57de6 100644
--- a/drivers/acpi/events/evxface.c
+++ b/drivers/acpi/events/evxface.c
@@ -479,7 +479,7 @@ unlock_and_exit:
* gpe_block - GPE block (NULL == FADT GPEs)
* Type - Whether this GPE should be treated as an
* edge- or level-triggered interrupt.
- * Handler - Address of the handler
+ * Address - Address of the handler
* Context - Value passed to the handler on each GPE
*
* RETURN: Status
@@ -493,11 +493,12 @@ acpi_install_gpe_handler (
acpi_handle gpe_device,
u32 gpe_number,
u32 type,
- acpi_gpe_handler handler,
+ acpi_event_handler address,
void *context)
{
- acpi_status status;
struct acpi_gpe_event_info *gpe_event_info;
+ struct acpi_handler_info *handler;
+ acpi_status status;
ACPI_FUNCTION_TRACE ("acpi_install_gpe_handler");
@@ -505,7 +506,7 @@ acpi_install_gpe_handler (
/* Parameter validation */
- if (!handler) {
+ if ((!address) || (type > ACPI_GPE_XRUPT_TYPE_MASK)) {
return_ACPI_STATUS (AE_BAD_PARAMETER);
}
@@ -524,27 +525,41 @@ acpi_install_gpe_handler (
/* Make sure that there isn't a handler there already */
- if (gpe_event_info->handler) {
+ if ((gpe_event_info->flags & ACPI_GPE_DISPATCH_MASK) == ACPI_GPE_DISPATCH_HANDLER) {
status = AE_ALREADY_EXISTS;
goto unlock_and_exit;
}
- /* Install the handler */
+ /* Allocate and init handler object */
- acpi_os_acquire_lock (acpi_gbl_gpe_lock, ACPI_NOT_ISR);
- gpe_event_info->handler = handler;
- gpe_event_info->context = context;
- gpe_event_info->flags = (u8) type;
- acpi_os_release_lock (acpi_gbl_gpe_lock, ACPI_NOT_ISR);
+ handler = ACPI_MEM_CALLOCATE (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;
- /* Clear the GPE (of stale events), the enable it */
+ /* Disable the GPE before installing the handler */
- status = acpi_hw_clear_gpe (gpe_event_info);
+ status = acpi_ev_disable_gpe (gpe_event_info);
if (ACPI_FAILURE (status)) {
goto unlock_and_exit;
}
- status = acpi_hw_enable_gpe (gpe_event_info);
+ /* Install the handler */
+
+ acpi_os_acquire_lock (acpi_gbl_gpe_lock, ACPI_NOT_ISR);
+ gpe_event_info->dispatch.handler = handler;
+
+ /* Setup up dispatch flags to indicate handler (vs. method) */
+
+ gpe_event_info->flags &= ~(ACPI_GPE_XRUPT_TYPE_MASK | ACPI_GPE_DISPATCH_MASK); /* Clear bits */
+ gpe_event_info->flags |= (u8) (type | ACPI_GPE_DISPATCH_HANDLER);
+
+ acpi_os_release_lock (acpi_gbl_gpe_lock, ACPI_NOT_ISR);
unlock_and_exit:
@@ -559,7 +574,7 @@ unlock_and_exit:
*
* PARAMETERS: gpe_number - The event to remove a handler
* gpe_block - GPE block (NULL == FADT GPEs)
- * Handler - Address of the handler
+ * Address - Address of the handler
*
* RETURN: Status
*
@@ -571,10 +586,11 @@ acpi_status
acpi_remove_gpe_handler (
acpi_handle gpe_device,
u32 gpe_number,
- acpi_gpe_handler handler)
+ acpi_event_handler address)
{
- acpi_status status;
struct acpi_gpe_event_info *gpe_event_info;
+ struct acpi_handler_info *handler;
+ acpi_status status;
ACPI_FUNCTION_TRACE ("acpi_remove_gpe_handler");
@@ -582,7 +598,7 @@ acpi_remove_gpe_handler (
/* Parameter validation */
- if (!handler) {
+ if (!address) {
return_ACPI_STATUS (AE_BAD_PARAMETER);
}
@@ -599,28 +615,45 @@ acpi_remove_gpe_handler (
goto unlock_and_exit;
}
- /* Disable the GPE before removing the handler */
+ /* Make sure that a handler is indeed installed */
- status = acpi_hw_disable_gpe (gpe_event_info);
- if (ACPI_FAILURE (status)) {
+ if ((gpe_event_info->flags & ACPI_GPE_DISPATCH_MASK) != ACPI_GPE_DISPATCH_HANDLER) {
+ status = AE_NOT_EXIST;
goto unlock_and_exit;
}
/* Make sure that the installed handler is the same */
- if (gpe_event_info->handler != handler) {
- (void) acpi_hw_enable_gpe (gpe_event_info);
+ if (gpe_event_info->dispatch.handler->address != address) {
status = AE_BAD_PARAMETER;
goto unlock_and_exit;
}
+ /* Disable the GPE before removing the handler */
+
+ status = acpi_ev_disable_gpe (gpe_event_info);
+ if (ACPI_FAILURE (status)) {
+ goto unlock_and_exit;
+ }
+
/* Remove the handler */
acpi_os_acquire_lock (acpi_gbl_gpe_lock, ACPI_NOT_ISR);
- gpe_event_info->handler = NULL;
- gpe_event_info->context = NULL;
+ 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, ACPI_NOT_ISR);
+ /* Now we can free the handler object */
+
+ ACPI_MEM_FREE (handler);
+
unlock_and_exit:
(void) acpi_ut_release_mutex (ACPI_MTX_EVENTS);
diff --git a/drivers/acpi/events/evxfevnt.c b/drivers/acpi/events/evxfevnt.c
index 640f51fb0ea9..5d51a04f6e0c 100644
--- a/drivers/acpi/events/evxfevnt.c
+++ b/drivers/acpi/events/evxfevnt.c
@@ -204,12 +204,11 @@ acpi_enable_event (
/*******************************************************************************
*
- * FUNCTION: acpi_enable_gpe
+ * FUNCTION: acpi_set_gpe_type
*
* PARAMETERS: gpe_device - Parent GPE Device
* gpe_number - GPE level within the GPE block
- * Flags - Just enable, or also wake enable?
- * Called from ISR or not
+ * Type - New GPE type
*
* RETURN: Status
*
@@ -218,26 +217,17 @@ acpi_enable_event (
******************************************************************************/
acpi_status
-acpi_enable_gpe (
+acpi_set_gpe_type (
acpi_handle gpe_device,
u32 gpe_number,
- u32 flags)
+ u8 type)
{
acpi_status status = AE_OK;
struct acpi_gpe_event_info *gpe_event_info;
- ACPI_FUNCTION_TRACE ("acpi_enable_gpe");
-
+ ACPI_FUNCTION_TRACE ("acpi_set_gpe_type");
- /* Use semaphore lock if not executing at interrupt level */
-
- if (flags & ACPI_NOT_ISR) {
- status = acpi_ut_acquire_mutex (ACPI_MTX_EVENTS);
- if (ACPI_FAILURE (status)) {
- return_ACPI_STATUS (status);
- }
- }
/* Ensure that we have a valid GPE number */
@@ -247,91 +237,79 @@ acpi_enable_gpe (
goto unlock_and_exit;
}
- /* Check for Wake vs Runtime GPE */
-
- if (flags & ACPI_EVENT_WAKE_ENABLE) {
- /* Ensure the requested wake GPE is disabled */
-
- status = acpi_hw_disable_gpe (gpe_event_info);
- if (ACPI_FAILURE (status)) {
- goto unlock_and_exit;
- }
+ if ((gpe_event_info->flags & ACPI_GPE_TYPE_MASK) == type) {
+ return_ACPI_STATUS (AE_OK);
+ }
- /* Defer Enable of Wake GPE until sleep time */
+ /* Disable the GPE if enabled */
- acpi_hw_enable_gpe_for_wakeup (gpe_event_info);
+ status = acpi_ev_disable_gpe (gpe_event_info);
+ if (ACPI_FAILURE (status)) {
+ return_ACPI_STATUS (status);
}
- else {
- /* Enable the requested runtime GPE */
- status = acpi_hw_enable_gpe (gpe_event_info);
- if (ACPI_FAILURE (status)) {
- goto unlock_and_exit;
- }
- }
+ /* Set the new type */
+ status = acpi_ev_set_gpe_type (gpe_event_info, type);
unlock_and_exit:
- if (flags & ACPI_NOT_ISR) {
- (void) acpi_ut_release_mutex (ACPI_MTX_EVENTS);
- }
return_ACPI_STATUS (status);
}
/*******************************************************************************
*
- * FUNCTION: acpi_disable_event
+ * FUNCTION: acpi_enable_gpe
*
- * PARAMETERS: Event - The fixed eventto be enabled
- * Flags - Reserved
+ * PARAMETERS: gpe_device - Parent GPE Device
+ * gpe_number - GPE level within the GPE block
+ * Flags - Just enable, or also wake enable?
+ * Called from ISR or not
*
* RETURN: Status
*
- * DESCRIPTION: Disable an ACPI event (fixed)
+ * DESCRIPTION: Enable an ACPI event (general purpose)
*
******************************************************************************/
acpi_status
-acpi_disable_event (
- u32 event,
+acpi_enable_gpe (
+ acpi_handle gpe_device,
+ u32 gpe_number,
u32 flags)
{
acpi_status status = AE_OK;
- u32 value;
+ struct acpi_gpe_event_info *gpe_event_info;
- ACPI_FUNCTION_TRACE ("acpi_disable_event");
+ ACPI_FUNCTION_TRACE ("acpi_enable_gpe");
- /* Decode the Fixed Event */
+ /* Use semaphore lock if not executing at interrupt level */
- if (event > ACPI_EVENT_MAX) {
- return_ACPI_STATUS (AE_BAD_PARAMETER);
+ if (flags & ACPI_NOT_ISR) {
+ status = acpi_ut_acquire_mutex (ACPI_MTX_EVENTS);
+ if (ACPI_FAILURE (status)) {
+ return_ACPI_STATUS (status);
+ }
}
- /*
- * Disable the requested fixed event (by writing a zero to the
- * enable register bit)
- */
- status = acpi_set_register (acpi_gbl_fixed_event_info[event].enable_register_id,
- 0, ACPI_MTX_LOCK);
- if (ACPI_FAILURE (status)) {
- return_ACPI_STATUS (status);
- }
+ /* Ensure that we have a valid GPE number */
- status = acpi_get_register (acpi_gbl_fixed_event_info[event].enable_register_id,
- &value, ACPI_MTX_LOCK);
- if (ACPI_FAILURE (status)) {
- return_ACPI_STATUS (status);
+ 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 (value != 0) {
- ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
- "Could not disable %s events\n", acpi_ut_get_event_name (event)));
- return_ACPI_STATUS (AE_NO_HARDWARE_RESPONSE);
- }
+ /* Perform the enable */
+ status = acpi_ev_enable_gpe (gpe_event_info, TRUE);
+
+unlock_and_exit:
+ if (flags & ACPI_NOT_ISR) {
+ (void) acpi_ut_release_mutex (ACPI_MTX_EVENTS);
+ }
return_ACPI_STATUS (status);
}
@@ -342,7 +320,7 @@ acpi_disable_event (
*
* PARAMETERS: gpe_device - Parent GPE Device
* gpe_number - GPE level within the GPE block
- * Flags - Just enable, or also wake enable?
+ * Flags - Just disable, or also wake disable?
* Called from ISR or not
*
* RETURN: Status
@@ -381,21 +359,69 @@ acpi_disable_gpe (
goto unlock_and_exit;
}
+ status = acpi_ev_disable_gpe (gpe_event_info);
+
+unlock_and_exit:
+ if (flags & ACPI_NOT_ISR) {
+ (void) acpi_ut_release_mutex (ACPI_MTX_EVENTS);
+ }
+ return_ACPI_STATUS (status);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: acpi_disable_event
+ *
+ * PARAMETERS: Event - The fixed eventto be enabled
+ * Flags - Reserved
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Disable an ACPI event (fixed)
+ *
+ ******************************************************************************/
+
+acpi_status
+acpi_disable_event (
+ u32 event,
+ u32 flags)
+{
+ acpi_status status = AE_OK;
+ u32 value;
+
+
+ ACPI_FUNCTION_TRACE ("acpi_disable_event");
+
+
+ /* Decode the Fixed Event */
+
+ if (event > ACPI_EVENT_MAX) {
+ return_ACPI_STATUS (AE_BAD_PARAMETER);
+ }
+
/*
- * Only disable the requested GPE number for wake if specified.
- * Otherwise, turn it totally off
+ * Disable the requested fixed event (by writing a zero to the
+ * enable register bit)
*/
- if (flags & ACPI_EVENT_WAKE_DISABLE) {
- acpi_hw_disable_gpe_for_wakeup (gpe_event_info);
+ status = acpi_set_register (acpi_gbl_fixed_event_info[event].enable_register_id,
+ 0, ACPI_MTX_LOCK);
+ if (ACPI_FAILURE (status)) {
+ return_ACPI_STATUS (status);
}
- else {
- status = acpi_hw_disable_gpe (gpe_event_info);
+
+ status = acpi_get_register (acpi_gbl_fixed_event_info[event].enable_register_id,
+ &value, ACPI_MTX_LOCK);
+ if (ACPI_FAILURE (status)) {
+ return_ACPI_STATUS (status);
}
-unlock_and_exit:
- if (flags & ACPI_NOT_ISR) {
- (void) acpi_ut_release_mutex (ACPI_MTX_EVENTS);
+ if (value != 0) {
+ ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
+ "Could not disable %s events\n", acpi_ut_get_event_name (event)));
+ return_ACPI_STATUS (AE_NO_HARDWARE_RESPONSE);
}
+
return_ACPI_STATUS (status);
}
diff --git a/drivers/acpi/events/evxfregn.c b/drivers/acpi/events/evxfregn.c
index b31d4fdfe03d..4ebe506a6ef0 100644
--- a/drivers/acpi/events/evxfregn.c
+++ b/drivers/acpi/events/evxfregn.c
@@ -76,12 +76,8 @@ acpi_install_address_space_handler (
acpi_adr_space_setup setup,
void *context)
{
- union acpi_operand_object *obj_desc;
- union acpi_operand_object *handler_obj;
struct acpi_namespace_node *node;
acpi_status status;
- acpi_object_type type;
- u16 flags = 0;
ACPI_FUNCTION_TRACE ("acpi_install_address_space_handler");
@@ -106,202 +102,16 @@ acpi_install_address_space_handler (
goto unlock_and_exit;
}
- /*
- * This registration is valid for only the types below
- * and the root. This is where the default handlers
- * get placed.
- */
- if ((node->type != ACPI_TYPE_DEVICE) &&
- (node->type != ACPI_TYPE_PROCESSOR) &&
- (node->type != ACPI_TYPE_THERMAL) &&
- (node != acpi_gbl_root_node)) {
- status = AE_BAD_PARAMETER;
- goto unlock_and_exit;
- }
-
- if (handler == ACPI_DEFAULT_HANDLER) {
- flags = ACPI_ADDR_HANDLER_DEFAULT_INSTALLED;
-
- switch (space_id) {
- case ACPI_ADR_SPACE_SYSTEM_MEMORY:
- handler = acpi_ex_system_memory_space_handler;
- setup = acpi_ev_system_memory_region_setup;
- break;
-
- case ACPI_ADR_SPACE_SYSTEM_IO:
- handler = acpi_ex_system_io_space_handler;
- setup = acpi_ev_io_space_region_setup;
- break;
-
- case ACPI_ADR_SPACE_PCI_CONFIG:
- handler = acpi_ex_pci_config_space_handler;
- setup = acpi_ev_pci_config_region_setup;
- break;
-
- case ACPI_ADR_SPACE_CMOS:
- handler = acpi_ex_cmos_space_handler;
- setup = acpi_ev_cmos_region_setup;
- break;
-
- case ACPI_ADR_SPACE_PCI_BAR_TARGET:
- handler = acpi_ex_pci_bar_space_handler;
- setup = acpi_ev_pci_bar_region_setup;
- break;
-
- case ACPI_ADR_SPACE_DATA_TABLE:
- handler = acpi_ex_data_table_space_handler;
- setup = NULL;
- break;
-
- default:
- status = AE_BAD_PARAMETER;
- goto unlock_and_exit;
- }
- }
-
- /* If the caller hasn't specified a setup routine, use the default */
-
- if (!setup) {
- setup = acpi_ev_default_region_setup;
- }
-
- /* Check for an existing internal object */
-
- obj_desc = acpi_ns_get_attached_object (node);
- if (obj_desc) {
- /*
- * The attached device object already exists.
- * Make sure the handler is not already installed.
- */
- handler_obj = obj_desc->device.handler;
-
- /* Walk the handler list for this device */
-
- while (handler_obj) {
- /* Same space_id indicates a handler already installed */
-
- if(handler_obj->address_space.space_id == space_id) {
- if (handler_obj->address_space.handler == handler) {
- /*
- * It is (relatively) OK to attempt to install the SAME
- * handler twice. This can easily happen with PCI_Config space.
- */
- status = AE_SAME_HANDLER;
- goto unlock_and_exit;
- }
- else {
- /* A handler is already installed */
-
- status = AE_ALREADY_EXISTS;
- }
- goto unlock_and_exit;
- }
-
- /* Walk the linked list of handlers */
-
- handler_obj = handler_obj->address_space.next;
- }
- }
- else {
- ACPI_DEBUG_PRINT ((ACPI_DB_OPREGION,
- "Creating object on Device %p while installing handler\n", node));
-
- /* obj_desc does not exist, create one */
-
- if (node->type == ACPI_TYPE_ANY) {
- type = ACPI_TYPE_DEVICE;
- }
- else {
- type = node->type;
- }
-
- obj_desc = acpi_ut_create_internal_object (type);
- if (!obj_desc) {
- status = AE_NO_MEMORY;
- goto unlock_and_exit;
- }
-
- /* Init new descriptor */
-
- obj_desc->common.type = (u8) type;
-
- /* Attach the new object to the Node */
+ /* Install the handler for all Regions for this Space ID */
- status = acpi_ns_attach_object (node, obj_desc, type);
-
- /* Remove local reference to the object */
-
- acpi_ut_remove_reference (obj_desc);
-
- if (ACPI_FAILURE (status)) {
- goto unlock_and_exit;
- }
- }
-
- ACPI_DEBUG_PRINT ((ACPI_DB_OPREGION,
- "Installing address handler for region %s(%X) on Device %4.4s %p(%p)\n",
- acpi_ut_get_region_name (space_id), space_id,
- acpi_ut_get_node_name (node), node, obj_desc));
-
- /*
- * Install the handler
- *
- * At this point there is no existing handler.
- * Just allocate the object for the handler and link it
- * into the list.
- */
- handler_obj = acpi_ut_create_internal_object (ACPI_TYPE_LOCAL_ADDRESS_HANDLER);
- if (!handler_obj) {
- status = AE_NO_MEMORY;
+ status = acpi_ev_install_space_handler (node, space_id, handler, setup, context);
+ if (ACPI_FAILURE (status)) {
goto unlock_and_exit;
}
- /* Init handler obj */
-
- handler_obj->address_space.space_id = (u8) space_id;
- handler_obj->address_space.hflags = flags;
- handler_obj->address_space.region_list = NULL;
- handler_obj->address_space.node = node;
- handler_obj->address_space.handler = handler;
- handler_obj->address_space.context = context;
- handler_obj->address_space.setup = setup;
-
- /* Install at head of Device.address_space list */
-
- handler_obj->address_space.next = obj_desc->device.handler;
-
- /*
- * The Device object is the first reference on the handler_obj.
- * Each region that uses the handler adds a reference.
- */
- obj_desc->device.handler = handler_obj;
-
- /*
- * Walk the namespace finding all of the regions this
- * handler will manage.
- *
- * Start at the device and search the branch toward
- * the leaf nodes until either the leaf is encountered or
- * a device is detected that has an address handler of the
- * same type.
- *
- * In either case, back up and search down the remainder
- * of the branch
- */
- status = acpi_ns_walk_namespace (ACPI_TYPE_ANY, device, ACPI_UINT32_MAX,
- ACPI_NS_WALK_UNLOCK, acpi_ev_install_handler,
- handler_obj, NULL);
-
- /*
- * Now we can run the _REG methods for all Regions for this
- * space ID. This is a separate walk in order to handle any
- * interdependencies between regions and _REG methods. (i.e. handlers
- * must be installed for all regions of this Space ID before we
- * can run any _REG methods.
- */
- status = acpi_ns_walk_namespace (ACPI_TYPE_ANY, device, ACPI_UINT32_MAX,
- ACPI_NS_WALK_UNLOCK, acpi_ev_reg_run,
- handler_obj, NULL);
+ /* Run all _REG methods for this address space */
+
+ status = acpi_ev_execute_reg_methods (node, space_id);
unlock_and_exit:
(void) acpi_ut_release_mutex (ACPI_MTX_NAMESPACE);
diff --git a/drivers/acpi/executer/exconfig.c b/drivers/acpi/executer/exconfig.c
index dfe7e0463f1b..f21771c76551 100644
--- a/drivers/acpi/executer/exconfig.c
+++ b/drivers/acpi/executer/exconfig.c
@@ -48,6 +48,7 @@
#include <acpi/acnamesp.h>
#include <acpi/acevents.h>
#include <acpi/actables.h>
+#include <acpi/acdispat.h>
#define _COMPONENT ACPI_EXECUTER
@@ -285,7 +286,7 @@ acpi_ex_load_op (
union acpi_operand_object *ddb_handle;
union acpi_operand_object *buffer_desc = NULL;
struct acpi_table_header *table_ptr = NULL;
- u8 *table_data_ptr;
+ acpi_physical_address address;
struct acpi_table_header table_header;
u32 i;
@@ -300,18 +301,39 @@ acpi_ex_load_op (
ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Load from Region %p %s\n",
obj_desc, acpi_ut_get_object_type_name (obj_desc)));
- /* Get the table header */
+ /*
+ * If the Region Address and Length have not been previously evaluated,
+ * evaluate them now and save the results.
+ */
+ if (!(obj_desc->common.flags & AOPOBJ_DATA_VALID)) {
+ status = acpi_ds_get_region_arguments (obj_desc);
+ if (ACPI_FAILURE (status)) {
+ return_ACPI_STATUS (status);
+ }
+ }
+
+ /* Get the base physical address of the region */
+
+ address = obj_desc->region.address;
+
+ /* Get the table length from the table header */
table_header.length = 0;
- for (i = 0; i < sizeof (struct acpi_table_header); i++) {
+ for (i = 0; i < 8; i++) {
status = acpi_ev_address_space_dispatch (obj_desc, ACPI_READ,
- (acpi_physical_address) i, 8,
+ (acpi_physical_address) i + address, 8,
((u8 *) &table_header) + i);
if (ACPI_FAILURE (status)) {
return_ACPI_STATUS (status);
}
}
+ /* Sanity check the table length */
+
+ if (table_header.length < sizeof (struct acpi_table_header)) {
+ return_ACPI_STATUS (AE_BAD_HEADER);
+ }
+
/* Allocate a buffer for the entire table */
table_ptr = ACPI_MEM_ALLOCATE (table_header.length);
@@ -319,17 +341,12 @@ acpi_ex_load_op (
return_ACPI_STATUS (AE_NO_MEMORY);
}
- /* Copy the header to the buffer */
-
- ACPI_MEMCPY (table_ptr, &table_header, sizeof (struct acpi_table_header));
- table_data_ptr = ACPI_PTR_ADD (u8, table_ptr, sizeof (struct acpi_table_header));
-
- /* Get the table from the op region */
+ /* Get the entire table from the op region */
for (i = 0; i < table_header.length; i++) {
status = acpi_ev_address_space_dispatch (obj_desc, ACPI_READ,
- (acpi_physical_address) i, 8,
- ((u8 *) table_data_ptr + i));
+ (acpi_physical_address) i + address, 8,
+ ((u8 *) table_ptr + i));
if (ACPI_FAILURE (status)) {
goto cleanup;
}
@@ -355,6 +372,12 @@ acpi_ex_load_op (
}
table_ptr = ACPI_CAST_PTR (struct acpi_table_header, buffer_desc->buffer.pointer);
+
+ /* Sanity check the table length */
+
+ if (table_ptr->length < sizeof (struct acpi_table_header)) {
+ return_ACPI_STATUS (AE_BAD_HEADER);
+ }
break;
diff --git a/drivers/acpi/executer/exmutex.c b/drivers/acpi/executer/exmutex.c
index cee2c126e7f9..c709ed2f5dcf 100644
--- a/drivers/acpi/executer/exmutex.c
+++ b/drivers/acpi/executer/exmutex.c
@@ -54,7 +54,7 @@
*
* FUNCTION: acpi_ex_unlink_mutex
*
- * PARAMETERS: *obj_desc - The mutex to be unlinked
+ * PARAMETERS: obj_desc - The mutex to be unlinked
*
* RETURN: Status
*
@@ -73,6 +73,8 @@ acpi_ex_unlink_mutex (
return;
}
+ /* Doubly linked list */
+
if (obj_desc->mutex.next) {
(obj_desc->mutex.next)->mutex.prev = obj_desc->mutex.prev;
}
@@ -90,8 +92,8 @@ acpi_ex_unlink_mutex (
*
* FUNCTION: acpi_ex_link_mutex
*
- * PARAMETERS: *obj_desc - The mutex to be linked
- * *list_head - head of the "acquired_mutex" list
+ * PARAMETERS: obj_desc - The mutex to be linked
+ * list_head - head of the "acquired_mutex" list
*
* RETURN: Status
*
@@ -130,8 +132,8 @@ acpi_ex_link_mutex (
*
* FUNCTION: acpi_ex_acquire_mutex
*
- * PARAMETERS: *time_desc - The 'time to delay' object descriptor
- * *obj_desc - The object descriptor for this op
+ * PARAMETERS: time_desc - The 'time to delay' object descriptor
+ * obj_desc - The object descriptor for this op
*
* RETURN: Status
*
@@ -173,9 +175,8 @@ acpi_ex_acquire_mutex (
return_ACPI_STATUS (AE_AML_MUTEX_ORDER);
}
- /*
- * Support for multiple acquires by the owning thread
- */
+ /* Support for multiple acquires by the owning thread */
+
if (obj_desc->mutex.owner_thread) {
/* Special case for Global Lock, allow all threads */
@@ -199,10 +200,11 @@ acpi_ex_acquire_mutex (
return_ACPI_STATUS (status);
}
- /* Have the mutex, update mutex and walk info */
+ /* Have the mutex: update mutex and walk info and save the sync_level */
- obj_desc->mutex.owner_thread = walk_state->thread;
+ obj_desc->mutex.owner_thread = walk_state->thread;
obj_desc->mutex.acquisition_depth = 1;
+ obj_desc->mutex.original_sync_level = walk_state->thread->current_sync_level;
walk_state->thread->current_sync_level = obj_desc->mutex.sync_level;
@@ -218,7 +220,7 @@ acpi_ex_acquire_mutex (
*
* FUNCTION: acpi_ex_release_mutex
*
- * PARAMETERS: *obj_desc - The object descriptor for this op
+ * PARAMETERS: obj_desc - The object descriptor for this op
*
* RETURN: Status
*
@@ -281,9 +283,8 @@ acpi_ex_release_mutex (
return_ACPI_STATUS (AE_AML_MUTEX_ORDER);
}
- /*
- * Match multiple Acquires with multiple Releases
- */
+ /* Match multiple Acquires with multiple Releases */
+
obj_desc->mutex.acquisition_depth--;
if (obj_desc->mutex.acquisition_depth != 0) {
/* Just decrement the depth and return */
@@ -299,10 +300,10 @@ acpi_ex_release_mutex (
status = acpi_ex_system_release_mutex (obj_desc);
- /* Update the mutex and walk state */
+ /* Update the mutex and walk state, restore sync_level before acquire */
obj_desc->mutex.owner_thread = NULL;
- walk_state->thread->current_sync_level = obj_desc->mutex.sync_level;
+ walk_state->thread->current_sync_level = obj_desc->mutex.original_sync_level;
return_ACPI_STATUS (status);
}
@@ -312,7 +313,7 @@ acpi_ex_release_mutex (
*
* FUNCTION: acpi_ex_release_all_mutexes
*
- * PARAMETERS: *mutex_list - Head of the mutex list
+ * PARAMETERS: mutex_list - Head of the mutex list
*
* RETURN: Status
*
@@ -332,9 +333,8 @@ acpi_ex_release_all_mutexes (
ACPI_FUNCTION_ENTRY ();
- /*
- * Traverse the list of owned mutexes, releasing each one.
- */
+ /* Traverse the list of owned mutexes, releasing each one */
+
while (next) {
this = next;
next = this->mutex.next;
@@ -352,7 +352,11 @@ acpi_ex_release_all_mutexes (
/* Mark mutex unowned */
- this->mutex.owner_thread = NULL;
+ this->mutex.owner_thread = NULL;
+
+ /* Update Thread sync_level (Last mutex is the important one) */
+
+ thread->current_sync_level = this->mutex.original_sync_level;
}
}
diff --git a/drivers/acpi/executer/exoparg2.c b/drivers/acpi/executer/exoparg2.c
index 70602ad44299..f20ab2bededf 100644
--- a/drivers/acpi/executer/exoparg2.c
+++ b/drivers/acpi/executer/exoparg2.c
@@ -97,6 +97,7 @@ acpi_ex_opcode_2A_0T_0R (
{
union acpi_operand_object **operand = &walk_state->operands[0];
struct acpi_namespace_node *node;
+ u32 value;
acpi_status status = AE_OK;
@@ -113,16 +114,46 @@ acpi_ex_opcode_2A_0T_0R (
node = (struct acpi_namespace_node *) operand[0];
+ /* Second value is the notify value */
+
+ value = (u32) operand[1]->integer.value;
+
/* Notifies allowed on this object? */
if (!acpi_ev_is_notify_object (node)) {
- ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Unexpected notify object type [%s]\n",
+ ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
+ "Unexpected notify object type [%s]\n",
acpi_ut_get_type_name (node->type)));
status = AE_AML_OPERAND_TYPE;
break;
}
+#ifdef ACPI_GPE_NOTIFY_CHECK
+ /*
+ * GPE method wake/notify check. Here, we want to ensure that we
+ * don't receive any "device_wake" Notifies from a GPE _Lxx or _Exx
+ * GPE method during system runtime. If we do, the GPE is marked
+ * as "wake-only" and disabled.
+ *
+ * 1) Is the Notify() value == device_wake?
+ * 2) Is this a GPE deferred method? (An _Lxx or _Exx method)
+ * 3) Did the original GPE happen at system runtime?
+ * (versus during wake)
+ *
+ * If all three cases are true, this is a wake-only GPE that should
+ * be disabled at runtime.
+ */
+ if (value == 2) /* device_wake */ {
+ status = acpi_ev_check_for_wake_only_gpe (walk_state->gpe_event_info);
+ if (ACPI_FAILURE (status)) {
+ /* AE_WAKE_ONLY_GPE only error, means ignore this notify */
+
+ return_ACPI_STATUS (AE_OK)
+ }
+ }
+#endif
+
/*
* Dispatch the notify to the appropriate handler
* NOTE: the request is queued for execution after this method
@@ -130,8 +161,7 @@ acpi_ex_opcode_2A_0T_0R (
* from this thread -- because handlers may in turn run other
* control methods.
*/
- status = acpi_ev_queue_notify_request (node,
- (u32) operand[1]->integer.value);
+ status = acpi_ev_queue_notify_request (node, value);
break;
diff --git a/drivers/acpi/hardware/hwgpe.c b/drivers/acpi/hardware/hwgpe.c
index f3fddc274691..da8b4002fc40 100644
--- a/drivers/acpi/hardware/hwgpe.c
+++ b/drivers/acpi/hardware/hwgpe.c
@@ -57,7 +57,8 @@
*
* RETURN: Status
*
- * DESCRIPTION: Enable a single GPE.
+ * DESCRIPTION: Enable a single GPE. Note: The bit for this GPE must already
+ * be set in the parent register enable_for_run mask.
*
******************************************************************************/
@@ -65,50 +66,8 @@ acpi_status
acpi_hw_enable_gpe (
struct acpi_gpe_event_info *gpe_event_info)
{
- u32 in_byte;
- acpi_status status;
-
-
- ACPI_FUNCTION_ENTRY ();
-
-
- /*
- * Read the current value of the register, set the appropriate bit
- * to enable the GPE, and write out the new register.
- */
- status = acpi_hw_low_level_read (8, &in_byte,
- &gpe_event_info->register_info->enable_address);
- if (ACPI_FAILURE (status)) {
- return (status);
- }
-
- /* Write with the new GPE bit enabled */
-
- status = acpi_hw_low_level_write (8, (in_byte | gpe_event_info->bit_mask),
- &gpe_event_info->register_info->enable_address);
-
- return (status);
-}
-
-
-/******************************************************************************
- *
- * FUNCTION: acpi_hw_enable_gpe_for_wakeup
- *
- * PARAMETERS: gpe_event_info - Info block for the GPE to be enabled
- *
- * RETURN: None
- *
- * DESCRIPTION: Keep track of which GPEs the OS has requested not be
- * disabled when going to sleep.
- *
- ******************************************************************************/
-
-void
-acpi_hw_enable_gpe_for_wakeup (
- struct acpi_gpe_event_info *gpe_event_info)
-{
struct acpi_gpe_register_info *gpe_register_info;
+ acpi_status status;
ACPI_FUNCTION_ENTRY ();
@@ -118,15 +77,15 @@ acpi_hw_enable_gpe_for_wakeup (
gpe_register_info = gpe_event_info->register_info;
if (!gpe_register_info) {
- return;
+ return (AE_NOT_EXIST);
}
- /*
- * Set the bit so we will not enable this GPE when sleeping (and disable
- * it upon wake)
- */
- gpe_register_info->wake_enable |= gpe_event_info->bit_mask;
- gpe_event_info->flags |= (ACPI_GPE_TYPE_WAKE | ACPI_GPE_ENABLED);
+ /* Write GPE enable register with the new GPE bit enabled */
+
+ status = acpi_hw_low_level_write (8, gpe_register_info->enable_for_run,
+ &gpe_register_info->enable_address);
+
+ return (status);
}
@@ -146,9 +105,8 @@ acpi_status
acpi_hw_disable_gpe (
struct acpi_gpe_event_info *gpe_event_info)
{
- u32 in_byte;
- acpi_status status;
struct acpi_gpe_register_info *gpe_register_info;
+ acpi_status status;
ACPI_FUNCTION_ENTRY ();
@@ -158,67 +116,14 @@ acpi_hw_disable_gpe (
gpe_register_info = gpe_event_info->register_info;
if (!gpe_register_info) {
- return (AE_BAD_PARAMETER);
- }
-
- /*
- * Read the current value of the register, clear the appropriate bit,
- * and write out the new register value to disable the GPE.
- */
- status = acpi_hw_low_level_read (8, &in_byte,
- &gpe_register_info->enable_address);
- if (ACPI_FAILURE (status)) {
- return (status);
+ return (AE_NOT_EXIST);
}
- /* Write the byte with this GPE bit cleared */
+ /* Write the GPE enable register with this GPE bit cleared */
- status = acpi_hw_low_level_write (8, (in_byte & ~(gpe_event_info->bit_mask)),
+ status = acpi_hw_low_level_write (8, gpe_register_info->enable_for_run,
&gpe_register_info->enable_address);
- if (ACPI_FAILURE (status)) {
- return (status);
- }
-
- /* Make sure this GPE is disabled for wake, also */
-
- acpi_hw_disable_gpe_for_wakeup (gpe_event_info);
- return (AE_OK);
-}
-
-
-/******************************************************************************
- *
- * FUNCTION: acpi_hw_disable_gpe_for_wakeup
- *
- * PARAMETERS: gpe_event_info - Info block for the GPE to be disabled
- *
- * RETURN: None
- *
- * DESCRIPTION: Keep track of which GPEs the OS has requested not be
- * disabled when going to sleep.
- *
- ******************************************************************************/
-
-void
-acpi_hw_disable_gpe_for_wakeup (
- struct acpi_gpe_event_info *gpe_event_info)
-{
- struct acpi_gpe_register_info *gpe_register_info;
-
-
- ACPI_FUNCTION_ENTRY ();
-
-
- /* Get the info block for the entire GPE register */
-
- gpe_register_info = gpe_event_info->register_info;
- if (!gpe_register_info) {
- return;
- }
-
- /* Clear the bit so we will disable this when sleeping */
-
- gpe_register_info->wake_enable &= ~(gpe_event_info->bit_mask);
+ return (status);
}
@@ -248,7 +153,7 @@ acpi_hw_clear_gpe (
* Write a one to the appropriate bit in the status register to
* clear this GPE.
*/
- status = acpi_hw_low_level_write (8, gpe_event_info->bit_mask,
+ status = acpi_hw_low_level_write (8, gpe_event_info->register_bit,
&gpe_event_info->register_info->status_address);
return (status);
@@ -274,7 +179,7 @@ acpi_hw_get_gpe_status (
acpi_event_status *event_status)
{
u32 in_byte;
- u8 bit_mask;
+ u8 register_bit;
struct acpi_gpe_register_info *gpe_register_info;
acpi_status status;
acpi_event_status local_event_status = 0;
@@ -293,33 +198,28 @@ acpi_hw_get_gpe_status (
/* Get the register bitmask for this GPE */
- bit_mask = gpe_event_info->bit_mask;
+ register_bit = gpe_event_info->register_bit;
- /* GPE Enabled? */
+ /* GPE currently enabled? (enabled for runtime?) */
- status = acpi_hw_low_level_read (8, &in_byte, &gpe_register_info->enable_address);
- if (ACPI_FAILURE (status)) {
- goto unlock_and_exit;
- }
-
- if (bit_mask & in_byte) {
+ if (register_bit & gpe_register_info->enable_for_run) {
local_event_status |= ACPI_EVENT_FLAG_ENABLED;
}
- /* GPE Enabled for wake? */
+ /* GPE enabled for wake? */
- if (bit_mask & gpe_register_info->wake_enable) {
+ if (register_bit & gpe_register_info->enable_for_wake) {
local_event_status |= ACPI_EVENT_FLAG_WAKE_ENABLED;
}
- /* GPE active (set)? */
+ /* GPE currently active (status bit == 1)? */
status = acpi_hw_low_level_read (8, &in_byte, &gpe_register_info->status_address);
if (ACPI_FAILURE (status)) {
goto unlock_and_exit;
}
- if (bit_mask & in_byte) {
+ if (register_bit & in_byte) {
local_event_status |= ACPI_EVENT_FLAG_SET;
}
@@ -411,64 +311,43 @@ acpi_hw_clear_gpe_block (
/******************************************************************************
*
- * FUNCTION: acpi_hw_prepare_gpe_block_for_sleep
+ * FUNCTION: acpi_hw_enable_runtime_gpe_block
*
* PARAMETERS: gpe_xrupt_info - GPE Interrupt info
* gpe_block - Gpe Block info
*
* RETURN: Status
*
- * DESCRIPTION: Disable all runtime GPEs and enable all wakeup GPEs -- within
- * a single GPE block
+ * DESCRIPTION: Enable all "runtime" GPEs within a GPE block. (Includes
+ * combination wake/run GPEs.)
*
******************************************************************************/
-static acpi_status
-acpi_hw_prepare_gpe_block_for_sleep (
+acpi_status
+acpi_hw_enable_runtime_gpe_block (
struct acpi_gpe_xrupt_info *gpe_xrupt_info,
struct acpi_gpe_block_info *gpe_block)
{
u32 i;
- struct acpi_gpe_register_info *gpe_register_info;
- u32 in_value;
acpi_status status;
- /* Get the register info for the entire GPE block */
-
- gpe_register_info = gpe_block->register_info;
+ /* NOTE: assumes that all GPEs are currently disabled */
/* Examine each GPE Register within the block */
for (i = 0; i < gpe_block->register_count; i++) {
- /*
- * Read the enabled/disabled status of all GPEs. We
- * will be using it to restore all the GPEs later.
- *
- * NOTE: Wake GPEs are are ALL disabled at this time, so when we wake
- * and restore this register, they will be automatically disabled.
- */
- status = acpi_hw_low_level_read (8, &in_value,
- &gpe_register_info->enable_address);
- if (ACPI_FAILURE (status)) {
- return (status);
+ if (!gpe_block->register_info[i].enable_for_run) {
+ continue;
}
- gpe_register_info->enable = (u8) in_value;
+ /* Enable all "runtime" GPEs in this register */
- /*
- * 1) Disable all runtime GPEs
- * 2) Enable all wakeup GPEs
- */
- status = acpi_hw_low_level_write (8, gpe_register_info->wake_enable,
- &gpe_register_info->enable_address);
+ status = acpi_hw_low_level_write (8, gpe_block->register_info[i].enable_for_run,
+ &gpe_block->register_info[i].enable_address);
if (ACPI_FAILURE (status)) {
return (status);
}
-
- /* Point to next GPE register */
-
- gpe_register_info++;
}
return (AE_OK);
@@ -477,114 +356,113 @@ acpi_hw_prepare_gpe_block_for_sleep (
/******************************************************************************
*
- * FUNCTION: acpi_hw_prepare_gpes_for_sleep
+ * FUNCTION: acpi_hw_enable_wakeup_gpe_block
*
- * PARAMETERS: None
+ * PARAMETERS: gpe_xrupt_info - GPE Interrupt info
+ * gpe_block - Gpe Block info
*
* RETURN: Status
*
- * DESCRIPTION: Disable all runtime GPEs, enable all wake GPEs.
- * Called with interrupts disabled. The interrupt handler also
- * modifies gpe_register_info->Enable, so it should not be
- * given the chance to run until after the runtime GPEs are
- * re-enabled.
+ * DESCRIPTION: Enable all "wake" GPEs within a GPE block. (Includes
+ * combination wake/run GPEs.)
*
******************************************************************************/
acpi_status
-acpi_hw_prepare_gpes_for_sleep (
- void)
+acpi_hw_enable_wakeup_gpe_block (
+ struct acpi_gpe_xrupt_info *gpe_xrupt_info,
+ struct acpi_gpe_block_info *gpe_block)
{
+ u32 i;
acpi_status status;
- ACPI_FUNCTION_ENTRY ();
+ /* Examine each GPE Register within the block */
+ for (i = 0; i < gpe_block->register_count; i++) {
+ /* Enable all "wake" GPEs in this register */
- status = acpi_ev_walk_gpe_list (acpi_hw_prepare_gpe_block_for_sleep);
- return (status);
+ status = acpi_hw_low_level_write (8, gpe_block->register_info[i].enable_for_wake,
+ &gpe_block->register_info[i].enable_address);
+ if (ACPI_FAILURE (status)) {
+ return (status);
+ }
+ }
+
+ return (AE_OK);
}
/******************************************************************************
*
- * FUNCTION: acpi_hw_restore_gpe_block_on_wake
+ * FUNCTION: acpi_hw_disable_all_gpes
*
- * PARAMETERS: gpe_xrupt_info - GPE Interrupt info
- * gpe_block - Gpe Block info
+ * PARAMETERS: None
*
* RETURN: Status
*
- * DESCRIPTION: Enable all runtime GPEs and disable all wake GPEs -- in one
- * GPE block
+ * DESCRIPTION: Disable and clear all GPEs
*
******************************************************************************/
-static acpi_status
-acpi_hw_restore_gpe_block_on_wake (
- struct acpi_gpe_xrupt_info *gpe_xrupt_info,
- struct acpi_gpe_block_info *gpe_block)
+acpi_status
+acpi_hw_disable_all_gpes (
+ void)
{
- u32 i;
- struct acpi_gpe_register_info *gpe_register_info;
acpi_status status;
- /* This callback processes one entire GPE block */
+ ACPI_FUNCTION_ENTRY ();
- /* Get the register info for the entire GPE block */
- gpe_register_info = gpe_block->register_info;
+ status = acpi_ev_walk_gpe_list (acpi_hw_disable_gpe_block);
+ status = acpi_ev_walk_gpe_list (acpi_hw_clear_gpe_block);
+ return (status);
+}
- /* Examine each GPE register within the block */
- for (i = 0; i < gpe_block->register_count; i++) {
- /* Clear the entire status register */
+/******************************************************************************
+ *
+ * FUNCTION: acpi_hw_enable_all_runtime_gpes
+ *
+ * PARAMETERS: None
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Enable all GPEs of the given type
+ *
+ ******************************************************************************/
- status = acpi_hw_low_level_write (8, 0xFF,
- &gpe_block->register_info[i].status_address);
- if (ACPI_FAILURE (status)) {
- return (status);
- }
+acpi_status
+acpi_hw_enable_all_runtime_gpes (
+ void)
+{
+ acpi_status status;
- /*
- * Restore the GPE Enable register, which will do the following:
- *
- * 1) Disable all wakeup GPEs
- * 2) Enable all runtime GPEs
- *
- * (On sleep, we saved the enabled status of all GPEs)
- */
- status = acpi_hw_low_level_write (8, gpe_register_info->enable,
- &gpe_register_info->enable_address);
- if (ACPI_FAILURE (status)) {
- return (status);
- }
- /* Point to next GPE register */
+ ACPI_FUNCTION_ENTRY ();
- gpe_register_info++;
- }
- return (AE_OK);
+ status = acpi_ev_walk_gpe_list (acpi_hw_clear_gpe_block);
+ status = acpi_ev_walk_gpe_list (acpi_hw_enable_runtime_gpe_block);
+ return (status);
}
/******************************************************************************
*
- * FUNCTION: acpi_hw_restore_gpes_on_wake
+ * FUNCTION: acpi_hw_enable_all_wakeup_gpes
*
* PARAMETERS: None
*
* RETURN: Status
*
- * DESCRIPTION: Enable all runtime GPEs and disable all wake GPEs -- in all
- * GPE blocks
+ * DESCRIPTION: Enable all GPEs of the given type
*
******************************************************************************/
acpi_status
-acpi_hw_restore_gpes_on_wake (
+acpi_hw_enable_all_wakeup_gpes (
void)
{
acpi_status status;
@@ -593,6 +471,8 @@ acpi_hw_restore_gpes_on_wake (
ACPI_FUNCTION_ENTRY ();
- status = acpi_ev_walk_gpe_list (acpi_hw_restore_gpe_block_on_wake);
+ status = acpi_ev_walk_gpe_list (acpi_hw_clear_gpe_block);
+ status = acpi_ev_walk_gpe_list (acpi_hw_enable_wakeup_gpe_block);
return (status);
}
+
diff --git a/drivers/acpi/hardware/hwregs.c b/drivers/acpi/hardware/hwregs.c
index a7c651316ce2..a2ce75c675d0 100644
--- a/drivers/acpi/hardware/hwregs.c
+++ b/drivers/acpi/hardware/hwregs.c
@@ -135,7 +135,7 @@ acpi_get_sleep_type_data (
u8 *sleep_type_b)
{
acpi_status status = AE_OK;
- union acpi_operand_object *obj_desc;
+ struct acpi_parameter_info info;
ACPI_FUNCTION_TRACE ("acpi_get_sleep_type_data");
@@ -152,8 +152,9 @@ acpi_get_sleep_type_data (
/*
* Evaluate the namespace object containing the values for this state
*/
+ info.parameters = NULL;
status = acpi_ns_evaluate_by_name ((char *) acpi_gbl_sleep_state_names[sleep_state],
- NULL, &obj_desc);
+ &info);
if (ACPI_FAILURE (status)) {
ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "%s while evaluating sleep_state [%s]\n",
acpi_format_exception (status), acpi_gbl_sleep_state_names[sleep_state]));
@@ -163,48 +164,50 @@ acpi_get_sleep_type_data (
/* Must have a return object */
- if (!obj_desc) {
+ if (!info.return_object) {
ACPI_REPORT_ERROR (("Missing Sleep State object\n"));
status = AE_NOT_EXIST;
}
/* It must be of type Package */
- else if (ACPI_GET_OBJECT_TYPE (obj_desc) != ACPI_TYPE_PACKAGE) {
+ else if (ACPI_GET_OBJECT_TYPE (info.return_object) != ACPI_TYPE_PACKAGE) {
ACPI_REPORT_ERROR (("Sleep State object not a Package\n"));
status = AE_AML_OPERAND_TYPE;
}
/* The package must have at least two elements */
- else if (obj_desc->package.count < 2) {
+ else if (info.return_object->package.count < 2) {
ACPI_REPORT_ERROR (("Sleep State package does not have at least two elements\n"));
status = AE_AML_NO_OPERAND;
}
/* The first two elements must both be of type Integer */
- else if ((ACPI_GET_OBJECT_TYPE (obj_desc->package.elements[0]) != ACPI_TYPE_INTEGER) ||
- (ACPI_GET_OBJECT_TYPE (obj_desc->package.elements[1]) != ACPI_TYPE_INTEGER)) {
+ else if ((ACPI_GET_OBJECT_TYPE (info.return_object->package.elements[0]) != ACPI_TYPE_INTEGER) ||
+ (ACPI_GET_OBJECT_TYPE (info.return_object->package.elements[1]) != ACPI_TYPE_INTEGER)) {
ACPI_REPORT_ERROR (("Sleep State package elements are not both Integers (%s, %s)\n",
- acpi_ut_get_object_type_name (obj_desc->package.elements[0]),
- acpi_ut_get_object_type_name (obj_desc->package.elements[1])));
+ acpi_ut_get_object_type_name (info.return_object->package.elements[0]),
+ acpi_ut_get_object_type_name (info.return_object->package.elements[1])));
status = AE_AML_OPERAND_TYPE;
}
else {
/*
* Valid _Sx_ package size, type, and value
*/
- *sleep_type_a = (u8) (obj_desc->package.elements[0])->integer.value;
- *sleep_type_b = (u8) (obj_desc->package.elements[1])->integer.value;
+ *sleep_type_a = (u8) (info.return_object->package.elements[0])->integer.value;
+ *sleep_type_b = (u8) (info.return_object->package.elements[1])->integer.value;
}
if (ACPI_FAILURE (status)) {
- ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "While evaluating sleep_state [%s], bad Sleep object %p type %s\n",
- acpi_gbl_sleep_state_names[sleep_state], obj_desc, acpi_ut_get_object_type_name (obj_desc)));
+ ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
+ "While evaluating sleep_state [%s], bad Sleep object %p type %s\n",
+ acpi_gbl_sleep_state_names[sleep_state], info.return_object,
+ acpi_ut_get_object_type_name (info.return_object)));
}
- acpi_ut_remove_reference (obj_desc);
+ acpi_ut_remove_reference (info.return_object);
return_ACPI_STATUS (status);
}
diff --git a/drivers/acpi/hardware/hwsleep.c b/drivers/acpi/hardware/hwsleep.c
index f0c04149fc95..e5e3cfc22c1d 100644
--- a/drivers/acpi/hardware/hwsleep.c
+++ b/drivers/acpi/hardware/hwsleep.c
@@ -265,19 +265,21 @@ acpi_enter_sleep_state (
sleep_type_reg_info = acpi_hw_get_bit_register_info (ACPI_BITREG_SLEEP_TYPE_A);
sleep_enable_reg_info = acpi_hw_get_bit_register_info (ACPI_BITREG_SLEEP_ENABLE);
- if (sleep_state != ACPI_STATE_S5) {
- /* Clear wake status */
+ /* Clear wake status */
- status = acpi_set_register (ACPI_BITREG_WAKE_STATUS, 1, ACPI_MTX_DO_NOT_LOCK);
- if (ACPI_FAILURE (status)) {
- return_ACPI_STATUS (status);
- }
+ status = acpi_set_register (ACPI_BITREG_WAKE_STATUS, 1, ACPI_MTX_DO_NOT_LOCK);
+ if (ACPI_FAILURE (status)) {
+ return_ACPI_STATUS (status);
+ }
- status = acpi_hw_clear_acpi_status (ACPI_MTX_DO_NOT_LOCK);
- if (ACPI_FAILURE (status)) {
- return_ACPI_STATUS (status);
- }
+ /* Clear all fixed and general purpose status bits */
+ status = acpi_hw_clear_acpi_status (ACPI_MTX_DO_NOT_LOCK);
+ if (ACPI_FAILURE (status)) {
+ return_ACPI_STATUS (status);
+ }
+
+ if (sleep_state != ACPI_STATE_S5) {
/* Disable BM arbitration */
status = acpi_set_register (ACPI_BITREG_ARB_DISABLE, 1, ACPI_MTX_DO_NOT_LOCK);
@@ -287,10 +289,16 @@ acpi_enter_sleep_state (
}
/*
- * 1) Disable all runtime GPEs
+ * 1) Disable/Clear all GPEs
* 2) Enable all wakeup GPEs
*/
- status = acpi_hw_prepare_gpes_for_sleep ();
+ status = acpi_hw_disable_all_gpes ();
+ if (ACPI_FAILURE (status)) {
+ return_ACPI_STATUS (status);
+ }
+ acpi_gbl_system_awake_and_running = FALSE;
+
+ status = acpi_hw_enable_all_wakeup_gpes ();
if (ACPI_FAILURE (status)) {
return_ACPI_STATUS (status);
}
@@ -420,10 +428,16 @@ acpi_enter_sleep_state_s4bios (
}
/*
- * 1) Disable all runtime GPEs
+ * 1) Disable/Clear all GPEs
* 2) Enable all wakeup GPEs
*/
- status = acpi_hw_prepare_gpes_for_sleep ();
+ status = acpi_hw_disable_all_gpes ();
+ if (ACPI_FAILURE (status)) {
+ return_ACPI_STATUS (status);
+ }
+ acpi_gbl_system_awake_and_running = FALSE;
+
+ status = acpi_hw_enable_all_wakeup_gpes ();
if (ACPI_FAILURE (status)) {
return_ACPI_STATUS (status);
}
@@ -540,10 +554,16 @@ acpi_leave_sleep_state (
/*
* Restore the GPEs:
- * 1) Disable all wakeup GPEs
+ * 1) Disable/Clear all GPEs
* 2) Enable all runtime GPEs
*/
- status = acpi_hw_restore_gpes_on_wake ();
+ status = acpi_hw_disable_all_gpes ();
+ if (ACPI_FAILURE (status)) {
+ return_ACPI_STATUS (status);
+ }
+ acpi_gbl_system_awake_and_running = TRUE;
+
+ status = acpi_hw_enable_all_runtime_gpes ();
if (ACPI_FAILURE (status)) {
return_ACPI_STATUS (status);
}
diff --git a/drivers/acpi/namespace/nsaccess.c b/drivers/acpi/namespace/nsaccess.c
index 23baf93bf80f..765217be42d7 100644
--- a/drivers/acpi/namespace/nsaccess.c
+++ b/drivers/acpi/namespace/nsaccess.c
@@ -193,7 +193,7 @@ acpi_ns_root_initialize (void)
case ACPI_TYPE_MUTEX:
obj_desc->mutex.node = new_node;
- obj_desc->mutex.sync_level = (u16) ACPI_STRTOUL
+ obj_desc->mutex.sync_level = (u8) ACPI_STRTOUL
(val, NULL, 10);
if (ACPI_STRCMP (init_val->name, "_GL_") == 0) {
diff --git a/drivers/acpi/namespace/nseval.c b/drivers/acpi/namespace/nseval.c
index b054b365ca8f..4a7bcf2cb619 100644
--- a/drivers/acpi/namespace/nseval.c
+++ b/drivers/acpi/namespace/nseval.c
@@ -77,13 +77,10 @@
acpi_status
acpi_ns_evaluate_relative (
- struct acpi_namespace_node *handle,
char *pathname,
- union acpi_operand_object **params,
- union acpi_operand_object **return_object)
+ struct acpi_parameter_info *info)
{
acpi_status status;
- struct acpi_namespace_node *prefix_node;
struct acpi_namespace_node *node = NULL;
union acpi_generic_state *scope_info;
char *internal_path = NULL;
@@ -95,7 +92,7 @@ acpi_ns_evaluate_relative (
/*
* Must have a valid object handle
*/
- if (!handle) {
+ if (!info || !info->node) {
return_ACPI_STATUS (AE_BAD_PARAMETER);
}
@@ -118,8 +115,8 @@ acpi_ns_evaluate_relative (
goto cleanup;
}
- prefix_node = acpi_ns_map_handle_to_node (handle);
- if (!prefix_node) {
+ info->node = acpi_ns_map_handle_to_node (info->node);
+ if (!info->node) {
(void) acpi_ut_release_mutex (ACPI_MTX_NAMESPACE);
status = AE_BAD_PARAMETER;
goto cleanup;
@@ -127,7 +124,7 @@ acpi_ns_evaluate_relative (
/* Lookup the name in the namespace */
- scope_info->scope.node = prefix_node;
+ scope_info->scope.node = info->node;
status = acpi_ns_lookup (scope_info, internal_path, ACPI_TYPE_ANY,
ACPI_IMODE_EXECUTE, ACPI_NS_NO_UPSEARCH, NULL,
&node);
@@ -147,7 +144,8 @@ acpi_ns_evaluate_relative (
ACPI_DEBUG_PRINT ((ACPI_DB_NAMES, "%s [%p] Value %p\n",
pathname, node, acpi_ns_get_attached_object (node)));
- status = acpi_ns_evaluate_by_handle (node, params, return_object);
+ info->node = node;
+ status = acpi_ns_evaluate_by_handle (info);
ACPI_DEBUG_PRINT ((ACPI_DB_NAMES, "*** Completed eval of object %s ***\n",
pathname));
@@ -166,6 +164,7 @@ cleanup1:
* FUNCTION: acpi_ns_evaluate_by_name
*
* PARAMETERS: Pathname - Fully qualified pathname to the object
+ * Info - Contains:
* return_object - Where to put method's return value (if
* any). If NULL, no value is returned.
* Params - List of parameters to pass to the method,
@@ -184,11 +183,9 @@ cleanup1:
acpi_status
acpi_ns_evaluate_by_name (
char *pathname,
- union acpi_operand_object **params,
- union acpi_operand_object **return_object)
+ struct acpi_parameter_info *info)
{
acpi_status status;
- struct acpi_namespace_node *node = NULL;
char *internal_path = NULL;
@@ -211,7 +208,7 @@ acpi_ns_evaluate_by_name (
status = acpi_ns_lookup (NULL, internal_path, ACPI_TYPE_ANY,
ACPI_IMODE_EXECUTE, ACPI_NS_NO_UPSEARCH, NULL,
- &node);
+ &info->node);
(void) acpi_ut_release_mutex (ACPI_MTX_NAMESPACE);
@@ -226,9 +223,9 @@ acpi_ns_evaluate_by_name (
* to evaluate it.
*/
ACPI_DEBUG_PRINT ((ACPI_DB_NAMES, "%s [%p] Value %p\n",
- pathname, node, acpi_ns_get_attached_object (node)));
+ pathname, info->node, acpi_ns_get_attached_object (info->node)));
- status = acpi_ns_evaluate_by_handle (node, params, return_object);
+ status = acpi_ns_evaluate_by_handle (info);
ACPI_DEBUG_PRINT ((ACPI_DB_NAMES, "*** Completed eval of object %s ***\n",
pathname));
@@ -254,6 +251,7 @@ cleanup:
* Params - List of parameters to pass to the method,
* terminated by NULL. Params itself may be
* NULL if no parameters are being passed.
+ * param_type - Type of Parameter list
* return_object - Where to put method's return value (if
* any). If NULL, no value is returned.
*
@@ -267,13 +265,9 @@ cleanup:
acpi_status
acpi_ns_evaluate_by_handle (
- struct acpi_namespace_node *handle,
- union acpi_operand_object **params,
- union acpi_operand_object **return_object)
+ struct acpi_parameter_info *info)
{
- struct acpi_namespace_node *node;
acpi_status status;
- union acpi_operand_object *local_return_object;
ACPI_FUNCTION_TRACE ("ns_evaluate_by_handle");
@@ -287,15 +281,13 @@ acpi_ns_evaluate_by_handle (
/* Parameter Validation */
- if (!handle) {
+ if (!info) {
return_ACPI_STATUS (AE_BAD_PARAMETER);
}
- if (return_object) {
- /* Initialize the return value to an invalid object */
+ /* Initialize the return value to an invalid object */
- *return_object = NULL;
- }
+ info->return_object = NULL;
/* Get the prefix handle and Node */
@@ -304,8 +296,8 @@ acpi_ns_evaluate_by_handle (
return_ACPI_STATUS (status);
}
- node = acpi_ns_map_handle_to_node (handle);
- if (!node) {
+ info->node = acpi_ns_map_handle_to_node (info->node);
+ if (!info->node) {
(void) acpi_ut_release_mutex (ACPI_MTX_NAMESPACE);
return_ACPI_STATUS (AE_BAD_PARAMETER);
}
@@ -315,8 +307,8 @@ acpi_ns_evaluate_by_handle (
* so that proper scoping context will be established
* before execution.
*/
- if (acpi_ns_get_type (node) == ACPI_TYPE_LOCAL_METHOD_ALIAS) {
- node = ACPI_CAST_PTR (struct acpi_namespace_node, node->object);
+ if (acpi_ns_get_type (info->node) == ACPI_TYPE_LOCAL_METHOD_ALIAS) {
+ info->node = ACPI_CAST_PTR (struct acpi_namespace_node, info->node->object);
}
/*
@@ -328,19 +320,18 @@ acpi_ns_evaluate_by_handle (
* In both cases, the namespace is unlocked by the
* acpi_ns* procedure
*/
- if (acpi_ns_get_type (node) == ACPI_TYPE_METHOD) {
+ if (acpi_ns_get_type (info->node) == ACPI_TYPE_METHOD) {
/*
* Case 1) We have an actual control method to execute
*/
- status = acpi_ns_execute_control_method (node, params,
- &local_return_object);
+ status = acpi_ns_execute_control_method (info);
}
else {
/*
* Case 2) Object is NOT a method, just return its
* current value
*/
- status = acpi_ns_get_object_value (node, &local_return_object);
+ status = acpi_ns_get_object_value (info);
}
/*
@@ -348,20 +339,6 @@ acpi_ns_evaluate_by_handle (
* be dealt with
*/
if (status == AE_CTRL_RETURN_VALUE) {
- /*
- * If the Method returned a value and the caller
- * provided a place to store a returned value, Copy
- * the returned value to the object descriptor provided
- * by the caller.
- */
- if (return_object) {
- /*
- * Valid return object, copy the pointer to
- * the returned object
- */
- *return_object = local_return_object;
- }
-
/* Map AE_CTRL_RETURN_VALUE to AE_OK, we are done with it */
status = AE_OK;
@@ -396,9 +373,7 @@ acpi_ns_evaluate_by_handle (
acpi_status
acpi_ns_execute_control_method (
- struct acpi_namespace_node *method_node,
- union acpi_operand_object **params,
- union acpi_operand_object **return_obj_desc)
+ struct acpi_parameter_info *info)
{
acpi_status status;
union acpi_operand_object *obj_desc;
@@ -409,7 +384,7 @@ acpi_ns_execute_control_method (
/* Verify that there is a method associated with this object */
- obj_desc = acpi_ns_get_attached_object (method_node);
+ obj_desc = acpi_ns_get_attached_object (info->node);
if (!obj_desc) {
ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "No attached method object\n"));
@@ -417,7 +392,7 @@ acpi_ns_execute_control_method (
return_ACPI_STATUS (AE_NULL_OBJECT);
}
- ACPI_DUMP_PATHNAME (method_node, "Execute Method:",
+ ACPI_DUMP_PATHNAME (info->node, "Execute Method:",
ACPI_LV_INFO, _COMPONENT);
ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Method at AML address %p Length %X\n",
@@ -444,7 +419,7 @@ acpi_ns_execute_control_method (
return_ACPI_STATUS (status);
}
- status = acpi_psx_execute (method_node, params, return_obj_desc);
+ status = acpi_psx_execute (info);
acpi_ex_exit_interpreter ();
return_ACPI_STATUS (status);
@@ -468,11 +443,10 @@ acpi_ns_execute_control_method (
acpi_status
acpi_ns_get_object_value (
- struct acpi_namespace_node *node,
- union acpi_operand_object **return_obj_desc)
+ struct acpi_parameter_info *info)
{
acpi_status status = AE_OK;
- struct acpi_namespace_node *resolved_node = node;
+ struct acpi_namespace_node *resolved_node = info->node;
ACPI_FUNCTION_TRACE ("ns_get_object_value");
@@ -518,9 +492,9 @@ acpi_ns_get_object_value (
if (ACPI_SUCCESS (status)) {
status = AE_CTRL_RETURN_VALUE;
- *return_obj_desc = ACPI_CAST_PTR (union acpi_operand_object, resolved_node);
+ info->return_object = ACPI_CAST_PTR (union acpi_operand_object, resolved_node);
ACPI_DEBUG_PRINT ((ACPI_DB_NAMES, "Returning object %p [%s]\n",
- *return_obj_desc, acpi_ut_get_object_type_name (*return_obj_desc)));
+ *info->return_object, acpi_ut_get_object_type_name (info->return_object)));
}
}
diff --git a/drivers/acpi/namespace/nsinit.c b/drivers/acpi/namespace/nsinit.c
index c8e9317ab446..7d40734184d2 100644
--- a/drivers/acpi/namespace/nsinit.c
+++ b/drivers/acpi/namespace/nsinit.c
@@ -337,25 +337,28 @@ acpi_ns_init_one_device (
void *context,
void **return_value)
{
- acpi_status status;
- struct acpi_namespace_node *node;
- u32 flags;
struct acpi_device_walk_info *info = (struct acpi_device_walk_info *) context;
+ struct acpi_parameter_info pinfo;
+ u32 flags;
+ acpi_status status;
ACPI_FUNCTION_TRACE ("ns_init_one_device");
- node = acpi_ns_map_handle_to_node (obj_handle);
- if (!node) {
+ pinfo.parameters = NULL;
+ pinfo.parameter_type = ACPI_PARAM_ARGS;
+
+ pinfo.node = acpi_ns_map_handle_to_node (obj_handle);
+ if (!pinfo.node) {
return_ACPI_STATUS (AE_BAD_PARAMETER);
}
/*
* We will run _STA/_INI on Devices and Processors only
*/
- if ((node->type != ACPI_TYPE_DEVICE) &&
- (node->type != ACPI_TYPE_PROCESSOR)) {
+ if ((pinfo.node->type != ACPI_TYPE_DEVICE) &&
+ (pinfo.node->type != ACPI_TYPE_PROCESSOR)) {
return_ACPI_STATUS (AE_OK);
}
@@ -368,11 +371,11 @@ acpi_ns_init_one_device (
/*
* Run _STA to determine if we can run _INI on the device.
*/
- ACPI_DEBUG_EXEC (acpi_ut_display_init_pathname (ACPI_TYPE_METHOD, node, "_STA"));
- status = acpi_ut_execute_STA (node, &flags);
+ ACPI_DEBUG_EXEC (acpi_ut_display_init_pathname (ACPI_TYPE_METHOD, pinfo.node, "_STA"));
+ status = acpi_ut_execute_STA (pinfo.node, &flags);
if (ACPI_FAILURE (status)) {
- if (node->type == ACPI_TYPE_DEVICE) {
+ if (pinfo.node->type == ACPI_TYPE_DEVICE) {
/* Ignore error and move on to next device */
return_ACPI_STATUS (AE_OK);
@@ -393,8 +396,8 @@ acpi_ns_init_one_device (
/*
* The device is present. Run _INI.
*/
- ACPI_DEBUG_EXEC (acpi_ut_display_init_pathname (ACPI_TYPE_METHOD, obj_handle, "_INI"));
- status = acpi_ns_evaluate_relative (obj_handle, "_INI", NULL, NULL);
+ ACPI_DEBUG_EXEC (acpi_ut_display_init_pathname (ACPI_TYPE_METHOD, pinfo.node, "_INI"));
+ status = acpi_ns_evaluate_relative ("_INI", &pinfo);
if (ACPI_FAILURE (status)) {
/* No _INI (AE_NOT_FOUND) means device requires no initialization */
@@ -402,7 +405,7 @@ acpi_ns_init_one_device (
/* Ignore error and move on to next device */
#ifdef ACPI_DEBUG_OUTPUT
- char *scope_name = acpi_ns_get_external_pathname (obj_handle);
+ char *scope_name = acpi_ns_get_external_pathname (pinfo.node);
ACPI_DEBUG_PRINT ((ACPI_DB_WARN, "%s._INI failed: %s\n",
scope_name, acpi_format_exception (status)));
@@ -422,7 +425,7 @@ acpi_ns_init_one_device (
if (acpi_gbl_init_handler) {
/* External initialization handler is present, call it */
- status = acpi_gbl_init_handler (obj_handle, ACPI_INIT_DEVICE_INI);
+ status = acpi_gbl_init_handler (pinfo.node, ACPI_INIT_DEVICE_INI);
}
diff --git a/drivers/acpi/namespace/nsparse.c b/drivers/acpi/namespace/nsparse.c
index f550ce5c19f2..530982a38aa4 100644
--- a/drivers/acpi/namespace/nsparse.c
+++ b/drivers/acpi/namespace/nsparse.c
@@ -94,8 +94,9 @@ acpi_ns_one_complete_parse (
return_ACPI_STATUS (AE_NO_MEMORY);
}
- status = acpi_ds_init_aml_walk (walk_state, parse_root, NULL, table_desc->aml_start,
- table_desc->aml_length, NULL, NULL, pass_number);
+ status = acpi_ds_init_aml_walk (walk_state, parse_root, NULL,
+ table_desc->aml_start, table_desc->aml_length,
+ NULL, pass_number);
if (ACPI_FAILURE (status)) {
acpi_ds_delete_walk_state (walk_state);
return_ACPI_STATUS (status);
diff --git a/drivers/acpi/namespace/nsxfeval.c b/drivers/acpi/namespace/nsxfeval.c
index 3128354436db..8e916b5e274e 100644
--- a/drivers/acpi/namespace/nsxfeval.c
+++ b/drivers/acpi/namespace/nsxfeval.c
@@ -174,8 +174,7 @@ acpi_evaluate_object (
{
acpi_status status;
acpi_status status2;
- union acpi_operand_object **internal_params = NULL;
- union acpi_operand_object *internal_return_obj = NULL;
+ struct acpi_parameter_info info;
acpi_size buffer_space_needed;
u32 i;
@@ -183,6 +182,11 @@ acpi_evaluate_object (
ACPI_FUNCTION_TRACE ("acpi_evaluate_object");
+ info.node = handle;
+ info.parameters = NULL;
+ info.return_object = NULL;
+ info.parameter_type = ACPI_PARAM_ARGS;
+
/*
* If there are parameters to be passed to the object
* (which must be a control method), the external objects
@@ -193,9 +197,10 @@ acpi_evaluate_object (
* Allocate a new parameter block for the internal objects
* Add 1 to count to allow for null terminated internal list
*/
- internal_params = ACPI_MEM_CALLOCATE (((acpi_size) external_params->count + 1) *
- sizeof (void *));
- if (!internal_params) {
+ info.parameters = ACPI_MEM_CALLOCATE (
+ ((acpi_size) external_params->count + 1) *
+ sizeof (void *));
+ if (!info.parameters) {
return_ACPI_STATUS (AE_NO_MEMORY);
}
@@ -205,15 +210,16 @@ acpi_evaluate_object (
*/
for (i = 0; i < external_params->count; i++) {
status = acpi_ut_copy_eobject_to_iobject (&external_params->pointer[i],
- &internal_params[i]);
+ &info.parameters[i]);
if (ACPI_FAILURE (status)) {
- acpi_ut_delete_internal_object_list (internal_params);
+ acpi_ut_delete_internal_object_list (info.parameters);
return_ACPI_STATUS (status);
}
}
- internal_params[external_params->count] = NULL;
+ info.parameters[external_params->count] = NULL;
}
+
/*
* Three major cases:
* 1) Fully qualified pathname
@@ -225,8 +231,7 @@ acpi_evaluate_object (
/*
* The path is fully qualified, just evaluate by name
*/
- status = acpi_ns_evaluate_by_name (pathname, internal_params,
- &internal_return_obj);
+ status = acpi_ns_evaluate_by_name (pathname, &info);
}
else if (!handle) {
/*
@@ -256,15 +261,13 @@ acpi_evaluate_object (
* The null pathname case means the handle is for
* the actual object to be evaluated
*/
- status = acpi_ns_evaluate_by_handle (handle, internal_params,
- &internal_return_obj);
+ status = acpi_ns_evaluate_by_handle (&info);
}
else {
/*
* Both a Handle and a relative Pathname
*/
- status = acpi_ns_evaluate_relative (handle, pathname, internal_params,
- &internal_return_obj);
+ status = acpi_ns_evaluate_relative (pathname, &info);
}
}
@@ -274,11 +277,11 @@ acpi_evaluate_object (
* copy the return value to an external object.
*/
if (return_buffer) {
- if (!internal_return_obj) {
+ if (!info.return_object) {
return_buffer->length = 0;
}
else {
- if (ACPI_GET_DESCRIPTOR_TYPE (internal_return_obj) == ACPI_DESC_TYPE_NAMED) {
+ if (ACPI_GET_DESCRIPTOR_TYPE (info.return_object) == ACPI_DESC_TYPE_NAMED) {
/*
* If we received a NS Node as a return object, this means that
* the object we are evaluating has nothing interesting to
@@ -288,7 +291,7 @@ acpi_evaluate_object (
* support for various types at a later date if necessary.
*/
status = AE_TYPE;
- internal_return_obj = NULL; /* No need to delete a NS Node */
+ info.return_object = NULL; /* No need to delete a NS Node */
return_buffer->length = 0;
}
@@ -297,7 +300,7 @@ acpi_evaluate_object (
* Find out how large a buffer is needed
* to contain the returned object
*/
- status = acpi_ut_get_object_size (internal_return_obj,
+ status = acpi_ut_get_object_size (info.return_object,
&buffer_space_needed);
if (ACPI_SUCCESS (status)) {
/* Validate/Allocate/Clear caller buffer */
@@ -309,13 +312,14 @@ acpi_evaluate_object (
*/
ACPI_DEBUG_PRINT ((ACPI_DB_INFO,
"Needed buffer size %X, %s\n",
- (u32) buffer_space_needed, acpi_format_exception (status)));
+ (u32) buffer_space_needed,
+ acpi_format_exception (status)));
}
else {
/*
* We have enough space for the object, build it
*/
- status = acpi_ut_copy_iobject_to_eobject (internal_return_obj,
+ status = acpi_ut_copy_iobject_to_eobject (info.return_object,
return_buffer);
}
}
@@ -323,7 +327,7 @@ acpi_evaluate_object (
}
}
- if (internal_return_obj) {
+ if (info.return_object) {
/*
* Delete the internal return object. NOTE: Interpreter
* must be locked to avoid race condition.
@@ -334,7 +338,7 @@ acpi_evaluate_object (
* Delete the internal return object. (Or at least
* decrement the reference count by one)
*/
- acpi_ut_remove_reference (internal_return_obj);
+ acpi_ut_remove_reference (info.return_object);
acpi_ex_exit_interpreter ();
}
}
@@ -342,10 +346,10 @@ acpi_evaluate_object (
/*
* Free the input parameter list (if we created one),
*/
- if (internal_params) {
+ if (info.parameters) {
/* Free the allocated parameter block */
- acpi_ut_delete_internal_object_list (internal_params);
+ acpi_ut_delete_internal_object_list (info.parameters);
}
return_ACPI_STATUS (status);
diff --git a/drivers/acpi/namespace/nsxfname.c b/drivers/acpi/namespace/nsxfname.c
index a1acb9f12b49..0508b4d79e2e 100644
--- a/drivers/acpi/namespace/nsxfname.c
+++ b/drivers/acpi/namespace/nsxfname.c
@@ -281,7 +281,7 @@ acpi_get_object_info (
if (info.type == ACPI_TYPE_DEVICE) {
/*
* Get extra info for ACPI Devices objects only:
- * Run the Device _HID, _UID, _CID, _STA, and _ADR methods.
+ * Run the Device _HID, _UID, _CID, _STA, _ADR and _sx_d methods.
*
* Note: none of these methods are required, so they may or may
* not be present for this device. The Info.Valid bitfield is used
@@ -330,7 +330,7 @@ acpi_get_object_info (
status = acpi_ut_execute_sxds (node, info.highest_dstates);
if (ACPI_SUCCESS (status)) {
- info.valid |= ACPI_VALID_STA;
+ info.valid |= ACPI_VALID_SXDS;
}
status = AE_OK;
diff --git a/drivers/acpi/parser/psxface.c b/drivers/acpi/parser/psxface.c
index b7917cfdcf8f..456172fe8039 100644
--- a/drivers/acpi/parser/psxface.c
+++ b/drivers/acpi/parser/psxface.c
@@ -57,7 +57,7 @@
*
* FUNCTION: acpi_psx_execute
*
- * PARAMETERS: method_node - A method object containing both the AML
+ * PARAMETERS: Info->Node - A method object containing both the AML
* address and length.
* **Params - List of parameters to pass to method,
* terminated by NULL. Params itself may be
@@ -73,9 +73,7 @@
acpi_status
acpi_psx_execute (
- struct acpi_namespace_node *method_node,
- union acpi_operand_object **params,
- union acpi_operand_object **return_obj_desc)
+ struct acpi_parameter_info *info)
{
acpi_status status;
union acpi_operand_object *obj_desc;
@@ -89,29 +87,31 @@ acpi_psx_execute (
/* Validate the Node and get the attached object */
- if (!method_node) {
+ if (!info || !info->node) {
return_ACPI_STATUS (AE_NULL_ENTRY);
}
- obj_desc = acpi_ns_get_attached_object (method_node);
+ obj_desc = acpi_ns_get_attached_object (info->node);
if (!obj_desc) {
return_ACPI_STATUS (AE_NULL_OBJECT);
}
/* Init for new method, wait on concurrency semaphore */
- status = acpi_ds_begin_method_execution (method_node, obj_desc, NULL);
+ status = acpi_ds_begin_method_execution (info->node, obj_desc, NULL);
if (ACPI_FAILURE (status)) {
return_ACPI_STATUS (status);
}
- if (params) {
+ if (info &&
+ (info->parameter_type == ACPI_PARAM_ARGS) &&
+ (info->parameters)) {
/*
* The caller "owns" the parameters, so give each one an extra
* reference
*/
- for (i = 0; params[i]; i++) {
- acpi_ut_add_reference (params[i]);
+ for (i = 0; info->parameters[i]; i++) {
+ acpi_ut_add_reference (info->parameters[i]);
}
}
@@ -121,7 +121,7 @@ acpi_psx_execute (
*/
ACPI_DEBUG_PRINT ((ACPI_DB_PARSE,
"**** Begin Method Parse **** Entry=%p obj=%p\n",
- method_node, obj_desc));
+ info->node, obj_desc));
/* Create and init a Root Node */
@@ -147,8 +147,9 @@ acpi_psx_execute (
goto cleanup2;
}
- status = acpi_ds_init_aml_walk (walk_state, op, method_node, obj_desc->method.aml_start,
- obj_desc->method.aml_length, NULL, NULL, 1);
+ status = acpi_ds_init_aml_walk (walk_state, op, info->node,
+ obj_desc->method.aml_start,
+ obj_desc->method.aml_length, NULL, 1);
if (ACPI_FAILURE (status)) {
goto cleanup3;
}
@@ -159,7 +160,6 @@ acpi_psx_execute (
acpi_ps_delete_parse_tree (op);
if (ACPI_FAILURE (status)) {
goto cleanup1; /* Walk state is already deleted */
-
}
/*
@@ -167,7 +167,7 @@ acpi_psx_execute (
*/
ACPI_DEBUG_PRINT ((ACPI_DB_PARSE,
"**** Begin Method Execution **** Entry=%p obj=%p\n",
- method_node, obj_desc));
+ info->node, obj_desc));
/* Create and init a Root Node */
@@ -179,8 +179,8 @@ acpi_psx_execute (
/* Init new op with the method name and pointer back to the NS node */
- acpi_ps_set_name (op, method_node->name.integer);
- op->common.node = method_node;
+ acpi_ps_set_name (op, info->node->name.integer);
+ op->common.node = info->node;
/* Create and initialize a new walk state */
@@ -190,8 +190,9 @@ acpi_psx_execute (
goto cleanup2;
}
- status = acpi_ds_init_aml_walk (walk_state, op, method_node, obj_desc->method.aml_start,
- obj_desc->method.aml_length, params, return_obj_desc, 3);
+ status = acpi_ds_init_aml_walk (walk_state, op, info->node,
+ obj_desc->method.aml_start,
+ obj_desc->method.aml_length, info, 3);
if (ACPI_FAILURE (status)) {
goto cleanup3;
}
@@ -210,13 +211,14 @@ cleanup2:
acpi_ps_delete_parse_tree (op);
cleanup1:
- if (params) {
+ if ((info->parameter_type == ACPI_PARAM_ARGS) &&
+ (info->parameters)) {
/* Take away the extra reference that we gave the parameters above */
- for (i = 0; params[i]; i++) {
+ for (i = 0; info->parameters[i]; i++) {
/* Ignore errors, just do them all */
- (void) acpi_ut_update_object_reference (params[i], REF_DECREMENT);
+ (void) acpi_ut_update_object_reference (info->parameters[i], REF_DECREMENT);
}
}
@@ -228,10 +230,10 @@ cleanup1:
* If the method has returned an object, signal this to the caller with
* a control exception code
*/
- if (*return_obj_desc) {
+ if (info->return_object) {
ACPI_DEBUG_PRINT ((ACPI_DB_PARSE, "Method returned obj_desc=%p\n",
- *return_obj_desc));
- ACPI_DUMP_STACK_ENTRY (*return_obj_desc);
+ info->return_object));
+ ACPI_DUMP_STACK_ENTRY (info->return_object);
status = AE_CTRL_RETURN_VALUE;
}
diff --git a/drivers/acpi/resources/rsutils.c b/drivers/acpi/resources/rsutils.c
index eaf77c635aa6..01dea9b9441c 100644
--- a/drivers/acpi/resources/rsutils.c
+++ b/drivers/acpi/resources/rsutils.c
@@ -289,6 +289,7 @@ acpi_rs_set_srs_method_data (
acpi_handle handle,
struct acpi_buffer *in_buffer)
{
+ struct acpi_parameter_info info;
union acpi_operand_object *params[2];
acpi_status status;
struct acpi_buffer buffer;
@@ -329,10 +330,14 @@ acpi_rs_set_srs_method_data (
params[0]->common.flags = AOPOBJ_DATA_VALID;
params[1] = NULL;
+ info.node = handle;
+ info.parameters = params;
+ info.parameter_type = ACPI_PARAM_ARGS;
+
/*
* Execute the method, no return value
*/
- status = acpi_ns_evaluate_relative (handle, "_SRS", params, NULL);
+ status = acpi_ns_evaluate_relative ("_SRS", &info);
/*
* Clean up and return the status from acpi_ns_evaluate_relative
diff --git a/drivers/acpi/utilities/uteval.c b/drivers/acpi/utilities/uteval.c
index c3f5900b6937..0aa1fde7ec49 100644
--- a/drivers/acpi/utilities/uteval.c
+++ b/drivers/acpi/utilities/uteval.c
@@ -133,7 +133,7 @@ acpi_ut_evaluate_object (
u32 expected_return_btypes,
union acpi_operand_object **return_desc)
{
- union acpi_operand_object *obj_desc;
+ struct acpi_parameter_info info;
acpi_status status;
u32 return_btype;
@@ -141,9 +141,13 @@ acpi_ut_evaluate_object (
ACPI_FUNCTION_TRACE ("ut_evaluate_object");
+ info.node = prefix_node;
+ info.parameters = NULL;
+ info.parameter_type = ACPI_PARAM_ARGS;
+
/* Evaluate the object/method */
- status = acpi_ns_evaluate_relative (prefix_node, path, NULL, &obj_desc);
+ status = acpi_ns_evaluate_relative (path, &info);
if (ACPI_FAILURE (status)) {
if (status == AE_NOT_FOUND) {
ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "[%4.4s.%s] was not found\n",
@@ -159,7 +163,7 @@ acpi_ut_evaluate_object (
/* Did we get a return object? */
- if (!obj_desc) {
+ if (!info.return_object) {
if (expected_return_btypes) {
ACPI_REPORT_METHOD_ERROR ("No object was returned from",
prefix_node, path, AE_NOT_EXIST);
@@ -172,7 +176,7 @@ acpi_ut_evaluate_object (
/* Map the return object type to the bitmapped type */
- switch (ACPI_GET_OBJECT_TYPE (obj_desc)) {
+ switch (ACPI_GET_OBJECT_TYPE (info.return_object)) {
case ACPI_TYPE_INTEGER:
return_btype = ACPI_BTYPE_INTEGER;
break;
@@ -202,17 +206,17 @@ acpi_ut_evaluate_object (
ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
"Type returned from %s was incorrect: %X\n",
- path, ACPI_GET_OBJECT_TYPE (obj_desc)));
+ path, ACPI_GET_OBJECT_TYPE (info.return_object)));
/* On error exit, we must delete the return object */
- acpi_ut_remove_reference (obj_desc);
+ acpi_ut_remove_reference (info.return_object);
return_ACPI_STATUS (AE_TYPE);
}
/* Object type is OK, return it */
- *return_desc = obj_desc;
+ *return_desc = info.return_object;
return_ACPI_STATUS (AE_OK);
}
diff --git a/drivers/acpi/utilities/utglobal.c b/drivers/acpi/utilities/utglobal.c
index 0cac0fd9ec5f..51d4b052f7bd 100644
--- a/drivers/acpi/utilities/utglobal.c
+++ b/drivers/acpi/utilities/utglobal.c
@@ -171,27 +171,40 @@ u8 acpi_gbl_shutdown = TRUE;
const u8 acpi_gbl_decode_to8bit [8] = {1,2,4,8,16,32,64,128};
-const char *acpi_gbl_sleep_state_names[ACPI_S_STATE_COUNT] = {
- "\\_S0_",
- "\\_S1_",
- "\\_S2_",
- "\\_S3_",
- "\\_S4_",
- "\\_S5_"};
-
-const char *acpi_gbl_highest_dstate_names[4] = {
- "_S1D",
- "_S2D",
- "_S3D",
- "_S4D"};
+const char *acpi_gbl_sleep_state_names[ACPI_S_STATE_COUNT] =
+{
+ "\\_S0_",
+ "\\_S1_",
+ "\\_S2_",
+ "\\_S3_",
+ "\\_S4_",
+ "\\_S5_"
+};
-/* Strings supported by the _OSI predefined (internal) method */
+const char *acpi_gbl_highest_dstate_names[4] =
+{
+ "_S1D",
+ "_S2D",
+ "_S3D",
+ "_S4D"
+};
-const char *acpi_gbl_valid_osi_strings[ACPI_NUM_OSI_STRINGS] = {
- "Linux",
- "Windows 2000",
- "Windows 2001",
- "Windows 2001.1"};
+/*
+ * Strings supported by the _OSI predefined (internal) method.
+ * When adding strings, be sure to update ACPI_NUM_OSI_STRINGS.
+ */
+const char *acpi_gbl_valid_osi_strings[ACPI_NUM_OSI_STRINGS] =
+{
+ "Linux",
+ "Windows 2000",
+ "Windows 2001",
+ "Windows 2001.1",
+ "Windows 2001 SP0",
+ "Windows 2001 SP1",
+ "Windows 2001 SP2",
+ "Windows 2001 SP3",
+ "Windows 2001 SP4"
+};
/******************************************************************************
@@ -887,6 +900,7 @@ acpi_ut_init_globals (
/* Hardware oriented */
acpi_gbl_events_initialized = FALSE;
+ acpi_gbl_system_awake_and_running = TRUE;
/* Namespace */
diff --git a/drivers/acpi/utilities/utxface.c b/drivers/acpi/utilities/utxface.c
index 5cbd93eeff0f..45c14f9ef31d 100644
--- a/drivers/acpi/utilities/utxface.c
+++ b/drivers/acpi/utilities/utxface.c
@@ -157,9 +157,8 @@ acpi_enable_subsystem (
}
}
- /*
- * Enable ACPI mode
- */
+ /* Enable ACPI mode */
+
if (!(flags & ACPI_NO_ACPI_ENABLE)) {
ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "[Init] Going into ACPI mode\n"));
@@ -173,7 +172,21 @@ acpi_enable_subsystem (
}
/*
- * Initialize ACPI Event handling
+ * Install the default op_region handlers. These are installed unless
+ * other handlers have already been installed via the
+ * install_address_space_handler interface.
+ */
+ if (!(flags & ACPI_NO_ADDRESS_SPACE_INIT)) {
+ ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "[Init] Installing default address space handlers\n"));
+
+ status = acpi_ev_install_region_handlers ();
+ if (ACPI_FAILURE (status)) {
+ return_ACPI_STATUS (status);
+ }
+ }
+
+ /*
+ * Initialize ACPI Event handling (Fixed and General Purpose)
*
* NOTE: We must have the hardware AND events initialized before we can execute
* ANY control methods SAFELY. Any control method can require ACPI hardware
@@ -182,18 +195,18 @@ acpi_enable_subsystem (
if (!(flags & ACPI_NO_EVENT_INIT)) {
ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "[Init] Initializing ACPI events\n"));
- status = acpi_ev_initialize ();
+ status = acpi_ev_initialize_events ();
if (ACPI_FAILURE (status)) {
return_ACPI_STATUS (status);
}
}
- /* Install the SCI handler, Global Lock handler, and GPE handlers */
+ /* Install the SCI handler and Global Lock handler */
if (!(flags & ACPI_NO_HANDLER_INIT)) {
- ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "[Init] Installing SCI/GL/GPE handlers\n"));
+ ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "[Init] Installing SCI/GL handlers\n"));
- status = acpi_ev_handler_initialize ();
+ status = acpi_ev_install_xrupt_handlers ();
if (ACPI_FAILURE (status)) {
return_ACPI_STATUS (status);
}
@@ -226,18 +239,16 @@ acpi_initialize_objects (
/*
- * Install the default op_region handlers. These are installed unless
- * other handlers have already been installed via the
- * install_address_space_handler interface.
+ * Run all _REG methods
*
- * NOTE: This will cause _REG methods to be run. Any objects accessed
+ * NOTE: Any objects accessed
* by the _REG methods will be automatically initialized, even if they
* contain executable AML (see call to acpi_ns_initialize_objects below).
*/
if (!(flags & ACPI_NO_ADDRESS_SPACE_INIT)) {
- ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "[Init] Installing default address space handlers\n"));
+ ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "[Init] Executing _REG op_region methods\n"));
- status = acpi_ev_init_address_spaces ();
+ status = acpi_ev_initialize_op_regions ();
if (ACPI_FAILURE (status)) {
return_ACPI_STATUS (status);
}
@@ -249,7 +260,7 @@ acpi_initialize_objects (
* objects: operation_regions, buffer_fields, Buffers, and Packages.
*/
if (!(flags & ACPI_NO_OBJECT_INIT)) {
- ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "[Init] Initializing ACPI Objects\n"));
+ ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "[Init] Completing Initialization of ACPI Objects\n"));
status = acpi_ns_initialize_objects ();
if (ACPI_FAILURE (status)) {
diff --git a/include/acpi/acconfig.h b/include/acpi/acconfig.h
index 908af3e75c44..50e17c4e869d 100644
--- a/include/acpi/acconfig.h
+++ b/include/acpi/acconfig.h
@@ -64,7 +64,7 @@
/* Version string */
-#define ACPI_CA_VERSION 0x20040402
+#define ACPI_CA_VERSION 0x20040427
/* Maximum objects in the various object caches */
@@ -187,7 +187,7 @@
/* Number of strings associated with the _OSI reserved method */
-#define ACPI_NUM_OSI_STRINGS 4
+#define ACPI_NUM_OSI_STRINGS 9
/******************************************************************************
diff --git a/include/acpi/acdispat.h b/include/acpi/acdispat.h
index 2a09e926cccc..e003a4f3ff4e 100644
--- a/include/acpi/acdispat.h
+++ b/include/acpi/acdispat.h
@@ -437,8 +437,7 @@ acpi_ds_init_aml_walk (
struct acpi_namespace_node *method_node,
u8 *aml_start,
u32 aml_length,
- union acpi_operand_object **params,
- union acpi_operand_object **return_obj_desc,
+ struct acpi_parameter_info *info,
u32 pass_number);
acpi_status
diff --git a/include/acpi/acevents.h b/include/acpi/acevents.h
index 4ab99b2fd670..16455d56ef83 100644
--- a/include/acpi/acevents.h
+++ b/include/acpi/acevents.h
@@ -46,11 +46,11 @@
acpi_status
-acpi_ev_initialize (
+acpi_ev_initialize_events (
void);
acpi_status
-acpi_ev_handler_initialize (
+acpi_ev_install_xrupt_handlers (
void);
@@ -117,6 +117,20 @@ u8
acpi_ev_valid_gpe_event (
struct acpi_gpe_event_info *gpe_event_info);
+acpi_status
+acpi_ev_update_gpe_enable_masks (
+ struct acpi_gpe_event_info *gpe_event_info,
+ u8 type);
+
+acpi_status
+acpi_ev_enable_gpe (
+ struct acpi_gpe_event_info *gpe_event_info,
+ u8 write_to_hardware);
+
+acpi_status
+acpi_ev_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,
@@ -139,6 +153,11 @@ acpi_status
acpi_ev_delete_gpe_block (
struct acpi_gpe_block_info *gpe_block);
+acpi_status
+acpi_ev_delete_gpe_handlers (
+ struct acpi_gpe_xrupt_info *gpe_xrupt_info,
+ struct acpi_gpe_block_info *gpe_block);
+
u32
acpi_ev_gpe_dispatch (
struct acpi_gpe_event_info *gpe_event_info,
@@ -148,12 +167,25 @@ u32
acpi_ev_gpe_detect (
struct acpi_gpe_xrupt_info *gpe_xrupt_list);
+acpi_status
+acpi_ev_set_gpe_type (
+ struct acpi_gpe_event_info *gpe_event_info,
+ u8 type);
+
+acpi_status
+acpi_ev_check_for_wake_only_gpe (
+ struct acpi_gpe_event_info *gpe_event_info);
+
/*
* Evregion - Address Space handling
*/
acpi_status
-acpi_ev_init_address_spaces (
+acpi_ev_install_region_handlers (
+ void);
+
+acpi_status
+acpi_ev_initialize_op_regions (
void);
acpi_status
@@ -183,6 +215,19 @@ acpi_ev_detach_region (
u8 acpi_ns_is_locked);
acpi_status
+acpi_ev_install_space_handler (
+ struct acpi_namespace_node *node,
+ acpi_adr_space_type space_id,
+ acpi_adr_space_handler handler,
+ acpi_adr_space_setup setup,
+ void *context);
+
+acpi_status
+acpi_ev_execute_reg_methods (
+ struct acpi_namespace_node *node,
+ acpi_adr_space_type space_id);
+
+acpi_status
acpi_ev_execute_reg_method (
union acpi_operand_object *region_obj,
u32 function);
diff --git a/include/acpi/acexcep.h b/include/acpi/acexcep.h
index 9441f5c1a7e8..abda2357e543 100644
--- a/include/acpi/acexcep.h
+++ b/include/acpi/acexcep.h
@@ -95,8 +95,9 @@
#define AE_LOGICAL_ADDRESS (acpi_status) (0x001B | AE_CODE_ENVIRONMENTAL)
#define AE_ABORT_METHOD (acpi_status) (0x001C | AE_CODE_ENVIRONMENTAL)
#define AE_SAME_HANDLER (acpi_status) (0x001D | AE_CODE_ENVIRONMENTAL)
+#define AE_WAKE_ONLY_GPE (acpi_status) (0x001E | AE_CODE_ENVIRONMENTAL)
-#define AE_CODE_ENV_MAX 0x001D
+#define AE_CODE_ENV_MAX 0x001E
/*
* Programmer exceptions
@@ -222,7 +223,8 @@ char const *acpi_gbl_exception_names_env[] =
"AE_NO_GLOBAL_LOCK",
"AE_LOGICAL_ADDRESS",
"AE_ABORT_METHOD",
- "AE_SAME_HANDLER"
+ "AE_SAME_HANDLER",
+ "AE_WAKE_ONLY_GPE"
};
char const *acpi_gbl_exception_names_pgm[] =
diff --git a/include/acpi/acglobal.h b/include/acpi/acglobal.h
index 397ca31fdf99..fb32a710d6a1 100644
--- a/include/acpi/acglobal.h
+++ b/include/acpi/acglobal.h
@@ -192,6 +192,7 @@ ACPI_EXTERN u8 acpi_gbl_step_to_next_call;
ACPI_EXTERN u8 acpi_gbl_acpi_hardware_present;
ACPI_EXTERN u8 acpi_gbl_global_lock_present;
ACPI_EXTERN u8 acpi_gbl_events_initialized;
+ACPI_EXTERN u8 acpi_gbl_system_awake_and_running;
extern u8 acpi_gbl_shutdown;
extern u32 acpi_gbl_startup_flags;
diff --git a/include/acpi/achware.h b/include/acpi/achware.h
index 2281f27ea226..a3e067c010e3 100644
--- a/include/acpi/achware.h
+++ b/include/acpi/achware.h
@@ -117,10 +117,6 @@ acpi_status
acpi_hw_enable_gpe (
struct acpi_gpe_event_info *gpe_event_info);
-void
-acpi_hw_enable_gpe_for_wakeup (
- struct acpi_gpe_event_info *gpe_event_info);
-
acpi_status
acpi_hw_disable_gpe (
struct acpi_gpe_event_info *gpe_event_info);
@@ -130,10 +126,6 @@ acpi_hw_disable_gpe_block (
struct acpi_gpe_xrupt_info *gpe_xrupt_info,
struct acpi_gpe_block_info *gpe_block);
-void
-acpi_hw_disable_gpe_for_wakeup (
- struct acpi_gpe_event_info *gpe_event_info);
-
acpi_status
acpi_hw_clear_gpe (
struct acpi_gpe_event_info *gpe_event_info);
@@ -149,13 +141,22 @@ acpi_hw_get_gpe_status (
acpi_event_status *event_status);
acpi_status
-acpi_hw_prepare_gpes_for_sleep (
+acpi_hw_disable_all_gpes (
void);
acpi_status
-acpi_hw_restore_gpes_on_wake (
+acpi_hw_enable_all_runtime_gpes (
void);
+acpi_status
+acpi_hw_enable_all_wakeup_gpes (
+ void);
+
+acpi_status
+acpi_hw_enable_runtime_gpe_block (
+ struct acpi_gpe_xrupt_info *gpe_xrupt_info,
+ struct acpi_gpe_block_info *gpe_block);
+
/* ACPI Timer prototypes */
diff --git a/include/acpi/aclocal.h b/include/acpi/aclocal.h
index eb1b957ed74e..2afff1148f0c 100644
--- a/include/acpi/aclocal.h
+++ b/include/acpi/aclocal.h
@@ -189,8 +189,6 @@ struct acpi_namespace_node
u8 type; /* Type associated with this name */
u16 owner_id;
union acpi_name_union name; /* ACPI Name, always 4 chars per ACPI spec */
-
-
union acpi_operand_object *object; /* Pointer to attached ACPI object (optional) */
struct acpi_namespace_node *child; /* First child */
struct acpi_namespace_node *peer; /* Next peer*/
@@ -211,10 +209,8 @@ struct acpi_namespace_node
#define ANOBJ_METHOD_LOCAL 0x10
#define ANOBJ_METHOD_NO_RETVAL 0x20
#define ANOBJ_METHOD_SOME_NO_RETVAL 0x40
-
#define ANOBJ_IS_BIT_OFFSET 0x80
-
/*
* ACPI Table Descriptor. One per ACPI table
*/
@@ -309,16 +305,31 @@ struct acpi_create_field_info
*
****************************************************************************/
-/* Information about a GPE, one per each GPE in an array */
+/* Dispatch info for each GPE -- either a method or handler, cannot be both */
-struct acpi_gpe_event_info
+struct acpi_handler_info
{
- struct acpi_namespace_node *method_node; /* Method node for this GPE level */
- acpi_gpe_handler handler; /* Address of handler, if any */
+ 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) */
+};
+
+union acpi_gpe_dispatch_info
+{
+ struct acpi_namespace_node *method_node; /* Method node for this GPE level */
+ struct acpi_handler_info *handler;
+};
+
+/*
+ * Information about a GPE, one per each GPE in an array.
+ * NOTE: Important to keep this struct as small as possible.
+ */
+struct acpi_gpe_event_info
+{
+ union acpi_gpe_dispatch_info dispatch; /* Either Method or Handler */
struct acpi_gpe_register_info *register_info; /* Backpointer to register info */
- u8 flags; /* Level or Edge */
- u8 bit_mask; /* This GPE within the register */
+ u8 flags; /* Misc info about this GPE */
+ u8 register_bit; /* This GPE bit within the register */
};
/* Information about a GPE register pair, one per each status/enable pair in an array */
@@ -327,9 +338,8 @@ struct acpi_gpe_register_info
{
struct acpi_generic_address status_address; /* Address of status reg */
struct acpi_generic_address enable_address; /* Address of enable reg */
- u8 status; /* Current value of status reg */
- u8 enable; /* Current value of enable reg */
- u8 wake_enable; /* Mask of bits to keep enabled when sleeping */
+ u8 enable_for_wake; /* GPEs to keep enabled when sleeping */
+ u8 enable_for_run; /* GPEs to keep enabled when running */
u8 base_gpe_number; /* Base GPE number for this register */
};
@@ -339,6 +349,7 @@ struct acpi_gpe_register_info
*/
struct acpi_gpe_block_info
{
+ struct acpi_namespace_node *node;
struct acpi_gpe_block_info *previous;
struct acpi_gpe_block_info *next;
struct acpi_gpe_xrupt_info *xrupt_block; /* Backpointer to interrupt block */
@@ -502,7 +513,7 @@ struct acpi_thread_state
struct acpi_walk_state *walk_state_list; /* Head of list of walk_states for this thread */
union acpi_operand_object *acquired_mutex_list; /* List of all currently acquired mutexes */
u32 thread_id; /* Running thread ID */
- u16 current_sync_level; /* Mutex Sync (nested acquire) level */
+ u8 current_sync_level; /* Mutex Sync (nested acquire) level */
};
diff --git a/include/acpi/acnamesp.h b/include/acpi/acnamesp.h
index de54ba7ba640..8cfd1afbac28 100644
--- a/include/acpi/acnamesp.h
+++ b/include/acpi/acnamesp.h
@@ -278,33 +278,25 @@ acpi_ns_dump_objects (
acpi_status
acpi_ns_evaluate_by_handle (
- struct acpi_namespace_node *prefix_node,
- union acpi_operand_object **params,
- union acpi_operand_object **return_object);
+ struct acpi_parameter_info *info);
acpi_status
acpi_ns_evaluate_by_name (
char *pathname,
- union acpi_operand_object **params,
- union acpi_operand_object **return_object);
+ struct acpi_parameter_info *info);
acpi_status
acpi_ns_evaluate_relative (
- struct acpi_namespace_node *prefix_node,
char *pathname,
- union acpi_operand_object **params,
- union acpi_operand_object **return_object);
+ struct acpi_parameter_info *info);
acpi_status
acpi_ns_execute_control_method (
- struct acpi_namespace_node *method_node,
- union acpi_operand_object **params,
- union acpi_operand_object **return_obj_desc);
+ struct acpi_parameter_info *info);
acpi_status
acpi_ns_get_object_value (
- struct acpi_namespace_node *object_node,
- union acpi_operand_object **return_obj_desc);
+ struct acpi_parameter_info *info);
/*
diff --git a/include/acpi/acobject.h b/include/acpi/acobject.h
index 51abddaf15a2..0d479722f4aa 100644
--- a/include/acpi/acobject.h
+++ b/include/acpi/acobject.h
@@ -204,13 +204,14 @@ struct acpi_object_method
struct acpi_object_mutex
{
ACPI_OBJECT_COMMON_HEADER
- u16 sync_level;
- u16 acquisition_depth;
- struct acpi_thread_state *owner_thread;
- void *semaphore;
+ u8 sync_level; /* 0-15, specified in Mutex() call */
+ u16 acquisition_depth; /* Allow multiple Acquires, same thread */
+ struct acpi_thread_state *owner_thread; /* Current owner of the mutex */
+ void *semaphore; /* Actual OS synchronization object */
union acpi_operand_object *prev; /* Link for list of acquired mutexes */
union acpi_operand_object *next; /* Link for list of acquired mutexes */
- struct acpi_namespace_node *node; /* containing object */
+ struct acpi_namespace_node *node; /* Containing namespace node */
+ u8 original_sync_level; /* Owner's original sync level (0-15) */
};
@@ -220,7 +221,7 @@ struct acpi_object_region
u8 space_id;
union acpi_operand_object *handler; /* Handler for region access */
- struct acpi_namespace_node *node; /* containing object */
+ struct acpi_namespace_node *node; /* Containing namespace node */
union acpi_operand_object *next;
u32 length;
acpi_physical_address address;
diff --git a/include/acpi/acparser.h b/include/acpi/acparser.h
index 562e66002ffa..42cc5b4d32a8 100644
--- a/include/acpi/acparser.h
+++ b/include/acpi/acparser.h
@@ -73,9 +73,7 @@ acpi_psx_load_table (
acpi_status
acpi_psx_execute (
- struct acpi_namespace_node *method_node,
- union acpi_operand_object **params,
- union acpi_operand_object **return_obj_desc);
+ struct acpi_parameter_info *info);
/******************************************************************************
diff --git a/include/acpi/acpixf.h b/include/acpi/acpixf.h
index e53a918679cb..54ae84dcfbcd 100644
--- a/include/acpi/acpixf.h
+++ b/include/acpi/acpixf.h
@@ -296,7 +296,7 @@ acpi_install_gpe_handler (
acpi_handle gpe_device,
u32 gpe_number,
u32 type,
- acpi_gpe_handler handler,
+ acpi_event_handler address,
void *context);
acpi_status
@@ -312,7 +312,7 @@ acpi_status
acpi_remove_gpe_handler (
acpi_handle gpe_device,
u32 gpe_number,
- acpi_gpe_handler handler);
+ acpi_event_handler address);
acpi_status
acpi_enable_event (
@@ -334,6 +334,12 @@ acpi_get_event_status (
acpi_event_status *event_status);
acpi_status
+acpi_set_gpe_type (
+ acpi_handle gpe_device,
+ u32 gpe_number,
+ u8 type);
+
+acpi_status
acpi_enable_gpe (
acpi_handle gpe_device,
u32 gpe_number,
diff --git a/include/acpi/acstruct.h b/include/acpi/acstruct.h
index 56a3782cdbef..e9a2b32e6cc3 100644
--- a/include/acpi/acstruct.h
+++ b/include/acpi/acstruct.h
@@ -69,13 +69,14 @@
struct acpi_walk_state
{
u8 data_type; /* To differentiate various internal objs MUST BE FIRST!*/\
+ u8 walk_type;
acpi_owner_id owner_id; /* Owner of objects created during the walk */
u8 last_predicate; /* Result of last predicate */
+ u8 reserved; /* For alignment */
u8 current_result; /* */
u8 next_op_info; /* Info about next_op */
u8 num_operands; /* Stack pointer for Operands[] array */
u8 return_used;
- u8 walk_type;
u16 opcode; /* Current AML opcode */
u8 scope_depth;
u8 reserved1;
@@ -91,7 +92,8 @@ struct acpi_walk_state
struct acpi_namespace_node arguments[ACPI_METHOD_NUM_ARGS]; /* Control method arguments */
union acpi_operand_object **caller_return_desc;
union acpi_generic_state *control_state; /* List of control states (nested IFs) */
- struct acpi_namespace_node *deferred_node; /* Used when executing deferred opcodes */
+ struct acpi_namespace_node *deferred_node; /* Used when executing deferred opcodes */
+ struct acpi_gpe_event_info *gpe_event_info; /* Info for GPE (_Lxx/_Exx methods only */
struct acpi_namespace_node local_variables[ACPI_METHOD_NUM_LOCALS]; /* Control method locals */
struct acpi_namespace_node *method_call_node; /* Called method Node*/
union acpi_parse_object *method_call_op; /* method_call Op if running a method */
@@ -200,4 +202,21 @@ union acpi_aml_operands
};
+/* Internal method parameter list */
+
+struct acpi_parameter_info
+{
+ struct acpi_namespace_node *node;
+ union acpi_operand_object **parameters;
+ union acpi_operand_object *return_object;
+ u8 parameter_type;
+ u8 return_object_type;
+};
+
+/* Types for parameter_type above */
+
+#define ACPI_PARAM_ARGS 0
+#define ACPI_PARAM_GPE 1
+
+
#endif
diff --git a/include/acpi/actbl.h b/include/acpi/actbl.h
index 55680ad34b55..b380c23584fe 100644
--- a/include/acpi/actbl.h
+++ b/include/acpi/actbl.h
@@ -288,19 +288,6 @@ struct smart_battery_table
};
-/*
- * High performance timer
- */
-struct hpet_table
-{
- ACPI_TABLE_HEADER_DEF
- u32 hardware_id;
- u32 base_address [3];
- u8 hpet_number;
- u16 clock_tick;
- u8 attributes;
-};
-
#pragma pack()
@@ -344,4 +331,20 @@ struct acpi_table_support
#include "actbl2.h" /* Acpi 2.0 table definitions */
+#pragma pack(1)
+/*
+ * High performance timer
+ */
+struct hpet_table
+{
+ ACPI_TABLE_HEADER_DEF
+ u32 hardware_id;
+ struct acpi_generic_address base_address;
+ u8 hpet_number;
+ u16 clock_tick;
+ u8 attributes;
+};
+
+#pragma pack()
+
#endif /* __ACTBL_H__ */
diff --git a/include/acpi/actypes.h b/include/acpi/actypes.h
index e6120c879ae0..cde7e1454d98 100644
--- a/include/acpi/actypes.h
+++ b/include/acpi/actypes.h
@@ -557,34 +557,56 @@ typedef u32 acpi_event_status;
#define ACPI_GPE_MAX 0xFF
#define ACPI_NUM_GPE 256
+#define ACPI_GPE_ENABLE 0
+#define ACPI_GPE_DISABLE 1
+
+
/*
* GPE info flags - Per GPE
- * +---------+-+-+-+
- * |Bits 8:3 |2|1|0|
- * +---------+-+-+-+
- * | | | |
- * | | | +- Edge or Level Triggered
- * | | +--- Type: Wake or Runtime
- * | +----- Enabled for wake?
- * +--------<Reserved>
+ * +-+-+-+---+---+-+
+ * |7|6|5|4:3|2:1|0|
+ * +-+-+-+---+---+-+
+ * | | | | | |
+ * | | | | | +--- Interrupt type: Edge or Level Triggered
+ * | | | | +--- Type: Wake-only, Runtime-only, or wake/runtime
+ * | | | +--- Type of dispatch -- to method, handler, or none
+ * | | +--- Enabled for runtime?
+ * | +--- Enabled for wake?
+ * +--- System state when GPE ocurred (running/waking)
*/
-#define ACPI_GPE_XRUPT_TYPE_MASK (u8) 1
-#define ACPI_GPE_LEVEL_TRIGGERED (u8) 1
-#define ACPI_GPE_EDGE_TRIGGERED (u8) 0
+#define ACPI_GPE_XRUPT_TYPE_MASK (u8) 0x01
+#define ACPI_GPE_LEVEL_TRIGGERED (u8) 0x01
+#define ACPI_GPE_EDGE_TRIGGERED (u8) 0x00
+
+#define ACPI_GPE_TYPE_MASK (u8) 0x06
+#define ACPI_GPE_TYPE_WAKE_RUN (u8) 0x06
+#define ACPI_GPE_TYPE_WAKE (u8) 0x02
+#define ACPI_GPE_TYPE_RUNTIME (u8) 0x04 /* Default */
+
+#define ACPI_GPE_DISPATCH_MASK (u8) 0x18
+#define ACPI_GPE_DISPATCH_HANDLER (u8) 0x08
+#define ACPI_GPE_DISPATCH_METHOD (u8) 0x10
+#define ACPI_GPE_DISPATCH_NOT_USED (u8) 0x00 /* Default */
+
+#define ACPI_GPE_RUN_ENABLE_MASK (u8) 0x20
+#define ACPI_GPE_RUN_ENABLED (u8) 0x20
+#define ACPI_GPE_RUN_DISABLED (u8) 0x00 /* Default */
-#define ACPI_GPE_TYPE_MASK (u8) 2
-#define ACPI_GPE_TYPE_WAKE (u8) 2
-#define ACPI_GPE_TYPE_RUNTIME (u8) 0 /* Default */
+#define ACPI_GPE_WAKE_ENABLE_MASK (u8) 0x40
+#define ACPI_GPE_WAKE_ENABLED (u8) 0x40
+#define ACPI_GPE_WAKE_DISABLED (u8) 0x00 /* Default */
-#define ACPI_GPE_ENABLE_MASK (u8) 4
-#define ACPI_GPE_ENABLED (u8) 4
-#define ACPI_GPE_DISABLED (u8) 0 /* Default */
+#define ACPI_GPE_ENABLE_MASK (u8) 0x60 /* Both run/wake */
+
+#define ACPI_GPE_SYSTEM_MASK (u8) 0x80
+#define ACPI_GPE_SYSTEM_RUNNING (u8) 0x80
+#define ACPI_GPE_SYSTEM_WAKING (u8) 0x00
/*
* Flags for GPE and Lock interfaces
*/
-#define ACPI_EVENT_WAKE_ENABLE 0x2
-#define ACPI_EVENT_WAKE_DISABLE 0x2
+#define ACPI_EVENT_WAKE_ENABLE 0x2 /* acpi_gpe_enable */
+#define ACPI_EVENT_WAKE_DISABLE 0x2 /* acpi_gpe_disable */
#define ACPI_NOT_ISR 0x1
#define ACPI_ISR 0x0
@@ -790,10 +812,6 @@ u32 (*acpi_event_handler) (
void *context);
typedef
-void (*acpi_gpe_handler) (
- void *context);
-
-typedef
void (*acpi_notify_handler) (
acpi_handle device,
u32 value,
@@ -880,6 +898,7 @@ struct acpi_compatible_id_list
#define ACPI_VALID_HID 0x0004
#define ACPI_VALID_UID 0x0008
#define ACPI_VALID_CID 0x0010
+#define ACPI_VALID_SXDS 0x0020
#define ACPI_COMMON_OBJ_INFO \
@@ -899,12 +918,12 @@ struct acpi_device_info
{
ACPI_COMMON_OBJ_INFO;
- u8 highest_dstates[4]; /* _sx_d values 0xFF indicates not valid */
u32 valid; /* Indicates which fields below are valid */
u32 current_status; /* _STA value */
acpi_integer address; /* _ADR value if any */
struct acpi_device_id hardware_id; /* _HID value if any */
struct acpi_device_id unique_id; /* _UID value if any */
+ u8 highest_dstates[4]; /* _sx_d values: 0xFF indicates not valid */
struct acpi_compatible_id_list compatibility_id; /* List of _CIDs if any */
};