diff options
| -rw-r--r-- | drivers/acpi/events/evevent.c | 12 | ||||
| -rw-r--r-- | drivers/acpi/events/evgpe.c | 577 | ||||
| -rw-r--r-- | drivers/acpi/events/evmisc.c | 116 | ||||
| -rw-r--r-- | drivers/acpi/events/evsci.c | 18 | ||||
| -rw-r--r-- | drivers/acpi/events/evxface.c | 34 | ||||
| -rw-r--r-- | drivers/acpi/events/evxfevnt.c | 27 | ||||
| -rw-r--r-- | drivers/acpi/hardware/hwgpe.c | 167 | ||||
| -rw-r--r-- | drivers/acpi/hardware/hwregs.c | 13 | ||||
| -rw-r--r-- | drivers/acpi/resources/rsutils.c | 54 | ||||
| -rw-r--r-- | drivers/acpi/resources/rsxface.c | 145 | ||||
| -rw-r--r-- | drivers/acpi/tables/tbconvrt.c | 10 | ||||
| -rw-r--r-- | drivers/acpi/utilities/utcopy.c | 8 | ||||
| -rw-r--r-- | drivers/acpi/utilities/utglobal.c | 6 | ||||
| -rw-r--r-- | include/acpi/acdebug.h | 3 | ||||
| -rw-r--r-- | include/acpi/acevents.h | 18 | ||||
| -rw-r--r-- | include/acpi/acglobal.h | 17 | ||||
| -rw-r--r-- | include/acpi/achware.h | 14 | ||||
| -rw-r--r-- | include/acpi/aclocal.h | 47 | ||||
| -rw-r--r-- | include/acpi/acpixf.h | 21 | ||||
| -rw-r--r-- | include/acpi/acresrc.h | 6 | ||||
| -rw-r--r-- | include/acpi/acutils.h | 2 |
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 |
