]> git.hungrycats.org Git - linux/commitdiff
ACPI: Add S4BIOS support (Pavel Machek)
authorAndy Grover <agrover@groveronline.com>
Thu, 27 Feb 2003 08:26:34 +0000 (00:26 -0800)
committerAndy Grover <agrover@groveronline.com>
Thu, 27 Feb 2003 08:26:34 +0000 (00:26 -0800)
drivers/acpi/sleep/main.c
drivers/acpi/sleep/proc.c
include/linux/suspend.h

index 4c6e991acf67ecc2bedd04ba47a78d22b8b78377..fc99856172413a9c1a4c9ffde35b443c40c58871 100644 (file)
@@ -183,14 +183,21 @@ acpi_system_suspend(
                status = acpi_enter_sleep_state(state);
                break;
 
-       case ACPI_STATE_S2:
 #ifdef CONFIG_SOFTWARE_SUSPEND
+       case ACPI_STATE_S2:
        case ACPI_STATE_S3:
                do_suspend_lowlevel(0);
+               break;
 #endif
+       case ACPI_STATE_S4:
+               do_suspend_lowlevel_s4bios(0);
+               break;
+       default:
+               printk(KERN_WARNING PREFIX "don't know how to handle %d state.\n", state);
                break;
        }
        local_irq_restore(flags);
+       printk(KERN_CRIT "Back to C!\n");
 
        return status;
 }
@@ -211,10 +218,20 @@ acpi_suspend (
        if (state < ACPI_STATE_S1 || state > ACPI_STATE_S5)
                return AE_ERROR;
 
+       /* Since we handle S4OS via a different path (swsusp), give up if no s4bios. */
+       if (state == ACPI_STATE_S4 && !acpi_gbl_FACS->S4bios_f)
+               return AE_ERROR;
+
+       /*
+        * TBD: S1 can be done without device_suspend.  Make a CONFIG_XX
+        * to handle however when S1 failed without device_suspend.
+        */
        freeze_processes();             /* device_suspend needs processes to be stopped */
 
        /* do we have a wakeup address for S2 and S3? */
-       if (state == ACPI_STATE_S2 || state == ACPI_STATE_S3) {
+       /* Here, we support only S4BIOS, those we set the wakeup address */
+       /* S4OS is only supported for now via swsusp.. */
+       if (state == ACPI_STATE_S2 || state == ACPI_STATE_S3 || ACPI_STATE_S4) {
                if (!acpi_wakeup_address)
                        return AE_ERROR;
                acpi_set_firmware_waking_vector((acpi_physical_address) acpi_wakeup_address);
@@ -268,6 +285,10 @@ static int __init acpi_sleep_init(void)
                        sleep_states[i] = 1;
                        printk(" S%d", i);
                }
+               if (i == ACPI_STATE_S4 && acpi_gbl_FACS->S4bios_f) {
+                       sleep_states[i] = 1;
+                       printk(" S4bios");
+               }
        }
        printk(")\n");
 
index 687d002187d36f349b941441b167acfd8a30e3d5..50f0bdfd0992411b3d364dff41c712cb9a1b99e5 100644 (file)
@@ -27,8 +27,11 @@ static int acpi_system_sleep_seq_show(struct seq_file *seq, void *offset)
        ACPI_FUNCTION_TRACE("acpi_system_sleep_seq_show");
 
        for (i = 0; i <= ACPI_STATE_S5; i++) {
-               if (sleep_states[i])
+               if (sleep_states[i]) {
                        seq_printf(seq,"S%d ", i);
+                       if (i == ACPI_STATE_S4 && acpi_gbl_FACS->S4bios_f)
+                               seq_printf(seq, "S4bios ");
+               }
        }
 
        seq_puts(seq, "\n");
index 80b4a657b49cb98f4628e5ec8cd06d412726a6e7..901d2ac58ba59599c802148f09fff1bf2f68c26e 100644 (file)
@@ -73,6 +73,7 @@ extern void do_magic_suspend_2(void);
 /* Communication between acpi and arch/i386/suspend.c */
 
 extern void do_suspend_lowlevel(int resume);
+extern void do_suspend_lowlevel_s4bios(int resume);
 
 #else
 static inline void software_suspend(void)