Пример #1
0
int
acpi_power_transition (
	struct acpi_device	*device,
	int			state)
{
	int			result = 0;
	struct acpi_handle_list	*cl = NULL;	/* Current Resources */
	struct acpi_handle_list	*tl = NULL;	/* Target Resources */
	int			i = 0;

	ACPI_FUNCTION_TRACE("acpi_power_transition");

	if (!device || (state < ACPI_STATE_D0) || (state > ACPI_STATE_D3))
		return_VALUE(-EINVAL);

	if ((device->power.state < ACPI_STATE_D0) || (device->power.state > ACPI_STATE_D3))
		return_VALUE(-ENODEV);

	cl = &device->power.states[device->power.state].resources;
	tl = &device->power.states[state].resources;

	device->power.state = ACPI_STATE_UNKNOWN;

	if (!cl->count && !tl->count) {
		result = -ENODEV;
		goto end;
	}

	/* TBD: Resources must be ordered. */

	/*
	 * First we reference all power resources required in the target list
	 * (e.g. so the device doesn't loose power while transitioning).
	 */
	for (i=0; i<tl->count; i++) {
		result = acpi_power_on(tl->handles[i]);
		if (result)
			goto end;
	}

	/*
	 * Then we dereference all power resources used in the current list.
	 */
	for (i=0; i<cl->count; i++) {
		result = acpi_power_off_device(cl->handles[i]);
		if (result)
			goto end;
	}

	/* We shouldn't change the state till all above operations succeed */
	device->power.state = state;
end:
	if (result)
		ACPI_DEBUG_PRINT((ACPI_DB_WARN, 
			"Error transitioning device [%s] to D%d\n",
			device->pnp.bus_id, state));

	return_VALUE(result);
}
Пример #2
0
int acpi_power_transition(struct acpi_device *device, int state)
{
	int result = 0;
	struct acpi_handle_list *cl = NULL;	/* Current Resources */
	struct acpi_handle_list *tl = NULL;	/* Target Resources */
	int i = 0;

	if (!device || (state < ACPI_STATE_D0) || (state > ACPI_STATE_D3))
		return -EINVAL;

	if (device->power.state == state)
		return 0;

	if ((device->power.state < ACPI_STATE_D0)
	    || (device->power.state > ACPI_STATE_D3))
		return -ENODEV;

	cl = &device->power.states[device->power.state].resources;
	tl = &device->power.states[state].resources;

	/* TBD: Resources must be ordered. */

	/*
	 * First we reference all power resources required in the target list
	 * (e.g. so the device doesn't lose power while transitioning).
	 */
	for (i = 0; i < tl->count; i++) {
		result = acpi_power_on(tl->handles[i]);
		if (result)
			goto end;
	}

	/*
	 * Then we dereference all power resources used in the current list.
	 */
	for (i = 0; i < cl->count; i++) {
		result = acpi_power_off_device(cl->handles[i]);
		if (result)
			goto end;
	}

     end:
	if (result)
		device->power.state = ACPI_STATE_UNKNOWN;
	else {
	/* We shouldn't change the state till all above operations succeed */
		device->power.state = state;
	}

	return result;
}
Пример #3
0
/*
 * Shutdown a wakeup device, counterpart of above method
 * 1. Execute _DSW (Device Sleep Wake) or (deprecated in ACPI 3.0) _PSW (Power
 *    State Wake) for the device, if present
 * 2. Shutdown down the power resources
 */
int acpi_disable_wakeup_device_power(struct acpi_device *dev)
{
	int i, err = 0;

	if (!dev || !dev->wakeup.flags.valid)
		return -EINVAL;

	mutex_lock(&acpi_device_lock);

	if (--dev->wakeup.prepare_count > 0)
		goto out;

	/*
	 * Executing the code below even if prepare_count is already zero when
	 * the function is called may be useful, for example for initialisation.
	 */
	if (dev->wakeup.prepare_count < 0)
		dev->wakeup.prepare_count = 0;

	err = acpi_device_sleep_wake(dev, 0, 0, 0);
	if (err)
		goto out;

	/* Close power resource */
	for (i = 0; i < dev->wakeup.resources.count; i++) {
		int ret = acpi_power_off_device(
				dev->wakeup.resources.handles[i]);
		if (ret) {
			printk(KERN_ERR PREFIX "Transition power state\n");
			dev->wakeup.flags.valid = 0;
			err = -ENODEV;
			goto out;
		}
	}

 out:
	mutex_unlock(&acpi_device_lock);
	return err;
}