/******************************************************************************* * * FUNCTION: acpi_install_fixed_event_handler * * PARAMETERS: event - Event type to enable. * handler - Pointer to the handler function for the * event * context - Value passed to the handler on each GPE * * RETURN: Status * * DESCRIPTION: Saves the pointer to the handler function and then enables the * event. * ******************************************************************************/ acpi_status acpi_install_fixed_event_handler(u32 event, acpi_event_handler handler, void *context) { acpi_status status; ACPI_FUNCTION_TRACE(acpi_install_fixed_event_handler); /* Parameter validation */ if (event > ACPI_EVENT_MAX) { return_ACPI_STATUS(AE_BAD_PARAMETER); } status = acpi_ut_acquire_mutex(ACPI_MTX_EVENTS); if (ACPI_FAILURE(status)) { return_ACPI_STATUS(status); } /* Do not allow multiple handlers */ if (acpi_gbl_fixed_event_handlers[event].handler) { status = AE_ALREADY_EXISTS; goto cleanup; } /* Install the handler before enabling the event */ acpi_gbl_fixed_event_handlers[event].handler = handler; acpi_gbl_fixed_event_handlers[event].context = context; status = acpi_clear_event(event); if (ACPI_SUCCESS(status)) status = acpi_enable_event(event, 0); if (ACPI_FAILURE(status)) { ACPI_WARNING((AE_INFO, "Could not enable fixed event - %s (%u)", acpi_ut_get_event_name(event), event)); /* Remove the handler */ acpi_gbl_fixed_event_handlers[event].handler = NULL; acpi_gbl_fixed_event_handlers[event].context = NULL; } else { ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Enabled fixed event %s (%X), Handler=%p\n", acpi_ut_get_event_name(event), event, handler)); } cleanup: (void)acpi_ut_release_mutex(ACPI_MTX_EVENTS); return_ACPI_STATUS(status); }
static u32 acpi_ev_fixed_event_dispatch(u32 event) { ACPI_FUNCTION_ENTRY(); /* Clear the status bit */ (void)acpi_write_bit_register(acpi_gbl_fixed_event_info[event]. status_register_id, ACPI_CLEAR_STATUS); /* * Make sure that a handler exists. If not, report an error * and disable the event to prevent further interrupts. */ if (!acpi_gbl_fixed_event_handlers[event].handler) { (void)acpi_write_bit_register(acpi_gbl_fixed_event_info[event]. enable_register_id, ACPI_DISABLE_EVENT); ACPI_ERROR((AE_INFO, "No installed handler for fixed event - %s (%u), disabling", acpi_ut_get_event_name(event), event)); return (ACPI_INTERRUPT_NOT_HANDLED); } /* Invoke the Fixed Event handler */ return ((acpi_gbl_fixed_event_handlers[event]. handler) (acpi_gbl_fixed_event_handlers[event].context)); }
/******************************************************************************* * * FUNCTION: acpi_remove_fixed_event_handler * * PARAMETERS: event - Event type to disable. * handler - Address of the handler * * RETURN: Status * * DESCRIPTION: Disables the event and unregisters the event handler. * ******************************************************************************/ acpi_status acpi_remove_fixed_event_handler(u32 event, acpi_event_handler handler) { acpi_status status = AE_OK; ACPI_FUNCTION_TRACE(acpi_remove_fixed_event_handler); /* Parameter validation */ if (event > ACPI_EVENT_MAX) { return_ACPI_STATUS(AE_BAD_PARAMETER); } status = acpi_ut_acquire_mutex(ACPI_MTX_EVENTS); if (ACPI_FAILURE(status)) { return_ACPI_STATUS(status); } /* Disable the event before removing the handler */ status = acpi_disable_event(event, 0); /* Always Remove the handler */ acpi_gbl_fixed_event_handlers[event].handler = NULL; acpi_gbl_fixed_event_handlers[event].context = NULL; if (ACPI_FAILURE(status)) { ACPI_WARNING((AE_INFO, "Could not disable fixed event - %s (%u)", acpi_ut_get_event_name(event), event)); } else { ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Disabled fixed event - %s (%X)\n", acpi_ut_get_event_name(event), event)); } (void)acpi_ut_release_mutex(ACPI_MTX_EVENTS); return_ACPI_STATUS(status); }
/******************************************************************************* * * FUNCTION: acpi_enable_event * * PARAMETERS: event - The fixed eventto be enabled * flags - Reserved * * RETURN: Status * * DESCRIPTION: Enable an ACPI event (fixed) * ******************************************************************************/ acpi_status acpi_enable_event(u32 event, u32 flags) { acpi_status status = AE_OK; u32 value; ACPI_FUNCTION_TRACE(acpi_enable_event); /* Decode the Fixed Event */ if (event > ACPI_EVENT_MAX) { return_ACPI_STATUS(AE_BAD_PARAMETER); } /* * Enable the requested fixed event (by writing a one to the enable * register bit) */ status = acpi_write_bit_register(acpi_gbl_fixed_event_info[event]. enable_register_id, ACPI_ENABLE_EVENT); if (ACPI_FAILURE(status)) { return_ACPI_STATUS(status); } /* Make sure that the hardware responded */ status = acpi_read_bit_register(acpi_gbl_fixed_event_info[event]. enable_register_id, &value); if (ACPI_FAILURE(status)) { return_ACPI_STATUS(status); } if (value != 1) { ACPI_ERROR((AE_INFO, "Could not enable %s event", acpi_ut_get_event_name(event))); return_ACPI_STATUS(AE_NO_HARDWARE_RESPONSE); } return_ACPI_STATUS(status); }
/******************************************************************************* * * FUNCTION: acpi_disable_event * * PARAMETERS: Event - The fixed eventto be enabled * Flags - Reserved * * RETURN: Status * * DESCRIPTION: Disable an ACPI event (fixed) * ******************************************************************************/ acpi_status acpi_disable_event(u32 event, u32 flags) { acpi_status status = AE_OK; u32 value; ACPI_FUNCTION_TRACE(acpi_disable_event); /* Decode the Fixed Event */ if (event > ACPI_EVENT_MAX) { return_ACPI_STATUS(AE_BAD_PARAMETER); } /* * Disable the requested fixed event (by writing a zero to the * enable register bit) */ status = acpi_set_register(acpi_gbl_fixed_event_info[event]. enable_register_id, 0); if (ACPI_FAILURE(status)) { return_ACPI_STATUS(status); } status = acpi_get_register(acpi_gbl_fixed_event_info[event]. enable_register_id, &value); if (ACPI_FAILURE(status)) { return_ACPI_STATUS(status); } if (value != 0) { ACPI_ERROR((AE_INFO, "Could not disable %s events", acpi_ut_get_event_name(event))); return_ACPI_STATUS(AE_NO_HARDWARE_RESPONSE); } return_ACPI_STATUS(status); }
void acpi_db_display_handlers(void) { union acpi_operand_object *obj_desc; union acpi_operand_object *handler_obj; acpi_adr_space_type space_id; u32 i; /* Operation region handlers */ acpi_os_printf("\nOperation Region Handlers at the namespace root:\n"); obj_desc = acpi_ns_get_attached_object(acpi_gbl_root_node); if (obj_desc) { for (i = 0; i < ACPI_ARRAY_LENGTH(acpi_gbl_space_id_list); i++) { space_id = acpi_gbl_space_id_list[i]; acpi_os_printf(ACPI_PREDEFINED_PREFIX, acpi_ut_get_region_name((u8)space_id), space_id); handler_obj = acpi_ev_find_region_handler(space_id, obj_desc->common_notify. handler); if (handler_obj) { acpi_os_printf(ACPI_HANDLER_PRESENT_STRING, (handler_obj->address_space. handler_flags & ACPI_ADDR_HANDLER_DEFAULT_INSTALLED) ? "Default" : "User", handler_obj->address_space. handler); goto found_handler; } /* There is no handler for this space_id */ acpi_os_printf("None\n"); found_handler: ; } /* Find all handlers for user-defined space_IDs */ handler_obj = obj_desc->common_notify.handler; while (handler_obj) { if (handler_obj->address_space.space_id >= ACPI_USER_REGION_BEGIN) { acpi_os_printf(ACPI_PREDEFINED_PREFIX, "User-defined ID", handler_obj->address_space. space_id); acpi_os_printf(ACPI_HANDLER_PRESENT_STRING, (handler_obj->address_space. handler_flags & ACPI_ADDR_HANDLER_DEFAULT_INSTALLED) ? "Default" : "User", handler_obj->address_space. handler); } handler_obj = handler_obj->address_space.next; } } #if (!ACPI_REDUCED_HARDWARE) /* Fixed event handlers */ acpi_os_printf("\nFixed Event Handlers:\n"); for (i = 0; i < ACPI_NUM_FIXED_EVENTS; i++) { acpi_os_printf(ACPI_PREDEFINED_PREFIX, acpi_ut_get_event_name(i), i); if (acpi_gbl_fixed_event_handlers[i].handler) { acpi_os_printf(ACPI_HANDLER_PRESENT_STRING, "User", acpi_gbl_fixed_event_handlers[i]. handler); } else { acpi_os_printf(ACPI_HANDLER_NOT_PRESENT_STRING, "None"); } } #endif /* !ACPI_REDUCED_HARDWARE */ /* Miscellaneous global handlers */ acpi_os_printf("\nMiscellaneous Global Handlers:\n"); for (i = 0; i < ACPI_ARRAY_LENGTH(acpi_gbl_handler_list); i++) { acpi_os_printf(ACPI_HANDLER_NAME_STRING, acpi_gbl_handler_list[i].name); if (acpi_gbl_handler_list[i].handler) { acpi_os_printf(ACPI_HANDLER_PRESENT_STRING, "User", acpi_gbl_handler_list[i].handler); } else { acpi_os_printf(ACPI_HANDLER_NOT_PRESENT_STRING, "None"); } } /* Other handlers that are installed throughout the namespace */ acpi_os_printf("\nOperation Region Handlers for specific devices:\n"); (void)acpi_walk_namespace(ACPI_TYPE_DEVICE, ACPI_ROOT_OBJECT, ACPI_UINT32_MAX, acpi_db_display_non_root_handlers, NULL, NULL, NULL); }