示例#1
0
void acpi_db_send_notify(char *name, u32 value)
{
	struct acpi_namespace_node *node;
	acpi_status status;

	/* Translate name to an Named object */

	node = acpi_db_convert_to_node(name);
	if (!node) {
		return;
	}

	/* Dispatch the notify if legal */

	if (acpi_ev_is_notify_object(node)) {
		status = acpi_ev_queue_notify_request(node, value);
		if (ACPI_FAILURE(status)) {
			acpi_os_printf("Could not queue notify\n");
		}
	} else {
		acpi_os_printf("Named object [%4.4s] Type %s, "
			       "must be Device/Thermal/Processor type\n",
			       acpi_ut_get_node_name(node),
			       acpi_ut_get_type_name(node->type));
	}
}
示例#2
0
void
acpi_db_send_notify (
	NATIVE_CHAR             *name,
	u32                     value)
{
	acpi_namespace_node     *node;


	/* Translate name to an Named object */

	node = acpi_db_local_ns_lookup (name);
	if (!node) {
		return;
	}

	/* Decode Named object type */

	switch (node->type) {
	case ACPI_TYPE_DEVICE:
	case ACPI_TYPE_THERMAL:

		 /* Send the notify */

		acpi_ev_queue_notify_request (node, value);
		break;

	default:
		acpi_os_printf ("Named object is not a device or a thermal object\n");
		break;
	}

}
示例#3
0
acpi_status
acpi_ex_opcode_2A_0T_0R (
	acpi_walk_state         *walk_state)
{
	acpi_operand_object     **operand = &walk_state->operands[0];
	acpi_namespace_node     *node;
	acpi_status             status = AE_OK;


	FUNCTION_TRACE_STR ("Ex_opcode_2A_0T_0R", acpi_ps_get_opcode_name (walk_state->opcode));


	/* Examine the opcode */

	switch (walk_state->opcode) {

	case AML_NOTIFY_OP:         /* Notify (Notify_object, Notify_value) */

		/* The first operand is a namespace node */

		node = (acpi_namespace_node *) operand[0];

		/* The node must refer to a device or thermal zone */

		if (node && operand[1])     /* TBD: is this check necessary? */ {
			switch (node->type) {
			case ACPI_TYPE_DEVICE:
			case ACPI_TYPE_THERMAL:

				/*
				 * Dispatch the notify to the appropriate handler
				 * NOTE: the request is queued for execution after this method
				 * completes.  The notify handlers are NOT invoked synchronously
				 * from this thread -- because handlers may in turn run other
				 * control methods.
				 */
				status = acpi_ev_queue_notify_request (node,
						 (u32) operand[1]->integer.value);
				break;

			default:
				ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Unexpected notify object type %X\n",
					node->type));

				status = AE_AML_OPERAND_TYPE;
				break;
			}
		}
		break;

	default:

		REPORT_ERROR (("Acpi_ex_opcode_2A_0T_0R: Unknown opcode %X\n", walk_state->opcode));
		status = AE_AML_BAD_OPCODE;
	}

	return_ACPI_STATUS (status);
}
示例#4
0
文件: evgpe.c 项目: 0-T-0/ps4-linux
static void ACPI_SYSTEM_XFACE acpi_ev_asynch_execute_gpe_method(void *context)
{
	struct acpi_gpe_event_info *gpe_event_info = context;
	acpi_status status = AE_OK;
	struct acpi_evaluate_info *info;
	struct acpi_gpe_notify_info *notify;

	ACPI_FUNCTION_TRACE(ev_asynch_execute_gpe_method);

	/* Do the correct dispatch - normal method or implicit notify */

	switch (ACPI_GPE_DISPATCH_TYPE(gpe_event_info->flags)) {
	case ACPI_GPE_DISPATCH_NOTIFY:
		/*
		 * Implicit notify.
		 * Dispatch a DEVICE_WAKE notify to the appropriate handler.
		 * NOTE: the request is queued for execution after this method
		 * completes. The notify handlers are NOT invoked synchronously
		 * from this thread -- because handlers may in turn run other
		 * control methods.
		 *
		 * June 2012: Expand implicit notify mechanism to support
		 * notifies on multiple device objects.
		 */
		notify = gpe_event_info->dispatch.notify_list;
		while (ACPI_SUCCESS(status) && notify) {
			status =
			    acpi_ev_queue_notify_request(notify->device_node,
							 ACPI_NOTIFY_DEVICE_WAKE);

			notify = notify->next;
		}

		break;

	case ACPI_GPE_DISPATCH_METHOD:

		/* Allocate the evaluation information block */

		info = ACPI_ALLOCATE_ZEROED(sizeof(struct acpi_evaluate_info));
		if (!info) {
			status = AE_NO_MEMORY;
		} else {
			/*
			 * Invoke the GPE Method (_Lxx, _Exx) i.e., evaluate the
			 * _Lxx/_Exx control method that corresponds to this GPE
			 */
			info->prefix_node =
			    gpe_event_info->dispatch.method_node;
			info->flags = ACPI_IGNORE_RETURN_VALUE;

			status = acpi_ns_evaluate(info);
			ACPI_FREE(info);
		}

		if (ACPI_FAILURE(status)) {
			ACPI_EXCEPTION((AE_INFO, status,
					"while evaluating GPE method [%4.4s]",
					acpi_ut_get_node_name(gpe_event_info->
							      dispatch.
							      method_node)));
		}
		break;

	default:

		goto error_exit;	/* Should never happen */
	}

	/* Defer enabling of GPE until all notify handlers are done */

	status = acpi_os_execute(OSL_NOTIFY_HANDLER,
				 acpi_ev_asynch_enable_gpe, gpe_event_info);
	if (ACPI_SUCCESS(status)) {
		return_VOID;
	}

error_exit:
	acpi_ev_asynch_enable_gpe(gpe_event_info);
	return_VOID;
}
/*******************************************************************************
 *
 * FUNCTION:    acpi_ex_opcode_2A_0T_0R
 *
 * PARAMETERS:  walk_state          - Current walk state
 *
 * RETURN:      Status
 *
 * DESCRIPTION: Execute opcode with two arguments, no target, and no return
 *              value.
 *
 * ALLOCATION:  Deletes both operands
 *
 ******************************************************************************/
acpi_status acpi_ex_opcode_2A_0T_0R(struct acpi_walk_state *walk_state)
{
	union acpi_operand_object **operand = &walk_state->operands[0];
	struct acpi_namespace_node *node;
	u32 value;
	acpi_status status = AE_OK;

	ACPI_FUNCTION_TRACE_STR("ex_opcode_2A_0T_0R",
				acpi_ps_get_opcode_name(walk_state->opcode));

	/* Examine the opcode */

	switch (walk_state->opcode) {
	case AML_NOTIFY_OP:	/* Notify (notify_object, notify_value) */

		/* The first operand is a namespace node */

		node = (struct acpi_namespace_node *)operand[0];

		/* Second value is the notify value */

		value = (u32) operand[1]->integer.value;

		/* Are notifies allowed on this object? */

		if (!acpi_ev_is_notify_object(node)) {
			ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
					  "Unexpected notify object type [%s]\n",
					  acpi_ut_get_type_name(node->type)));

			status = AE_AML_OPERAND_TYPE;
			break;
		}
#ifdef ACPI_GPE_NOTIFY_CHECK
		/*
		 * GPE method wake/notify check.  Here, we want to ensure that we
		 * don't receive any "device_wake" Notifies from a GPE _Lxx or _Exx
		 * GPE method during system runtime.  If we do, the GPE is marked
		 * as "wake-only" and disabled.
		 *
		 * 1) Is the Notify() value == device_wake?
		 * 2) Is this a GPE deferred method?  (An _Lxx or _Exx method)
		 * 3) Did the original GPE happen at system runtime?
		 *    (versus during wake)
		 *
		 * If all three cases are true, this is a wake-only GPE that should
		 * be disabled at runtime.
		 */
		if (value == 2) {	/* device_wake */
			status =
			    acpi_ev_check_for_wake_only_gpe(walk_state->
							    gpe_event_info);
			if (ACPI_FAILURE(status)) {
				/* AE_WAKE_ONLY_GPE only error, means ignore this notify */

				return_ACPI_STATUS(AE_OK)
			}
		}
#endif

		/*
		 * Dispatch the notify to the appropriate handler
		 * NOTE: the request is queued for execution after this method
		 * completes.  The notify handlers are NOT invoked synchronously
		 * from this thread -- because handlers may in turn run other
		 * control methods.
		 */
		status = acpi_ev_queue_notify_request(node, value);
		break;

	default:

		ACPI_REPORT_ERROR(("acpi_ex_opcode_2A_0T_0R: Unknown opcode %X\n", walk_state->opcode));
		status = AE_AML_BAD_OPCODE;
	}
示例#6
0
文件: evgpe.c 项目: AllenDou/linux
static void ACPI_SYSTEM_XFACE acpi_ev_asynch_execute_gpe_method(void *context)
{
	struct acpi_gpe_event_info *gpe_event_info = context;
	acpi_status status;
	struct acpi_gpe_event_info *local_gpe_event_info;
	struct acpi_evaluate_info *info;
	struct acpi_gpe_notify_info *notify;

	ACPI_FUNCTION_TRACE(ev_asynch_execute_gpe_method);

	/* Allocate a local GPE block */

	local_gpe_event_info =
	    ACPI_ALLOCATE_ZEROED(sizeof(struct acpi_gpe_event_info));
	if (!local_gpe_event_info) {
		ACPI_EXCEPTION((AE_INFO, AE_NO_MEMORY, "while handling a GPE"));
		return_VOID;
	}

	status = acpi_ut_acquire_mutex(ACPI_MTX_EVENTS);
	if (ACPI_FAILURE(status)) {
		ACPI_FREE(local_gpe_event_info);
		return_VOID;
	}

	/* Must revalidate the gpe_number/gpe_block */

	if (!acpi_ev_valid_gpe_event(gpe_event_info)) {
		status = acpi_ut_release_mutex(ACPI_MTX_EVENTS);
		ACPI_FREE(local_gpe_event_info);
		return_VOID;
	}

	/*
	 * Take a snapshot of the GPE info for this level - we copy the info to
	 * prevent a race condition with remove_handler/remove_block.
	 */
	ACPI_MEMCPY(local_gpe_event_info, gpe_event_info,
		    sizeof(struct acpi_gpe_event_info));

	status = acpi_ut_release_mutex(ACPI_MTX_EVENTS);
	if (ACPI_FAILURE(status)) {
		return_VOID;
	}

	/* Do the correct dispatch - normal method or implicit notify */

	switch (local_gpe_event_info->flags & ACPI_GPE_DISPATCH_MASK) {
	case ACPI_GPE_DISPATCH_NOTIFY:

		/*
		 * Implicit notify.
		 * Dispatch a DEVICE_WAKE notify to the appropriate handler.
		 * NOTE: the request is queued for execution after this method
		 * completes. The notify handlers are NOT invoked synchronously
		 * from this thread -- because handlers may in turn run other
		 * control methods.
		 *
		 * June 2012: Expand implicit notify mechanism to support
		 * notifies on multiple device objects.
		 */
		notify = local_gpe_event_info->dispatch.notify_list;
		while (ACPI_SUCCESS(status) && notify) {
			status =
			    acpi_ev_queue_notify_request(notify->device_node,
							 ACPI_NOTIFY_DEVICE_WAKE);

			notify = notify->next;
		}

		break;

	case ACPI_GPE_DISPATCH_METHOD:

		/* Allocate the evaluation information block */

		info = ACPI_ALLOCATE_ZEROED(sizeof(struct acpi_evaluate_info));
		if (!info) {
			status = AE_NO_MEMORY;
		} else {
			/*
			 * Invoke the GPE Method (_Lxx, _Exx) i.e., evaluate the _Lxx/_Exx
			 * control method that corresponds to this GPE
			 */
			info->prefix_node =
			    local_gpe_event_info->dispatch.method_node;
			info->flags = ACPI_IGNORE_RETURN_VALUE;

			status = acpi_ns_evaluate(info);
			ACPI_FREE(info);
		}

		if (ACPI_FAILURE(status)) {
			ACPI_EXCEPTION((AE_INFO, status,
					"while evaluating GPE method [%4.4s]",
					acpi_ut_get_node_name
					(local_gpe_event_info->dispatch.
					 method_node)));
		}

		break;

	default:
		return_VOID;    /* Should never happen */
	}

	/* Defer enabling of GPE until all notify handlers are done */

	status = acpi_os_execute(OSL_NOTIFY_HANDLER,
				 acpi_ev_asynch_enable_gpe,
				 local_gpe_event_info);
	if (ACPI_FAILURE(status)) {
		ACPI_FREE(local_gpe_event_info);
	}
	return_VOID;
}