summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndy Grover <agrover@groveronline.com>2003-02-27 00:23:08 -0800
committerAndy Grover <agrover@groveronline.com>2003-02-27 00:23:08 -0800
commitda8bbd484da33232f351709c57fee02502b29547 (patch)
treeeea076f2ea3e91ccedf02f84356043b634e2e913
parentdb72219bc0b3bcaddb0d92e6f532a99450dd9c03 (diff)
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 ""
-rw-r--r--drivers/acpi/events/evevent.c12
-rw-r--r--drivers/acpi/events/evgpe.c577
-rw-r--r--drivers/acpi/events/evmisc.c116
-rw-r--r--drivers/acpi/events/evsci.c18
-rw-r--r--drivers/acpi/events/evxface.c34
-rw-r--r--drivers/acpi/events/evxfevnt.c27
-rw-r--r--drivers/acpi/hardware/hwgpe.c167
-rw-r--r--drivers/acpi/hardware/hwregs.c13
-rw-r--r--drivers/acpi/resources/rsutils.c54
-rw-r--r--drivers/acpi/resources/rsxface.c145
-rw-r--r--drivers/acpi/tables/tbconvrt.c10
-rw-r--r--drivers/acpi/utilities/utcopy.c8
-rw-r--r--drivers/acpi/utilities/utglobal.c6
-rw-r--r--include/acpi/acdebug.h3
-rw-r--r--include/acpi/acevents.h18
-rw-r--r--include/acpi/acglobal.h17
-rw-r--r--include/acpi/achware.h14
-rw-r--r--include/acpi/aclocal.h47
-rw-r--r--include/acpi/acpixf.h21
-rw-r--r--include/acpi/acresrc.h6
-rw-r--r--include/acpi/acutils.h2
21 files changed, 538 insertions, 777 deletions
diff --git a/drivers/acpi/events/evevent.c b/drivers/acpi/events/evevent.c
index 27092988918c..d0614cb9e945 100644
--- a/drivers/acpi/events/evevent.c
+++ b/drivers/acpi/events/evevent.c
@@ -110,7 +110,7 @@ acpi_ev_initialize (
*
* 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 (
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 */
status = acpi_ev_init_global_lock_handler ();
diff --git a/drivers/acpi/events/evgpe.c b/drivers/acpi/events/evgpe.c
index bf8ba0e85b1b..172c00aaa01b 100644
--- a/drivers/acpi/events/evgpe.c
+++ b/drivers/acpi/events/evgpe.c
@@ -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
+ * RETURN: None.
*
- * DESCRIPTION: Initialize the GPE data structures
+ * DESCRIPTION: Returns the event_info struct
+ * associated with this GPE.
*
- ******************************************************************************/
-
-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
- *
- * DESCRIPTION: Called from acpi_walk_namespace. Expects each object to be a
- * control method under the _GPE portion of the namespace.
- * 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:
- * "_Lnn" or "_Enn"
- * Where:
- * L - means that the GPE is level triggered
- * E - means that the GPE is edge triggered
- * nn - is the GPE number [in HEX]
+ * TBD: this function will go away when full support of GPE block devices
+ * is implemented!
*
******************************************************************************/
-static acpi_status
-acpi_ev_save_method_info (
- acpi_handle obj_handle,
- u32 level,
- void *obj_desc,
- void **return_value)
+struct acpi_gpe_event_info *
+acpi_ev_get_gpe_event_info (
+ u32 gpe_number)
{
- u32 gpe_number;
- 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,
- &((struct acpi_namespace_node *) obj_handle)->name.integer);
- name[ACPI_NAME_SIZE] = 0;
-
- /*
- * Edge/Level determination is based on the 2nd character of the method name
- */
- 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);
- }
+ struct acpi_gpe_block_info *gpe_block;
- /* Convert the last two characters of the name to the GPE Number */
- gpe_number = ACPI_STRTOUL (&name[2], NULL, 16);
- if (gpe_number == ACPI_UINT32_MAX) {
- /* Conversion failed; invalid method, just ignore it */
+ /* Examine GPE Block 0 */
- 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);
+ gpe_block = acpi_gbl_gpe_block_list_head;
+ if (!gpe_block) {
+ return (NULL);
}
- /* Get GPE index and ensure that we have a valid GPE number */
-
- 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 number associated with method is not valid %s\n",
- name));
- return (AE_OK);
+ if ((gpe_number >= gpe_block->block_base_number) &&
+ (gpe_number < gpe_block->block_base_number + (gpe_block->register_count * 8))) {
+ return (&gpe_block->event_info[gpe_number - gpe_block->block_base_number]);
}
- /*
- * Now we can add this information to the gpe_number_info block
- * for use during dispatch of this GPE.
- */
- gpe_number_info->type = type;
- gpe_number_info->method_node = (struct acpi_namespace_node *) obj_handle;
+ /* Examine GPE Block 1 */
- /*
- * Enable the GPE (SCIs should be disabled at this point)
- */
- status = acpi_hw_enable_gpe (gpe_number);
- if (ACPI_FAILURE (status)) {
- return (status);
+ gpe_block = gpe_block->next;
+ if (!gpe_block) {
+ return (NULL);
}
- ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "Registered GPE method %s as GPE number %2.2X\n",
- 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);
+ if ((gpe_number >= gpe_block->block_base_number) &&
+ (gpe_number < gpe_block->block_base_number + (gpe_block->register_count * 8))) {
+ return (&gpe_block->event_info[gpe_number - gpe_block->block_base_number]);
}
- /* 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);
+ return (NULL);
}
-
/*******************************************************************************
*
* FUNCTION: acpi_ev_gpe_detect
@@ -470,62 +123,74 @@ acpi_ev_gpe_detect (void)
struct acpi_gpe_register_info *gpe_register_info;
u32 in_value;
acpi_status status;
+ struct acpi_gpe_block_info *gpe_block;
ACPI_FUNCTION_NAME ("ev_gpe_detect");
- /*
- * Read all of the 8-bit GPE status and enable registers
- * in both of the register blocks, saving all of it.
- * Find all currently active GP events.
- */
- for (i = 0; i < acpi_gbl_gpe_register_count; i++) {
- gpe_register_info = &acpi_gbl_gpe_register_info[i];
+ /* Examine all GPE blocks attached to this interrupt level */
- 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;
- if (ACPI_FAILURE (status)) {
- return (ACPI_INTERRUPT_NOT_HANDLED);
- }
+ gpe_block = acpi_gbl_gpe_block_list_head;
+ while (gpe_block) {
+ /*
+ * Read all of the 8-bit GPE status and enable registers
+ * in this GPE block, saving all of them.
+ * Find all currently active GP events.
+ */
+ for (i = 0; i < gpe_block->register_count; i++) {
+ /* Get the next status/enable pair */
- 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;
- if (ACPI_FAILURE (status)) {
- return (ACPI_INTERRUPT_NOT_HANDLED);
- }
+ 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);
+ gpe_register_info->status = (u8) in_value;
+ if (ACPI_FAILURE (status)) {
+ return (ACPI_INTERRUPT_NOT_HANDLED);
+ }
- ACPI_DEBUG_PRINT ((ACPI_DB_INTERRUPTS,
- "GPE block at %8.8X%8.8X - Values: Enable %02X Status %02X\n",
- ACPI_HIDWORD (gpe_register_info->enable_address.address),
- ACPI_LODWORD (gpe_register_info->enable_address.address),
- gpe_register_info->enable,
- gpe_register_info->status));
+ 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;
+ if (ACPI_FAILURE (status)) {
+ return (ACPI_INTERRUPT_NOT_HANDLED);
+ }
- /* First check if there is anything active at all in this register */
+ ACPI_DEBUG_PRINT ((ACPI_DB_INTERRUPTS,
+ "GPE block at %8.8X%8.8X - Values: Enable %02X Status %02X\n",
+ ACPI_HIDWORD (gpe_register_info->enable_address.address),
+ ACPI_LODWORD (gpe_register_info->enable_address.address),
+ gpe_register_info->enable,
+ gpe_register_info->status));
- enabled_status_byte = (u8) (gpe_register_info->status &
- gpe_register_info->enable);
- if (!enabled_status_byte) {
- /* No active GPEs in this register, move on */
+ /* First check if there is anything active at all in this register */
- continue;
- }
+ enabled_status_byte = (u8) (gpe_register_info->status &
+ gpe_register_info->enable);
+ if (!enabled_status_byte) {
+ /* No active GPEs in this register, move on */
- /* Now look at the individual GPEs in this byte register */
+ continue;
+ }
+
+ /* Now look at the individual GPEs in this byte register */
- for (j = 0, bit_mask = 1; j < ACPI_GPE_REGISTER_WIDTH; j++, bit_mask <<= 1) {
- /* Examine one GPE bit */
+ for (j = 0, bit_mask = 1; j < ACPI_GPE_REGISTER_WIDTH; j++, bit_mask <<= 1) {
+ /* Examine one GPE bit */
- if (enabled_status_byte & bit_mask) {
- /*
- * Found an active GPE. Dispatch the event to a handler
- * or method.
- */
- int_status |= acpi_ev_gpe_dispatch (
- gpe_register_info->base_gpe_number + j);
+ if (enabled_status_byte & bit_mask) {
+ /*
+ * Found an active GPE. Dispatch the event to a handler
+ * or method.
+ */
+ int_status |= acpi_ev_gpe_dispatch (
+ &gpe_block->event_info[(i * ACPI_GPE_REGISTER_WIDTH) +j]);
+ }
}
}
+
+ gpe_block = gpe_block->next;
}
return (int_status);
@@ -536,7 +201,7 @@ acpi_ev_gpe_detect (void)
*
* 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
*
@@ -552,20 +217,14 @@ static void ACPI_SYSTEM_XFACE
acpi_ev_asynch_execute_gpe_method (
void *context)
{
- u32 gpe_number = (u32) ACPI_TO_INTEGER (context);
- u32 gpe_number_index;
- struct acpi_gpe_number_info gpe_number_info;
+ struct acpi_gpe_event_info *gpe_event_info = (void *) context;
+ u32 gpe_number = 0;
acpi_status status;
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
* info to prevent a race condition with remove_handler.
@@ -575,40 +234,38 @@ acpi_ev_asynch_execute_gpe_method (
return_VOID;
}
- gpe_number_info = acpi_gbl_gpe_number_info [gpe_number_index];
status = acpi_ut_release_mutex (ACPI_MTX_EVENTS);
if (ACPI_FAILURE (status)) {
return_VOID;
}
- if (gpe_number_info.method_node) {
+ if (gpe_event_info->method_node) {
/*
* Invoke the GPE Method (_Lxx, _Exx):
* (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)) {
ACPI_REPORT_ERROR (("%s while evaluating method [%4.4s] for GPE[%2.2X]\n",
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
* the event.
*/
- status = acpi_hw_clear_gpe (gpe_number);
+ status = acpi_hw_clear_gpe (gpe_event_info);
if (ACPI_FAILURE (status)) {
return_VOID;
}
}
- /*
- * Enable the GPE.
- */
- (void) acpi_hw_enable_gpe (gpe_number);
+ /* Enable this GPE */
+
+ (void) acpi_hw_enable_gpe (gpe_event_info);
return_VOID;
}
@@ -617,7 +274,7 @@ acpi_ev_asynch_execute_gpe_method (
*
* 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
*
@@ -629,9 +286,9 @@ acpi_ev_asynch_execute_gpe_method (
u32
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;
@@ -639,23 +296,14 @@ acpi_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
* level-triggered events are cleared after the GPE is serviced.
*/
- if (gpe_number_info->type & ACPI_EVENT_EDGE_TRIGGERED) {
- status = acpi_hw_clear_gpe (gpe_number);
+ if (gpe_event_info->type & ACPI_EVENT_EDGE_TRIGGERED) {
+ status = acpi_hw_clear_gpe (gpe_event_info);
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);
}
}
@@ -667,19 +315,20 @@ 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_number_info->handler) {
+ if (gpe_event_info->handler) {
/* 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
* chance to run.
*/
- status = acpi_hw_disable_gpe (gpe_number);
+ status = acpi_hw_disable_gpe (gpe_event_info);
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);
}
@@ -688,22 +337,27 @@ acpi_ev_gpe_dispatch (
*/
if (ACPI_FAILURE (acpi_os_queue_for_execution (OSD_PRIORITY_GPE,
acpi_ev_asynch_execute_gpe_method,
- ACPI_TO_POINTER (gpe_number)))) {
- ACPI_REPORT_ERROR (("acpi_ev_gpe_dispatch: Unable to queue handler for GPE[%2.2X], event is disabled\n", 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));
}
}
else {
/* 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
* 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)) {
- 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);
}
}
@@ -711,10 +365,11 @@ acpi_ev_gpe_dispatch (
/*
* It is now safe to clear level-triggered evnets.
*/
- if (gpe_number_info->type & ACPI_EVENT_LEVEL_TRIGGERED) {
- status = acpi_hw_clear_gpe (gpe_number);
+ if (gpe_event_info->type & ACPI_EVENT_LEVEL_TRIGGERED) {
+ status = acpi_hw_clear_gpe (gpe_event_info);
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);
}
}
diff --git a/drivers/acpi/events/evmisc.c b/drivers/acpi/events/evmisc.c
index d268a3589e2f..c855939c865e 100644
--- a/drivers/acpi/events/evmisc.c
+++ b/drivers/acpi/events/evmisc.c
@@ -86,84 +86,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
*
* PARAMETERS:
@@ -601,6 +523,9 @@ acpi_ev_terminate (void)
{
acpi_native_uint i;
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");
@@ -625,13 +550,19 @@ acpi_ev_terminate (void)
/*
* Disable all GPEs
*/
- for (i = 0; i < acpi_gbl_gpe_number_max; i++) {
- if (acpi_ev_get_gpe_number_index ((u32)i) != ACPI_GPE_INVALID) {
- status = acpi_hw_disable_gpe((u32) i);
+ gpe_block = acpi_gbl_gpe_block_list_head;
+ while (gpe_block) {
+ 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)) {
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)
}
/*
- * Free global tables, etc.
+ * Free global GPE blocks and related info structures
*/
- if (acpi_gbl_gpe_register_info) {
- ACPI_MEM_FREE (acpi_gbl_gpe_register_info);
- acpi_gbl_gpe_register_info = NULL;
- }
-
- if (acpi_gbl_gpe_number_info) {
- ACPI_MEM_FREE (acpi_gbl_gpe_number_info);
- acpi_gbl_gpe_number_info = NULL;
- }
-
- if (acpi_gbl_gpe_number_to_index) {
- ACPI_MEM_FREE (acpi_gbl_gpe_number_to_index);
- acpi_gbl_gpe_number_to_index = NULL;
+ gpe_block = acpi_gbl_gpe_block_list_head;
+ while (gpe_block) {
+ next_gpe_block = gpe_block->next;
+ ACPI_MEM_FREE (gpe_block->event_info);
+ ACPI_MEM_FREE (gpe_block->register_info);
+ ACPI_MEM_FREE (gpe_block);
+
+ gpe_block = next_gpe_block;
}
return_VOID;
diff --git a/drivers/acpi/events/evsci.c b/drivers/acpi/events/evsci.c
index 6ff37930215a..e16fef750644 100644
--- a/drivers/acpi/events/evsci.c
+++ b/drivers/acpi/events/evsci.c
@@ -69,38 +69,24 @@ acpi_ev_sci_handler (
void *context)
{
u32 interrupt_handled = ACPI_INTERRUPT_NOT_HANDLED;
- u32 value;
- acpi_status status;
ACPI_FUNCTION_TRACE("ev_sci_handler");
/*
- * Make sure that ACPI is enabled by checking SCI_EN. Note that we are
- * required to treat the SCI interrupt as sharable, level, active low.
+ * We are guaranteed by the ACPI CA initialization/shutdown code that
+ * 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:
- * -------------
* Check for and dispatch any Fixed acpi_events that have occurred
*/
interrupt_handled |= acpi_ev_fixed_event_detect ();
/*
* GPEs:
- * -----
* Check for and dispatch any GPEs that have occurred
*/
interrupt_handled |= acpi_ev_gpe_detect ();
diff --git a/drivers/acpi/events/evxface.c b/drivers/acpi/events/evxface.c
index c85806d1bb4c..b6fed42b1f77 100644
--- a/drivers/acpi/events/evxface.c
+++ b/drivers/acpi/events/evxface.c
@@ -492,7 +492,7 @@ acpi_install_gpe_handler (
void *context)
{
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");
@@ -506,8 +506,8 @@ acpi_install_gpe_handler (
/* Ensure that we have a valid GPE number */
- gpe_number_info = acpi_ev_get_gpe_number_info (gpe_number);
- if (!gpe_number_info) {
+ gpe_event_info = acpi_ev_get_gpe_event_info (gpe_number);
+ if (!gpe_event_info) {
return_ACPI_STATUS (AE_BAD_PARAMETER);
}
@@ -518,25 +518,25 @@ acpi_install_gpe_handler (
/* Make sure that there isn't a handler there already */
- if (gpe_number_info->handler) {
+ if (gpe_event_info->handler) {
status = AE_ALREADY_EXISTS;
goto cleanup;
}
/* Install the handler */
- gpe_number_info->handler = handler;
- gpe_number_info->context = context;
- gpe_number_info->type = (u8) type;
+ gpe_event_info->handler = handler;
+ gpe_event_info->context = context;
+ gpe_event_info->type = (u8) type;
/* 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)) {
goto cleanup;
}
- status = acpi_hw_enable_gpe (gpe_number);
+ status = acpi_hw_enable_gpe (gpe_event_info);
cleanup:
@@ -564,7 +564,7 @@ acpi_remove_gpe_handler (
acpi_gpe_handler handler)
{
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");
@@ -578,14 +578,14 @@ acpi_remove_gpe_handler (
/* Ensure that we have a valid GPE number */
- gpe_number_info = acpi_ev_get_gpe_number_info (gpe_number);
- if (!gpe_number_info) {
+ gpe_event_info = acpi_ev_get_gpe_event_info (gpe_number);
+ if (!gpe_event_info) {
return_ACPI_STATUS (AE_BAD_PARAMETER);
}
/* 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)) {
return_ACPI_STATUS (status);
}
@@ -597,16 +597,16 @@ acpi_remove_gpe_handler (
/* Make sure that the installed handler is the same */
- if (gpe_number_info->handler != handler) {
- (void) acpi_hw_enable_gpe (gpe_number);
+ if (gpe_event_info->handler != handler) {
+ (void) acpi_hw_enable_gpe (gpe_event_info);
status = AE_BAD_PARAMETER;
goto cleanup;
}
/* Remove the handler */
- gpe_number_info->handler = NULL;
- gpe_number_info->context = NULL;
+ gpe_event_info->handler = NULL;
+ gpe_event_info->context = NULL;
cleanup:
diff --git a/drivers/acpi/events/evxfevnt.c b/drivers/acpi/events/evxfevnt.c
index 7d1e275d64c1..7e42ba9fd538 100644
--- a/drivers/acpi/events/evxfevnt.c
+++ b/drivers/acpi/events/evxfevnt.c
@@ -163,6 +163,7 @@ acpi_enable_event (
{
acpi_status status = AE_OK;
u32 value;
+ struct acpi_gpe_event_info *gpe_event_info;
ACPI_FUNCTION_TRACE ("acpi_enable_event");
@@ -209,19 +210,20 @@ acpi_enable_event (
/* 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);
}
/* Enable the requested GPE number */
- status = acpi_hw_enable_gpe (event);
+ status = acpi_hw_enable_gpe (gpe_event_info);
if (ACPI_FAILURE (status)) {
return_ACPI_STATUS (status);
}
if (flags & ACPI_EVENT_WAKE_ENABLE) {
- acpi_hw_enable_gpe_for_wakeup (event);
+ acpi_hw_enable_gpe_for_wakeup (gpe_event_info);
}
break;
@@ -257,6 +259,7 @@ acpi_disable_event (
{
acpi_status status = AE_OK;
u32 value;
+ struct acpi_gpe_event_info *gpe_event_info;
ACPI_FUNCTION_TRACE ("acpi_disable_event");
@@ -301,7 +304,8 @@ acpi_disable_event (
/* 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);
}
@@ -311,10 +315,10 @@ acpi_disable_event (
*/
if (flags & ACPI_EVENT_WAKE_DISABLE) {
- acpi_hw_disable_gpe_for_wakeup (event);
+ acpi_hw_disable_gpe_for_wakeup (gpe_event_info);
}
else {
- status = acpi_hw_disable_gpe (event);
+ status = acpi_hw_disable_gpe (gpe_event_info);
}
break;
@@ -346,6 +350,7 @@ acpi_clear_event (
u32 type)
{
acpi_status status = AE_OK;
+ struct acpi_gpe_event_info *gpe_event_info;
ACPI_FUNCTION_TRACE ("acpi_clear_event");
@@ -375,11 +380,12 @@ acpi_clear_event (
/* 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);
}
- status = acpi_hw_clear_gpe (event);
+ status = acpi_hw_clear_gpe (gpe_event_info);
break;
@@ -415,6 +421,7 @@ acpi_get_event_status (
acpi_event_status *event_status)
{
acpi_status status = AE_OK;
+ struct acpi_gpe_event_info *gpe_event_info;
ACPI_FUNCTION_TRACE ("acpi_get_event_status");
@@ -447,7 +454,8 @@ acpi_get_event_status (
/* 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);
}
@@ -464,3 +472,4 @@ acpi_get_event_status (
return_ACPI_STATUS (status);
}
+
diff --git a/drivers/acpi/hardware/hwgpe.c b/drivers/acpi/hardware/hwgpe.c
index 3d0d9c8c6c5a..c18601e117e6 100644
--- a/drivers/acpi/hardware/hwgpe.c
+++ b/drivers/acpi/hardware/hwgpe.c
@@ -51,26 +51,6 @@
/******************************************************************************
*
- * 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
*
* PARAMETERS: gpe_number - The GPE
@@ -83,37 +63,29 @@ acpi_hw_get_gpe_bit_mask (
acpi_status
acpi_hw_enable_gpe (
- u32 gpe_number)
+ struct acpi_gpe_event_info *gpe_event_info)
{
u32 in_byte;
acpi_status status;
- struct acpi_gpe_register_info *gpe_register_info;
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
* to enable the GPE, and write out the new register.
*/
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)) {
return (status);
}
/* Write with the new GPE bit enabled */
- status = acpi_hw_low_level_write (8, (in_byte | acpi_hw_get_gpe_bit_mask (gpe_number)),
- &gpe_register_info->enable_address, 0);
+ status = acpi_hw_low_level_write (8, (in_byte | gpe_event_info->bit_mask),
+ &gpe_event_info->register_info->enable_address, 0);
return (status);
}
@@ -134,7 +106,7 @@ acpi_hw_enable_gpe (
void
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;
@@ -144,7 +116,7 @@ acpi_hw_enable_gpe_for_wakeup (
/* 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) {
return;
}
@@ -152,7 +124,7 @@ acpi_hw_enable_gpe_for_wakeup (
/*
* 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 (
acpi_status
acpi_hw_disable_gpe (
- u32 gpe_number)
+ struct acpi_gpe_event_info *gpe_event_info)
{
u32 in_byte;
acpi_status status;
@@ -182,7 +154,7 @@ acpi_hw_disable_gpe (
/* 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) {
return (AE_BAD_PARAMETER);
}
@@ -199,13 +171,13 @@ acpi_hw_disable_gpe (
/* 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);
if (ACPI_FAILURE (status)) {
return (status);
}
- acpi_hw_disable_gpe_for_wakeup(gpe_number);
+ acpi_hw_disable_gpe_for_wakeup (gpe_event_info);
return (AE_OK);
}
@@ -225,7 +197,7 @@ acpi_hw_disable_gpe (
void
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;
@@ -235,7 +207,7 @@ acpi_hw_disable_gpe_for_wakeup (
/* 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) {
return;
}
@@ -243,7 +215,7 @@ acpi_hw_disable_gpe_for_wakeup (
/*
* 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 (
acpi_status
acpi_hw_clear_gpe (
- u32 gpe_number)
+ struct acpi_gpe_event_info *gpe_event_info)
{
acpi_status status;
- struct acpi_gpe_register_info *gpe_register_info;
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
* clear this GPE.
*/
- status = acpi_hw_low_level_write (8, acpi_hw_get_gpe_bit_mask (gpe_number),
- &gpe_register_info->status_address, 0);
+ status = acpi_hw_low_level_write (8, gpe_event_info->bit_mask,
+ &gpe_event_info->register_info->status_address, 0);
return (status);
}
@@ -308,6 +272,7 @@ acpi_hw_get_gpe_status (
u32 in_byte;
u8 bit_mask;
struct acpi_gpe_register_info *gpe_register_info;
+ struct acpi_gpe_event_info *gpe_event_info;
acpi_status status;
acpi_event_status local_event_status = 0;
@@ -319,16 +284,18 @@ acpi_hw_get_gpe_status (
return (AE_BAD_PARAMETER);
}
- /* Get the info block for the entire GPE register */
-
- gpe_register_info = acpi_ev_get_gpe_register_info (gpe_number);
- if (!gpe_register_info) {
+ gpe_event_info = acpi_ev_get_gpe_event_info (gpe_number);
+ if (!gpe_event_info) {
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 */
- bit_mask = acpi_hw_get_gpe_bit_mask (gpe_number);
+ bit_mask = gpe_event_info->bit_mask;
/* GPE Enabled? */
@@ -375,7 +342,7 @@ acpi_hw_get_gpe_status (
*
* DESCRIPTION: Disable all non-wakeup GPEs
* 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
* re-enabled.
*
@@ -389,40 +356,49 @@ acpi_hw_disable_non_wakeup_gpes (
struct acpi_gpe_register_info *gpe_register_info;
u32 in_value;
acpi_status status;
+ struct acpi_gpe_block_info *gpe_block;
ACPI_FUNCTION_ENTRY ();
- for (i = 0; i < acpi_gbl_gpe_register_count; i++) {
- /* Get the info block for the entire GPE register */
+ gpe_block = acpi_gbl_gpe_block_list_head;
+ 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) {
return (AE_BAD_PARAMETER);
}
- /*
- * Read the enabled status of all GPEs. We
- * will be using it to restore all the GPEs later.
- */
- status = acpi_hw_low_level_read (8, &in_value,
- &gpe_register_info->enable_address, 0);
- if (ACPI_FAILURE (status)) {
- return (status);
+ for (i = 0; i < gpe_block->register_count; i++) {
+ /*
+ * Read the enabled status of all GPEs. We
+ * will be using it to restore all the GPEs later.
+ */
+ status = acpi_hw_low_level_read (8, &in_value,
+ &gpe_register_info->enable_address, 0);
+ if (ACPI_FAILURE (status)) {
+ return (status);
+ }
+
+ gpe_register_info->enable = (u8) in_value;
+
+ /*
+ * Disable all GPEs except wakeup GPEs.
+ */
+ status = acpi_hw_low_level_write (8, gpe_register_info->wake_enable,
+ &gpe_register_info->enable_address, 0);
+ if (ACPI_FAILURE (status)) {
+ return (status);
+ }
+
+ gpe_register_info++;
}
- gpe_register_info->enable = (u8) in_value;
-
- /*
- * Disable all GPEs except wakeup GPEs.
- */
- status = acpi_hw_low_level_write (8, gpe_register_info->wake_enable,
- &gpe_register_info->enable_address, 0);
- if (ACPI_FAILURE (status)) {
- return (status);
- }
+ gpe_block = gpe_block->next;
}
+
return (AE_OK);
}
@@ -446,28 +422,37 @@ acpi_hw_enable_non_wakeup_gpes (
u32 i;
struct acpi_gpe_register_info *gpe_register_info;
acpi_status status;
+ struct acpi_gpe_block_info *gpe_block;
ACPI_FUNCTION_ENTRY ();
- for (i = 0; i < acpi_gbl_gpe_register_count; i++) {
- /* Get the info block for the entire GPE register */
+ gpe_block = acpi_gbl_gpe_block_list_head;
+ 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) {
return (AE_BAD_PARAMETER);
}
- /*
- * We previously stored the enabled status of all GPEs.
- * Blast them back in.
- */
- status = acpi_hw_low_level_write (8, gpe_register_info->enable,
- &gpe_register_info->enable_address, 0);
- if (ACPI_FAILURE (status)) {
- return (status);
+ for (i = 0; i < gpe_block->register_count; i++) {
+ /*
+ * We previously stored the enabled status of all GPEs.
+ * Blast them back in.
+ */
+ status = acpi_hw_low_level_write (8, gpe_register_info->enable,
+ &gpe_register_info->enable_address, 0);
+ if (ACPI_FAILURE (status)) {
+ return (status);
+ }
+
+ gpe_register_info++;
}
+
+ gpe_block = gpe_block->next;
}
+
return (AE_OK);
}
diff --git a/drivers/acpi/hardware/hwregs.c b/drivers/acpi/hardware/hwregs.c
index 00d844228185..046ad4014d51 100644
--- a/drivers/acpi/hardware/hwregs.c
+++ b/drivers/acpi/hardware/hwregs.c
@@ -67,8 +67,8 @@ acpi_status
acpi_hw_clear_acpi_status (void)
{
acpi_native_uint i;
- acpi_native_uint gpe_block;
acpi_status status;
+ struct acpi_gpe_block_info *gpe_block;
ACPI_FUNCTION_TRACE ("hw_clear_acpi_status");
@@ -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++) {
- for (i = 0; i < acpi_gbl_gpe_block_info[gpe_block].register_count; i++) {
+ gpe_block = acpi_gbl_gpe_block_list_head;
+ while (gpe_block) {
+ for (i = 0; i < gpe_block->register_count; i++) {
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)) {
goto unlock_and_exit;
}
}
+
+ gpe_block = gpe_block->next;
}
unlock_and_exit:
diff --git a/drivers/acpi/resources/rsutils.c b/drivers/acpi/resources/rsutils.c
index 6480adf82402..64e54840d2da 100644
--- a/drivers/acpi/resources/rsutils.c
+++ b/drivers/acpi/resources/rsutils.c
@@ -214,6 +214,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
*
* PARAMETERS: Handle - a handle to the containing object
diff --git a/drivers/acpi/resources/rsxface.c b/drivers/acpi/resources/rsxface.c
index ca3aee318f2b..6167ddd5b012 100644
--- a/drivers/acpi/resources/rsxface.c
+++ b/drivers/acpi/resources/rsxface.c
@@ -212,6 +212,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
*
* PARAMETERS: device_handle - a handle to the device object for the
@@ -252,3 +336,64 @@ acpi_set_current_resources (
status = acpi_rs_set_srs_method_data (device_handle, in_buffer);
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);
+}
diff --git a/drivers/acpi/tables/tbconvrt.c b/drivers/acpi/tables/tbconvrt.c
index b81e1178cc47..ae9f5977f0d0 100644
--- a/drivers/acpi/tables/tbconvrt.c
+++ b/drivers/acpi/tables/tbconvrt.c
@@ -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->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->xgpe0_blk, local_fadt->gpe0_blk_len, 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->xgpe0_blk, 0, local_fadt->V1_gpe0_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 (
if (!(local_fadt->xgpe0_blk.address)) {
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)) {
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
diff --git a/drivers/acpi/utilities/utcopy.c b/drivers/acpi/utilities/utcopy.c
index 870da95755dc..441920d56f6a 100644
--- a/drivers/acpi/utilities/utcopy.c
+++ b/drivers/acpi/utilities/utcopy.c
@@ -645,11 +645,11 @@ acpi_ut_copy_simple_object (
/*
* 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,
* the actual pointer was already copied above)
*/
- if ((source_desc->buffer.length) &&
+ if ((source_desc->buffer.pointer) &&
(!(source_desc->common.flags & AOPOBJ_STATIC_POINTER))) {
dest_desc->buffer.pointer = ACPI_MEM_ALLOCATE (source_desc->buffer.length);
if (!dest_desc->buffer.pointer) {
@@ -665,11 +665,11 @@ acpi_ut_copy_simple_object (
/*
* 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,
* the actual pointer was already copied above)
*/
- if ((source_desc->string.length) &&
+ if ((source_desc->string.pointer) &&
(!(source_desc->common.flags & AOPOBJ_STATIC_POINTER))) {
dest_desc->string.pointer = ACPI_MEM_ALLOCATE ((acpi_size) source_desc->string.length + 1);
if (!dest_desc->string.pointer) {
diff --git a/drivers/acpi/utilities/utglobal.c b/drivers/acpi/utilities/utglobal.c
index 205081ff1670..e5eeb6fa1411 100644
--- a/drivers/acpi/utilities/utglobal.c
+++ b/drivers/acpi/utilities/utglobal.c
@@ -729,6 +729,10 @@ acpi_ut_init_globals (
acpi_gbl_acpi_mutex_info[i].use_count = 0;
}
+ /* GPE support */
+
+ acpi_gbl_gpe_block_list_head = NULL;
+
/* Global notify handlers */
acpi_gbl_sys_notify.handler = NULL;
@@ -766,8 +770,6 @@ acpi_ut_init_globals (
/* Hardware oriented */
- acpi_gbl_gpe_register_info = NULL;
- acpi_gbl_gpe_number_info = NULL;
acpi_gbl_events_initialized = FALSE;
/* Namespace */
diff --git a/include/acpi/acdebug.h b/include/acpi/acdebug.h
index cd2b474ec837..ae75649c348b 100644
--- a/include/acpi/acdebug.h
+++ b/include/acpi/acdebug.h
@@ -177,6 +177,9 @@ acpi_db_display_resources (
char *object_arg);
void
+acpi_db_display_gpes (void);
+
+void
acpi_db_check_integrity (
void);
diff --git a/include/acpi/acevents.h b/include/acpi/acevents.h
index 1a4b232179e8..0301e19427b8 100644
--- a/include/acpi/acevents.h
+++ b/include/acpi/acevents.h
@@ -91,14 +91,6 @@ acpi_status
acpi_ev_init_global_lock_handler (
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
acpi_ev_get_gpe_number_index (
u32 gpe_number);
@@ -117,17 +109,17 @@ acpi_ev_notify_dispatch (
* Evgpe - GPE handling and dispatch
*/
-acpi_status
-acpi_ev_gpe_initialize (
- void);
+struct acpi_gpe_event_info *
+acpi_ev_get_gpe_event_info (
+ u32 gpe_number);
acpi_status
-acpi_ev_init_gpe_control_methods (
+acpi_ev_gpe_initialize (
void);
u32
acpi_ev_gpe_dispatch (
- u32 gpe_number);
+ struct acpi_gpe_event_info *gpe_event_info);
u32
acpi_ev_gpe_detect (
diff --git a/include/acpi/acglobal.h b/include/acpi/acglobal.h
index b6713c925987..8a6978e75505 100644
--- a/include/acpi/acglobal.h
+++ b/include/acpi/acglobal.h
@@ -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];
ACPI_EXTERN struct acpi_fixed_event_handler acpi_gbl_fixed_event_handlers[ACPI_NUM_FIXED_EVENTS];
-
-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;
+ACPI_EXTERN struct acpi_gpe_block_info *acpi_gbl_gpe_block_list_head;
/*****************************************************************************
diff --git a/include/acpi/achware.h b/include/acpi/achware.h
index af0240db7963..de4a84220ed3 100644
--- a/include/acpi/achware.h
+++ b/include/acpi/achware.h
@@ -115,29 +115,25 @@ acpi_hw_clear_acpi_status (
/* GPE support */
-u8
-acpi_hw_get_gpe_bit_mask (
- u32 gpe_number);
-
acpi_status
acpi_hw_enable_gpe (
- u32 gpe_number);
+ struct acpi_gpe_event_info *gpe_event_info);
void
acpi_hw_enable_gpe_for_wakeup (
- u32 gpe_number);
+ struct acpi_gpe_event_info *gpe_event_info);
acpi_status
acpi_hw_disable_gpe (
- u32 gpe_number);
+ struct acpi_gpe_event_info *gpe_event_info);
void
acpi_hw_disable_gpe_for_wakeup (
- u32 gpe_number);
+ struct acpi_gpe_event_info *gpe_event_info);
acpi_status
acpi_hw_clear_gpe (
- u32 gpe_number);
+ struct acpi_gpe_event_info *gpe_event_info);
acpi_status
acpi_hw_get_gpe_status (
diff --git a/include/acpi/aclocal.h b/include/acpi/aclocal.h
index 2ab9bee98a31..47c3f4a1de2d 100644
--- a/include/acpi/aclocal.h
+++ b/include/acpi/aclocal.h
@@ -308,25 +308,28 @@ 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;
- u16 register_count;
- u8 block_base_number;
+ struct acpi_namespace_node *method_node; /* Method node for this GPE level */
+ acpi_gpe_handler handler; /* Address of handler, if any */
+ 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 */
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 base_gpe_number; /* Base GPE number for this register */
+ 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 base_gpe_number; /* Base GPE number for this register */
};
@@ -334,23 +337,21 @@ struct acpi_gpe_register_info
#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 */
- acpi_gpe_handler handler; /* Address of handler, if any */
- void *context; /* Context to be passed to handler */
- u8 type; /* Level or Edge */
- u8 bit_mask;
+ struct acpi_gpe_block_info *previous;
+ struct acpi_gpe_block_info *next;
+ struct acpi_gpe_block_info *next_on_interrupt;
+ struct acpi_gpe_register_info *register_info;
+ 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 */
struct acpi_fixed_event_handler
diff --git a/include/acpi/acpixf.h b/include/acpi/acpixf.h
index 581cf961fb35..a1ff7679f6e7 100644
--- a/include/acpi/acpixf.h
+++ b/include/acpi/acpixf.h
@@ -339,6 +339,12 @@ acpi_get_event_status (
* Resource interfaces
*/
+typedef
+acpi_status (*ACPI_WALK_RESOURCE_CALLBACK) (
+ struct acpi_resource *resource,
+ void *context);
+
+
acpi_status
acpi_get_current_resources(
acpi_handle device_handle,
@@ -350,6 +356,13 @@ acpi_get_possible_resources(
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_set_current_resources (
acpi_handle device_handle,
struct acpi_buffer *in_buffer);
@@ -359,6 +372,10 @@ acpi_get_irq_routing_table (
acpi_handle bus_device_handle,
struct acpi_buffer *ret_buffer);
+acpi_status
+acpi_resource_to_address64 (
+ struct acpi_resource *resource,
+ struct acpi_resource_address64 *out);
/*
* Hardware (ACPI device) interfaces
@@ -399,6 +416,10 @@ acpi_enter_sleep_state (
u8 sleep_state);
acpi_status
+acpi_enter_sleep_state_s4bios (
+ void);
+
+acpi_status
acpi_leave_sleep_state (
u8 sleep_state);
diff --git a/include/acpi/acresrc.h b/include/acpi/acresrc.h
index fa2e298d6c0a..814c77078178 100644
--- a/include/acpi/acresrc.h
+++ b/include/acpi/acresrc.h
@@ -66,6 +66,12 @@ acpi_rs_get_prs_method_data (
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_rs_set_srs_method_data (
acpi_handle handle,
struct acpi_buffer *ret_buffer);
diff --git a/include/acpi/acutils.h b/include/acpi/acutils.h
index 114793ddf698..576ad04ca41f 100644
--- a/include/acpi/acutils.h
+++ b/include/acpi/acutils.h
@@ -463,6 +463,8 @@ acpi_ut_delete_internal_object_list (
#define METHOD_NAME__SEG "_SEG"
#define METHOD_NAME__BBN "_BBN"
#define METHOD_NAME__PRT "_PRT"
+#define METHOD_NAME__CRS "_CRS"
+#define METHOD_NAME__PRS "_PRS"
acpi_status