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 /drivers/acpi | |
parent | 413f81eba35d6ede9289b0c8a920c013a84fac71 (diff) | |
download | kernel_goldelico_gta04-815ab0fd40579ad2aa42058298073503648762b9.zip kernel_goldelico_gta04-815ab0fd40579ad2aa42058298073503648762b9.tar.gz kernel_goldelico_gta04-815ab0fd40579ad2aa42058298073503648762b9.tar.bz2 |
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>
Diffstat (limited to 'drivers/acpi')
-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 f7ca8c5..c1d59cf 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, * Suspend / resume control */ static int acpi_idle_suspend; +static u32 saved_bm_rld; + +static void acpi_idle_bm_rld_save(void) +{ + acpi_read_bit_register(ACPI_BITREG_BUS_MASTER_RLD, &saved_bm_rld); +} +static void acpi_idle_bm_rld_restore(void) +{ + u32 resumed_bm_rld; + + acpi_read_bit_register(ACPI_BITREG_BUS_MASTER_RLD, &resumed_bm_rld); + + if (resumed_bm_rld != saved_bm_rld) + acpi_write_bit_register(ACPI_BITREG_BUS_MASTER_RLD, saved_bm_rld); +} int acpi_processor_suspend(struct acpi_device * device, pm_message_t state) { + if (acpi_idle_suspend == 1) + return 0; + + acpi_idle_bm_rld_save(); acpi_idle_suspend = 1; return 0; } int acpi_processor_resume(struct acpi_device * device) { + if (acpi_idle_suspend == 0) + return 0; + + acpi_idle_bm_rld_restore(); acpi_idle_suspend = 0; return 0; } |