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; if (dev->wakeup.prepare_count < 0) dev->wakeup.prepare_count = 0; err = acpi_device_sleep_wake(dev, 0, 0, 0); if (err) goto out; for (i = 0; i < dev->wakeup.resources.count; i++) { int ret = acpi_power_off(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; }
/* * 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; }
/* * 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; }