diff options
| author | Rafael J. Wysocki <rjw@sisk.pl> | 2008-09-06 07:13:01 -0400 |
|---|---|---|
| committer | Len Brown <len.brown@intel.com> | 2008-10-16 20:45:35 -0400 |
| commit | a6629105dd03d370fcb31e97bddf223fa4bb651e (patch) | |
| tree | c7a516ef2ef9aee0ad38d41b35fb59a530b015da /drivers/acpi/hardware | |
| parent | e49f711cc8f3bf8d719a9f5c86e79ecc0a72bf70 (diff) | |
ACPI suspend: Always use the 32-bit waking vector
According to the ACPI specification 2.0c and later, the 64-bit waking vector
should be cleared and the 32-bit waking vector should be used, unless we want
the wake-up code to be called by the BIOS in Protected Mode. Moreover, some
systems (for example HP dv5-1004nr) are known to fail to resume if the 64-bit
waking vector is used. Therefore, modify the code to clear the 64-bit waking
vector, for FACS version 1 or greater, and set the 32-bit one before suspend.
http://bugzilla.kernel.org/show_bug.cgi?id=11368
Signed-off-by: Rafael J. Wysocki <rjw@sisk.pl>
Signed-off-by: Len Brown <len.brown@intel.com>
Diffstat (limited to 'drivers/acpi/hardware')
| -rw-r--r-- | drivers/acpi/hardware/hwsleep.c | 37 |
1 files changed, 11 insertions, 26 deletions
diff --git a/drivers/acpi/hardware/hwsleep.c b/drivers/acpi/hardware/hwsleep.c index 130a44b79687..25dccdf179b9 100644 --- a/drivers/acpi/hardware/hwsleep.c +++ b/drivers/acpi/hardware/hwsleep.c | |||
| @@ -78,19 +78,17 @@ acpi_set_firmware_waking_vector(acpi_physical_address physical_address) | |||
| 78 | return_ACPI_STATUS(status); | 78 | return_ACPI_STATUS(status); |
| 79 | } | 79 | } |
| 80 | 80 | ||
| 81 | /* Set the vector */ | 81 | /* |
| 82 | * According to the ACPI specification 2.0c and later, the 64-bit | ||
| 83 | * waking vector should be cleared and the 32-bit waking vector should | ||
| 84 | * be used, unless we want the wake-up code to be called by the BIOS in | ||
| 85 | * Protected Mode. Some systems (for example HP dv5-1004nr) are known | ||
| 86 | * to fail to resume if the 64-bit vector is used. | ||
| 87 | */ | ||
| 88 | if (facs->version >= 1) | ||
| 89 | facs->xfirmware_waking_vector = 0; | ||
| 82 | 90 | ||
| 83 | if ((facs->length < 32) || (!(facs->xfirmware_waking_vector))) { | 91 | facs->firmware_waking_vector = (u32)physical_address; |
| 84 | /* | ||
| 85 | * ACPI 1.0 FACS or short table or optional X_ field is zero | ||
| 86 | */ | ||
| 87 | facs->firmware_waking_vector = (u32) physical_address; | ||
| 88 | } else { | ||
| 89 | /* | ||
| 90 | * ACPI 2.0 FACS with valid X_ field | ||
| 91 | */ | ||
| 92 | facs->xfirmware_waking_vector = physical_address; | ||
| 93 | } | ||
| 94 | 92 | ||
| 95 | return_ACPI_STATUS(AE_OK); | 93 | return_ACPI_STATUS(AE_OK); |
| 96 | } | 94 | } |
| @@ -134,20 +132,7 @@ acpi_get_firmware_waking_vector(acpi_physical_address * physical_address) | |||
| 134 | } | 132 | } |
| 135 | 133 | ||
| 136 | /* Get the vector */ | 134 | /* Get the vector */ |
| 137 | 135 | *physical_address = (acpi_physical_address)facs->firmware_waking_vector; | |
| 138 | if ((facs->length < 32) || (!(facs->xfirmware_waking_vector))) { | ||
| 139 | /* | ||
| 140 | * ACPI 1.0 FACS or short table or optional X_ field is zero | ||
| 141 | */ | ||
| 142 | *physical_address = | ||
| 143 | (acpi_physical_address) facs->firmware_waking_vector; | ||
| 144 | } else { | ||
| 145 | /* | ||
| 146 | * ACPI 2.0 FACS with valid X_ field | ||
| 147 | */ | ||
| 148 | *physical_address = | ||
| 149 | (acpi_physical_address) facs->xfirmware_waking_vector; | ||
| 150 | } | ||
| 151 | 136 | ||
| 152 | return_ACPI_STATUS(AE_OK); | 137 | return_ACPI_STATUS(AE_OK); |
| 153 | } | 138 | } |
