aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/acpi
diff options
context:
space:
mode:
authorZhao Yakui <yakui.zhao@intel.com>2008-03-19 01:26:54 -0400
committerLen Brown <len.brown@intel.com>2008-04-09 21:57:22 -0400
commit729b2bdbfa19dd9be98dbd49caf2773b3271cc24 (patch)
tree525cca2b27a6252e54fea99db36d748ba299e32c /drivers/acpi
parent7180c4c9e09888db0a188f729c96c6d7bd61fa83 (diff)
ACPI : Disable the device's ability to wake the sleeping system in the boot phase
In some machines some GPE is shared by several ACPI devices, for example: sleep button, keyboard, mouse. At the same time one of them is non-wake(runtime) device and the other are wake devices. In such case OSPM should call the _PSW object to disable the device's ability to wake the sleeping system in the boot phase. Otherwise there will be ACPI interrupt flood triggered by the GPE input. 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. http://bugzilla.kernel.org/show_bug.cgi?id=10224 Signed-off-by: Zhao Yakui <yakui.zhao@intel.com> Signed-off-by: Zhang Rui <rui.zhang@intel.com> Signed-off-by: Len Brown <len.brown@intel.com>
Diffstat (limited to 'drivers/acpi')
-rw-r--r--drivers/acpi/scan.c43
1 files changed, 42 insertions, 1 deletions
diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c
index e6ce262b5d44..bd32351854ac 100644
--- a/drivers/acpi/scan.c
+++ b/drivers/acpi/scan.c
@@ -692,6 +692,9 @@ static int acpi_bus_get_wakeup_device_flags(struct acpi_device *device)
692 acpi_status status = 0; 692 acpi_status status = 0;
693 struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL }; 693 struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };
694 union acpi_object *package = NULL; 694 union acpi_object *package = NULL;
695 union acpi_object in_arg[3];
696 struct acpi_object_list arg_list = { 3, in_arg };
697 acpi_status psw_status = AE_OK;
695 698
696 struct acpi_device_id button_device_ids[] = { 699 struct acpi_device_id button_device_ids[] = {
697 {"PNP0C0D", 0}, 700 {"PNP0C0D", 0},
@@ -700,7 +703,6 @@ static int acpi_bus_get_wakeup_device_flags(struct acpi_device *device)
700 {"", 0}, 703 {"", 0},
701 }; 704 };
702 705
703
704 /* _PRW */ 706 /* _PRW */
705 status = acpi_evaluate_object(device->handle, "_PRW", NULL, &buffer); 707 status = acpi_evaluate_object(device->handle, "_PRW", NULL, &buffer);
706 if (ACPI_FAILURE(status)) { 708 if (ACPI_FAILURE(status)) {
@@ -718,6 +720,45 @@ static int acpi_bus_get_wakeup_device_flags(struct acpi_device *device)
718 kfree(buffer.pointer); 720 kfree(buffer.pointer);
719 721
720 device->wakeup.flags.valid = 1; 722 device->wakeup.flags.valid = 1;
723 /* Call _PSW/_DSW object to disable its ability to wake the sleeping
724 * system for the ACPI device with the _PRW object.
725 * The _PSW object is depreciated in ACPI 3.0 and is replaced by _DSW.
726 * So it is necessary to call _DSW object first. Only when it is not
727 * present will the _PSW object used.
728 */
729 /*
730 * Three agruments are needed for the _DSW object.
731 * Argument 0: enable/disable the wake capabilities
732 * When _DSW object is called to disable the wake capabilities, maybe
733 * the first argument is filled. The value of the other two agruments
734 * is meaningless.
735 */
736 in_arg[0].type = ACPI_TYPE_INTEGER;
737 in_arg[0].integer.value = 0;
738 in_arg[1].type = ACPI_TYPE_INTEGER;
739 in_arg[1].integer.value = 0;
740 in_arg[2].type = ACPI_TYPE_INTEGER;
741 in_arg[2].integer.value = 0;
742 psw_status = acpi_evaluate_object(device->handle, "_DSW",
743 &arg_list, NULL);
744 if (ACPI_FAILURE(psw_status) && (psw_status != AE_NOT_FOUND))
745 ACPI_DEBUG_PRINT((ACPI_DB_INFO, "error in evaluate _DSW\n"));
746 /*
747 * When the _DSW object is not present, OSPM will call _PSW object.
748 */
749 if (psw_status == AE_NOT_FOUND) {
750 /*
751 * Only one agruments is required for the _PSW object.
752 * agrument 0: enable/disable the wake capabilities
753 */
754 arg_list.count = 1;
755 in_arg[0].integer.value = 0;
756 psw_status = acpi_evaluate_object(device->handle, "_PSW",
757 &arg_list, NULL);
758 if (ACPI_FAILURE(psw_status) && (psw_status != AE_NOT_FOUND))
759 ACPI_DEBUG_PRINT((ACPI_DB_INFO, "error in "
760 "evaluate _PSW\n"));
761 }
721 /* Power button, Lid switch always enable wakeup */ 762 /* Power button, Lid switch always enable wakeup */
722 if (!acpi_match_device_ids(device, button_device_ids)) 763 if (!acpi_match_device_ids(device, button_device_ids))
723 device->wakeup.flags.run_wake = 1; 764 device->wakeup.flags.run_wake = 1;