diff options
author | Len Brown <len.brown@intel.com> | 2009-05-07 22:19:45 -0400 |
---|---|---|
committer | Len Brown <len.brown@intel.com> | 2009-05-15 22:44:05 -0400 |
commit | 815ab0fd40579ad2aa42058298073503648762b9 (patch) | |
tree | b9e00755f79f98b29b27b711c50ee9d46e1e9dc2 | |
parent | 413f81eba35d6ede9289b0c8a920c013a84fac71 (diff) |
ACPI: suspend: restore BM_RLD on resume
In 2.6.29,
31878dd86b7df9a147f5e6cc6e07092b4308782b
"ACPI: remove BM_RLD access from idle entry path"
moved BM_RLD initialization to init-time from run time.
But we discovered that some BIOS do not restore BM_RLD
after suspend, causing device errors on C3 and C4
after resume. So now the kernel restores BM_RLD.
http://bugzilla.kernel.org/show_bug.cgi?id=13032
Signed-off-by: Len Brown <len.brown@intel.com>
-rw-r--r-- | drivers/acpi/processor_idle.c | 23 |
1 files changed, 23 insertions, 0 deletions
diff --git a/drivers/acpi/processor_idle.c b/drivers/acpi/processor_idle.c index f7ca8c55956b..c1d59cfdb5fb 100644 --- a/drivers/acpi/processor_idle.c +++ b/drivers/acpi/processor_idle.c | |||
@@ -202,15 +202,38 @@ static void acpi_state_timer_broadcast(struct acpi_processor *pr, | |||
202 | * Suspend / resume control | 202 | * Suspend / resume control |
203 | */ | 203 | */ |
204 | static int acpi_idle_suspend; | 204 | static int acpi_idle_suspend; |
205 | static u32 saved_bm_rld; | ||
206 | |||
207 | static void acpi_idle_bm_rld_save(void) | ||
208 | { | ||
209 | acpi_read_bit_register(ACPI_BITREG_BUS_MASTER_RLD, &saved_bm_rld); | ||
210 | } | ||
211 | static void acpi_idle_bm_rld_restore(void) | ||
212 | { | ||
213 | u32 resumed_bm_rld; | ||
214 | |||
215 | acpi_read_bit_register(ACPI_BITREG_BUS_MASTER_RLD, &resumed_bm_rld); | ||
216 | |||
217 | if (resumed_bm_rld != saved_bm_rld) | ||
218 | acpi_write_bit_register(ACPI_BITREG_BUS_MASTER_RLD, saved_bm_rld); | ||
219 | } | ||
205 | 220 | ||
206 | int acpi_processor_suspend(struct acpi_device * device, pm_message_t state) | 221 | int acpi_processor_suspend(struct acpi_device * device, pm_message_t state) |
207 | { | 222 | { |
223 | if (acpi_idle_suspend == 1) | ||
224 | return 0; | ||
225 | |||
226 | acpi_idle_bm_rld_save(); | ||
208 | acpi_idle_suspend = 1; | 227 | acpi_idle_suspend = 1; |
209 | return 0; | 228 | return 0; |
210 | } | 229 | } |
211 | 230 | ||
212 | int acpi_processor_resume(struct acpi_device * device) | 231 | int acpi_processor_resume(struct acpi_device * device) |
213 | { | 232 | { |
233 | if (acpi_idle_suspend == 0) | ||
234 | return 0; | ||
235 | |||
236 | acpi_idle_bm_rld_restore(); | ||
214 | acpi_idle_suspend = 0; | 237 | acpi_idle_suspend = 0; |
215 | return 0; | 238 | return 0; |
216 | } | 239 | } |