diff options
| author | Patrick Mochel <mochel@osdl.org> | 2003-09-08 02:41:39 -0700 |
|---|---|---|
| committer | Patrick Mochel <mochel@osdl.org> | 2003-09-08 02:41:39 -0700 |
| commit | 2d6e58e7b2ee73edfab739e122f4d95f51ab5b89 (patch) | |
| tree | 4c6202c799511d72b5abacede2089b527975dbdf /kernel | |
| parent | 128b46cd4bc9ebfa5117800e7c20870343e465ad (diff) | |
[power] Fix swsusp with preempt and clean up.
In order to snapshot memory, interrupts must be disabled. However, in order
to write the saved image to disk, interrupts must be re-enabled and devices
resumed. Previously, both actions were called from swsusp_arch_suspend().
This patch separates those two actions has only the snapshotting routine
called from swsusp_arch_suspend(). swsusp now handles it's own disabling of
interrupts only for the time required. This is now handled from swsusp_save()
and swsusp_write() now handles writing the image only (called with interrupts
enabled).
swsusp_save_image() was renamed to swsusp_suspend() (and the old incarnation
deleted since it was simply a wrapper).
Diffstat (limited to 'kernel')
| -rw-r--r-- | kernel/power/disk.c | 26 | ||||
| -rw-r--r-- | kernel/power/swsusp.c | 44 |
2 files changed, 30 insertions, 40 deletions
diff --git a/kernel/power/disk.c b/kernel/power/disk.c index e7e40119d917..64a3130a5411 100644 --- a/kernel/power/disk.c +++ b/kernel/power/disk.c @@ -163,27 +163,27 @@ int pm_suspend_disk(void) pr_debug("PM: snapshotting memory.\n"); in_suspend = 1; - local_irq_disable(); if ((error = swsusp_save())) goto Done; - pr_debug("PM: writing image.\n"); + if (in_suspend) { + pr_debug("PM: writing image.\n"); - /* - * FIXME: Leftover from swsusp. Are they necessary? - */ - mb(); - barrier(); + /* + * FIXME: Leftover from swsusp. Are they necessary? + */ + mb(); + barrier(); - error = swsusp_write(); - if (!error && in_suspend) { - error = power_down(pm_disk_mode); - pr_debug("PM: Power down failed.\n"); + error = swsusp_write(); + if (!error) { + error = power_down(pm_disk_mode); + pr_debug("PM: Power down failed.\n"); + } } else pr_debug("PM: Image restored successfully.\n"); swsusp_free(); Done: - local_irq_enable(); finish(); return error; } @@ -217,7 +217,6 @@ static int pm_resume(void) barrier(); mb(); - local_irq_disable(); /* FIXME: The following (comment and mdelay()) are from swsusp. * Are they really necessary? @@ -231,7 +230,6 @@ static int pm_resume(void) pr_debug("PM: Restoring saved image.\n"); swsusp_restore(); - local_irq_enable(); pr_debug("PM: Restore failed, recovering.n"); finish(); Free: diff --git a/kernel/power/swsusp.c b/kernel/power/swsusp.c index e9a1e97a2f2b..bb795b6dc537 100644 --- a/kernel/power/swsusp.c +++ b/kernel/power/swsusp.c @@ -416,11 +416,12 @@ static suspend_pagedir_t *create_suspend_pagedir(int nr_copy_pages) } -static int suspend_prepare_image(void) +int swsusp_suspend(void) { struct sysinfo i; unsigned int nr_needed_pages = 0; + read_swapfiles(); drain_local_pages(); pagedir_nosave = NULL; @@ -486,12 +487,10 @@ static int suspend_prepare_image(void) static int suspend_save_image(void) { int error; - local_irq_enable(); device_resume(); lock_swapdevices(); error = write_suspend_image(); lock_swapdevices(); - local_irq_disable(); return error; } @@ -515,35 +514,17 @@ int swsusp_resume(void) if (!resume) { save_processor_state(); SAVE_REGISTERS - swsusp_suspend(); - return; + return swsusp_suspend(); } GO_TO_SWAPPER_PAGE_TABLES COPY_PAGES_BACK RESTORE_REGISTERS restore_processor_state(); - swsusp_resume(); + return swsusp_resume(); */ -int swsusp_suspend(void) -{ - int error; - read_swapfiles(); - error = suspend_prepare_image(); - if (!error) - error = suspend_save_image(); - if (error) { - printk(KERN_EMERG "%sSuspend failed, trying to recover...\n", - name_suspend); - barrier(); - mb(); - mdelay(1000); - } - return error; -} - /* More restore stuff */ /* FIXME: Why not memcpy(to, from, 1<<pagedir_order*PAGE_SIZE)? */ @@ -870,11 +851,18 @@ static int __init read_suspend_image(void) int swsusp_save(void) { + int error; + #if defined (CONFIG_HIGHMEM) || defined (COFNIG_DISCONTIGMEM) printk("swsusp is not supported with high- or discontig-mem.\n"); return -EPERM; #endif - return arch_prepare_suspend(); + if ((error = arch_prepare_suspend())) + return error; + local_irq_disable(); + error = swsusp_arch_suspend(0); + local_irq_enable(); + return error; } @@ -890,7 +878,7 @@ int swsusp_save(void) int swsusp_write(void) { - return swsusp_arch_suspend(0); + return suspend_save_image(); } @@ -933,7 +921,11 @@ int __init swsusp_read(void) int __init swsusp_restore(void) { - return swsusp_arch_suspend(1); + int error; + local_irq_disable(); + error = swsusp_arch_suspend(1); + local_irq_enable(); + return error; } |
