acpi_status acpi_ev_create_gpe_block(struct acpi_namespace_node *gpe_device, struct acpi_generic_address *gpe_block_address, u32 register_count, u8 gpe_block_base_number, u32 interrupt_number, struct acpi_gpe_block_info **return_gpe_block) { acpi_status status; struct acpi_gpe_block_info *gpe_block; struct acpi_gpe_walk_info walk_info; ACPI_FUNCTION_TRACE(ev_create_gpe_block); if (!register_count) { return_ACPI_STATUS(AE_OK); } /* 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); } /* Initialize the new GPE block */ gpe_block->node = gpe_device; gpe_block->gpe_count = (u16)(register_count * ACPI_GPE_REGISTER_WIDTH); gpe_block->initialized = FALSE; gpe_block->register_count = register_count; gpe_block->block_base_number = gpe_block_base_number; ACPI_MEMCPY(&gpe_block->block_address, gpe_block_address, sizeof(struct acpi_generic_address)); /* * 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); return_ACPI_STATUS(status); } acpi_gbl_all_gpes_initialized = FALSE; /* Find all GPE methods (_Lxx or_Exx) for this block */ walk_info.gpe_block = gpe_block; walk_info.gpe_device = gpe_device; walk_info.execute_by_owner_id = FALSE; status = acpi_ns_walk_namespace(ACPI_TYPE_METHOD, gpe_device, ACPI_UINT32_MAX, ACPI_NS_WALK_NO_UNLOCK, acpi_ev_match_gpe_method, NULL, &walk_info, NULL); /* Return the new block */ if (return_gpe_block) { (*return_gpe_block) = gpe_block; } ACPI_DEBUG_PRINT((ACPI_DB_INIT, "GPE %02X to %02X [%4.4s] %u regs on int 0x%X\n", (u32) gpe_block->block_base_number, (u32) (gpe_block->block_base_number + (gpe_block->gpe_count - 1)), gpe_device->name.ascii, gpe_block->register_count, interrupt_number)); /* Update global count of currently available GPEs */ acpi_current_gpe_count += gpe_block->gpe_count; return_ACPI_STATUS(AE_OK); }
acpi_status acpi_ev_create_gpe_block ( struct acpi_namespace_node *gpe_device, struct acpi_generic_address *gpe_block_address, u32 register_count, u8 gpe_block_base_number, u32 interrupt_level, struct acpi_gpe_block_info **return_gpe_block) { struct acpi_gpe_block_info *gpe_block; acpi_status status; ACPI_FUNCTION_TRACE ("ev_create_gpe_block"); if (!register_count) { return_ACPI_STATUS (AE_OK); } /* Allocate a new GPE block */ gpe_block = ACPI_MEM_CALLOCATE (sizeof (struct acpi_gpe_block_info)); if (!gpe_block) { return_ACPI_STATUS (AE_NO_MEMORY); } /* Initialize the new GPE block */ gpe_block->register_count = register_count; gpe_block->block_base_number = gpe_block_base_number; ACPI_MEMCPY (&gpe_block->block_address, gpe_block_address, sizeof (struct acpi_generic_address)); /* Create the register_info and event_info sub-structures */ status = acpi_ev_create_gpe_info_blocks (gpe_block); if (ACPI_FAILURE (status)) { ACPI_MEM_FREE (gpe_block); return_ACPI_STATUS (status); } /* Install the new block in the global list(s) */ status = acpi_ev_install_gpe_block (gpe_block, interrupt_level); if (ACPI_FAILURE (status)) { ACPI_MEM_FREE (gpe_block); return_ACPI_STATUS (status); } /* Dump info about this GPE block */ ACPI_DEBUG_PRINT ((ACPI_DB_INIT, "GPE %02d to %02d [%4.4s] %d regs at %8.8X%8.8X on int %d\n", gpe_block->block_base_number, (u32) (gpe_block->block_base_number + ((gpe_block->register_count * ACPI_GPE_REGISTER_WIDTH) -1)), gpe_device->name.ascii, gpe_block->register_count, ACPI_HIDWORD (gpe_block->block_address.address), ACPI_LODWORD (gpe_block->block_address.address), interrupt_level)); /* Find all GPE methods (_Lxx, _Exx) for this block */ status = acpi_ns_walk_namespace (ACPI_TYPE_METHOD, gpe_device, ACPI_UINT32_MAX, ACPI_NS_WALK_NO_UNLOCK, acpi_ev_save_method_info, gpe_block, NULL); /* Return the new block */ if (return_gpe_block) { (*return_gpe_block) = gpe_block; } return_ACPI_STATUS (AE_OK); }