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); }
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; }
/* * 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; }