Beispiel #1
0
/*******************************************************************************
 *
 * FUNCTION:    acpi_ex_system_wait_semaphore
 *
 * PARAMETERS:  Semaphore       - Semaphore to wait on
 *              Timeout         - Max time to wait
 *
 * RETURN:      Status
 *
 * DESCRIPTION: Implements a semaphore wait with a check to see if the
 *              semaphore is available immediately.  If it is not, the
 *              interpreter is released before waiting.
 *
 ******************************************************************************/
acpi_status acpi_ex_system_wait_semaphore(acpi_semaphore semaphore, u16 timeout)
{
    acpi_status status;

    ACPI_FUNCTION_TRACE(ex_system_wait_semaphore);

    status = acpi_os_wait_semaphore(semaphore, 1, ACPI_DO_NOT_WAIT);
    if (ACPI_SUCCESS(status)) {
        return_ACPI_STATUS(status);
    }

    if (status == AE_TIME) {

        /* We must wait, so unlock the interpreter */

        acpi_ex_relinquish_interpreter();

        status = acpi_os_wait_semaphore(semaphore, 1, timeout);

        ACPI_DEBUG_PRINT((ACPI_DB_EXEC,
                  "*** Thread awake after blocking, %s\n",
                  acpi_format_exception(status)));

        /* Reacquire the interpreter */

        acpi_ex_reacquire_interpreter();
    }

    return_ACPI_STATUS(status);
}
Beispiel #2
0
acpi_status acpi_ex_system_do_suspend(acpi_integer how_long)
{
    ACPI_FUNCTION_ENTRY();

    /* Since this thread will sleep, we must release the interpreter */

    acpi_ex_relinquish_interpreter();

    acpi_os_sleep(how_long);

    /* And now we must get the interpreter again */

    acpi_ex_reacquire_interpreter();
    return (AE_OK);
}
Beispiel #3
0
acpi_status acpi_ex_system_do_sleep(u64 how_long)
{
	ACPI_FUNCTION_ENTRY();

	/* Since this thread will sleep, we must release the interpreter */

	acpi_ex_relinquish_interpreter();

	/*
	 * For compatibility with other ACPI implementations and to prevent
	 * accidental deep sleeps, limit the sleep time to something reasonable.
	 */
	if (how_long > ACPI_MAX_SLEEP) {
		how_long = ACPI_MAX_SLEEP;
	}

	acpi_os_sleep(how_long);

	/* And now we must get the interpreter again */

	acpi_ex_reacquire_interpreter();
	return (AE_OK);
}
Beispiel #4
0
acpi_status
acpi_ev_queue_notify_request(struct acpi_namespace_node * node,
			     u32 notify_value)
{
	union acpi_operand_object *obj_desc;
	union acpi_operand_object *handler_obj = NULL;
	union acpi_generic_state *notify_info;
	acpi_status status = AE_OK;

	ACPI_FUNCTION_NAME(ev_queue_notify_request);

	/*
	 * For value 3 (Ejection Request), some device method may need to be run.
	 * For value 2 (Device Wake) if _PRW exists, the _PS0 method may need
	 *   to be run.
	 * For value 0x80 (Status Change) on the power button or sleep button,
	 *   initiate soft-off or sleep operation?
	 */
	ACPI_DEBUG_PRINT((ACPI_DB_INFO,
			  "Dispatching Notify(%X) on node %p\n", notify_value,
			  node));

	if (notify_value <= 7) {
		ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Notify value: %s\n",
				  acpi_notify_value_names[notify_value]));
	} else {
		ACPI_DEBUG_PRINT((ACPI_DB_INFO,
				  "Notify value: 0x%2.2X **Device Specific**\n",
				  notify_value));
	}

	/* Get the notify object attached to the NS Node */

	obj_desc = acpi_ns_get_attached_object(node);
	if (obj_desc) {

		/* We have the notify object, Get the right handler */

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

			if (notify_value <= ACPI_MAX_SYS_NOTIFY) {
				handler_obj =
				    obj_desc->common_notify.system_notify;
			} else {
				handler_obj =
				    obj_desc->common_notify.device_notify;
			}
			break;

		default:
			/* All other types are not supported */
			return (AE_TYPE);
		}
	}

	/* If there is any handler to run, schedule the dispatcher */

	if ((acpi_gbl_system_notify.handler
	     && (notify_value <= ACPI_MAX_SYS_NOTIFY))
	    || (acpi_gbl_device_notify.handler
		&& (notify_value > ACPI_MAX_SYS_NOTIFY)) || handler_obj) {
		notify_info = acpi_ut_create_generic_state();
		if (!notify_info) {
			return (AE_NO_MEMORY);
		}

		notify_info->common.descriptor_type =
		    ACPI_DESC_TYPE_STATE_NOTIFY;
		notify_info->notify.node = node;
		notify_info->notify.value = (u16) notify_value;
		notify_info->notify.handler_obj = handler_obj;

		acpi_ex_relinquish_interpreter();

		acpi_ev_notify_dispatch(notify_info);

		acpi_ex_reacquire_interpreter();
	}

	if (!handler_obj) {
		/*
		 * There is no per-device notify handler for this device.
		 * This may or may not be a problem.
		 */
		ACPI_DEBUG_PRINT((ACPI_DB_INFO,
				  "No notify handler for Notify(%4.4s, %X) node %p\n",
				  acpi_ut_get_node_name(node), notify_value,
				  node));
	}

	return (status);
}