]> git.neil.brown.name Git - history.git/commitdiff
[PATCH] Fix suspend-to-RAM in 2.5.20
authorPavel Machek <pavel@ucw.cz>
Mon, 3 Jun 2002 06:25:44 +0000 (23:25 -0700)
committerLinus Torvalds <torvalds@penguin.transmeta.com>
Mon, 3 Jun 2002 06:25:44 +0000 (23:25 -0700)
I created arch/i386/suspend.c not to clash with ACPI people so much in
future. (More stuff is going to move into it in the future, to clean
up functions that really do not belong to the headers.)

arch/i386/kernel/Makefile
arch/i386/kernel/suspend.c [new file with mode: 0644]
drivers/acpi/system.c
include/asm-i386/suspend.h

index 9f534753206228f065e3bafb2c111a20373017f7..8ca2b738265cf9795d80bec6ba9523dd9fedaf6d 100644 (file)
@@ -24,6 +24,8 @@ obj-$(CONFIG_ACPI_SLEEP)      += acpi_wakeup.o
 obj-$(CONFIG_SMP)              += smp.o smpboot.o trampoline.o
 obj-$(CONFIG_X86_LOCAL_APIC)   += mpparse.o apic.o nmi.o
 obj-$(CONFIG_X86_IO_APIC)      += io_apic.o
+obj-$(CONFIG_SOFTWARE_SUSPEND) += suspend.o
+obj-$(CONFIG_ACPI_SLEEP)       += suspend.o
 ifdef CONFIG_VISWS
 obj-y += setup-visws.o
 obj-$(CONFIG_X86_VISWS_APIC)   += visws_apic.o
diff --git a/arch/i386/kernel/suspend.c b/arch/i386/kernel/suspend.c
new file mode 100644 (file)
index 0000000..9302e60
--- /dev/null
@@ -0,0 +1,45 @@
+/*
+ * Suspend support specific for i386.
+ *
+ * Distribute under GPLv2
+ *
+ * Copyright (c) 2002 Pavel Machek <pavel@suse.cz>
+ */
+
+#define ACPI_C
+#include <linux/config.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/types.h>
+#include <linux/spinlock.h>
+#include <linux/poll.h>
+#include <linux/delay.h>
+#include <linux/sysrq.h>
+#include <linux/compatmac.h>
+#include <linux/proc_fs.h>
+#include <linux/irq.h>
+#include <linux/pm.h>
+#include <linux/device.h>
+#include <linux/suspend.h>
+#include <asm/uaccess.h>
+#include <asm/acpi.h>
+
+
+void do_suspend_lowlevel(int resume)
+{
+/*
+ * FIXME: This function should really be written in assembly. Actually
+ * requirement is that it does not touch stack, because %esp will be
+ * wrong during resume before restore_processor_context(). Check
+ * assembly if you modify this.
+ */
+       if (!resume) {
+               save_processor_context();
+               acpi_save_register_state((unsigned long)&&acpi_sleep_done);
+               acpi_enter_sleep_state(3);
+               return;
+       }
+acpi_sleep_done:
+       restore_processor_context();
+}
index a6b3e8d377ee62a1dc8d4fa7d7d2db185d07e028..f7cd2fc8635b76be9ac0b8eddf848f3cd9a80567 100644 (file)
@@ -260,10 +260,8 @@ acpi_system_suspend(
        u32                     state)
 {
        acpi_status             status = AE_ERROR;
-#if 0
        unsigned long           flags = 0;
 
-       /* this is very broken, so don't do anything until it's fixed */
        save_flags(flags);
        
        switch (state)
@@ -289,8 +287,6 @@ acpi_sleep_done:
        fix_processor_context();
 
        restore_flags(flags);
-#endif
-       printk("ACPI: ACPI-based suspend currently broken, aborting\n");
 
        return status;
 }
index 203e10e23cb7b4dcbe061d026a786988d536b6a3..b41d88f4592855c8b00d8fc0bb3162133f67e7e5 100644 (file)
@@ -294,3 +294,27 @@ static void do_magic(int resume)
 }
 #endif 
 
+#ifdef CONFIG_ACPI_SLEEP
+extern unsigned long saved_eip;
+extern unsigned long saved_esp;
+extern unsigned long saved_ebp;
+extern unsigned long saved_ebx;
+extern unsigned long saved_esi;
+extern unsigned long saved_edi;
+
+static inline void acpi_save_register_state(unsigned long return_point)
+{
+       saved_eip = return_point;
+       asm volatile ("movl %%esp,(%0)" : "=m" (saved_esp));
+       asm volatile ("movl %%ebp,(%0)" : "=m" (saved_ebp));
+       asm volatile ("movl %%ebx,(%0)" : "=m" (saved_ebx));
+       asm volatile ("movl %%edi,(%0)" : "=m" (saved_edi));
+       asm volatile ("movl %%esi,(%0)" : "=m" (saved_esi));
+}
+
+#define acpi_restore_register_state()  do {} while (0)
+
+/* routines for saving/restoring kernel state */
+extern int acpi_save_state_mem(void);
+extern int acpi_save_state_disk(void);
+#endif