Commit c74c7c6a authored by Andy Grover's avatar Andy Grover

ACPI: Add S4BIOS support (Pavel Machek)

parent e1494263
...@@ -183,14 +183,21 @@ acpi_system_suspend( ...@@ -183,14 +183,21 @@ acpi_system_suspend(
status = acpi_enter_sleep_state(state); status = acpi_enter_sleep_state(state);
break; break;
case ACPI_STATE_S2:
#ifdef CONFIG_SOFTWARE_SUSPEND #ifdef CONFIG_SOFTWARE_SUSPEND
case ACPI_STATE_S2:
case ACPI_STATE_S3: case ACPI_STATE_S3:
do_suspend_lowlevel(0); do_suspend_lowlevel(0);
break;
#endif #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; break;
} }
local_irq_restore(flags); local_irq_restore(flags);
printk(KERN_CRIT "Back to C!\n");
return status; return status;
} }
...@@ -211,10 +218,20 @@ acpi_suspend ( ...@@ -211,10 +218,20 @@ acpi_suspend (
if (state < ACPI_STATE_S1 || state > ACPI_STATE_S5) if (state < ACPI_STATE_S1 || state > ACPI_STATE_S5)
return AE_ERROR; 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 */ freeze_processes(); /* device_suspend needs processes to be stopped */
/* do we have a wakeup address for S2 and S3? */ /* 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) if (!acpi_wakeup_address)
return AE_ERROR; return AE_ERROR;
acpi_set_firmware_waking_vector((acpi_physical_address) acpi_wakeup_address); acpi_set_firmware_waking_vector((acpi_physical_address) acpi_wakeup_address);
...@@ -268,6 +285,10 @@ static int __init acpi_sleep_init(void) ...@@ -268,6 +285,10 @@ static int __init acpi_sleep_init(void)
sleep_states[i] = 1; sleep_states[i] = 1;
printk(" S%d", i); printk(" S%d", i);
} }
if (i == ACPI_STATE_S4 && acpi_gbl_FACS->S4bios_f) {
sleep_states[i] = 1;
printk(" S4bios");
}
} }
printk(")\n"); printk(")\n");
......
...@@ -27,8 +27,11 @@ static int acpi_system_sleep_seq_show(struct seq_file *seq, void *offset) ...@@ -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"); ACPI_FUNCTION_TRACE("acpi_system_sleep_seq_show");
for (i = 0; i <= ACPI_STATE_S5; i++) { for (i = 0; i <= ACPI_STATE_S5; i++) {
if (sleep_states[i]) if (sleep_states[i]) {
seq_printf(seq,"S%d ", 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"); seq_puts(seq, "\n");
......
...@@ -73,6 +73,7 @@ extern void do_magic_suspend_2(void); ...@@ -73,6 +73,7 @@ extern void do_magic_suspend_2(void);
/* Communication between acpi and arch/i386/suspend.c */ /* Communication between acpi and arch/i386/suspend.c */
extern void do_suspend_lowlevel(int resume); extern void do_suspend_lowlevel(int resume);
extern void do_suspend_lowlevel_s4bios(int resume);
#else #else
static inline void software_suspend(void) static inline void software_suspend(void)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment