void acpi_db_generate_gpe(char *gpe_arg, char *block_arg) { u32 block_number = 0; u32 gpe_number; struct acpi_gpe_event_info *gpe_event_info; gpe_number = strtoul(gpe_arg, NULL, 0); /* * If no block arg, or block arg == 0 or 1, use the FADT-defined * GPE blocks. */ if (block_arg) { block_number = strtoul(block_arg, NULL, 0); if (block_number == 1) { block_number = 0; } } gpe_event_info = acpi_ev_get_gpe_event_info(ACPI_TO_POINTER(block_number), gpe_number); if (!gpe_event_info) { acpi_os_printf("Invalid GPE\n"); return; } (void)acpi_ev_gpe_dispatch(NULL, gpe_event_info, gpe_number); }
u32 acpi_ev_gpe_detect (void) { u32 int_status = INTERRUPT_NOT_HANDLED; u32 i; u32 j; u8 enabled_status_byte; u8 bit_mask; PROC_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++) { acpi_os_read_port (acpi_gbl_gpe_registers[i].status_addr, &acpi_gbl_gpe_registers[i].status, 8); acpi_os_read_port (acpi_gbl_gpe_registers[i].enable_addr, &acpi_gbl_gpe_registers[i].enable, 8); ACPI_DEBUG_PRINT ((ACPI_DB_INTERRUPTS, "GPE block at %X - Enable %08X Status %08X\n", acpi_gbl_gpe_registers[i].enable_addr, acpi_gbl_gpe_registers[i].status, acpi_gbl_gpe_registers[i].enable)); /* First check if there is anything active at all in this register */ enabled_status_byte = (u8) (acpi_gbl_gpe_registers[i].status & acpi_gbl_gpe_registers[i].enable); if (!enabled_status_byte) { /* No active GPEs in this register, move on */ continue; } /* Now look at the individual GPEs in this byte register */ for (j = 0, bit_mask = 1; j < 8; 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 ( acpi_gbl_gpe_registers[i].gpe_base + j); } } } return (int_status); }
u32 acpi_ev_gpe_detect(struct acpi_gpe_xrupt_info *gpe_xrupt_list) { acpi_status status; struct acpi_gpe_block_info *gpe_block; struct acpi_namespace_node *gpe_device; struct acpi_gpe_register_info *gpe_register_info; struct acpi_gpe_event_info *gpe_event_info; u32 gpe_number; struct acpi_gpe_handler_info *gpe_handler_info; u32 int_status = ACPI_INTERRUPT_NOT_HANDLED; u8 enabled_status_byte; u32 status_reg; u32 enable_reg; acpi_cpu_flags flags; u32 i; u32 j; ACPI_FUNCTION_NAME(ev_gpe_detect); /* Check for the case where there are no GPEs */ if (!gpe_xrupt_list) { return (int_status); } /* * We need to obtain the GPE lock for both the data structs and registers * Note: Not necessary to obtain the hardware lock, since the GPE * registers are owned by the gpe_lock. */ flags = acpi_os_acquire_lock(acpi_gbl_gpe_lock); /* Examine all GPE blocks attached to this interrupt level */ gpe_block = gpe_xrupt_list->gpe_block_list_head; while (gpe_block) { gpe_device = gpe_block->node; /* * 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 */ gpe_register_info = &gpe_block->register_info[i]; /* * Optimization: If there are no GPEs enabled within this * register, we can safely ignore the entire register. */ if (!(gpe_register_info->enable_for_run | gpe_register_info->enable_for_wake)) { ACPI_DEBUG_PRINT((ACPI_DB_INTERRUPTS, "Ignore disabled registers for GPE %02X-%02X: " "RunEnable=%02X, WakeEnable=%02X\n", gpe_register_info-> base_gpe_number, gpe_register_info-> base_gpe_number + (ACPI_GPE_REGISTER_WIDTH - 1), gpe_register_info-> enable_for_run, gpe_register_info-> enable_for_wake)); continue; } /* Read the Status Register */ status = acpi_hw_read(&status_reg, &gpe_register_info->status_address); if (ACPI_FAILURE(status)) { goto unlock_and_exit; } /* Read the Enable Register */ status = acpi_hw_read(&enable_reg, &gpe_register_info->enable_address); if (ACPI_FAILURE(status)) { goto unlock_and_exit; } ACPI_DEBUG_PRINT((ACPI_DB_INTERRUPTS, "Read registers for GPE %02X-%02X: Status=%02X, Enable=%02X, " "RunEnable=%02X, WakeEnable=%02X\n", gpe_register_info->base_gpe_number, gpe_register_info->base_gpe_number + (ACPI_GPE_REGISTER_WIDTH - 1), status_reg, enable_reg, gpe_register_info->enable_for_run, gpe_register_info->enable_for_wake)); /* Check if there is anything active at all in this register */ enabled_status_byte = (u8)(status_reg & enable_reg); if (!enabled_status_byte) { /* No active GPEs in this register, move on */ continue; } /* Now look at the individual GPEs in this byte register */ for (j = 0; j < ACPI_GPE_REGISTER_WIDTH; j++) { /* Examine one GPE bit */ gpe_event_info = &gpe_block-> event_info[((acpi_size) i * ACPI_GPE_REGISTER_WIDTH) + j]; gpe_number = j + gpe_register_info->base_gpe_number; if (enabled_status_byte & (1 << j)) { /* Invoke global event handler if present */ acpi_gpe_count++; if (acpi_gbl_global_event_handler) { acpi_gbl_global_event_handler (ACPI_EVENT_TYPE_GPE, gpe_device, gpe_number, acpi_gbl_global_event_handler_context); } /* Found an active GPE */ if (ACPI_GPE_DISPATCH_TYPE (gpe_event_info->flags) == ACPI_GPE_DISPATCH_RAW_HANDLER) { /* Dispatch the event to a raw handler */ gpe_handler_info = gpe_event_info->dispatch. handler; /* * There is no protection around the namespace node * and the GPE handler to ensure a safe destruction * because: * 1. The namespace node is expected to always * exist after loading a table. * 2. The GPE handler is expected to be flushed by * acpi_os_wait_events_complete() before the * destruction. */ acpi_os_release_lock (acpi_gbl_gpe_lock, flags); int_status |= gpe_handler_info-> address(gpe_device, gpe_number, gpe_handler_info-> context); flags = acpi_os_acquire_lock (acpi_gbl_gpe_lock); } else { /* * Dispatch the event to a standard handler or * method. */ int_status |= acpi_ev_gpe_dispatch (gpe_device, gpe_event_info, gpe_number); } } } } gpe_block = gpe_block->next; } unlock_and_exit: acpi_os_release_lock(acpi_gbl_gpe_lock, flags); return (int_status); }
u32 acpi_ev_gpe_detect(struct acpi_gpe_xrupt_info * gpe_xrupt_list) { acpi_status status; struct acpi_gpe_block_info *gpe_block; struct acpi_gpe_register_info *gpe_register_info; u32 int_status = ACPI_INTERRUPT_NOT_HANDLED; u8 enabled_status_byte; u32 status_reg; u32 enable_reg; acpi_cpu_flags flags; u32 i; u32 j; ACPI_FUNCTION_NAME(ev_gpe_detect); /* Check for the case where there are no GPEs */ if (!gpe_xrupt_list) { return (int_status); } /* * We need to obtain the GPE lock for both the data structs and registers * Note: Not necessary to obtain the hardware lock, since the GPE * registers are owned by the gpe_lock. */ flags = acpi_os_acquire_lock(acpi_gbl_gpe_lock); /* Examine all GPE blocks attached to this interrupt level */ gpe_block = gpe_xrupt_list->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 */ gpe_register_info = &gpe_block->register_info[i]; /* Read the Status Register */ status = acpi_hw_read(&status_reg, &gpe_register_info->status_address); if (ACPI_FAILURE(status)) { goto unlock_and_exit; } /* Read the Enable Register */ status = acpi_hw_read(&enable_reg, &gpe_register_info->enable_address); if (ACPI_FAILURE(status)) { goto unlock_and_exit; } ACPI_DEBUG_PRINT((ACPI_DB_INTERRUPTS, "Read GPE Register at GPE%X: Status=%02X, Enable=%02X\n", gpe_register_info->base_gpe_number, status_reg, enable_reg)); /* Check if there is anything active at all in this register */ enabled_status_byte = (u8) (status_reg & enable_reg); if (!enabled_status_byte) { /* No active GPEs in this register, move on */ continue; } /* Now look at the individual GPEs in this byte register */ for (j = 0; j < ACPI_GPE_REGISTER_WIDTH; j++) { /* Examine one GPE bit */ if (enabled_status_byte & (1 << j)) { /* * Found an active GPE. Dispatch the event to a handler * or method. */ int_status |= acpi_ev_gpe_dispatch(&gpe_block-> event_info[((acpi_size) i * ACPI_GPE_REGISTER_WIDTH) + j], j + gpe_register_info->base_gpe_number); } } } gpe_block = gpe_block->next; } unlock_and_exit: acpi_os_release_lock(acpi_gbl_gpe_lock, flags); return (int_status); }
u32 acpi_ev_gpe_detect ( struct acpi_gpe_xrupt_info *gpe_xrupt_list) { u32 int_status = ACPI_INTERRUPT_NOT_HANDLED; u8 enabled_status_byte; struct acpi_gpe_register_info *gpe_register_info; u32 status_reg; u32 enable_reg; acpi_status status; struct acpi_gpe_block_info *gpe_block; acpi_native_uint i; acpi_native_uint j; ACPI_FUNCTION_NAME ("ev_gpe_detect"); /* Check for the case where there are no GPEs */ if (!gpe_xrupt_list) { return (int_status); } /* Examine all GPE blocks attached to this interrupt level */ acpi_os_acquire_lock (acpi_gbl_gpe_lock, ACPI_ISR); gpe_block = gpe_xrupt_list->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 */ gpe_register_info = &gpe_block->register_info[i]; /* Read the Status Register */ status = acpi_hw_low_level_read (ACPI_GPE_REGISTER_WIDTH, &status_reg, &gpe_register_info->status_address); if (ACPI_FAILURE (status)) { goto unlock_and_exit; } /* Read the Enable Register */ status = acpi_hw_low_level_read (ACPI_GPE_REGISTER_WIDTH, &enable_reg, &gpe_register_info->enable_address); if (ACPI_FAILURE (status)) { goto unlock_and_exit; } ACPI_DEBUG_PRINT ((ACPI_DB_INTERRUPTS, "GPE pair: Status %8.8X%8.8X = %02X, Enable %8.8X%8.8X = %02X\n", ACPI_FORMAT_UINT64 ( gpe_register_info->status_address.address), status_reg, ACPI_FORMAT_UINT64 ( gpe_register_info->enable_address.address), enable_reg)); /* First check if there is anything active at all in this register */ enabled_status_byte = (u8) (status_reg & enable_reg); if (!enabled_status_byte) { /* No active GPEs in this register, move on */ continue; } /* Now look at the individual GPEs in this byte register */ for (j = 0; j < ACPI_GPE_REGISTER_WIDTH; j++) { /* Examine one GPE bit */ if (enabled_status_byte & acpi_gbl_decode_to8bit[j]) { /* * 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], (u32) j + gpe_register_info->base_gpe_number); } } } gpe_block = gpe_block->next; } unlock_and_exit: acpi_os_release_lock (acpi_gbl_gpe_lock, ACPI_ISR); return (int_status); }
u32 acpi_ev_gpe_detect ( struct acpi_gpe_xrupt_info *gpe_xrupt_list) { u32 int_status = ACPI_INTERRUPT_NOT_HANDLED; u8 enabled_status_byte; u8 bit_mask; struct acpi_gpe_register_info *gpe_register_info; u32 in_value; acpi_status status; struct acpi_gpe_block_info *gpe_block; u32 gpe_number; u32 i; u32 j; ACPI_FUNCTION_NAME ("ev_gpe_detect"); /* Examine all GPE blocks attached to this interrupt level */ acpi_os_acquire_lock (acpi_gbl_gpe_lock, ACPI_ISR); gpe_block = gpe_xrupt_list->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 */ gpe_register_info = &gpe_block->register_info[i]; /* Read the Status Register */ status = acpi_hw_low_level_read (ACPI_GPE_REGISTER_WIDTH, &in_value, &gpe_register_info->status_address); gpe_register_info->status = (u8) in_value; if (ACPI_FAILURE (status)) { goto unlock_and_exit; } /* Read the Enable Register */ status = acpi_hw_low_level_read (ACPI_GPE_REGISTER_WIDTH, &in_value, &gpe_register_info->enable_address); gpe_register_info->enable = (u8) in_value; if (ACPI_FAILURE (status)) { goto unlock_and_exit; } ACPI_DEBUG_PRINT ((ACPI_DB_INTERRUPTS, "GPE pair: Status %8.8X%8.8X = %02X, Enable %8.8X%8.8X = %02X\n", ACPI_HIDWORD (gpe_register_info->status_address.address), ACPI_LODWORD (gpe_register_info->status_address.address), gpe_register_info->status, ACPI_HIDWORD (gpe_register_info->enable_address.address), ACPI_LODWORD (gpe_register_info->enable_address.address), gpe_register_info->enable)); /* First check if there is anything active at all in this register */ enabled_status_byte = (u8) (gpe_register_info->status & gpe_register_info->enable); if (!enabled_status_byte) { /* No active GPEs in this register, move on */ 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 */ if (enabled_status_byte & bit_mask) { /* * Found an active GPE. Dispatch the event to a handler * or method. */ gpe_number = (i * ACPI_GPE_REGISTER_WIDTH) + j; int_status |= acpi_ev_gpe_dispatch ( &gpe_block->event_info[gpe_number], gpe_number + gpe_block->register_info[gpe_number].base_gpe_number); } } } gpe_block = gpe_block->next; } unlock_and_exit: acpi_os_release_lock (acpi_gbl_gpe_lock, ACPI_ISR); return (int_status); }
u32 acpi_ev_gpe_detect(struct acpi_gpe_xrupt_info * gpe_xrupt_list) { acpi_status status; struct acpi_gpe_block_info *gpe_block; struct acpi_gpe_register_info *gpe_register_info; u32 int_status = ACPI_INTERRUPT_NOT_HANDLED; u8 enabled_status_byte; u32 status_reg; u32 enable_reg; acpi_cpu_flags flags; u32 i; u32 j; ACPI_FUNCTION_NAME(ev_gpe_detect); if (!gpe_xrupt_list) { return (int_status); } flags = acpi_os_acquire_lock(acpi_gbl_gpe_lock); gpe_block = gpe_xrupt_list->gpe_block_list_head; while (gpe_block) { for (i = 0; i < gpe_block->register_count; i++) { gpe_register_info = &gpe_block->register_info[i]; status = acpi_hw_read(&status_reg, &gpe_register_info->status_address); if (ACPI_FAILURE(status)) { goto unlock_and_exit; } status = acpi_hw_read(&enable_reg, &gpe_register_info->enable_address); if (ACPI_FAILURE(status)) { goto unlock_and_exit; } ACPI_DEBUG_PRINT((ACPI_DB_INTERRUPTS, "Read GPE Register at GPE%X: Status=%02X, Enable=%02X\n", gpe_register_info->base_gpe_number, status_reg, enable_reg)); enabled_status_byte = (u8) (status_reg & enable_reg); if (!enabled_status_byte) { continue; } for (j = 0; j < ACPI_GPE_REGISTER_WIDTH; j++) { if (enabled_status_byte & (1 << j)) { int_status |= acpi_ev_gpe_dispatch(&gpe_block-> event_info[((acpi_size) i * ACPI_GPE_REGISTER_WIDTH) + j], j + gpe_register_info->base_gpe_number); } } } gpe_block = gpe_block->next; } unlock_and_exit: acpi_os_release_lock(acpi_gbl_gpe_lock, flags); return (int_status); }