X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=drivers%2Facpi%2Fpower.c;h=419b371d95ad83ee4612f43722472b60e5f536bf;hb=6a77f38946aaee1cd85eeec6cf4229b204c15071;hp=4dcfcd566d977f23e2a0255ef95436d42ad9d0e5;hpb=5273a3df6485dc2ad6aa7ddd441b9a21970f003b;p=linux-2.6.git diff --git a/drivers/acpi/power.c b/drivers/acpi/power.c index 4dcfcd566..419b371d9 100644 --- a/drivers/acpi/power.c +++ b/drivers/acpi/power.c @@ -288,6 +288,86 @@ acpi_power_off_device ( return_VALUE(0); } +/* + * Prepare a wakeup device, two steps (Ref ACPI 2.0:P229): + * 1. Power on the power resources required for the wakeup device + * 2. Enable _PSW (power state wake) for the device if present + */ +int acpi_enable_wakeup_device_power (struct acpi_device *dev) +{ + union acpi_object arg = {ACPI_TYPE_INTEGER}; + struct acpi_object_list arg_list = {1, &arg}; + acpi_status status = AE_OK; + int i; + int ret = 0; + + ACPI_FUNCTION_TRACE("acpi_enable_wakeup_device_power"); + if (!dev || !dev->wakeup.flags.valid) + return_VALUE(-1); + + arg.integer.value = 1; + /* Open power resource */ + for (i = 0; i < dev->wakeup.resources.count; i++) { + ret = acpi_power_on(dev->wakeup.resources.handles[i]); + if (ret) { + ACPI_DEBUG_PRINT((ACPI_DB_ERROR, + "Error transition power state\n")); + dev->wakeup.flags.valid = 0; + return_VALUE(-1); + } + } + + /* Execute PSW */ + status = acpi_evaluate_object(dev->handle, "_PSW", &arg_list, NULL); + if (ACPI_FAILURE(status) && (status != AE_NOT_FOUND)) { + ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Error evaluate _PSW\n")); + dev->wakeup.flags.valid = 0; + ret = -1; + } + + return_VALUE(ret); +} + +/* + * Shutdown a wakeup device, counterpart of above method + * 1. Disable _PSW (power state wake) + * 2. Shutdown down the power resources + */ +int acpi_disable_wakeup_device_power (struct acpi_device *dev) +{ + union acpi_object arg = {ACPI_TYPE_INTEGER}; + struct acpi_object_list arg_list = {1, &arg}; + acpi_status status = AE_OK; + int i; + int ret = 0; + + ACPI_FUNCTION_TRACE("acpi_disable_wakeup_device_power"); + + if (!dev || !dev->wakeup.flags.valid) + return_VALUE(-1); + + arg.integer.value = 0; + /* Execute PSW */ + status = acpi_evaluate_object(dev->handle, "_PSW", &arg_list, NULL); + if (ACPI_FAILURE(status) && (status != AE_NOT_FOUND)) { + ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Error evaluate _PSW\n")); + dev->wakeup.flags.valid = 0; + return_VALUE(-1); + } + + /* Close power resource */ + for (i = 0; i < dev->wakeup.resources.count; i++) { + ret = acpi_power_off_device(dev->wakeup.resources.handles[i]); + if (ret) { + ACPI_DEBUG_PRINT((ACPI_DB_ERROR, + "Error transition power state\n")); + dev->wakeup.flags.valid = 0; + return_VALUE(-1); + } + } + + return_VALUE(ret); +} /* -------------------------------------------------------------------------- Device Power Management @@ -433,7 +513,7 @@ static int acpi_power_seq_show(struct seq_file *seq, void *offset) resource->references); end: - return 0; + return_VALUE(0); } static int acpi_power_open_fs(struct inode *inode, struct file *file) @@ -482,6 +562,8 @@ acpi_power_remove_fs ( ACPI_FUNCTION_TRACE("acpi_power_remove_fs"); if (acpi_device_dir(device)) { + remove_proc_entry(ACPI_POWER_FILE_STATUS, + acpi_device_dir(device)); remove_proc_entry(acpi_device_bid(device), acpi_power_dir); acpi_device_dir(device) = NULL; }