summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPavel Machek <pavel@ucw.cz>2003-02-23 22:45:35 -0800
committerGreg Kroah-Hartman <greg@kroah.com>2003-02-23 22:45:35 -0800
commit7cfa0dcdc09e1ca1946a8fbbc65c964e9e956561 (patch)
tree4ee2d7f1d61905ab9ecf365f4da9af293e18e79c
parent9f58fa6064ff7b101dab0bba6192edf992b195ee (diff)
[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
-rw-r--r--arch/i386/kernel/acpi/sleep.c26
-rw-r--r--arch/i386/kernel/acpi/wakeup.S3
-rw-r--r--arch/i386/kernel/dmi_scan.c21
-rw-r--r--kernel/suspend.c2
-rw-r--r--mm/pdflush.c6
5 files changed, 44 insertions, 14 deletions
diff --git a/arch/i386/kernel/acpi/sleep.c b/arch/i386/kernel/acpi/sleep.c
index a3493baee101..74f61498cc2f 100644
--- a/arch/i386/kernel/acpi/sleep.c
+++ b/arch/i386/kernel/acpi/sleep.c
@@ -2,6 +2,7 @@
* sleep.c - x86-specific ACPI sleep support.
*
* Copyright (C) 2001-2003 Patrick Mochel
+ * Copyright (C) 2001-2003 Pavel Machek <pavel@suse.cz>
*/
#include <linux/acpi.h>
@@ -34,10 +35,8 @@ static void init_low_mapping(pgd_t *pgd, int pgd_limit)
*/
int acpi_save_state_mem (void)
{
-#if CONFIG_X86_PAE
- panic("S3 and PAE do not like each other for now.");
- return 1;
-#endif
+ if (!acpi_wakeup_address)
+ return 1;
init_low_mapping(swapper_pg_dir, USER_PTRS_PER_PGD);
memcpy((void *) acpi_wakeup_address, &wakeup_start, &wakeup_end - &wakeup_start);
acpi_copy_wakeup_routine(acpi_wakeup_address);
@@ -65,17 +64,24 @@ void acpi_restore_state_mem (void)
/**
* 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
- * runtime allocator allows specification of <16M pages, but not
- * <1M pages.
+ * runtime allocator allows specification of <16MB pages, but not
+ * <1MB pages.
*/
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);
- if ((&wakeup_end - &wakeup_start) > PAGE_SIZE)
- printk(KERN_CRIT "ACPI: Wakeup code way too big, will crash on attempt to suspend\n");
- printk(KERN_DEBUG "ACPI: have wakeup address 0x%8.8lx\n", acpi_wakeup_address);
+ if (!acpi_wakeup_address)
+ printk(KERN_ERR "ACPI: Cannot allocate lowmem, S3 disabled.\n");
}
static int __init acpi_sleep_setup(char *str)
diff --git a/arch/i386/kernel/acpi/wakeup.S b/arch/i386/kernel/acpi/wakeup.S
index 55bbd2a5e4db..5f5728f9d0a1 100644
--- a/arch/i386/kernel/acpi/wakeup.S
+++ b/arch/i386/kernel/acpi/wakeup.S
@@ -44,6 +44,9 @@ wakeup_code:
testl $1, video_flags - wakeup_code
jz 1f
lcall $0xc000,$3
+ movw %cs, %ax
+ movw %ax, %ds # Bios might have played with that
+ movw %ax, %ss
1:
testl $2, video_flags - wakeup_code
diff --git a/arch/i386/kernel/dmi_scan.c b/arch/i386/kernel/dmi_scan.c
index f904e15904ae..0dda1be8ebef 100644
--- a/arch/i386/kernel/dmi_scan.c
+++ b/arch/i386/kernel/dmi_scan.c
@@ -455,7 +455,7 @@ static __init int broken_pirq(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;
}
@@ -470,6 +470,21 @@ static __init int init_ints_after_s1(struct dmi_blacklist *d)
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
* disabled before the suspend. Linux used to get terribly confused by that.
@@ -743,6 +758,10 @@ static __initdata struct dmi_blacklist dmi_blacklist[]={
MATCH(DMI_PRODUCT_NAME, "S4030CDT/4.3"),
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.", {
MATCH(DMI_SYS_VENDOR, "IBM"),
diff --git a/kernel/suspend.c b/kernel/suspend.c
index 392b1d4ef16c..5bcf2e90b48a 100644
--- a/kernel/suspend.c
+++ b/kernel/suspend.c
@@ -604,12 +604,12 @@ static void restore_console(void)
static int prepare_suspend_processes(void)
{
+ sys_sync(); /* Syncing needs pdflushd, so do it before stopping processes */
if (freeze_processes()) {
printk( KERN_ERR "Suspend failed: Not all processes stopped!\n" );
thaw_processes();
return 1;
}
- sys_sync();
return 0;
}
diff --git a/mm/pdflush.c b/mm/pdflush.c
index b1375644c519..deb33a7755f0 100644
--- a/mm/pdflush.c
+++ b/mm/pdflush.c
@@ -103,9 +103,11 @@ static int __pdflush(struct pdflush_work *my_work)
my_work->when_i_went_to_sleep = jiffies;
spin_unlock_irq(&pdflush_lock);
- if (current->flags & PF_FREEZE)
- refrigerator(PF_IOTHREAD);
schedule();
+ if (current->flags & PF_FREEZE) {
+ refrigerator(PF_IOTHREAD);
+ continue;
+ }
spin_lock_irq(&pdflush_lock);
if (!list_empty(&my_work->list)) {