/******************************************************************************* * * FUNCTION: acpi_ev_install_gpe_block * * PARAMETERS: gpe_block - New GPE block * interrupt_number - Xrupt to be associated with this * GPE block * * RETURN: Status * * DESCRIPTION: Install new GPE block with mutex support *
******************************************************************************/
status = acpi_ut_acquire_mutex(ACPI_MTX_EVENTS); if (ACPI_FAILURE(status)) {
return_ACPI_STATUS(status);
}
/* Disable all GPEs in this block */
status =
acpi_hw_disable_gpe_block(gpe_block->xrupt_block, gpe_block, NULL); if (ACPI_FAILURE(status)) {
return_ACPI_STATUS(status);
}
if (!gpe_block->previous && !gpe_block->next) {
/* This is the last gpe_block on this interrupt */
status = acpi_ev_delete_gpe_xrupt(gpe_block->xrupt_block); if (ACPI_FAILURE(status)) { goto unlock_and_exit;
}
} else { /* Remove the block on this interrupt with lock */
gpe_register_info = ACPI_ALLOCATE_ZEROED((acpi_size)gpe_block->
register_count * sizeof(struct
acpi_gpe_register_info)); if (!gpe_register_info) {
ACPI_ERROR((AE_INFO, "Could not allocate the GpeRegisterInfo table"));
return_ACPI_STATUS(AE_NO_MEMORY);
}
/* * Allocate the GPE event_info block. There are eight distinct GPEs * per register. Initialization to zeros is sufficient.
*/
gpe_event_info = ACPI_ALLOCATE_ZEROED((acpi_size)gpe_block->gpe_count * sizeof(struct
acpi_gpe_event_info)); if (!gpe_event_info) {
ACPI_ERROR((AE_INFO, "Could not allocate the GpeEventInfo table"));
status = AE_NO_MEMORY; goto error_exit;
}
/* * Initialize the GPE Register and Event structures. 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.
*/
this_register = gpe_register_info;
this_event = gpe_event_info;
for (i = 0; i < gpe_block->register_count; i++) {
/* Init the register_info for this GPE register (8 GPEs) */
this_register->base_gpe_number = (u16)
(gpe_block->block_base_number +
(i * ACPI_GPE_REGISTER_WIDTH));
status = acpi_hw_gpe_write(0x00, &this_register->enable_address); if (ACPI_FAILURE(status)) { goto error_exit;
}
/* Clear any pending GPE events within this register */
status = acpi_hw_gpe_write(0xFF, &this_register->status_address); if (ACPI_FAILURE(status)) { goto error_exit;
}
this_register++;
}
return_ACPI_STATUS(AE_OK);
error_exit: if (gpe_register_info) {
ACPI_FREE(gpe_register_info);
} if (gpe_event_info) {
ACPI_FREE(gpe_event_info);
}
return_ACPI_STATUS(status);
}
/******************************************************************************* * * FUNCTION: acpi_ev_create_gpe_block * * PARAMETERS: gpe_device - Handle to the parent GPE block * gpe_block_address - Address and space_ID * register_count - Number of GPE register pairs in the block * gpe_block_base_number - Starting GPE number for the block * interrupt_number - H/W interrupt for the block * return_gpe_block - Where the new block descriptor is returned * * RETURN: Status * * DESCRIPTION: Create and Install a block of GPE registers. All GPEs within * the block are disabled at exit. * Note: Assumes namespace is locked. *
******************************************************************************/
if (space_id == ACPI_ADR_SPACE_SYSTEM_IO) {
status = acpi_hw_validate_io_block(address,
ACPI_GPE_REGISTER_WIDTH,
register_count); if (ACPI_FAILURE(status))
return_ACPI_STATUS(status);
}
/* Allocate a new GPE block */
gpe_block = ACPI_ALLOCATE_ZEROED(sizeof(struct acpi_gpe_block_info)); if (!gpe_block) {
return_ACPI_STATUS(AE_NO_MEMORY);
}
/* * Create the register_info and event_info sub-structures * Note: disables and clears all GPEs in the block
*/
status = acpi_ev_create_gpe_info_blocks(gpe_block); if (ACPI_FAILURE(status)) {
ACPI_FREE(gpe_block);
return_ACPI_STATUS(status);
}
/* Install the new block in the global lists */
status = acpi_ev_install_gpe_block(gpe_block, interrupt_number); if (ACPI_FAILURE(status)) {
ACPI_FREE(gpe_block->register_info);
ACPI_FREE(gpe_block->event_info);
ACPI_FREE(gpe_block);
return_ACPI_STATUS(status);
}
acpi_gbl_all_gpes_initialized = FALSE;
/* Find all GPE methods (_Lxx or_Exx) for this block */
/* * Ignore a null GPE block (e.g., if no GPE block 1 exists), and * any GPE blocks that have been initialized already.
*/ if (!gpe_block || gpe_block->initialized) {
return_ACPI_STATUS(AE_OK);
}
/* * Enable all GPEs that have a corresponding method and have the * ACPI_GPE_CAN_WAKE flag unset. Any other GPEs within this block * must be enabled via the acpi_enable_gpe() interface.
*/
gpe_enabled_count = 0;
for (i = 0; i < gpe_block->register_count; i++) { for (j = 0; j < ACPI_GPE_REGISTER_WIDTH; j++) {
/* * Ignore GPEs that have no corresponding _Lxx/_Exx method * and GPEs that are used for wakeup
*/ if ((ACPI_GPE_DISPATCH_TYPE(gpe_event_info->flags) !=
ACPI_GPE_DISPATCH_METHOD)
|| (gpe_event_info->flags & ACPI_GPE_CAN_WAKE)) { continue;
}
status = acpi_ev_add_gpe_reference(gpe_event_info, FALSE); if (ACPI_FAILURE(status)) {
ACPI_EXCEPTION((AE_INFO, status, "Could not enable GPE 0x%02X",
gpe_number)); continue;
}
gpe_event_info->flags |= ACPI_GPE_AUTO_ENABLED;
if (is_polling_needed &&
ACPI_GPE_IS_POLLING_NEEDED(gpe_event_info)) {
*is_polling_needed = TRUE;
}
gpe_enabled_count++;
}
}
if (gpe_enabled_count) {
ACPI_INFO(("Enabled %u GPEs in block %02X to %02X",
gpe_enabled_count, (u32)gpe_block->block_base_number,
(u32)(gpe_block->block_base_number +
(gpe_block->gpe_count - 1))));
}
gpe_block->initialized = TRUE;
return_ACPI_STATUS(AE_OK);
}
#endif/* !ACPI_REDUCED_HARDWARE */
Messung V0.5
¤ Dauer der Verarbeitung: 0.26 Sekunden
(vorverarbeitet)
¤
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.