Commit 7cfa0dcd authored by Pavel Machek's avatar Pavel Machek Committed by Greg Kroah-Hartman

[PATCH] swsusp and S3 fixes

These are minor fixes for swsusp and S3 sleep.

 - #ifdef mess in acpi_save_state_mem() is simplified
 - better error handling in reserving bootmem
 - handle video bioses that play with segment registers
 - automagic support for S3 on toshiba notebook
 - don't try to sync() when pdflush is already stopped
 - reorder actions to make pdflush not complain
parent 9f58fa60
...@@ -2,6 +2,7 @@ ...@@ -2,6 +2,7 @@
* sleep.c - x86-specific ACPI sleep support. * sleep.c - x86-specific ACPI sleep support.
* *
* Copyright (C) 2001-2003 Patrick Mochel * Copyright (C) 2001-2003 Patrick Mochel
* Copyright (C) 2001-2003 Pavel Machek <pavel@suse.cz>
*/ */
#include <linux/acpi.h> #include <linux/acpi.h>
...@@ -34,10 +35,8 @@ static void init_low_mapping(pgd_t *pgd, int pgd_limit) ...@@ -34,10 +35,8 @@ static void init_low_mapping(pgd_t *pgd, int pgd_limit)
*/ */
int acpi_save_state_mem (void) int acpi_save_state_mem (void)
{ {
#if CONFIG_X86_PAE if (!acpi_wakeup_address)
panic("S3 and PAE do not like each other for now."); return 1;
return 1;
#endif
init_low_mapping(swapper_pg_dir, USER_PTRS_PER_PGD); init_low_mapping(swapper_pg_dir, USER_PTRS_PER_PGD);
memcpy((void *) acpi_wakeup_address, &wakeup_start, &wakeup_end - &wakeup_start); memcpy((void *) acpi_wakeup_address, &wakeup_start, &wakeup_end - &wakeup_start);
acpi_copy_wakeup_routine(acpi_wakeup_address); acpi_copy_wakeup_routine(acpi_wakeup_address);
...@@ -65,17 +64,24 @@ void acpi_restore_state_mem (void) ...@@ -65,17 +64,24 @@ void acpi_restore_state_mem (void)
/** /**
* acpi_reserve_bootmem - do _very_ early ACPI initialisation * acpi_reserve_bootmem - do _very_ early ACPI initialisation
* *
* We allocate a page in low memory for the wakeup * We allocate a page from the first 1MB of memory for the wakeup
* routine for when we come back from a sleep state. The * routine for when we come back from a sleep state. The
* runtime allocator allows specification of <16M pages, but not * runtime allocator allows specification of <16MB pages, but not
* <1M pages. * <1MB pages.
*/ */
void __init acpi_reserve_bootmem(void) void __init acpi_reserve_bootmem(void)
{ {
if ((&wakeup_end - &wakeup_start) > PAGE_SIZE) {
printk(KERN_ERR "ACPI: Wakeup code way too big, S3 disabled.\n");
return;
}
#if CONFIG_X86_PAE
printk(KERN_ERR "ACPI: S3 and PAE do not like each other for now, S3 disabled.\n");
return;
#endif
acpi_wakeup_address = (unsigned long)alloc_bootmem_low(PAGE_SIZE); acpi_wakeup_address = (unsigned long)alloc_bootmem_low(PAGE_SIZE);
if ((&wakeup_end - &wakeup_start) > PAGE_SIZE) if (!acpi_wakeup_address)
printk(KERN_CRIT "ACPI: Wakeup code way too big, will crash on attempt to suspend\n"); printk(KERN_ERR "ACPI: Cannot allocate lowmem, S3 disabled.\n");
printk(KERN_DEBUG "ACPI: have wakeup address 0x%8.8lx\n", acpi_wakeup_address);
} }
static int __init acpi_sleep_setup(char *str) static int __init acpi_sleep_setup(char *str)
......
...@@ -44,6 +44,9 @@ wakeup_code: ...@@ -44,6 +44,9 @@ wakeup_code:
testl $1, video_flags - wakeup_code testl $1, video_flags - wakeup_code
jz 1f jz 1f
lcall $0xc000,$3 lcall $0xc000,$3
movw %cs, %ax
movw %ax, %ds # Bios might have played with that
movw %ax, %ss
1: 1:
testl $2, video_flags - wakeup_code testl $2, video_flags - wakeup_code
......
...@@ -455,7 +455,7 @@ static __init int broken_pirq(struct dmi_blacklist *d) ...@@ -455,7 +455,7 @@ static __init int broken_pirq(struct dmi_blacklist *d)
static __init int broken_toshiba_keyboard(struct dmi_blacklist *d) static __init int broken_toshiba_keyboard(struct dmi_blacklist *d)
{ {
printk(KERN_WARNING "Toshiba with broken keyboard detected. If your keyboard sometimes generates 3 keypresses instead of one, contact pavel@ucw.cz\n"); printk(KERN_WARNING "Toshiba with broken keyboard detected. If your keyboard sometimes generates 3 keypresses instead of one, see http://davyd.ucc.asn.au/projects/toshiba/README\n");
return 0; return 0;
} }
...@@ -470,6 +470,21 @@ static __init int init_ints_after_s1(struct dmi_blacklist *d) ...@@ -470,6 +470,21 @@ static __init int init_ints_after_s1(struct dmi_blacklist *d)
return 0; return 0;
} }
static __init int reset_videomode_after_s3(struct dmi_blacklist *d)
{
/* See acpi_wakeup.S */
extern long acpi_video_flags;
acpi_video_flags |= 2;
return 0;
}
static __init int reset_videobios_after_s3(struct dmi_blacklist *d)
{
extern long acpi_video_flags;
acpi_video_flags |= 1;
return 0;
}
/* /*
* Some Bioses enable the PS/2 mouse (touchpad) at resume, even if it was * Some Bioses enable the PS/2 mouse (touchpad) at resume, even if it was
* disabled before the suspend. Linux used to get terribly confused by that. * disabled before the suspend. Linux used to get terribly confused by that.
...@@ -743,6 +758,10 @@ static __initdata struct dmi_blacklist dmi_blacklist[]={ ...@@ -743,6 +758,10 @@ static __initdata struct dmi_blacklist dmi_blacklist[]={
MATCH(DMI_PRODUCT_NAME, "S4030CDT/4.3"), MATCH(DMI_PRODUCT_NAME, "S4030CDT/4.3"),
NO_MATCH, NO_MATCH, NO_MATCH NO_MATCH, NO_MATCH, NO_MATCH
} }, } },
{ reset_videomode_after_s3, "Toshiba Satellite 4030cdt", { /* Reset video mode after returning from ACPI S3 sleep */
MATCH(DMI_PRODUCT_NAME, "S4030CDT/4.3"),
NO_MATCH, NO_MATCH, NO_MATCH
} },
{ print_if_true, KERN_WARNING "IBM T23 - BIOS 1.03b+ and controller firmware 1.02+ may be needed for Linux APM.", { { print_if_true, KERN_WARNING "IBM T23 - BIOS 1.03b+ and controller firmware 1.02+ may be needed for Linux APM.", {
MATCH(DMI_SYS_VENDOR, "IBM"), MATCH(DMI_SYS_VENDOR, "IBM"),
......
...@@ -604,12 +604,12 @@ static void restore_console(void) ...@@ -604,12 +604,12 @@ static void restore_console(void)
static int prepare_suspend_processes(void) static int prepare_suspend_processes(void)
{ {
sys_sync(); /* Syncing needs pdflushd, so do it before stopping processes */
if (freeze_processes()) { if (freeze_processes()) {
printk( KERN_ERR "Suspend failed: Not all processes stopped!\n" ); printk( KERN_ERR "Suspend failed: Not all processes stopped!\n" );
thaw_processes(); thaw_processes();
return 1; return 1;
} }
sys_sync();
return 0; return 0;
} }
......
...@@ -103,9 +103,11 @@ static int __pdflush(struct pdflush_work *my_work) ...@@ -103,9 +103,11 @@ static int __pdflush(struct pdflush_work *my_work)
my_work->when_i_went_to_sleep = jiffies; my_work->when_i_went_to_sleep = jiffies;
spin_unlock_irq(&pdflush_lock); spin_unlock_irq(&pdflush_lock);
if (current->flags & PF_FREEZE)
refrigerator(PF_IOTHREAD);
schedule(); schedule();
if (current->flags & PF_FREEZE) {
refrigerator(PF_IOTHREAD);
continue;
}
spin_lock_irq(&pdflush_lock); spin_lock_irq(&pdflush_lock);
if (!list_empty(&my_work->list)) { if (!list_empty(&my_work->list)) {
......
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