示例#1
0
/*******************************************************************************
 *
 * 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);
}
示例#2
0
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));
}
示例#3
0
/*******************************************************************************
 *
 * 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);
}
示例#5
0
/*******************************************************************************
 *
 * 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);
}
示例#6
0
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);
}