Commit 2d6e58e7 authored by Patrick Mochel's avatar Patrick Mochel

[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).
parent 128b46cd
......@@ -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:
......
......@@ -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;
}
......
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