Merge branches 'release', 'acpica', 'bugzilla-10224', 'bugzilla-9772', 'bugzilla...
[pandora-kernel.git] / drivers / acpi / scan.c
index 6b1999b..6d85289 100644 (file)
@@ -677,9 +677,8 @@ acpi_bus_extract_wakeup_device_power_package(struct acpi_device *device,
        device->wakeup.resources.count = package->package.count - 2;
        for (i = 0; i < device->wakeup.resources.count; i++) {
                element = &(package->package.elements[i + 2]);
-               if (element->type != ACPI_TYPE_ANY) {
+               if (element->type != ACPI_TYPE_LOCAL_REFERENCE)
                        return AE_BAD_DATA;
-               }
 
                device->wakeup.resources.handles[i] = element->reference.handle;
        }
@@ -692,6 +691,9 @@ static int acpi_bus_get_wakeup_device_flags(struct acpi_device *device)
        acpi_status status = 0;
        struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };
        union acpi_object *package = NULL;
+       union acpi_object in_arg[3];
+       struct acpi_object_list arg_list = { 3, in_arg };
+       acpi_status psw_status = AE_OK;
 
        struct acpi_device_id button_device_ids[] = {
                {"PNP0C0D", 0},
@@ -700,7 +702,6 @@ static int acpi_bus_get_wakeup_device_flags(struct acpi_device *device)
                {"", 0},
        };
 
-
        /* _PRW */
        status = acpi_evaluate_object(device->handle, "_PRW", NULL, &buffer);
        if (ACPI_FAILURE(status)) {
@@ -718,6 +719,45 @@ static int acpi_bus_get_wakeup_device_flags(struct acpi_device *device)
        kfree(buffer.pointer);
 
        device->wakeup.flags.valid = 1;
+       /* Call _PSW/_DSW object to disable its ability to wake the sleeping
+        * system for the ACPI device with the _PRW object.
+        * The _PSW object is depreciated in ACPI 3.0 and is replaced by _DSW.
+        * So it is necessary to call _DSW object first. Only when it is not
+        * present will the _PSW object used.
+        */
+       /*
+        * Three agruments are needed for the _DSW object.
+        * Argument 0: enable/disable the wake capabilities
+        * When _DSW object is called to disable the wake capabilities, maybe
+        * the first argument is filled. The value of the other two agruments
+        * is meaningless.
+        */
+       in_arg[0].type = ACPI_TYPE_INTEGER;
+       in_arg[0].integer.value = 0;
+       in_arg[1].type = ACPI_TYPE_INTEGER;
+       in_arg[1].integer.value = 0;
+       in_arg[2].type = ACPI_TYPE_INTEGER;
+       in_arg[2].integer.value = 0;
+       psw_status = acpi_evaluate_object(device->handle, "_DSW",
+                                               &arg_list, NULL);
+       if (ACPI_FAILURE(psw_status) && (psw_status != AE_NOT_FOUND))
+               ACPI_DEBUG_PRINT((ACPI_DB_INFO, "error in evaluate _DSW\n"));
+       /*
+        * When the _DSW object is not present, OSPM will call _PSW object.
+        */
+       if (psw_status == AE_NOT_FOUND) {
+               /*
+                * Only one agruments is required for the _PSW object.
+                * agrument 0: enable/disable the wake capabilities
+                */
+               arg_list.count = 1;
+               in_arg[0].integer.value = 0;
+               psw_status = acpi_evaluate_object(device->handle, "_PSW",
+                                               &arg_list, NULL);
+               if (ACPI_FAILURE(psw_status) && (psw_status != AE_NOT_FOUND))
+                       ACPI_DEBUG_PRINT((ACPI_DB_INFO, "error in "
+                                               "evaluate _PSW\n"));
+       }
        /* Power button, Lid switch always enable wakeup */
        if (!acpi_match_device_ids(device, button_device_ids))
                device->wakeup.flags.run_wake = 1;