mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
* S4bios support
@ 2002-06-12 19:28 Pavel Machek
  2002-06-14 17:14 ` Ducrot Bruno
  0 siblings, 1 reply; 4+ messages in thread
From: Pavel Machek @ 2002-06-12 19:28 UTC (permalink / raw)
  To: kernel list, ACPI mailing list, ducrot

Hi!

I ported s4bios support to 2.5.21 and make it somehow work on my
machine. It suspend, resumes (with nice graphics ;-), but kernel does
not wake up devices properly. If someone wants to play...
									Pavel
--- linux-swsusp/arch/i386/kernel/suspend.c	Wed Jun 12 08:39:31 2002
+++ linux-s4bios/arch/i386/kernel/suspend.c	Wed Jun 12 20:31:43 2002
@@ -302,3 +302,18 @@
 	do_magic_resume_2();
 }
 #endif
+
+void do_suspend_magic_s4bios(int resume)
+{
+	if (!resume) {
+		save_processor_context();
+		acpi_save_register_state((unsigned long) &&acpi_sleep_done);
+		acpi_enter_s4bios();
+		return;
+	}
+acpi_sleep_done:
+	restore_processor_context();
+	printk("CPU context restored...\n");
+}
+
+
--- linux-swsusp/drivers/acpi/hardware/hwsleep.c	Mon Jun  3 11:43:29 2002
+++ linux-s4bios/drivers/acpi/hardware/hwsleep.c	Wed Jun 12 20:51:44 2002
@@ -24,6 +24,8 @@
  *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  */
 
+#include <linux/delay.h>
+
 #include "acpi.h"
 
 #define _COMPONENT          ACPI_HARDWARE
@@ -289,9 +291,10 @@
 		 * away entirely.
 		 */
 		acpi_os_stall (10000000);
-
+#if 0
 		status = acpi_hw_register_write (ACPI_MTX_LOCK, ACPI_REGISTER_PM1_CONTROL,
 				 sleep_enable_reg_info->access_bit_mask);
+#endif
 		if (ACPI_FAILURE (status)) {
 			return_ACPI_STATUS (status);
 		}
@@ -311,6 +314,56 @@
 
 	return_ACPI_STATUS (AE_OK);
 }
+
+
+/******************************************************************************
+ *
+ * FUNCTION:    Acpi_enter_s4bios
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Perform a s4 bios request.
+ *
+ ******************************************************************************/
+
+acpi_status
+acpi_enter_s4bios (void)
+{
+	acpi_status         status;
+	u32                     in_value;
+
+	ACPI_FUNCTION_TRACE ("Acpi_enter_s4bios");
+	printk("Acpi_enter_s4bios\n");
+
+	acpi_set_register (ACPI_BITREG_WAKE_STATUS, 1, ACPI_MTX_LOCK);
+	printk("2\n");
+	acpi_hw_clear_acpi_status();
+
+	printk("3\n");
+	acpi_hw_disable_non_wakeup_gpes();
+
+	printk("4\n");
+	ACPI_FLUSH_CPU_CACHE();
+
+	printk("go");
+	mdelay(1000);
+	status = acpi_os_write_port (acpi_gbl_FADT->smi_cmd, (acpi_integer) acpi_gbl_FADT->S4bios_req, 8);
+
+	printk("5\n");
+	do {
+		status = acpi_get_register (ACPI_BITREG_WAKE_STATUS, &in_value, ACPI_MTX_LOCK);
+		if (ACPI_FAILURE (status)) {
+			return_ACPI_STATUS (status);
+		}
+
+		printk("6");
+		/* Spin until we wake */
+
+	} while (!in_value);
+
+	return_ACPI_STATUS (AE_OK);
+}
+
 
 /******************************************************************************
  *
--- linux-swsusp/drivers/acpi/system.c	Mon Jun 10 23:03:25 2002
+++ linux-s4bios/drivers/acpi/system.c	Wed Jun 12 21:05:08 2002
@@ -26,6 +26,7 @@
 #define ACPI_C
 #define HAVE_NEW_DEVICE_MODEL
 
+#define HAVE_NEW_DEVICE_MODEL
 #include <linux/config.h>
 #include <linux/kernel.h>
 #include <linux/module.h>
@@ -99,6 +100,17 @@
 	acpi_enter_sleep_state(ACPI_STATE_S5);
 }
 
+static void
+acpi_enter_suspend_to_disk(void)
+{
+	acpi_set_firmware_waking_vector((ACPI_PHYSICAL_ADDRESS) acpi_wakeup_address);
+	acpi_enter_sleep_state_prep(ACPI_STATE_S4);
+	ACPI_DISABLE_IRQS();
+	acpi_enter_sleep_state(ACPI_STATE_S4);
+	acpi_set_firmware_waking_vector((ACPI_PHYSICAL_ADDRESS) 0);
+}
+
+
 #endif /*CONFIG_PM*/
 
 
@@ -199,8 +211,10 @@
 		if (state > ACPI_STATE_S1) {
 			error = acpi_save_state_mem();
 
+#if 0
 			if (!error && (state == ACPI_STATE_S4))
 				error = acpi_save_state_disk();
+#endif
 
 #ifdef HAVE_NEW_DEVICE_MODEL
 			if (error) {
@@ -278,6 +292,9 @@
 	case ACPI_STATE_S3:
 		do_suspend_lowlevel(0);
 		break;
+	case ACPI_STATE_S4:
+		do_suspend_magic_s4bios(0);
+		break;
 	}
 	restore_flags(flags);
 
@@ -300,7 +317,21 @@
 	if (state < ACPI_STATE_S1 || state > ACPI_STATE_S5)
 		return AE_ERROR;
 
-	freeze_processes();		/* device_suspend needs processes to be stopped */
+	switch (state) {
+	case ACPI_STATE_S1:
+		break;
+	case ACPI_STATE_S2:
+	case ACPI_STATE_S3:
+	case ACPI_STATE_S4:
+		/* do we have a wakeup address for S2, S3 and S4? */
+		if (!acpi_wakeup_address)
+			return AE_ERROR;
+		freeze_processes();
+		acpi_set_firmware_waking_vector((ACPI_PHYSICAL_ADDRESS) acpi_wakeup_address);
+		break;
+	default:
+		break;
+	}
 
 	/* do we have a wakeup address for S2 and S3? */
 	if (state == ACPI_STATE_S2 || state == ACPI_STATE_S3) {
@@ -326,15 +357,22 @@
 	 * mode. So, we run these unconditionaly to make sure we have a usable system
 	 * no matter what.
 	 */
-	acpi_system_restore_state(state);
+	printk("restore_state\n");
+//	acpi_system_restore_state(state);
+	printk("leave_sleep\n");
 	acpi_leave_sleep_state(state);
+	printk("enable\n");
 
 	/* make sure interrupts are enabled */
 	ACPI_ENABLE_IRQS();
 
-	/* reset firmware waking vector */
-	acpi_set_firmware_waking_vector((ACPI_PHYSICAL_ADDRESS) 0);
-	thaw_processes();
+	if (state != ACPI_STATE_S1) {
+		/* reset firmware waking vector */
+		acpi_set_firmware_waking_vector((ACPI_PHYSICAL_ADDRESS) 0);
+
+		thaw_processes();
+	}
+	printk("ready?\n");
 
 	return status;
 }
@@ -717,7 +755,7 @@
 
 	
 #ifdef CONFIG_SOFTWARE_SUSPEND
-	if (state == 4) {
+	if (state == 4 && state_string[1] != 'b') {
 		software_suspend();
 		return_VALUE(count);
 	}
--- linux-swsusp/include/asm-i386/acpi.h	Mon Jun  3 11:43:37 2002
+++ linux-s4bios/include/asm-i386/acpi.h	Wed Jun 12 11:00:21 2002
@@ -138,6 +138,9 @@
 /* early initialization routine */
 extern void acpi_reserve_bootmem(void);
 
+extern void do_suspend_magic(int);
+extern void do_suspend_magic_s4(int);
+
 #endif /*CONFIG_ACPI_SLEEP*/
 
 #endif /*__KERNEL__*/
--- linux-swsusp/include/linux/suspend.h	Wed Jun 12 08:43:51 2002
+++ linux-s4bios/include/linux/suspend.h	Wed Jun 12 11:00:21 2002
@@ -48,6 +48,9 @@
 /* mm/vmscan.c */
 extern int shrink_mem(void);
 
+/* kernel/signal.c */
+extern inline void signal_wake_up (struct task_struct *);
+
 /* kernel/suspend.c */
 extern void software_suspend(void);
 extern void software_resume(void);
@@ -55,6 +58,9 @@
 extern int register_suspend_notifier(struct notifier_block *);
 extern int unregister_suspend_notifier(struct notifier_block *);
 extern void refrigerator(unsigned long);
+
+extern int freeze_processes(void);
+extern void thaw_processes(void); 
 
 extern int freeze_processes(void);
 extern void thaw_processes(void);

-- 
(about SSSCA) "I don't say this lightly.  However, I really think that the U.S.
no longer is classifiable as a democracy, but rather as a plutocracy." --hpa

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: S4bios support
  2002-06-12 19:28 S4bios support Pavel Machek
@ 2002-06-14 17:14 ` Ducrot Bruno
  2002-06-16 20:44   ` Pavel Machek
  0 siblings, 1 reply; 4+ messages in thread
From: Ducrot Bruno @ 2002-06-14 17:14 UTC (permalink / raw)
  To: Pavel Machek; +Cc: kernel list, ACPI mailing list, ducrot

On Wed, Jun 12, 2002 at 09:28:21PM +0200, Pavel Machek wrote:
> Hi!
> 
> I ported s4bios support to 2.5.21 and make it somehow work on my
> machine. It suspend, resumes (with nice graphics ;-), but kernel does
> not wake up devices properly. If someone wants to play...

What kind of issues you got ?

-- 
Ducrot Bruno
http://www.poupinou.org        Page profaissionelle
http://toto.tu-me-saoules.com  Haume page

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: S4bios support
  2002-06-14 17:14 ` Ducrot Bruno
@ 2002-06-16 20:44   ` Pavel Machek
  0 siblings, 0 replies; 4+ messages in thread
From: Pavel Machek @ 2002-06-16 20:44 UTC (permalink / raw)
  To: Ducrot Bruno; +Cc: kernel list, ACPI mailing list, ducrot

> On Wed, Jun 12, 2002 at 09:28:21PM +0200, Pavel Machek wrote:
> > Hi!
> > 
> > I ported s4bios support to 2.5.21 and make it somehow work on my
> > machine. It suspend, resumes (with nice graphics ;-), but kernel does
> > not wake up devices properly. If someone wants to play...
> 
> What kind of issues you got ?

Lockup on awake.

-- 
Casualities in World Trade Center: ~3k dead inside the building,
cryptography in U.S.A. and free speech in Czech Republic.

^ permalink raw reply	[flat|nested] 4+ messages in thread

* S4bios support
@ 2003-02-11 18:54 Pavel Machek
  0 siblings, 0 replies; 4+ messages in thread
From: Pavel Machek @ 2003-02-11 18:54 UTC (permalink / raw)
  To: Andrew Grover, ACPI mailing list, kernel list

Hi!

S4bios is easier to use [no possibility to boot into wrong kernel;
machine actually indicates it is sleeping, not powered down], has
nicer progress bars, etc... I'd like to see it in. Please apply,

							Pavel

--- clean/arch/i386/kernel/acpi_wakeup.S	2003-02-11 17:40:33.000000000 +0100
+++ linux/arch/i386/kernel/acpi_wakeup.S	2003-02-11 12:51:03.000000000 +0100
@@ -314,6 +316,31 @@
 	pushl saved_context_eflags ; popfl
 	ret
 
+ENTRY(do_suspend_lowlevel_s4bios)
+	cmpl $0,4(%esp)
+	jne ret_point
+	call save_processor_state
+
+	movl %esp, saved_context_esp
+	movl %eax, saved_context_eax
+	movl %ebx, saved_context_ebx
+	movl %ecx, saved_context_ecx
+	movl %edx, saved_context_edx
+	movl %ebp, saved_context_ebp
+	movl %esi, saved_context_esi
+	movl %edi, saved_context_edi
+	pushfl ; popl saved_context_eflags
+
+	movl $ret_point,saved_eip
+	movl %esp,saved_esp
+	movl %ebp,saved_ebp
+	movl %ebx,saved_ebx
+	movl %edi,saved_edi
+	movl %esi,saved_esi
+
+	call acpi_enter_sleep_state_s4bios
+	ret
+
 ALIGN
 # saved registers
 saved_gdt:	.long	0,0
--- clean/drivers/acpi/acpi_ksyms.c	2003-02-11 17:40:46.000000000 +0100
+++ linux/drivers/acpi/acpi_ksyms.c	2003-02-11 17:51:05.000000000 +0100
@@ -86,6 +86,7 @@
 EXPORT_SYMBOL(acpi_get_register);
 EXPORT_SYMBOL(acpi_set_register);
 EXPORT_SYMBOL(acpi_enter_sleep_state);
+EXPORT_SYMBOL(acpi_enter_sleep_state_s4bios);
 EXPORT_SYMBOL(acpi_get_system_info);
 EXPORT_SYMBOL(acpi_get_devices);
 
--- clean/drivers/acpi/hardware/hwsleep.c	2003-01-17 23:09:33.000000000 +0100
+++ linux/drivers/acpi/hardware/hwsleep.c	2003-02-10 18:17:00.000000000 +0100
@@ -316,6 +316,51 @@
 	return_ACPI_STATUS (AE_OK);
 }
 
+
+/******************************************************************************
+ *
+ * FUNCTION:    acpi_enter_sleep_state_s4bios
+ *
+ * PARAMETERS:  None
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Perform a s4 bios request.
+ *              THIS FUNCTION MUST BE CALLED WITH INTERRUPTS DISABLED
+ *
+ ******************************************************************************/
+
+acpi_status
+acpi_enter_sleep_state_s4bios (
+	void)
+{
+	u32                     in_value;
+	acpi_status             status;
+
+
+	ACPI_FUNCTION_TRACE ("Acpi_enter_sleep_state_s4bios");
+
+	acpi_set_register (ACPI_BITREG_WAKE_STATUS, 1, ACPI_MTX_LOCK);
+	acpi_hw_clear_acpi_status();
+
+	acpi_hw_disable_non_wakeup_gpes();
+
+	ACPI_FLUSH_CPU_CACHE();
+
+	status = acpi_os_write_port (acpi_gbl_FADT->smi_cmd, (acpi_integer) acpi_gbl_FADT->S4bios_req, 8);
+
+	do {
+		acpi_os_stall(1000);
+		status = acpi_get_register (ACPI_BITREG_WAKE_STATUS, &in_value, ACPI_MTX_LOCK);
+		if (ACPI_FAILURE (status)) {
+			return_ACPI_STATUS (status);
+		}
+	} while (!in_value);
+ 
+ 	return_ACPI_STATUS (AE_OK);
+ }
+ 
+
 /******************************************************************************
  *
  * FUNCTION:    acpi_leave_sleep_state
--- clean/drivers/acpi/sleep.c	2003-01-05 22:58:25.000000000 +0100
+++ linux/drivers/acpi/sleep.c	2003-02-10 18:17:00.000000000 +0100
@@ -223,14 +224,20 @@
 		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);
 
 	return status;
 }
@@ -251,10 +259,20 @@
 	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);
@@ -297,8 +315,11 @@
 	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");
@@ -337,12 +358,16 @@
 	if (!sleep_states[state])
 		return_VALUE(-ENODEV);
 
+	if (state == 4 && state_string[1] != 'b') {
 #ifdef CONFIG_SOFTWARE_SUSPEND
-	if (state == 4) {
 		software_suspend();
 		return_VALUE(count);
-	}
+#else
+		printk(KERN_WARNING PREFIX "no swsusp support!?\n");
+		printk(KERN_WARNING PREFIX "Trying S4bios instead\n");
 #endif
+	}
+
 	status = acpi_suspend(state);
 
 	if (ACPI_FAILURE(status))
@@ -662,6 +687,10 @@
 			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");
 
--- clean/include/acpi/acpixf.h	2003-02-11 17:41:27.000000000 +0100
+++ linux/include/acpi/acpixf.h	2003-02-11 19:02:51.000000000 +0100
@@ -380,6 +380,10 @@
 	u8                              sleep_state);
 
 acpi_status
+acpi_enter_sleep_state_s4bios (
+	void);
+
+acpi_status
 acpi_leave_sleep_state (
 	u8                              sleep_state);
 
--- clean/include/linux/suspend.h	2003-01-05 22:58:44.000000000 +0100
+++ linux/include/linux/suspend.h	2003-02-10 18:17:01.000000000 +0100
@@ -73,6 +73,7 @@
 /* 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)

-- 
When do you have a heart between your knees?
[Johanka's followup: and *two* hearts?]

^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2003-02-12 20:38 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2002-06-12 19:28 S4bios support Pavel Machek
2002-06-14 17:14 ` Ducrot Bruno
2002-06-16 20:44   ` Pavel Machek
2003-02-11 18:54 Pavel Machek

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox

all inboxes | Powered by JetHome®