Commit da8bbd48 authored by Andy Grover's avatar Andy Grover

ACPI: Interpreter update

  - Add acpi_walk_resource support (Bjorn Helgaas)
  - Add S4BIOS support (Pavel Machek)
  - Rewrite GPE code to deal with future GPE block devices
  - Fix a bug that caused long delays when receiving SCIs
  - Fix a bug that causes oopses when battery strings are ""
parent db72219b
...@@ -110,7 +110,7 @@ acpi_ev_initialize ( ...@@ -110,7 +110,7 @@ acpi_ev_initialize (
* *
* RETURN: Status * RETURN: Status
* *
* DESCRIPTION: Install handlers for the SCI, Global Lock, and GPEs. * DESCRIPTION: Install interrupt handlers for the SCI and Global Lock
* *
******************************************************************************/ ******************************************************************************/
...@@ -134,16 +134,6 @@ acpi_ev_handler_initialize ( ...@@ -134,16 +134,6 @@ acpi_ev_handler_initialize (
return_ACPI_STATUS (status); return_ACPI_STATUS (status);
} }
/* Install handlers for control method GPE handlers (_Lxx, _Exx) */
status = acpi_ev_init_gpe_control_methods ();
if (ACPI_FAILURE (status)) {
ACPI_REPORT_ERROR ((
"Unable to initialize GPE control methods, %s\n",
acpi_format_exception (status)));
return_ACPI_STATUS (status);
}
/* Install the handler for the Global Lock */ /* Install the handler for the Global Lock */
status = acpi_ev_init_global_lock_handler (); status = acpi_ev_init_global_lock_handler ();
......
...@@ -51,401 +51,54 @@ ...@@ -51,401 +51,54 @@
/******************************************************************************* /*******************************************************************************
* *
* FUNCTION: acpi_ev_gpe_initialize * FUNCTION: acpi_ev_get_gpe_event_info
* *
* PARAMETERS: None * PARAMETERS: gpe_number - Raw GPE number
*
* RETURN: Status
*
* DESCRIPTION: Initialize the GPE data structures
*
******************************************************************************/
acpi_status
acpi_ev_gpe_initialize (void)
{
acpi_native_uint i;
acpi_native_uint j;
u32 gpe_block;
u32 gpe_register;
u32 gpe_number_index;
u32 gpe_number;
struct acpi_gpe_register_info *gpe_register_info;
acpi_status status;
ACPI_FUNCTION_TRACE ("ev_gpe_initialize");
/*
* Initialize the GPE Block globals
*
* Why the GPE register block lengths are divided by 2: From the ACPI Spec,
* section "General-Purpose Event Registers", we have:
*
* "Each register block contains two registers of equal length
* GPEx_STS and GPEx_EN (where x is 0 or 1). The length of the
* GPE0_STS and GPE0_EN registers is equal to half the GPE0_LEN
* The length of the GPE1_STS and GPE1_EN registers is equal to
* half the GPE1_LEN. If a generic register block is not supported
* then its respective block pointer and block length values in the
* FADT table contain zeros. The GPE0_LEN and GPE1_LEN do not need
* to be the same size."
*/
acpi_gbl_gpe_block_info[0].register_count = 0;
acpi_gbl_gpe_block_info[1].register_count = 0;
acpi_gbl_gpe_block_info[0].block_address = &acpi_gbl_FADT->xgpe0_blk;
acpi_gbl_gpe_block_info[1].block_address = &acpi_gbl_FADT->xgpe1_blk;
acpi_gbl_gpe_block_info[0].block_base_number = 0;
acpi_gbl_gpe_block_info[1].block_base_number = acpi_gbl_FADT->gpe1_base;
/*
* Determine the maximum GPE number for this machine.
*
* Note: both GPE0 and GPE1 are optional, and either can exist without
* the other.
* If EITHER the register length OR the block address are zero, then that
* particular block is not supported.
*/
if (acpi_gbl_FADT->xgpe0_blk.register_bit_width && acpi_gbl_FADT->xgpe0_blk.address) {
/* GPE block 0 exists (has both length and address > 0) */
acpi_gbl_gpe_block_info[0].register_count = (u16) (acpi_gbl_FADT->xgpe0_blk.register_bit_width / (ACPI_GPE_REGISTER_WIDTH * 2));
acpi_gbl_gpe_number_max = (acpi_gbl_gpe_block_info[0].register_count * ACPI_GPE_REGISTER_WIDTH) - 1;
}
if (acpi_gbl_FADT->xgpe1_blk.register_bit_width && acpi_gbl_FADT->xgpe1_blk.address) {
/* GPE block 1 exists (has both length and address > 0) */
acpi_gbl_gpe_block_info[1].register_count = (u16) (acpi_gbl_FADT->xgpe1_blk.register_bit_width / (ACPI_GPE_REGISTER_WIDTH * 2));
/* Check for GPE0/GPE1 overlap (if both banks exist) */
if ((acpi_gbl_gpe_block_info[0].register_count) &&
(acpi_gbl_gpe_number_max >= acpi_gbl_FADT->gpe1_base)) {
ACPI_REPORT_ERROR ((
"GPE0 block (GPE 0 to %d) overlaps the GPE1 block (GPE %d to %d) - Ignoring GPE1\n",
acpi_gbl_gpe_number_max, acpi_gbl_FADT->gpe1_base,
acpi_gbl_FADT->gpe1_base + ((acpi_gbl_gpe_block_info[1].register_count * ACPI_GPE_REGISTER_WIDTH) - 1)));
/* Ignore GPE1 block by setting the register count to zero */
acpi_gbl_gpe_block_info[1].register_count = 0;
}
else {
/*
* GPE0 and GPE1 do not have to be contiguous in the GPE number space,
* But, GPE0 always starts at zero.
*/
acpi_gbl_gpe_number_max = acpi_gbl_FADT->gpe1_base +
((acpi_gbl_gpe_block_info[1].register_count * ACPI_GPE_REGISTER_WIDTH) - 1);
}
}
/* Exit if there are no GPE registers */
acpi_gbl_gpe_register_count = acpi_gbl_gpe_block_info[0].register_count +
acpi_gbl_gpe_block_info[1].register_count;
if (!acpi_gbl_gpe_register_count) {
/* GPEs are not required by ACPI, this is OK */
ACPI_REPORT_INFO (("There are no GPE blocks defined in the FADT\n"));
return_ACPI_STATUS (AE_OK);
}
/* Check for Max GPE number out-of-range */
if (acpi_gbl_gpe_number_max > ACPI_GPE_MAX) {
ACPI_REPORT_ERROR (("Maximum GPE number from FADT is too large: 0x%X\n",
acpi_gbl_gpe_number_max));
return_ACPI_STATUS (AE_BAD_VALUE);
}
/* Allocate the GPE number-to-index translation table */
acpi_gbl_gpe_number_to_index = ACPI_MEM_CALLOCATE (
sizeof (struct acpi_gpe_index_info) *
((acpi_size) acpi_gbl_gpe_number_max + 1));
if (!acpi_gbl_gpe_number_to_index) {
ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
"Could not allocate the gpe_number_to_index table\n"));
return_ACPI_STATUS (AE_NO_MEMORY);
}
/* Set the Gpe index table to GPE_INVALID */
ACPI_MEMSET (acpi_gbl_gpe_number_to_index, (int) ACPI_GPE_INVALID,
sizeof (struct acpi_gpe_index_info) * ((acpi_size) acpi_gbl_gpe_number_max + 1));
/* Allocate the GPE register information block */
acpi_gbl_gpe_register_info = ACPI_MEM_CALLOCATE (
(acpi_size) acpi_gbl_gpe_register_count *
sizeof (struct acpi_gpe_register_info));
if (!acpi_gbl_gpe_register_info) {
ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
"Could not allocate the gpe_register_info table\n"));
goto error_exit1;
}
/*
* Allocate the GPE dispatch handler block. There are eight distinct GPEs
* per register. Initialization to zeros is sufficient.
*/
acpi_gbl_gpe_number_info = ACPI_MEM_CALLOCATE (
((acpi_size) acpi_gbl_gpe_register_count * ACPI_GPE_REGISTER_WIDTH) *
sizeof (struct acpi_gpe_number_info));
if (!acpi_gbl_gpe_number_info) {
ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Could not allocate the gpe_number_info table\n"));
goto error_exit2;
}
/*
* Initialize the GPE information and validation tables. A goal of these
* tables is to hide the fact that there are two separate GPE register sets
* in a given gpe hardware block, the status registers occupy the first half,
* and the enable registers occupy the second half. Another goal is to hide
* the fact that there may be multiple GPE hardware blocks.
*/
gpe_register = 0;
gpe_number_index = 0;
for (gpe_block = 0; gpe_block < ACPI_MAX_GPE_BLOCKS; gpe_block++) {
for (i = 0; i < acpi_gbl_gpe_block_info[gpe_block].register_count; i++) {
gpe_register_info = &acpi_gbl_gpe_register_info[gpe_register];
/* Init the Register info for this entire GPE register (8 GPEs) */
gpe_register_info->base_gpe_number = (u8) (acpi_gbl_gpe_block_info[gpe_block].block_base_number
+ (i * ACPI_GPE_REGISTER_WIDTH));
ACPI_STORE_ADDRESS (gpe_register_info->status_address.address,
(acpi_gbl_gpe_block_info[gpe_block].block_address->address
+ i));
ACPI_STORE_ADDRESS (gpe_register_info->enable_address.address,
(acpi_gbl_gpe_block_info[gpe_block].block_address->address
+ i
+ acpi_gbl_gpe_block_info[gpe_block].register_count));
gpe_register_info->status_address.address_space_id = acpi_gbl_gpe_block_info[gpe_block].block_address->address_space_id;
gpe_register_info->enable_address.address_space_id = acpi_gbl_gpe_block_info[gpe_block].block_address->address_space_id;
gpe_register_info->status_address.register_bit_width = ACPI_GPE_REGISTER_WIDTH;
gpe_register_info->enable_address.register_bit_width = ACPI_GPE_REGISTER_WIDTH;
gpe_register_info->status_address.register_bit_offset = ACPI_GPE_REGISTER_WIDTH;
gpe_register_info->enable_address.register_bit_offset = ACPI_GPE_REGISTER_WIDTH;
/* Init the Index mapping info for each GPE number within this register */
for (j = 0; j < ACPI_GPE_REGISTER_WIDTH; j++) {
gpe_number = gpe_register_info->base_gpe_number + (u32) j;
acpi_gbl_gpe_number_to_index[gpe_number].number_index = (u8) gpe_number_index;
acpi_gbl_gpe_number_info[gpe_number_index].bit_mask = acpi_gbl_decode_to8bit[j];
gpe_number_index++;
}
/*
* Clear the status/enable registers. Note that status registers
* are cleared by writing a '1', while enable registers are cleared
* by writing a '0'.
*/
status = acpi_hw_low_level_write (ACPI_GPE_REGISTER_WIDTH, 0x00, &gpe_register_info->enable_address, 0);
if (ACPI_FAILURE (status)) {
return_ACPI_STATUS (status);
}
status = acpi_hw_low_level_write (ACPI_GPE_REGISTER_WIDTH, 0xFF, &gpe_register_info->status_address, 0);
if (ACPI_FAILURE (status)) {
return_ACPI_STATUS (status);
}
gpe_register++;
}
if (i) {
/* Dump info about this valid GPE block */
ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "GPE Block%d: %X registers at %8.8X%8.8X\n",
(s32) gpe_block, acpi_gbl_gpe_block_info[0].register_count,
ACPI_HIDWORD (acpi_gbl_gpe_block_info[gpe_block].block_address->address),
ACPI_LODWORD (acpi_gbl_gpe_block_info[gpe_block].block_address->address)));
ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "GPE Block%d defined as GPE%d to GPE%d\n",
(s32) gpe_block,
(u32) acpi_gbl_gpe_block_info[gpe_block].block_base_number,
(u32) (acpi_gbl_gpe_block_info[gpe_block].block_base_number +
((acpi_gbl_gpe_block_info[gpe_block].register_count * ACPI_GPE_REGISTER_WIDTH) -1))));
}
}
return_ACPI_STATUS (AE_OK);
/* Error cleanup */
error_exit2:
ACPI_MEM_FREE (acpi_gbl_gpe_register_info);
error_exit1:
ACPI_MEM_FREE (acpi_gbl_gpe_number_to_index);
return_ACPI_STATUS (AE_NO_MEMORY);
}
/*******************************************************************************
*
* FUNCTION: acpi_ev_save_method_info
* *
* PARAMETERS: None * RETURN: None.
*
* RETURN: None
* *
* DESCRIPTION: Called from acpi_walk_namespace. Expects each object to be a * DESCRIPTION: Returns the event_info struct
* control method under the _GPE portion of the namespace. * associated with this GPE.
* Extract the name and GPE type from the object, saving this
* information for quick lookup during GPE dispatch
* *
* The name of each GPE control method is of the form: * TBD: this function will go away when full support of GPE block devices
* "_Lnn" or "_Enn" * is implemented!
* Where:
* L - means that the GPE is level triggered
* E - means that the GPE is edge triggered
* nn - is the GPE number [in HEX]
* *
******************************************************************************/ ******************************************************************************/
static acpi_status struct acpi_gpe_event_info *
acpi_ev_save_method_info ( acpi_ev_get_gpe_event_info (
acpi_handle obj_handle, u32 gpe_number)
u32 level,
void *obj_desc,
void **return_value)
{ {
u32 gpe_number; struct acpi_gpe_block_info *gpe_block;
struct acpi_gpe_number_info *gpe_number_info;
char name[ACPI_NAME_SIZE + 1];
u8 type;
acpi_status status;
ACPI_FUNCTION_NAME ("ev_save_method_info");
/* Extract the name from the object and convert to a string */
ACPI_MOVE_UNALIGNED32_TO_32 (name, /* Examine GPE Block 0 */
&((struct acpi_namespace_node *) obj_handle)->name.integer);
name[ACPI_NAME_SIZE] = 0;
/* gpe_block = acpi_gbl_gpe_block_list_head;
* Edge/Level determination is based on the 2nd character of the method name if (!gpe_block) {
*/ return (NULL);
switch (name[1]) {
case 'L':
type = ACPI_EVENT_LEVEL_TRIGGERED;
break;
case 'E':
type = ACPI_EVENT_EDGE_TRIGGERED;
break;
default:
/* Unknown method type, just ignore it! */
ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
"Unknown GPE method type: %s (name not of form _Lnn or _Enn)\n",
name));
return (AE_OK);
} }
/* Convert the last two characters of the name to the GPE Number */ if ((gpe_number >= gpe_block->block_base_number) &&
(gpe_number < gpe_block->block_base_number + (gpe_block->register_count * 8))) {
gpe_number = ACPI_STRTOUL (&name[2], NULL, 16); return (&gpe_block->event_info[gpe_number - gpe_block->block_base_number]);
if (gpe_number == ACPI_UINT32_MAX) {
/* Conversion failed; invalid method, just ignore it */
ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
"Could not extract GPE number from name: %s (name not of form _Lnn or _Enn)\n",
name));
return (AE_OK);
} }
/* Get GPE index and ensure that we have a valid GPE number */ /* Examine GPE Block 1 */
gpe_number_info = acpi_ev_get_gpe_number_info (gpe_number);
if (!gpe_number_info) {
/* Not valid, all we can do here is ignore it */
ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, gpe_block = gpe_block->next;
"GPE number associated with method is not valid %s\n", if (!gpe_block) {
name)); return (NULL);
return (AE_OK);
} }
/* if ((gpe_number >= gpe_block->block_base_number) &&
* Now we can add this information to the gpe_number_info block (gpe_number < gpe_block->block_base_number + (gpe_block->register_count * 8))) {
* for use during dispatch of this GPE. return (&gpe_block->event_info[gpe_number - gpe_block->block_base_number]);
*/
gpe_number_info->type = type;
gpe_number_info->method_node = (struct acpi_namespace_node *) obj_handle;
/*
* Enable the GPE (SCIs should be disabled at this point)
*/
status = acpi_hw_enable_gpe (gpe_number);
if (ACPI_FAILURE (status)) {
return (status);
} }
ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "Registered GPE method %s as GPE number %2.2X\n", return (NULL);
name, gpe_number));
return (AE_OK);
} }
/*******************************************************************************
*
* FUNCTION: acpi_ev_init_gpe_control_methods
*
* PARAMETERS: None
*
* RETURN: Status
*
* DESCRIPTION: Obtain the control methods associated with the GPEs.
* NOTE: Must be called AFTER namespace initialization!
*
******************************************************************************/
acpi_status
acpi_ev_init_gpe_control_methods (void)
{
acpi_status status;
ACPI_FUNCTION_TRACE ("ev_init_gpe_control_methods");
/* Get a permanent handle to the _GPE object */
status = acpi_get_handle (NULL, "\\_GPE", &acpi_gbl_gpe_obj_handle);
if (ACPI_FAILURE (status)) {
return_ACPI_STATUS (status);
}
/* Traverse the namespace under \_GPE to find all methods there */
status = acpi_walk_namespace (ACPI_TYPE_METHOD, acpi_gbl_gpe_obj_handle,
ACPI_UINT32_MAX, acpi_ev_save_method_info,
NULL, NULL);
return_ACPI_STATUS (status);
}
/******************************************************************************* /*******************************************************************************
* *
* FUNCTION: acpi_ev_gpe_detect * FUNCTION: acpi_ev_gpe_detect
...@@ -470,26 +123,35 @@ acpi_ev_gpe_detect (void) ...@@ -470,26 +123,35 @@ acpi_ev_gpe_detect (void)
struct acpi_gpe_register_info *gpe_register_info; struct acpi_gpe_register_info *gpe_register_info;
u32 in_value; u32 in_value;
acpi_status status; acpi_status status;
struct acpi_gpe_block_info *gpe_block;
ACPI_FUNCTION_NAME ("ev_gpe_detect"); ACPI_FUNCTION_NAME ("ev_gpe_detect");
/* Examine all GPE blocks attached to this interrupt level */
gpe_block = acpi_gbl_gpe_block_list_head;
while (gpe_block) {
/* /*
* Read all of the 8-bit GPE status and enable registers * Read all of the 8-bit GPE status and enable registers
* in both of the register blocks, saving all of it. * in this GPE block, saving all of them.
* Find all currently active GP events. * Find all currently active GP events.
*/ */
for (i = 0; i < acpi_gbl_gpe_register_count; i++) { for (i = 0; i < gpe_block->register_count; i++) {
gpe_register_info = &acpi_gbl_gpe_register_info[i]; /* Get the next status/enable pair */
gpe_register_info = &gpe_block->register_info[i];
status = acpi_hw_low_level_read (ACPI_GPE_REGISTER_WIDTH, &in_value, &gpe_register_info->status_address, 0); status = acpi_hw_low_level_read (ACPI_GPE_REGISTER_WIDTH, &in_value,
&gpe_register_info->status_address, 0);
gpe_register_info->status = (u8) in_value; gpe_register_info->status = (u8) in_value;
if (ACPI_FAILURE (status)) { if (ACPI_FAILURE (status)) {
return (ACPI_INTERRUPT_NOT_HANDLED); return (ACPI_INTERRUPT_NOT_HANDLED);
} }
status = acpi_hw_low_level_read (ACPI_GPE_REGISTER_WIDTH, &in_value, &gpe_register_info->enable_address, 0); status = acpi_hw_low_level_read (ACPI_GPE_REGISTER_WIDTH, &in_value,
&gpe_register_info->enable_address, 0);
gpe_register_info->enable = (u8) in_value; gpe_register_info->enable = (u8) in_value;
if (ACPI_FAILURE (status)) { if (ACPI_FAILURE (status)) {
return (ACPI_INTERRUPT_NOT_HANDLED); return (ACPI_INTERRUPT_NOT_HANDLED);
...@@ -523,11 +185,14 @@ acpi_ev_gpe_detect (void) ...@@ -523,11 +185,14 @@ acpi_ev_gpe_detect (void)
* or method. * or method.
*/ */
int_status |= acpi_ev_gpe_dispatch ( int_status |= acpi_ev_gpe_dispatch (
gpe_register_info->base_gpe_number + j); &gpe_block->event_info[(i * ACPI_GPE_REGISTER_WIDTH) +j]);
} }
} }
} }
gpe_block = gpe_block->next;
}
return (int_status); return (int_status);
} }
...@@ -536,7 +201,7 @@ acpi_ev_gpe_detect (void) ...@@ -536,7 +201,7 @@ acpi_ev_gpe_detect (void)
* *
* FUNCTION: acpi_ev_asynch_execute_gpe_method * FUNCTION: acpi_ev_asynch_execute_gpe_method
* *
* PARAMETERS: gpe_number - The 0-based GPE number * PARAMETERS: gpe_event_info - Info for this GPE
* *
* RETURN: None * RETURN: None
* *
...@@ -552,20 +217,14 @@ static void ACPI_SYSTEM_XFACE ...@@ -552,20 +217,14 @@ static void ACPI_SYSTEM_XFACE
acpi_ev_asynch_execute_gpe_method ( acpi_ev_asynch_execute_gpe_method (
void *context) void *context)
{ {
u32 gpe_number = (u32) ACPI_TO_INTEGER (context); struct acpi_gpe_event_info *gpe_event_info = (void *) context;
u32 gpe_number_index; u32 gpe_number = 0;
struct acpi_gpe_number_info gpe_number_info;
acpi_status status; acpi_status status;
ACPI_FUNCTION_TRACE ("ev_asynch_execute_gpe_method"); ACPI_FUNCTION_TRACE ("ev_asynch_execute_gpe_method");
gpe_number_index = acpi_ev_get_gpe_number_index (gpe_number);
if (gpe_number_index == ACPI_GPE_INVALID) {
return_VOID;
}
/* /*
* Take a snapshot of the GPE info for this level - we copy the * Take a snapshot of the GPE info for this level - we copy the
* info to prevent a race condition with remove_handler. * info to prevent a race condition with remove_handler.
...@@ -575,40 +234,38 @@ acpi_ev_asynch_execute_gpe_method ( ...@@ -575,40 +234,38 @@ acpi_ev_asynch_execute_gpe_method (
return_VOID; return_VOID;
} }
gpe_number_info = acpi_gbl_gpe_number_info [gpe_number_index];
status = acpi_ut_release_mutex (ACPI_MTX_EVENTS); status = acpi_ut_release_mutex (ACPI_MTX_EVENTS);
if (ACPI_FAILURE (status)) { if (ACPI_FAILURE (status)) {
return_VOID; return_VOID;
} }
if (gpe_number_info.method_node) { if (gpe_event_info->method_node) {
/* /*
* Invoke the GPE Method (_Lxx, _Exx): * Invoke the GPE Method (_Lxx, _Exx):
* (Evaluate the _Lxx/_Exx control method that corresponds to this GPE.) * (Evaluate the _Lxx/_Exx control method that corresponds to this GPE.)
*/ */
status = acpi_ns_evaluate_by_handle (gpe_number_info.method_node, NULL, NULL); status = acpi_ns_evaluate_by_handle (gpe_event_info->method_node, NULL, NULL);
if (ACPI_FAILURE (status)) { if (ACPI_FAILURE (status)) {
ACPI_REPORT_ERROR (("%s while evaluating method [%4.4s] for GPE[%2.2X]\n", ACPI_REPORT_ERROR (("%s while evaluating method [%4.4s] for GPE[%2.2X]\n",
acpi_format_exception (status), acpi_format_exception (status),
gpe_number_info.method_node->name.ascii, gpe_number)); gpe_event_info->method_node->name.ascii, gpe_number));
} }
} }
if (gpe_number_info.type & ACPI_EVENT_LEVEL_TRIGGERED) { if (gpe_event_info->type & ACPI_EVENT_LEVEL_TRIGGERED) {
/* /*
* GPE is level-triggered, we clear the GPE status bit after handling * GPE is level-triggered, we clear the GPE status bit after handling
* the event. * the event.
*/ */
status = acpi_hw_clear_gpe (gpe_number); status = acpi_hw_clear_gpe (gpe_event_info);
if (ACPI_FAILURE (status)) { if (ACPI_FAILURE (status)) {
return_VOID; return_VOID;
} }
} }
/* /* Enable this GPE */
* Enable the GPE.
*/ (void) acpi_hw_enable_gpe (gpe_event_info);
(void) acpi_hw_enable_gpe (gpe_number);
return_VOID; return_VOID;
} }
...@@ -617,7 +274,7 @@ acpi_ev_asynch_execute_gpe_method ( ...@@ -617,7 +274,7 @@ acpi_ev_asynch_execute_gpe_method (
* *
* FUNCTION: acpi_ev_gpe_dispatch * FUNCTION: acpi_ev_gpe_dispatch
* *
* PARAMETERS: gpe_number - The 0-based GPE number * PARAMETERS: gpe_event_info - info for this GPE
* *
* RETURN: INTERRUPT_HANDLED or INTERRUPT_NOT_HANDLED * RETURN: INTERRUPT_HANDLED or INTERRUPT_NOT_HANDLED
* *
...@@ -629,33 +286,24 @@ acpi_ev_asynch_execute_gpe_method ( ...@@ -629,33 +286,24 @@ acpi_ev_asynch_execute_gpe_method (
u32 u32
acpi_ev_gpe_dispatch ( acpi_ev_gpe_dispatch (
u32 gpe_number) struct acpi_gpe_event_info *gpe_event_info)
{ {
struct acpi_gpe_number_info *gpe_number_info; u32 gpe_number = 0; /* TBD: remove */
acpi_status status; acpi_status status;
ACPI_FUNCTION_TRACE ("ev_gpe_dispatch"); ACPI_FUNCTION_TRACE ("ev_gpe_dispatch");
/*
* We don't have to worry about mutex on gpe_number_info because we are
* executing at interrupt level.
*/
gpe_number_info = acpi_ev_get_gpe_number_info (gpe_number);
if (!gpe_number_info) {
ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "GPE[%X] is not a valid event\n", gpe_number));
return_VALUE (ACPI_INTERRUPT_NOT_HANDLED);
}
/* /*
* If edge-triggered, clear the GPE status bit now. Note that * If edge-triggered, clear the GPE status bit now. Note that
* level-triggered events are cleared after the GPE is serviced. * level-triggered events are cleared after the GPE is serviced.
*/ */
if (gpe_number_info->type & ACPI_EVENT_EDGE_TRIGGERED) { if (gpe_event_info->type & ACPI_EVENT_EDGE_TRIGGERED) {
status = acpi_hw_clear_gpe (gpe_number); status = acpi_hw_clear_gpe (gpe_event_info);
if (ACPI_FAILURE (status)) { if (ACPI_FAILURE (status)) {
ACPI_REPORT_ERROR (("acpi_ev_gpe_dispatch: Unable to clear GPE[%2.2X]\n", gpe_number)); ACPI_REPORT_ERROR (("acpi_ev_gpe_dispatch: Unable to clear GPE[%2.2X]\n",
gpe_number));
return_VALUE (ACPI_INTERRUPT_NOT_HANDLED); return_VALUE (ACPI_INTERRUPT_NOT_HANDLED);
} }
} }
...@@ -667,19 +315,20 @@ acpi_ev_gpe_dispatch ( ...@@ -667,19 +315,20 @@ acpi_ev_gpe_dispatch (
* If there is neither a handler nor a method, we disable the level to * If there is neither a handler nor a method, we disable the level to
* prevent further events from coming in here. * prevent further events from coming in here.
*/ */
if (gpe_number_info->handler) { if (gpe_event_info->handler) {
/* Invoke the installed handler (at interrupt level) */ /* Invoke the installed handler (at interrupt level) */
gpe_number_info->handler (gpe_number_info->context); gpe_event_info->handler (gpe_event_info->context);
} }
else if (gpe_number_info->method_node) { else if (gpe_event_info->method_node) {
/* /*
* Disable GPE, so it doesn't keep firing before the method has a * Disable GPE, so it doesn't keep firing before the method has a
* chance to run. * chance to run.
*/ */
status = acpi_hw_disable_gpe (gpe_number); status = acpi_hw_disable_gpe (gpe_event_info);
if (ACPI_FAILURE (status)) { if (ACPI_FAILURE (status)) {
ACPI_REPORT_ERROR (("acpi_ev_gpe_dispatch: Unable to disable GPE[%2.2X]\n", gpe_number)); ACPI_REPORT_ERROR (("acpi_ev_gpe_dispatch: Unable to disable GPE[%2.2X]\n",
gpe_number));
return_VALUE (ACPI_INTERRUPT_NOT_HANDLED); return_VALUE (ACPI_INTERRUPT_NOT_HANDLED);
} }
...@@ -688,22 +337,27 @@ acpi_ev_gpe_dispatch ( ...@@ -688,22 +337,27 @@ acpi_ev_gpe_dispatch (
*/ */
if (ACPI_FAILURE (acpi_os_queue_for_execution (OSD_PRIORITY_GPE, if (ACPI_FAILURE (acpi_os_queue_for_execution (OSD_PRIORITY_GPE,
acpi_ev_asynch_execute_gpe_method, acpi_ev_asynch_execute_gpe_method,
ACPI_TO_POINTER (gpe_number)))) { gpe_event_info))) {
ACPI_REPORT_ERROR (("acpi_ev_gpe_dispatch: Unable to queue handler for GPE[%2.2X], event is disabled\n", gpe_number)); ACPI_REPORT_ERROR ((
"acpi_ev_gpe_dispatch: Unable to queue handler for GPE[%2.2X], event is disabled\n",
gpe_number));
} }
} }
else { else {
/* No handler or method to run! */ /* No handler or method to run! */
ACPI_REPORT_ERROR (("acpi_ev_gpe_dispatch: No handler or method for GPE[%2.2X], disabling event\n", gpe_number)); ACPI_REPORT_ERROR ((
"acpi_ev_gpe_dispatch: No handler or method for GPE[%2.2X], disabling event\n",
gpe_number));
/* /*
* Disable the GPE. The GPE will remain disabled until the ACPI * Disable the GPE. The GPE will remain disabled until the ACPI
* Core Subsystem is restarted, or the handler is reinstalled. * Core Subsystem is restarted, or the handler is reinstalled.
*/ */
status = acpi_hw_disable_gpe (gpe_number); status = acpi_hw_disable_gpe (gpe_event_info);
if (ACPI_FAILURE (status)) { if (ACPI_FAILURE (status)) {
ACPI_REPORT_ERROR (("acpi_ev_gpe_dispatch: Unable to disable GPE[%2.2X]\n", gpe_number)); ACPI_REPORT_ERROR (("acpi_ev_gpe_dispatch: Unable to disable GPE[%2.2X]\n",
gpe_number));
return_VALUE (ACPI_INTERRUPT_NOT_HANDLED); return_VALUE (ACPI_INTERRUPT_NOT_HANDLED);
} }
} }
...@@ -711,10 +365,11 @@ acpi_ev_gpe_dispatch ( ...@@ -711,10 +365,11 @@ acpi_ev_gpe_dispatch (
/* /*
* It is now safe to clear level-triggered evnets. * It is now safe to clear level-triggered evnets.
*/ */
if (gpe_number_info->type & ACPI_EVENT_LEVEL_TRIGGERED) { if (gpe_event_info->type & ACPI_EVENT_LEVEL_TRIGGERED) {
status = acpi_hw_clear_gpe (gpe_number); status = acpi_hw_clear_gpe (gpe_event_info);
if (ACPI_FAILURE (status)) { if (ACPI_FAILURE (status)) {
ACPI_REPORT_ERROR (("acpi_ev_gpe_dispatch: Unable to clear GPE[%2.2X]\n", gpe_number)); ACPI_REPORT_ERROR (("acpi_ev_gpe_dispatch: Unable to clear GPE[%2.2X]\n",
gpe_number));
return_VALUE (ACPI_INTERRUPT_NOT_HANDLED); return_VALUE (ACPI_INTERRUPT_NOT_HANDLED);
} }
} }
......
...@@ -84,84 +84,6 @@ acpi_ev_is_notify_object ( ...@@ -84,84 +84,6 @@ acpi_ev_is_notify_object (
} }
/*******************************************************************************
*
* FUNCTION: acpi_ev_get_gpe_register_info
*
* PARAMETERS: gpe_number - Raw GPE number
*
* RETURN: Pointer to the info struct for this GPE register.
*
* DESCRIPTION: Returns the register index (index into the GPE register info
* table) associated with this GPE.
*
******************************************************************************/
struct acpi_gpe_register_info *
acpi_ev_get_gpe_register_info (
u32 gpe_number)
{
if (gpe_number > acpi_gbl_gpe_number_max) {
return (NULL);
}
return (&acpi_gbl_gpe_register_info [ACPI_DIV_8 (acpi_gbl_gpe_number_to_index[gpe_number].number_index)]);
}
/*******************************************************************************
*
* FUNCTION: acpi_ev_get_gpe_number_info
*
* PARAMETERS: gpe_number - Raw GPE number
*
* RETURN: None.
*
* DESCRIPTION: Returns the number index (index into the GPE number info table)
* associated with this GPE.
*
******************************************************************************/
struct acpi_gpe_number_info *
acpi_ev_get_gpe_number_info (
u32 gpe_number)
{
if (gpe_number > acpi_gbl_gpe_number_max) {
return (NULL);
}
return (&acpi_gbl_gpe_number_info [acpi_gbl_gpe_number_to_index[gpe_number].number_index]);
}
/*******************************************************************************
*
* FUNCTION: acpi_ev_get_gpe_number_index
*
* PARAMETERS: gpe_number - Raw GPE number
*
* RETURN: None.
*
* DESCRIPTION: Returns the number index (index into the GPE number info table)
* associated with this GPE.
*
******************************************************************************/
u32
acpi_ev_get_gpe_number_index (
u32 gpe_number)
{
if (gpe_number > acpi_gbl_gpe_number_max) {
return (ACPI_GPE_INVALID);
}
return (acpi_gbl_gpe_number_to_index[gpe_number].number_index);
}
/******************************************************************************* /*******************************************************************************
* *
* FUNCTION: acpi_ev_queue_notify_request * FUNCTION: acpi_ev_queue_notify_request
...@@ -601,6 +523,9 @@ acpi_ev_terminate (void) ...@@ -601,6 +523,9 @@ acpi_ev_terminate (void)
{ {
acpi_native_uint i; acpi_native_uint i;
acpi_status status; acpi_status status;
struct acpi_gpe_block_info *gpe_block;
struct acpi_gpe_block_info *next_gpe_block;
struct acpi_gpe_event_info *gpe_event_info;
ACPI_FUNCTION_TRACE ("ev_terminate"); ACPI_FUNCTION_TRACE ("ev_terminate");
...@@ -625,13 +550,19 @@ acpi_ev_terminate (void) ...@@ -625,13 +550,19 @@ acpi_ev_terminate (void)
/* /*
* Disable all GPEs * Disable all GPEs
*/ */
for (i = 0; i < acpi_gbl_gpe_number_max; i++) { gpe_block = acpi_gbl_gpe_block_list_head;
if (acpi_ev_get_gpe_number_index ((u32)i) != ACPI_GPE_INVALID) { while (gpe_block) {
status = acpi_hw_disable_gpe((u32) i); gpe_event_info = gpe_block->event_info;
for (i = 0; i < (gpe_block->register_count * 8); i++) {
status = acpi_hw_disable_gpe (gpe_event_info);
if (ACPI_FAILURE (status)) { if (ACPI_FAILURE (status)) {
ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Could not disable GPE %d\n", (u32) i)); ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Could not disable GPE %d\n", (u32) i));
} }
gpe_event_info++;
} }
gpe_block = gpe_block->next;
} }
/* /*
...@@ -654,21 +585,16 @@ acpi_ev_terminate (void) ...@@ -654,21 +585,16 @@ acpi_ev_terminate (void)
} }
/* /*
* Free global tables, etc. * Free global GPE blocks and related info structures
*/ */
if (acpi_gbl_gpe_register_info) { gpe_block = acpi_gbl_gpe_block_list_head;
ACPI_MEM_FREE (acpi_gbl_gpe_register_info); while (gpe_block) {
acpi_gbl_gpe_register_info = NULL; next_gpe_block = gpe_block->next;
} ACPI_MEM_FREE (gpe_block->event_info);
ACPI_MEM_FREE (gpe_block->register_info);
if (acpi_gbl_gpe_number_info) { ACPI_MEM_FREE (gpe_block);
ACPI_MEM_FREE (acpi_gbl_gpe_number_info);
acpi_gbl_gpe_number_info = NULL; gpe_block = next_gpe_block;
}
if (acpi_gbl_gpe_number_to_index) {
ACPI_MEM_FREE (acpi_gbl_gpe_number_to_index);
acpi_gbl_gpe_number_to_index = NULL;
} }
return_VOID; return_VOID;
......
...@@ -69,38 +69,24 @@ acpi_ev_sci_handler ( ...@@ -69,38 +69,24 @@ acpi_ev_sci_handler (
void *context) void *context)
{ {
u32 interrupt_handled = ACPI_INTERRUPT_NOT_HANDLED; u32 interrupt_handled = ACPI_INTERRUPT_NOT_HANDLED;
u32 value;
acpi_status status;
ACPI_FUNCTION_TRACE("ev_sci_handler"); ACPI_FUNCTION_TRACE("ev_sci_handler");
/* /*
* Make sure that ACPI is enabled by checking SCI_EN. Note that we are * We are guaranteed by the ACPI CA initialization/shutdown code that
* required to treat the SCI interrupt as sharable, level, active low. * if this interrupt handler is installed, ACPI is enabled.
*/ */
status = acpi_get_register (ACPI_BITREG_SCI_ENABLE, &value, ACPI_MTX_DO_NOT_LOCK);
if (ACPI_FAILURE (status)) {
return (ACPI_INTERRUPT_NOT_HANDLED);
}
if (!value) {
/* ACPI is not enabled; this interrupt cannot be for us */
return_VALUE (ACPI_INTERRUPT_NOT_HANDLED);
}
/* /*
* Fixed acpi_events: * Fixed acpi_events:
* -------------
* Check for and dispatch any Fixed acpi_events that have occurred * Check for and dispatch any Fixed acpi_events that have occurred
*/ */
interrupt_handled |= acpi_ev_fixed_event_detect (); interrupt_handled |= acpi_ev_fixed_event_detect ();
/* /*
* GPEs: * GPEs:
* -----
* Check for and dispatch any GPEs that have occurred * Check for and dispatch any GPEs that have occurred
*/ */
interrupt_handled |= acpi_ev_gpe_detect (); interrupt_handled |= acpi_ev_gpe_detect ();
......
...@@ -492,7 +492,7 @@ acpi_install_gpe_handler ( ...@@ -492,7 +492,7 @@ acpi_install_gpe_handler (
void *context) void *context)
{ {
acpi_status status; acpi_status status;
struct acpi_gpe_number_info *gpe_number_info; struct acpi_gpe_event_info *gpe_event_info;
ACPI_FUNCTION_TRACE ("acpi_install_gpe_handler"); ACPI_FUNCTION_TRACE ("acpi_install_gpe_handler");
...@@ -506,8 +506,8 @@ acpi_install_gpe_handler ( ...@@ -506,8 +506,8 @@ acpi_install_gpe_handler (
/* Ensure that we have a valid GPE number */ /* Ensure that we have a valid GPE number */
gpe_number_info = acpi_ev_get_gpe_number_info (gpe_number); gpe_event_info = acpi_ev_get_gpe_event_info (gpe_number);
if (!gpe_number_info) { if (!gpe_event_info) {
return_ACPI_STATUS (AE_BAD_PARAMETER); return_ACPI_STATUS (AE_BAD_PARAMETER);
} }
...@@ -518,25 +518,25 @@ acpi_install_gpe_handler ( ...@@ -518,25 +518,25 @@ acpi_install_gpe_handler (
/* Make sure that there isn't a handler there already */ /* Make sure that there isn't a handler there already */
if (gpe_number_info->handler) { if (gpe_event_info->handler) {
status = AE_ALREADY_EXISTS; status = AE_ALREADY_EXISTS;
goto cleanup; goto cleanup;
} }
/* Install the handler */ /* Install the handler */
gpe_number_info->handler = handler; gpe_event_info->handler = handler;
gpe_number_info->context = context; gpe_event_info->context = context;
gpe_number_info->type = (u8) type; gpe_event_info->type = (u8) type;
/* Clear the GPE (of stale events), the enable it */ /* Clear the GPE (of stale events), the enable it */
status = acpi_hw_clear_gpe (gpe_number); status = acpi_hw_clear_gpe (gpe_event_info);
if (ACPI_FAILURE (status)) { if (ACPI_FAILURE (status)) {
goto cleanup; goto cleanup;
} }
status = acpi_hw_enable_gpe (gpe_number); status = acpi_hw_enable_gpe (gpe_event_info);
cleanup: cleanup:
...@@ -564,7 +564,7 @@ acpi_remove_gpe_handler ( ...@@ -564,7 +564,7 @@ acpi_remove_gpe_handler (
acpi_gpe_handler handler) acpi_gpe_handler handler)
{ {
acpi_status status; acpi_status status;
struct acpi_gpe_number_info *gpe_number_info; struct acpi_gpe_event_info *gpe_event_info;
ACPI_FUNCTION_TRACE ("acpi_remove_gpe_handler"); ACPI_FUNCTION_TRACE ("acpi_remove_gpe_handler");
...@@ -578,14 +578,14 @@ acpi_remove_gpe_handler ( ...@@ -578,14 +578,14 @@ acpi_remove_gpe_handler (
/* Ensure that we have a valid GPE number */ /* Ensure that we have a valid GPE number */
gpe_number_info = acpi_ev_get_gpe_number_info (gpe_number); gpe_event_info = acpi_ev_get_gpe_event_info (gpe_number);
if (!gpe_number_info) { if (!gpe_event_info) {
return_ACPI_STATUS (AE_BAD_PARAMETER); return_ACPI_STATUS (AE_BAD_PARAMETER);
} }
/* Disable the GPE before removing the handler */ /* Disable the GPE before removing the handler */
status = acpi_hw_disable_gpe (gpe_number); status = acpi_hw_disable_gpe (gpe_event_info);
if (ACPI_FAILURE (status)) { if (ACPI_FAILURE (status)) {
return_ACPI_STATUS (status); return_ACPI_STATUS (status);
} }
...@@ -597,16 +597,16 @@ acpi_remove_gpe_handler ( ...@@ -597,16 +597,16 @@ acpi_remove_gpe_handler (
/* Make sure that the installed handler is the same */ /* Make sure that the installed handler is the same */
if (gpe_number_info->handler != handler) { if (gpe_event_info->handler != handler) {
(void) acpi_hw_enable_gpe (gpe_number); (void) acpi_hw_enable_gpe (gpe_event_info);
status = AE_BAD_PARAMETER; status = AE_BAD_PARAMETER;
goto cleanup; goto cleanup;
} }
/* Remove the handler */ /* Remove the handler */
gpe_number_info->handler = NULL; gpe_event_info->handler = NULL;
gpe_number_info->context = NULL; gpe_event_info->context = NULL;
cleanup: cleanup:
......
...@@ -163,6 +163,7 @@ acpi_enable_event ( ...@@ -163,6 +163,7 @@ acpi_enable_event (
{ {
acpi_status status = AE_OK; acpi_status status = AE_OK;
u32 value; u32 value;
struct acpi_gpe_event_info *gpe_event_info;
ACPI_FUNCTION_TRACE ("acpi_enable_event"); ACPI_FUNCTION_TRACE ("acpi_enable_event");
...@@ -209,19 +210,20 @@ acpi_enable_event ( ...@@ -209,19 +210,20 @@ acpi_enable_event (
/* Ensure that we have a valid GPE number */ /* Ensure that we have a valid GPE number */
if (acpi_ev_get_gpe_number_index (event) == ACPI_GPE_INVALID) { gpe_event_info = acpi_ev_get_gpe_event_info (event);
if (!gpe_event_info) {
return_ACPI_STATUS (AE_BAD_PARAMETER); return_ACPI_STATUS (AE_BAD_PARAMETER);
} }
/* Enable the requested GPE number */ /* Enable the requested GPE number */
status = acpi_hw_enable_gpe (event); status = acpi_hw_enable_gpe (gpe_event_info);
if (ACPI_FAILURE (status)) { if (ACPI_FAILURE (status)) {
return_ACPI_STATUS (status); return_ACPI_STATUS (status);
} }
if (flags & ACPI_EVENT_WAKE_ENABLE) { if (flags & ACPI_EVENT_WAKE_ENABLE) {
acpi_hw_enable_gpe_for_wakeup (event); acpi_hw_enable_gpe_for_wakeup (gpe_event_info);
} }
break; break;
...@@ -257,6 +259,7 @@ acpi_disable_event ( ...@@ -257,6 +259,7 @@ acpi_disable_event (
{ {
acpi_status status = AE_OK; acpi_status status = AE_OK;
u32 value; u32 value;
struct acpi_gpe_event_info *gpe_event_info;
ACPI_FUNCTION_TRACE ("acpi_disable_event"); ACPI_FUNCTION_TRACE ("acpi_disable_event");
...@@ -301,7 +304,8 @@ acpi_disable_event ( ...@@ -301,7 +304,8 @@ acpi_disable_event (
/* Ensure that we have a valid GPE number */ /* Ensure that we have a valid GPE number */
if (acpi_ev_get_gpe_number_index (event) == ACPI_GPE_INVALID) { gpe_event_info = acpi_ev_get_gpe_event_info (event);
if (!gpe_event_info) {
return_ACPI_STATUS (AE_BAD_PARAMETER); return_ACPI_STATUS (AE_BAD_PARAMETER);
} }
...@@ -311,10 +315,10 @@ acpi_disable_event ( ...@@ -311,10 +315,10 @@ acpi_disable_event (
*/ */
if (flags & ACPI_EVENT_WAKE_DISABLE) { if (flags & ACPI_EVENT_WAKE_DISABLE) {
acpi_hw_disable_gpe_for_wakeup (event); acpi_hw_disable_gpe_for_wakeup (gpe_event_info);
} }
else { else {
status = acpi_hw_disable_gpe (event); status = acpi_hw_disable_gpe (gpe_event_info);
} }
break; break;
...@@ -346,6 +350,7 @@ acpi_clear_event ( ...@@ -346,6 +350,7 @@ acpi_clear_event (
u32 type) u32 type)
{ {
acpi_status status = AE_OK; acpi_status status = AE_OK;
struct acpi_gpe_event_info *gpe_event_info;
ACPI_FUNCTION_TRACE ("acpi_clear_event"); ACPI_FUNCTION_TRACE ("acpi_clear_event");
...@@ -375,11 +380,12 @@ acpi_clear_event ( ...@@ -375,11 +380,12 @@ acpi_clear_event (
/* Ensure that we have a valid GPE number */ /* Ensure that we have a valid GPE number */
if (acpi_ev_get_gpe_number_index (event) == ACPI_GPE_INVALID) { gpe_event_info = acpi_ev_get_gpe_event_info (event);
if (!gpe_event_info) {
return_ACPI_STATUS (AE_BAD_PARAMETER); return_ACPI_STATUS (AE_BAD_PARAMETER);
} }
status = acpi_hw_clear_gpe (event); status = acpi_hw_clear_gpe (gpe_event_info);
break; break;
...@@ -415,6 +421,7 @@ acpi_get_event_status ( ...@@ -415,6 +421,7 @@ acpi_get_event_status (
acpi_event_status *event_status) acpi_event_status *event_status)
{ {
acpi_status status = AE_OK; acpi_status status = AE_OK;
struct acpi_gpe_event_info *gpe_event_info;
ACPI_FUNCTION_TRACE ("acpi_get_event_status"); ACPI_FUNCTION_TRACE ("acpi_get_event_status");
...@@ -447,7 +454,8 @@ acpi_get_event_status ( ...@@ -447,7 +454,8 @@ acpi_get_event_status (
/* Ensure that we have a valid GPE number */ /* Ensure that we have a valid GPE number */
if (acpi_ev_get_gpe_number_index (event) == ACPI_GPE_INVALID) { gpe_event_info = acpi_ev_get_gpe_event_info (event);
if (!gpe_event_info) {
return_ACPI_STATUS (AE_BAD_PARAMETER); return_ACPI_STATUS (AE_BAD_PARAMETER);
} }
...@@ -464,3 +472,4 @@ acpi_get_event_status ( ...@@ -464,3 +472,4 @@ acpi_get_event_status (
return_ACPI_STATUS (status); return_ACPI_STATUS (status);
} }
...@@ -49,26 +49,6 @@ ...@@ -49,26 +49,6 @@
ACPI_MODULE_NAME ("hwgpe") ACPI_MODULE_NAME ("hwgpe")
/******************************************************************************
*
* FUNCTION: acpi_hw_get_gpe_bit_mask
*
* PARAMETERS: gpe_number - The GPE
*
* RETURN: Gpe register bitmask for this gpe level
*
* DESCRIPTION: Get the bitmask for this GPE
*
******************************************************************************/
u8
acpi_hw_get_gpe_bit_mask (
u32 gpe_number)
{
return (acpi_gbl_gpe_number_info [acpi_ev_get_gpe_number_index (gpe_number)].bit_mask);
}
/****************************************************************************** /******************************************************************************
* *
* FUNCTION: acpi_hw_enable_gpe * FUNCTION: acpi_hw_enable_gpe
...@@ -83,37 +63,29 @@ acpi_hw_get_gpe_bit_mask ( ...@@ -83,37 +63,29 @@ acpi_hw_get_gpe_bit_mask (
acpi_status acpi_status
acpi_hw_enable_gpe ( acpi_hw_enable_gpe (
u32 gpe_number) struct acpi_gpe_event_info *gpe_event_info)
{ {
u32 in_byte; u32 in_byte;
acpi_status status; acpi_status status;
struct acpi_gpe_register_info *gpe_register_info;
ACPI_FUNCTION_ENTRY (); ACPI_FUNCTION_ENTRY ();
/* Get the info block for the entire GPE register */
gpe_register_info = acpi_ev_get_gpe_register_info (gpe_number);
if (!gpe_register_info) {
return (AE_BAD_PARAMETER);
}
/* /*
* Read the current value of the register, set the appropriate bit * Read the current value of the register, set the appropriate bit
* to enable the GPE, and write out the new register. * to enable the GPE, and write out the new register.
*/ */
status = acpi_hw_low_level_read (8, &in_byte, status = acpi_hw_low_level_read (8, &in_byte,
&gpe_register_info->enable_address, 0); &gpe_event_info->register_info->enable_address, 0);
if (ACPI_FAILURE (status)) { if (ACPI_FAILURE (status)) {
return (status); return (status);
} }
/* Write with the new GPE bit enabled */ /* Write with the new GPE bit enabled */
status = acpi_hw_low_level_write (8, (in_byte | acpi_hw_get_gpe_bit_mask (gpe_number)), status = acpi_hw_low_level_write (8, (in_byte | gpe_event_info->bit_mask),
&gpe_register_info->enable_address, 0); &gpe_event_info->register_info->enable_address, 0);
return (status); return (status);
} }
...@@ -134,7 +106,7 @@ acpi_hw_enable_gpe ( ...@@ -134,7 +106,7 @@ acpi_hw_enable_gpe (
void void
acpi_hw_enable_gpe_for_wakeup ( acpi_hw_enable_gpe_for_wakeup (
u32 gpe_number) struct acpi_gpe_event_info *gpe_event_info)
{ {
struct acpi_gpe_register_info *gpe_register_info; struct acpi_gpe_register_info *gpe_register_info;
...@@ -144,7 +116,7 @@ acpi_hw_enable_gpe_for_wakeup ( ...@@ -144,7 +116,7 @@ acpi_hw_enable_gpe_for_wakeup (
/* Get the info block for the entire GPE register */ /* Get the info block for the entire GPE register */
gpe_register_info = acpi_ev_get_gpe_register_info (gpe_number); gpe_register_info = gpe_event_info->register_info;
if (!gpe_register_info) { if (!gpe_register_info) {
return; return;
} }
...@@ -152,7 +124,7 @@ acpi_hw_enable_gpe_for_wakeup ( ...@@ -152,7 +124,7 @@ acpi_hw_enable_gpe_for_wakeup (
/* /*
* Set the bit so we will not disable this when sleeping * Set the bit so we will not disable this when sleeping
*/ */
gpe_register_info->wake_enable |= acpi_hw_get_gpe_bit_mask (gpe_number); gpe_register_info->wake_enable |= gpe_event_info->bit_mask;
} }
...@@ -170,7 +142,7 @@ acpi_hw_enable_gpe_for_wakeup ( ...@@ -170,7 +142,7 @@ acpi_hw_enable_gpe_for_wakeup (
acpi_status acpi_status
acpi_hw_disable_gpe ( acpi_hw_disable_gpe (
u32 gpe_number) struct acpi_gpe_event_info *gpe_event_info)
{ {
u32 in_byte; u32 in_byte;
acpi_status status; acpi_status status;
...@@ -182,7 +154,7 @@ acpi_hw_disable_gpe ( ...@@ -182,7 +154,7 @@ acpi_hw_disable_gpe (
/* Get the info block for the entire GPE register */ /* Get the info block for the entire GPE register */
gpe_register_info = acpi_ev_get_gpe_register_info (gpe_number); gpe_register_info = gpe_event_info->register_info;
if (!gpe_register_info) { if (!gpe_register_info) {
return (AE_BAD_PARAMETER); return (AE_BAD_PARAMETER);
} }
...@@ -199,13 +171,13 @@ acpi_hw_disable_gpe ( ...@@ -199,13 +171,13 @@ acpi_hw_disable_gpe (
/* Write the byte with this GPE bit cleared */ /* Write the byte with this GPE bit cleared */
status = acpi_hw_low_level_write (8, (in_byte & ~(acpi_hw_get_gpe_bit_mask (gpe_number))), status = acpi_hw_low_level_write (8, (in_byte & ~(gpe_event_info->bit_mask)),
&gpe_register_info->enable_address, 0); &gpe_register_info->enable_address, 0);
if (ACPI_FAILURE (status)) { if (ACPI_FAILURE (status)) {
return (status); return (status);
} }
acpi_hw_disable_gpe_for_wakeup(gpe_number); acpi_hw_disable_gpe_for_wakeup (gpe_event_info);
return (AE_OK); return (AE_OK);
} }
...@@ -225,7 +197,7 @@ acpi_hw_disable_gpe ( ...@@ -225,7 +197,7 @@ acpi_hw_disable_gpe (
void void
acpi_hw_disable_gpe_for_wakeup ( acpi_hw_disable_gpe_for_wakeup (
u32 gpe_number) struct acpi_gpe_event_info *gpe_event_info)
{ {
struct acpi_gpe_register_info *gpe_register_info; struct acpi_gpe_register_info *gpe_register_info;
...@@ -235,7 +207,7 @@ acpi_hw_disable_gpe_for_wakeup ( ...@@ -235,7 +207,7 @@ acpi_hw_disable_gpe_for_wakeup (
/* Get the info block for the entire GPE register */ /* Get the info block for the entire GPE register */
gpe_register_info = acpi_ev_get_gpe_register_info (gpe_number); gpe_register_info = gpe_event_info->register_info;
if (!gpe_register_info) { if (!gpe_register_info) {
return; return;
} }
...@@ -243,7 +215,7 @@ acpi_hw_disable_gpe_for_wakeup ( ...@@ -243,7 +215,7 @@ acpi_hw_disable_gpe_for_wakeup (
/* /*
* Clear the bit so we will disable this when sleeping * Clear the bit so we will disable this when sleeping
*/ */
gpe_register_info->wake_enable &= ~(acpi_hw_get_gpe_bit_mask (gpe_number)); gpe_register_info->wake_enable &= ~(gpe_event_info->bit_mask);
} }
...@@ -261,28 +233,20 @@ acpi_hw_disable_gpe_for_wakeup ( ...@@ -261,28 +233,20 @@ acpi_hw_disable_gpe_for_wakeup (
acpi_status acpi_status
acpi_hw_clear_gpe ( acpi_hw_clear_gpe (
u32 gpe_number) struct acpi_gpe_event_info *gpe_event_info)
{ {
acpi_status status; acpi_status status;
struct acpi_gpe_register_info *gpe_register_info;
ACPI_FUNCTION_ENTRY (); ACPI_FUNCTION_ENTRY ();
/* Get the info block for the entire GPE register */
gpe_register_info = acpi_ev_get_gpe_register_info (gpe_number);
if (!gpe_register_info) {
return (AE_BAD_PARAMETER);
}
/* /*
* Write a one to the appropriate bit in the status register to * Write a one to the appropriate bit in the status register to
* clear this GPE. * clear this GPE.
*/ */
status = acpi_hw_low_level_write (8, acpi_hw_get_gpe_bit_mask (gpe_number), status = acpi_hw_low_level_write (8, gpe_event_info->bit_mask,
&gpe_register_info->status_address, 0); &gpe_event_info->register_info->status_address, 0);
return (status); return (status);
} }
...@@ -308,6 +272,7 @@ acpi_hw_get_gpe_status ( ...@@ -308,6 +272,7 @@ acpi_hw_get_gpe_status (
u32 in_byte; u32 in_byte;
u8 bit_mask; u8 bit_mask;
struct acpi_gpe_register_info *gpe_register_info; struct acpi_gpe_register_info *gpe_register_info;
struct acpi_gpe_event_info *gpe_event_info;
acpi_status status; acpi_status status;
acpi_event_status local_event_status = 0; acpi_event_status local_event_status = 0;
...@@ -319,16 +284,18 @@ acpi_hw_get_gpe_status ( ...@@ -319,16 +284,18 @@ acpi_hw_get_gpe_status (
return (AE_BAD_PARAMETER); return (AE_BAD_PARAMETER);
} }
/* Get the info block for the entire GPE register */ gpe_event_info = acpi_ev_get_gpe_event_info (gpe_number);
if (!gpe_event_info) {
gpe_register_info = acpi_ev_get_gpe_register_info (gpe_number);
if (!gpe_register_info) {
return (AE_BAD_PARAMETER); return (AE_BAD_PARAMETER);
} }
/* Get the info block for the entire GPE register */
gpe_register_info = gpe_event_info->register_info;
/* Get the register bitmask for this GPE */ /* Get the register bitmask for this GPE */
bit_mask = acpi_hw_get_gpe_bit_mask (gpe_number); bit_mask = gpe_event_info->bit_mask;
/* GPE Enabled? */ /* GPE Enabled? */
...@@ -375,7 +342,7 @@ acpi_hw_get_gpe_status ( ...@@ -375,7 +342,7 @@ acpi_hw_get_gpe_status (
* *
* DESCRIPTION: Disable all non-wakeup GPEs * DESCRIPTION: Disable all non-wakeup GPEs
* Call with interrupts disabled. The interrupt handler also * Call with interrupts disabled. The interrupt handler also
* modifies acpi_gbl_gpe_register_info[i].Enable, so it should not be * modifies gpe_register_info->Enable, so it should not be
* given the chance to run until after non-wake GPEs are * given the chance to run until after non-wake GPEs are
* re-enabled. * re-enabled.
* *
...@@ -389,19 +356,22 @@ acpi_hw_disable_non_wakeup_gpes ( ...@@ -389,19 +356,22 @@ acpi_hw_disable_non_wakeup_gpes (
struct acpi_gpe_register_info *gpe_register_info; struct acpi_gpe_register_info *gpe_register_info;
u32 in_value; u32 in_value;
acpi_status status; acpi_status status;
struct acpi_gpe_block_info *gpe_block;
ACPI_FUNCTION_ENTRY (); ACPI_FUNCTION_ENTRY ();
for (i = 0; i < acpi_gbl_gpe_register_count; i++) { gpe_block = acpi_gbl_gpe_block_list_head;
/* Get the info block for the entire GPE register */ while (gpe_block) {
/* Get the register info for the entire GPE block */
gpe_register_info = &acpi_gbl_gpe_register_info[i]; gpe_register_info = gpe_block->register_info;
if (!gpe_register_info) { if (!gpe_register_info) {
return (AE_BAD_PARAMETER); return (AE_BAD_PARAMETER);
} }
for (i = 0; i < gpe_block->register_count; i++) {
/* /*
* Read the enabled status of all GPEs. We * Read the enabled status of all GPEs. We
* will be using it to restore all the GPEs later. * will be using it to restore all the GPEs later.
...@@ -422,7 +392,13 @@ acpi_hw_disable_non_wakeup_gpes ( ...@@ -422,7 +392,13 @@ acpi_hw_disable_non_wakeup_gpes (
if (ACPI_FAILURE (status)) { if (ACPI_FAILURE (status)) {
return (status); return (status);
} }
gpe_register_info++;
}
gpe_block = gpe_block->next;
} }
return (AE_OK); return (AE_OK);
} }
...@@ -446,19 +422,22 @@ acpi_hw_enable_non_wakeup_gpes ( ...@@ -446,19 +422,22 @@ acpi_hw_enable_non_wakeup_gpes (
u32 i; u32 i;
struct acpi_gpe_register_info *gpe_register_info; struct acpi_gpe_register_info *gpe_register_info;
acpi_status status; acpi_status status;
struct acpi_gpe_block_info *gpe_block;
ACPI_FUNCTION_ENTRY (); ACPI_FUNCTION_ENTRY ();
for (i = 0; i < acpi_gbl_gpe_register_count; i++) { gpe_block = acpi_gbl_gpe_block_list_head;
/* Get the info block for the entire GPE register */ while (gpe_block) {
/* Get the register info for the entire GPE block */
gpe_register_info = &acpi_gbl_gpe_register_info[i]; gpe_register_info = gpe_block->register_info;
if (!gpe_register_info) { if (!gpe_register_info) {
return (AE_BAD_PARAMETER); return (AE_BAD_PARAMETER);
} }
for (i = 0; i < gpe_block->register_count; i++) {
/* /*
* We previously stored the enabled status of all GPEs. * We previously stored the enabled status of all GPEs.
* Blast them back in. * Blast them back in.
...@@ -468,6 +447,12 @@ acpi_hw_enable_non_wakeup_gpes ( ...@@ -468,6 +447,12 @@ acpi_hw_enable_non_wakeup_gpes (
if (ACPI_FAILURE (status)) { if (ACPI_FAILURE (status)) {
return (status); return (status);
} }
gpe_register_info++;
} }
gpe_block = gpe_block->next;
}
return (AE_OK); return (AE_OK);
} }
...@@ -67,8 +67,8 @@ acpi_status ...@@ -67,8 +67,8 @@ acpi_status
acpi_hw_clear_acpi_status (void) acpi_hw_clear_acpi_status (void)
{ {
acpi_native_uint i; acpi_native_uint i;
acpi_native_uint gpe_block;
acpi_status status; acpi_status status;
struct acpi_gpe_block_info *gpe_block;
ACPI_FUNCTION_TRACE ("hw_clear_acpi_status"); ACPI_FUNCTION_TRACE ("hw_clear_acpi_status");
...@@ -100,16 +100,19 @@ acpi_hw_clear_acpi_status (void) ...@@ -100,16 +100,19 @@ acpi_hw_clear_acpi_status (void)
} }
} }
/* Clear the GPE Bits */ /* Clear the GPE Bits in all GPE registers in all GPE blocks */
for (gpe_block = 0; gpe_block < ACPI_MAX_GPE_BLOCKS; gpe_block++) { gpe_block = acpi_gbl_gpe_block_list_head;
for (i = 0; i < acpi_gbl_gpe_block_info[gpe_block].register_count; i++) { while (gpe_block) {
for (i = 0; i < gpe_block->register_count; i++) {
status = acpi_hw_low_level_write (8, 0xFF, status = acpi_hw_low_level_write (8, 0xFF,
acpi_gbl_gpe_block_info[gpe_block].block_address, (u32) i); &gpe_block->register_info[i].status_address, (u32) i);
if (ACPI_FAILURE (status)) { if (ACPI_FAILURE (status)) {
goto unlock_and_exit; goto unlock_and_exit;
} }
} }
gpe_block = gpe_block->next;
} }
unlock_and_exit: unlock_and_exit:
......
...@@ -212,6 +212,60 @@ acpi_rs_get_prs_method_data ( ...@@ -212,6 +212,60 @@ acpi_rs_get_prs_method_data (
} }
/*******************************************************************************
*
* FUNCTION: acpi_rs_get_method_data
*
* PARAMETERS: Handle - a handle to the containing object
* ret_buffer - a pointer to a buffer structure for the
* results
*
* RETURN: Status
*
* DESCRIPTION: This function is called to get the _CRS or _PRS value of an
* object contained in an object specified by the handle passed in
*
* If the function fails an appropriate status will be returned
* and the contents of the callers buffer is undefined.
*
******************************************************************************/
acpi_status
acpi_rs_get_method_data (
acpi_handle handle,
char *path,
struct acpi_buffer *ret_buffer)
{
union acpi_operand_object *obj_desc;
acpi_status status;
ACPI_FUNCTION_TRACE ("rs_get_method_data");
/* Parameters guaranteed valid by caller */
/*
* Execute the method, no parameters
*/
status = acpi_ut_evaluate_object (handle, path, ACPI_BTYPE_BUFFER, &obj_desc);
if (ACPI_FAILURE (status)) {
return_ACPI_STATUS (status);
}
/*
* Make the call to create a resource linked list from the
* byte stream buffer that comes back from the method
* execution.
*/
status = acpi_rs_create_resource_list (obj_desc, ret_buffer);
/* On exit, we must delete the object returned by evaluate_object */
acpi_ut_remove_reference (obj_desc);
return_ACPI_STATUS (status);
}
/******************************************************************************* /*******************************************************************************
* *
* FUNCTION: acpi_rs_set_srs_method_data * FUNCTION: acpi_rs_set_srs_method_data
......
...@@ -210,6 +210,90 @@ acpi_get_possible_resources ( ...@@ -210,6 +210,90 @@ acpi_get_possible_resources (
} }
/*******************************************************************************
*
* FUNCTION: acpi_walk_resources
*
* PARAMETERS: device_handle - a handle to the device object for the
* device we are querying
* Path - method name of the resources we want
* (METHOD_NAME__CRS or METHOD_NAME__PRS)
* user_function - called for each resource
* Context - passed to user_function
*
* RETURN: Status
*
* DESCRIPTION: Retrieves the current or possible resource list for the
* specified device. The user_function is called once for
* each resource in the list.
*
******************************************************************************/
acpi_status
acpi_walk_resources (
acpi_handle device_handle,
char *path,
ACPI_WALK_RESOURCE_CALLBACK user_function,
void *context)
{
acpi_status status;
struct acpi_buffer buffer = {ACPI_ALLOCATE_BUFFER, NULL};
struct acpi_resource *resource;
ACPI_FUNCTION_TRACE ("acpi_walk_resources");
if (!device_handle ||
(ACPI_STRNCMP (path, METHOD_NAME__CRS, sizeof (METHOD_NAME__CRS)) &&
ACPI_STRNCMP (path, METHOD_NAME__PRS, sizeof (METHOD_NAME__PRS)))) {
return_ACPI_STATUS (AE_BAD_PARAMETER);
}
status = acpi_rs_get_method_data (device_handle, path, &buffer);
if (ACPI_FAILURE (status)) {
return_ACPI_STATUS (status);
}
resource = (struct acpi_resource *) buffer.pointer;
for (;;) {
if (!resource || resource->id == ACPI_RSTYPE_END_TAG) {
break;
}
status = user_function (resource, context);
switch (status) {
case AE_OK:
case AE_CTRL_DEPTH:
/* Just keep going */
status = AE_OK;
break;
case AE_CTRL_TERMINATE:
/* Exit now, with OK stats */
status = AE_OK;
goto cleanup;
default:
/* All others are valid exceptions */
goto cleanup;
}
resource = ACPI_NEXT_RESOURCE (resource);
}
cleanup:
acpi_os_free (buffer.pointer);
return_ACPI_STATUS (status);
}
/******************************************************************************* /*******************************************************************************
* *
* FUNCTION: acpi_set_current_resources * FUNCTION: acpi_set_current_resources
...@@ -252,3 +336,64 @@ acpi_set_current_resources ( ...@@ -252,3 +336,64 @@ acpi_set_current_resources (
status = acpi_rs_set_srs_method_data (device_handle, in_buffer); status = acpi_rs_set_srs_method_data (device_handle, in_buffer);
return_ACPI_STATUS (status); return_ACPI_STATUS (status);
} }
#define COPY_FIELD(out, in, field) out->field = in->field
#define COPY_ADDRESS(out, in) \
COPY_FIELD(out, in, resource_type); \
COPY_FIELD(out, in, producer_consumer); \
COPY_FIELD(out, in, decode); \
COPY_FIELD(out, in, min_address_fixed); \
COPY_FIELD(out, in, max_address_fixed); \
COPY_FIELD(out, in, attribute); \
COPY_FIELD(out, in, granularity); \
COPY_FIELD(out, in, min_address_range); \
COPY_FIELD(out, in, max_address_range); \
COPY_FIELD(out, in, address_translation_offset); \
COPY_FIELD(out, in, address_length); \
COPY_FIELD(out, in, resource_source);
/*******************************************************************************
*
* FUNCTION: acpi_resource_to_address64
*
* PARAMETERS: resource - Pointer to a resource
* out - Pointer to the users's return
* buffer (a struct
* struct acpi_resource_address64)
*
* RETURN: Status
*
* DESCRIPTION: If the resource is an address16, address32, or address64,
* copy it to the address64 return buffer. This saves the
* caller from having to duplicate code for different-sized
* addresses.
*
******************************************************************************/
acpi_status
acpi_resource_to_address64 (
struct acpi_resource *resource,
struct acpi_resource_address64 *out)
{
struct acpi_resource_address16 *address16;
struct acpi_resource_address32 *address32;
struct acpi_resource_address64 *address64;
switch (resource->id) {
case ACPI_RSTYPE_ADDRESS16:
address16 = (struct acpi_resource_address16 *) &resource->data;
COPY_ADDRESS(out, address16);
break;
case ACPI_RSTYPE_ADDRESS32:
address32 = (struct acpi_resource_address32 *) &resource->data;
COPY_ADDRESS(out, address32);
break;
case ACPI_RSTYPE_ADDRESS64:
address64 = (struct acpi_resource_address64 *) &resource->data;
COPY_ADDRESS(out, address64);
break;
default:
return (AE_BAD_PARAMETER);
}
return (AE_OK);
}
...@@ -239,9 +239,8 @@ acpi_tb_convert_fadt1 ( ...@@ -239,9 +239,8 @@ acpi_tb_convert_fadt1 (
ASL_BUILD_GAS_FROM_V1_ENTRY (local_fadt->xpm1b_cnt_blk, local_fadt->pm1_cnt_len, local_fadt->V1_pm1b_cnt_blk); ASL_BUILD_GAS_FROM_V1_ENTRY (local_fadt->xpm1b_cnt_blk, local_fadt->pm1_cnt_len, local_fadt->V1_pm1b_cnt_blk);
ASL_BUILD_GAS_FROM_V1_ENTRY (local_fadt->xpm2_cnt_blk, local_fadt->pm2_cnt_len, local_fadt->V1_pm2_cnt_blk); ASL_BUILD_GAS_FROM_V1_ENTRY (local_fadt->xpm2_cnt_blk, local_fadt->pm2_cnt_len, local_fadt->V1_pm2_cnt_blk);
ASL_BUILD_GAS_FROM_V1_ENTRY (local_fadt->xpm_tmr_blk, local_fadt->pm_tm_len, local_fadt->V1_pm_tmr_blk); ASL_BUILD_GAS_FROM_V1_ENTRY (local_fadt->xpm_tmr_blk, local_fadt->pm_tm_len, local_fadt->V1_pm_tmr_blk);
ASL_BUILD_GAS_FROM_V1_ENTRY (local_fadt->xgpe0_blk, local_fadt->gpe0_blk_len, local_fadt->V1_gpe0_blk); ASL_BUILD_GAS_FROM_V1_ENTRY (local_fadt->xgpe0_blk, 0, local_fadt->V1_gpe0_blk);
ASL_BUILD_GAS_FROM_V1_ENTRY (local_fadt->xgpe1_blk, local_fadt->gpe1_blk_len, local_fadt->V1_gpe1_blk); ASL_BUILD_GAS_FROM_V1_ENTRY (local_fadt->xgpe1_blk, 0, local_fadt->V1_gpe1_blk);
} }
...@@ -314,15 +313,16 @@ acpi_tb_convert_fadt2 ( ...@@ -314,15 +313,16 @@ acpi_tb_convert_fadt2 (
if (!(local_fadt->xgpe0_blk.address)) { if (!(local_fadt->xgpe0_blk.address)) {
ASL_BUILD_GAS_FROM_V1_ENTRY (local_fadt->xgpe0_blk, ASL_BUILD_GAS_FROM_V1_ENTRY (local_fadt->xgpe0_blk,
local_fadt->gpe0_blk_len, local_fadt->V1_gpe0_blk); 0, local_fadt->V1_gpe0_blk);
} }
if (!(local_fadt->xgpe1_blk.address)) { if (!(local_fadt->xgpe1_blk.address)) {
ASL_BUILD_GAS_FROM_V1_ENTRY (local_fadt->xgpe1_blk, ASL_BUILD_GAS_FROM_V1_ENTRY (local_fadt->xgpe1_blk,
local_fadt->gpe1_blk_len, local_fadt->V1_gpe1_blk); 0, local_fadt->V1_gpe1_blk);
} }
} }
/******************************************************************************* /*******************************************************************************
* *
* FUNCTION: acpi_tb_convert_table_fadt * FUNCTION: acpi_tb_convert_table_fadt
......
...@@ -645,11 +645,11 @@ acpi_ut_copy_simple_object ( ...@@ -645,11 +645,11 @@ acpi_ut_copy_simple_object (
/* /*
* Allocate and copy the actual buffer if and only if: * Allocate and copy the actual buffer if and only if:
* 1) There is a valid buffer (length > 0) * 1) There is a valid buffer pointer
* 2) The buffer is not static (not in an ACPI table) (in this case, * 2) The buffer is not static (not in an ACPI table) (in this case,
* the actual pointer was already copied above) * the actual pointer was already copied above)
*/ */
if ((source_desc->buffer.length) && if ((source_desc->buffer.pointer) &&
(!(source_desc->common.flags & AOPOBJ_STATIC_POINTER))) { (!(source_desc->common.flags & AOPOBJ_STATIC_POINTER))) {
dest_desc->buffer.pointer = ACPI_MEM_ALLOCATE (source_desc->buffer.length); dest_desc->buffer.pointer = ACPI_MEM_ALLOCATE (source_desc->buffer.length);
if (!dest_desc->buffer.pointer) { if (!dest_desc->buffer.pointer) {
...@@ -665,11 +665,11 @@ acpi_ut_copy_simple_object ( ...@@ -665,11 +665,11 @@ acpi_ut_copy_simple_object (
/* /*
* Allocate and copy the actual string if and only if: * Allocate and copy the actual string if and only if:
* 1) There is a valid string (length > 0) * 1) There is a valid string pointer
* 2) The string is not static (not in an ACPI table) (in this case, * 2) The string is not static (not in an ACPI table) (in this case,
* the actual pointer was already copied above) * the actual pointer was already copied above)
*/ */
if ((source_desc->string.length) && if ((source_desc->string.pointer) &&
(!(source_desc->common.flags & AOPOBJ_STATIC_POINTER))) { (!(source_desc->common.flags & AOPOBJ_STATIC_POINTER))) {
dest_desc->string.pointer = ACPI_MEM_ALLOCATE ((acpi_size) source_desc->string.length + 1); dest_desc->string.pointer = ACPI_MEM_ALLOCATE ((acpi_size) source_desc->string.length + 1);
if (!dest_desc->string.pointer) { if (!dest_desc->string.pointer) {
......
...@@ -729,6 +729,10 @@ acpi_ut_init_globals ( ...@@ -729,6 +729,10 @@ acpi_ut_init_globals (
acpi_gbl_acpi_mutex_info[i].use_count = 0; acpi_gbl_acpi_mutex_info[i].use_count = 0;
} }
/* GPE support */
acpi_gbl_gpe_block_list_head = NULL;
/* Global notify handlers */ /* Global notify handlers */
acpi_gbl_sys_notify.handler = NULL; acpi_gbl_sys_notify.handler = NULL;
...@@ -766,8 +770,6 @@ acpi_ut_init_globals ( ...@@ -766,8 +770,6 @@ acpi_ut_init_globals (
/* Hardware oriented */ /* Hardware oriented */
acpi_gbl_gpe_register_info = NULL;
acpi_gbl_gpe_number_info = NULL;
acpi_gbl_events_initialized = FALSE; acpi_gbl_events_initialized = FALSE;
/* Namespace */ /* Namespace */
......
...@@ -176,6 +176,9 @@ void ...@@ -176,6 +176,9 @@ void
acpi_db_display_resources ( acpi_db_display_resources (
char *object_arg); char *object_arg);
void
acpi_db_display_gpes (void);
void void
acpi_db_check_integrity ( acpi_db_check_integrity (
void); void);
......
...@@ -91,14 +91,6 @@ acpi_status ...@@ -91,14 +91,6 @@ acpi_status
acpi_ev_init_global_lock_handler ( acpi_ev_init_global_lock_handler (
void); void);
struct acpi_gpe_register_info *
acpi_ev_get_gpe_register_info (
u32 gpe_number);
struct acpi_gpe_number_info *
acpi_ev_get_gpe_number_info (
u32 gpe_number);
u32 u32
acpi_ev_get_gpe_number_index ( acpi_ev_get_gpe_number_index (
u32 gpe_number); u32 gpe_number);
...@@ -117,17 +109,17 @@ acpi_ev_notify_dispatch ( ...@@ -117,17 +109,17 @@ acpi_ev_notify_dispatch (
* Evgpe - GPE handling and dispatch * Evgpe - GPE handling and dispatch
*/ */
acpi_status struct acpi_gpe_event_info *
acpi_ev_gpe_initialize ( acpi_ev_get_gpe_event_info (
void); u32 gpe_number);
acpi_status acpi_status
acpi_ev_init_gpe_control_methods ( acpi_ev_gpe_initialize (
void); void);
u32 u32
acpi_ev_gpe_dispatch ( acpi_ev_gpe_dispatch (
u32 gpe_number); struct acpi_gpe_event_info *gpe_event_info);
u32 u32
acpi_ev_gpe_detect ( acpi_ev_gpe_detect (
......
...@@ -234,22 +234,7 @@ ACPI_EXTERN u8 acpi_gbl_sleep_type_b; ...@@ -234,22 +234,7 @@ ACPI_EXTERN u8 acpi_gbl_sleep_type_b;
extern struct acpi_fixed_event_info acpi_gbl_fixed_event_info[ACPI_NUM_FIXED_EVENTS]; extern struct acpi_fixed_event_info acpi_gbl_fixed_event_info[ACPI_NUM_FIXED_EVENTS];
ACPI_EXTERN struct acpi_fixed_event_handler acpi_gbl_fixed_event_handlers[ACPI_NUM_FIXED_EVENTS]; ACPI_EXTERN struct acpi_fixed_event_handler acpi_gbl_fixed_event_handlers[ACPI_NUM_FIXED_EVENTS];
ACPI_EXTERN struct acpi_gpe_block_info *acpi_gbl_gpe_block_list_head;
ACPI_EXTERN acpi_handle acpi_gbl_gpe_obj_handle;
ACPI_EXTERN u32 acpi_gbl_gpe_register_count;
ACPI_EXTERN u32 acpi_gbl_gpe_number_max;
ACPI_EXTERN struct acpi_gpe_register_info *acpi_gbl_gpe_register_info;
ACPI_EXTERN struct acpi_gpe_number_info *acpi_gbl_gpe_number_info;
ACPI_EXTERN struct acpi_gpe_block_info acpi_gbl_gpe_block_info[ACPI_MAX_GPE_BLOCKS];
/*
* GPE translation table
* Indexed by the GPE number, returns a valid index into the global GPE tables.
*
* This table is needed because the GPE numbers supported by block 1 do not
* have to be contiguous with the GPE numbers supported by block 0.
*/
ACPI_EXTERN struct acpi_gpe_index_info *acpi_gbl_gpe_number_to_index;
/***************************************************************************** /*****************************************************************************
......
...@@ -115,29 +115,25 @@ acpi_hw_clear_acpi_status ( ...@@ -115,29 +115,25 @@ acpi_hw_clear_acpi_status (
/* GPE support */ /* GPE support */
u8
acpi_hw_get_gpe_bit_mask (
u32 gpe_number);
acpi_status acpi_status
acpi_hw_enable_gpe ( acpi_hw_enable_gpe (
u32 gpe_number); struct acpi_gpe_event_info *gpe_event_info);
void void
acpi_hw_enable_gpe_for_wakeup ( acpi_hw_enable_gpe_for_wakeup (
u32 gpe_number); struct acpi_gpe_event_info *gpe_event_info);
acpi_status acpi_status
acpi_hw_disable_gpe ( acpi_hw_disable_gpe (
u32 gpe_number); struct acpi_gpe_event_info *gpe_event_info);
void void
acpi_hw_disable_gpe_for_wakeup ( acpi_hw_disable_gpe_for_wakeup (
u32 gpe_number); struct acpi_gpe_event_info *gpe_event_info);
acpi_status acpi_status
acpi_hw_clear_gpe ( acpi_hw_clear_gpe (
u32 gpe_number); struct acpi_gpe_event_info *gpe_event_info);
acpi_status acpi_status
acpi_hw_get_gpe_status ( acpi_hw_get_gpe_status (
......
...@@ -308,13 +308,16 @@ struct acpi_create_field_info ...@@ -308,13 +308,16 @@ struct acpi_create_field_info
* *
****************************************************************************/ ****************************************************************************/
/* Information about each GPE register block */ /* Information about each particular GPE level */
struct acpi_gpe_block_info struct acpi_gpe_event_info
{ {
struct acpi_generic_address *block_address; struct acpi_namespace_node *method_node; /* Method node for this GPE level */
u16 register_count; acpi_gpe_handler handler; /* Address of handler, if any */
u8 block_base_number; void *context; /* Context to be passed to handler */
struct acpi_gpe_register_info *register_info;
u8 type; /* Level or Edge */
u8 bit_mask;
}; };
/* Information about a particular GPE register pair */ /* Information about a particular GPE register pair */
...@@ -334,23 +337,21 @@ struct acpi_gpe_register_info ...@@ -334,23 +337,21 @@ struct acpi_gpe_register_info
#define ACPI_GPE_EDGE_TRIGGERED 2 #define ACPI_GPE_EDGE_TRIGGERED 2
/* Information about each particular GPE level */ /* Information about each GPE register block */
struct acpi_gpe_number_info struct acpi_gpe_block_info
{ {
struct acpi_namespace_node *method_node; /* Method node for this GPE level */ struct acpi_gpe_block_info *previous;
acpi_gpe_handler handler; /* Address of handler, if any */ struct acpi_gpe_block_info *next;
void *context; /* Context to be passed to handler */ struct acpi_gpe_block_info *next_on_interrupt;
u8 type; /* Level or Edge */ struct acpi_gpe_register_info *register_info;
u8 bit_mask; struct acpi_gpe_event_info *event_info;
struct acpi_generic_address block_address;
u32 register_count;
u8 block_base_number;
}; };
struct acpi_gpe_index_info
{
u8 number_index;
};
/* Information about each particular fixed event */ /* Information about each particular fixed event */
struct acpi_fixed_event_handler struct acpi_fixed_event_handler
......
...@@ -339,6 +339,12 @@ acpi_get_event_status ( ...@@ -339,6 +339,12 @@ acpi_get_event_status (
* Resource interfaces * Resource interfaces
*/ */
typedef
acpi_status (*ACPI_WALK_RESOURCE_CALLBACK) (
struct acpi_resource *resource,
void *context);
acpi_status acpi_status
acpi_get_current_resources( acpi_get_current_resources(
acpi_handle device_handle, acpi_handle device_handle,
...@@ -349,6 +355,13 @@ acpi_get_possible_resources( ...@@ -349,6 +355,13 @@ acpi_get_possible_resources(
acpi_handle device_handle, acpi_handle device_handle,
struct acpi_buffer *ret_buffer); struct acpi_buffer *ret_buffer);
acpi_status
acpi_walk_resources (
acpi_handle device_handle,
char *path,
ACPI_WALK_RESOURCE_CALLBACK user_function,
void *context);
acpi_status acpi_status
acpi_set_current_resources ( acpi_set_current_resources (
acpi_handle device_handle, acpi_handle device_handle,
...@@ -359,6 +372,10 @@ acpi_get_irq_routing_table ( ...@@ -359,6 +372,10 @@ acpi_get_irq_routing_table (
acpi_handle bus_device_handle, acpi_handle bus_device_handle,
struct acpi_buffer *ret_buffer); struct acpi_buffer *ret_buffer);
acpi_status
acpi_resource_to_address64 (
struct acpi_resource *resource,
struct acpi_resource_address64 *out);
/* /*
* Hardware (ACPI device) interfaces * Hardware (ACPI device) interfaces
...@@ -398,6 +415,10 @@ acpi_status ...@@ -398,6 +415,10 @@ acpi_status
acpi_enter_sleep_state ( acpi_enter_sleep_state (
u8 sleep_state); u8 sleep_state);
acpi_status
acpi_enter_sleep_state_s4bios (
void);
acpi_status acpi_status
acpi_leave_sleep_state ( acpi_leave_sleep_state (
u8 sleep_state); u8 sleep_state);
......
...@@ -65,6 +65,12 @@ acpi_rs_get_prs_method_data ( ...@@ -65,6 +65,12 @@ acpi_rs_get_prs_method_data (
acpi_handle handle, acpi_handle handle,
struct acpi_buffer *ret_buffer); struct acpi_buffer *ret_buffer);
acpi_status
acpi_rs_get_method_data (
acpi_handle handle,
char *path,
struct acpi_buffer *ret_buffer);
acpi_status acpi_status
acpi_rs_set_srs_method_data ( acpi_rs_set_srs_method_data (
acpi_handle handle, acpi_handle handle,
......
...@@ -463,6 +463,8 @@ acpi_ut_delete_internal_object_list ( ...@@ -463,6 +463,8 @@ acpi_ut_delete_internal_object_list (
#define METHOD_NAME__SEG "_SEG" #define METHOD_NAME__SEG "_SEG"
#define METHOD_NAME__BBN "_BBN" #define METHOD_NAME__BBN "_BBN"
#define METHOD_NAME__PRT "_PRT" #define METHOD_NAME__PRT "_PRT"
#define METHOD_NAME__CRS "_CRS"
#define METHOD_NAME__PRS "_PRS"
acpi_status acpi_status
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment