Gitweb:     
http://git.kernel.org/git/?p=linux/kernel/git/torvalds/linux-2.6.git;a=commit;h=b04e7bdb984e3b7f62fb7f44146a529f88cc7639
Commit:     b04e7bdb984e3b7f62fb7f44146a529f88cc7639
Parent:     1f0cff6e4d579ab0fe671c02fcd842694e46b90f
Author:     Thomas Gleixner <[EMAIL PROTECTED]>
AuthorDate: Sat Sep 22 22:29:05 2007 +0000
Committer:  Linus Torvalds <[EMAIL PROTECTED]>
CommitDate: Sat Sep 22 17:15:34 2007 -0700

    ACPI: disable lower idle C-states across suspend/resume
    
    device_suspend() calls ACPI suspend functions, which seems to have undesired
    side effects on lower idle C-states. It took me some time to realize that
    especially the VAIO BIOSes (both Andrews jinxed UP and my elfstruck SMP one)
    show this effect. I'm quite sure that other bug reports against 
suspend/resume
    about turning the system into a brick have the same root cause.
    
    After fishing in the dark for quite some time, I realized that removing the 
ACPI
    processor module before suspend (this removes the lower C-state 
functionality)
    made the problem disappear. Interestingly enough the propability of having a
    bricked box is influenced by various factors (interrupts, size of the ram 
image,
    ...). Even adding a bunch of printks in the wrong places made the problem go
    away. The previous periodic tick implementation simply pampered over the
    problem, which explains why the dyntick / clockevents changes made this more
    prominent.
    
    We avoid complex functionality during the boot process and we have to do the
    same during suspend/resume. It is a similar scenario and equaly fragile.
    
    Add suspend / resume functions to the ACPI processor code and disable the 
lower
    idle C-states across suspend/resume. Fall back to the default idle
    implementation (halt) instead.
    
    Signed-off-by: Thomas Gleixner <[EMAIL PROTECTED]>
    Tested-by: Andrew Morton <[EMAIL PROTECTED]>
    Cc: Len Brown <[EMAIL PROTECTED]>
    Cc: Venkatesh Pallipadi <[EMAIL PROTECTED]>
    Cc: Rafael J. Wysocki <[EMAIL PROTECTED]>
    Signed-off-by: Linus Torvalds <[EMAIL PROTECTED]>
---
 drivers/acpi/processor_core.c |    2 ++
 drivers/acpi/processor_idle.c |   19 ++++++++++++++++++-
 include/acpi/processor.h      |    2 ++
 3 files changed, 22 insertions(+), 1 deletions(-)

diff --git a/drivers/acpi/processor_core.c b/drivers/acpi/processor_core.c
index 2afb3d2..9f11dc2 100644
--- a/drivers/acpi/processor_core.c
+++ b/drivers/acpi/processor_core.c
@@ -102,6 +102,8 @@ static struct acpi_driver acpi_processor_driver = {
                .add = acpi_processor_add,
                .remove = acpi_processor_remove,
                .start = acpi_processor_start,
+               .suspend = acpi_processor_suspend,
+               .resume = acpi_processor_resume,
                },
 };
 
diff --git a/drivers/acpi/processor_idle.c b/drivers/acpi/processor_idle.c
index d9b8af7..f182613 100644
--- a/drivers/acpi/processor_idle.c
+++ b/drivers/acpi/processor_idle.c
@@ -325,6 +325,23 @@ static void acpi_state_timer_broadcast(struct 
acpi_processor *pr,
 
 #endif
 
+/*
+ * Suspend / resume control
+ */
+static int acpi_idle_suspend;
+
+int acpi_processor_suspend(struct acpi_device * device, pm_message_t state)
+{
+       acpi_idle_suspend = 1;
+       return 0;
+}
+
+int acpi_processor_resume(struct acpi_device * device)
+{
+       acpi_idle_suspend = 0;
+       return 0;
+}
+
 static void acpi_processor_idle(void)
 {
        struct acpi_processor *pr = NULL;
@@ -355,7 +372,7 @@ static void acpi_processor_idle(void)
        }
 
        cx = pr->power.state;
-       if (!cx) {
+       if (!cx || acpi_idle_suspend) {
                if (pm_idle_save)
                        pm_idle_save();
                else
diff --git a/include/acpi/processor.h b/include/acpi/processor.h
index ec3ffda..99934a9 100644
--- a/include/acpi/processor.h
+++ b/include/acpi/processor.h
@@ -320,6 +320,8 @@ int acpi_processor_power_init(struct acpi_processor *pr,
 int acpi_processor_cst_has_changed(struct acpi_processor *pr);
 int acpi_processor_power_exit(struct acpi_processor *pr,
                              struct acpi_device *device);
+int acpi_processor_suspend(struct acpi_device * device, pm_message_t state);
+int acpi_processor_resume(struct acpi_device * device);
 
 /* in processor_thermal.c */
 int acpi_processor_get_limit_info(struct acpi_processor *pr);
-
To unsubscribe from this list: send the line "unsubscribe git-commits-head" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to