int acpi_enable_wakeup_device_power(struct acpi_device *dev, int sleep_state) { int i, err = 0; if (!dev || !dev->wakeup.flags.valid) return -EINVAL; mutex_lock(&acpi_device_lock); if (dev->wakeup.prepare_count++) goto out; for (i = 0; i < dev->wakeup.resources.count; i++) { int ret = acpi_power_on(dev->wakeup.resources.handles[i]); if (ret) { printk(KERN_ERR PREFIX "Transition power state\n"); dev->wakeup.flags.valid = 0; err = -ENODEV; goto err_out; } } err = acpi_device_sleep_wake(dev, 1, sleep_state, 3); err_out: if (err) dev->wakeup.prepare_count = 0; out: mutex_unlock(&acpi_device_lock); return err; }
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; }
static int acpi_power_on_list(struct acpi_handle_list *list) { int result = 0; int i; for (i = 0; i < list->count; i++) { result = acpi_power_on(list->handles[i]); if (result) { __acpi_power_off_list(list, i); break; } } return result; }
/* * Prepare a wakeup device, two steps (Ref ACPI 2.0:P229): * 1. Power on the power resources required for the wakeup device * 2. Execute _DSW (Device Sleep Wake) or (deprecated in ACPI 3.0) _PSW (Power * State Wake) for the device, if present */ int acpi_enable_wakeup_device_power(struct acpi_device *dev, int sleep_state) { int i, err = 0; if (!dev || !dev->wakeup.flags.valid) return -EINVAL; mutex_lock(&acpi_device_lock); if (dev->wakeup.prepare_count++) goto out; /* Open power resource */ for (i = 0; i < dev->wakeup.resources.count; i++) { int ret = acpi_power_on(dev->wakeup.resources.handles[i]); if (ret) { printk(KERN_ERR PREFIX "Transition power state\n"); dev->wakeup.flags.valid = 0; err = -ENODEV; goto err_out; } } /* * Passing 3 as the third argument below means the device may be placed * in arbitrary power state afterwards. */ err = acpi_device_sleep_wake(dev, 1, sleep_state, 3); err_out: if (err) dev->wakeup.prepare_count = 0; out: mutex_unlock(&acpi_device_lock); return err; }