Commit 5f662298 authored by Pavel Machek's avatar Pavel Machek Committed by Linus Torvalds

[PATCH] swsusp/dm: Use right levels for device_suspend()

This almost changes no code (constant is still "3"), but at least it uses
right constants for device_suspend() and fixes types at few points.  Also
puts explanation of constants to the Documentation.
Signed-off-by: default avatarAndrew Morton <akpm@osdl.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@osdl.org>
parent 0ba6102f
...@@ -229,3 +229,91 @@ module is re-inserted during it's ->probe() (or equivalent) method. ...@@ -229,3 +229,91 @@ module is re-inserted during it's ->probe() (or equivalent) method.
The driver core will not call any extra functions when binding the The driver core will not call any extra functions when binding the
device to the driver. device to the driver.
pm_message_t meaning
pm_message_t has two fields. event ("major"), and flags. If driver
does not know event code, it aborts the request, returning error. Some
drivers may need to deal with special cases based on the actual type
of suspend operation being done at the system level. This is why
there are flags.
Event codes are:
ON -- no need to do anything except special cases like broken
HW.
# NOTIFICATION -- pretty much same as ON?
FREEZE -- stop DMA and interrupts, and be prepared to reinit HW from
scratch. That probably means stop accepting upstream requests, the
actual policy of what to do with them being specific to a given
driver. It's acceptable for a network driver to just drop packets
while a block driver is expected to block the queue so no request is
lost. (Use IDE as an example on how to do that). FREEZE requires no
power state change, and it's expected for drivers to be able to
quickly transition back to operating state.
SUSPEND -- like FREEZE, but also put hardware into low-power state. If
there's need to distinguish several levels of sleep, additional flag
is probably best way to do that.
Transitions are only from a resumed state to a suspended state, never
between 2 suspended states. (ON -> FREEZE or ON -> SUSPEND can happen,
FREEZE -> SUSPEND or SUSPEND -> FREEZE can not).
All events are:
[NOTE NOTE NOTE: If you are driver author, you should not care; you
should only look at event, and ignore flags.]
#Prepare for suspend -- userland is still running but we are going to
#enter suspend state. This gives drivers chance to load firmware from
#disk and store it in memory, or do other activities taht require
#operating userland, ability to kmalloc GFP_KERNEL, etc... All of these
#are forbiden once the suspend dance is started.. event = ON, flags =
#PREPARE_TO_SUSPEND
Apm standby -- prepare for APM event. Quiesce devices to make life
easier for APM BIOS. event = FREEZE, flags = APM_STANDBY
Apm suspend -- same as APM_STANDBY, but it we should probably avoid
spinning down disks. event = FREEZE, flags = APM_SUSPEND
System halt, reboot -- quiesce devices to make life easier for BIOS. event
= FREEZE, flags = SYSTEM_HALT or SYSTEM_REBOOT
System shutdown -- at least disks need to be spun down, or data may be
lost. Quiesce devices, just to make life easier for BIOS. event =
FREEZE, flags = SYSTEM_SHUTDOWN
Kexec -- turn off DMAs and put hardware into some state where new
kernel can take over. event = FREEZE, flags = KEXEC
Powerdown at end of swsusp -- very similar to SYSTEM_SHUTDOWN, except wake
may need to be enabled on some devices. This actually has at least 3
subtypes, system can reboot, enter S4 and enter S5 at the end of
swsusp. event = FREEZE, flags = SWSUSP and one of SYSTEM_REBOOT,
SYSTEM_SHUTDOWN, SYSTEM_S4
Suspend to ram -- put devices into low power state. event = SUSPEND,
flags = SUSPEND_TO_RAM
Freeze for swsusp snapshot -- stop DMA and interrupts. No need to put
devices into low power mode, but you must be able to reinitialize
device from scratch in resume method. This has two flavors, its done
once on suspending kernel, once on resuming kernel. event = FREEZE,
flags = DURING_SUSPEND or DURING_RESUME
Device detach requested from /sys -- deinitialize device; proably same as
SYSTEM_SHUTDOWN, I do not understand this one too much. probably event
= FREEZE, flags = DEV_DETACH.
#These are not really events sent:
#
#System fully on -- device is working normally; this is probably never
#passed to suspend() method... event = ON, flags = 0
#
#Ready after resume -- userland is now running, again. Time to free any
#memory you ate during prepare to suspend... event = ON, flags =
#READY_AFTER_RESUME
#
...@@ -1201,8 +1201,8 @@ static int suspend(int vetoable) ...@@ -1201,8 +1201,8 @@ static int suspend(int vetoable)
printk(KERN_CRIT "apm: suspend was vetoed, but suspending anyway.\n"); printk(KERN_CRIT "apm: suspend was vetoed, but suspending anyway.\n");
} }
device_suspend(3); device_suspend(PMSG_SUSPEND);
device_power_down(3); device_power_down(PMSG_SUSPEND);
/* serialize with the timer interrupt */ /* serialize with the timer interrupt */
write_seqlock_irq(&xtime_lock); write_seqlock_irq(&xtime_lock);
...@@ -1255,7 +1255,7 @@ static void standby(void) ...@@ -1255,7 +1255,7 @@ static void standby(void)
{ {
int err; int err;
device_power_down(3); device_power_down(PMSG_SUSPEND);
/* serialize with the timer interrupt */ /* serialize with the timer interrupt */
write_seqlock_irq(&xtime_lock); write_seqlock_irq(&xtime_lock);
/* If needed, notify drivers here */ /* If needed, notify drivers here */
......
...@@ -159,7 +159,7 @@ static int acpi_pm_finish(suspend_state_t pm_state) ...@@ -159,7 +159,7 @@ static int acpi_pm_finish(suspend_state_t pm_state)
int acpi_suspend(u32 acpi_state) int acpi_suspend(u32 acpi_state)
{ {
u32 states[] = { suspend_state_t states[] = {
[1] = PM_SUSPEND_STANDBY, [1] = PM_SUSPEND_STANDBY,
[3] = PM_SUSPEND_MEM, [3] = PM_SUSPEND_MEM,
[4] = PM_SUSPEND_DISK, [4] = PM_SUSPEND_DISK,
......
...@@ -51,7 +51,7 @@ static void power_down(suspend_disk_method_t mode) ...@@ -51,7 +51,7 @@ static void power_down(suspend_disk_method_t mode)
local_irq_save(flags); local_irq_save(flags);
switch(mode) { switch(mode) {
case PM_DISK_PLATFORM: case PM_DISK_PLATFORM:
device_power_down(PM_SUSPEND_DISK); device_power_down(PMSG_SUSPEND);
error = pm_ops->enter(PM_SUSPEND_DISK); error = pm_ops->enter(PM_SUSPEND_DISK);
break; break;
case PM_DISK_SHUTDOWN: case PM_DISK_SHUTDOWN:
...@@ -144,8 +144,10 @@ static int prepare(void) ...@@ -144,8 +144,10 @@ static int prepare(void)
free_some_memory(); free_some_memory();
disable_nonboot_cpus(); disable_nonboot_cpus();
if ((error = device_suspend(PM_SUSPEND_DISK))) if ((error = device_suspend(PMSG_FREEZE))) {
printk("Some devices failed to suspend\n");
goto Finish; goto Finish;
}
return 0; return 0;
Finish: Finish:
......
...@@ -65,7 +65,7 @@ static int suspend_prepare(suspend_state_t state) ...@@ -65,7 +65,7 @@ static int suspend_prepare(suspend_state_t state)
goto Thaw; goto Thaw;
} }
if ((error = device_suspend(state))) if ((error = device_suspend(PMSG_SUSPEND)))
goto Finish; goto Finish;
return 0; return 0;
Finish: Finish:
...@@ -78,13 +78,14 @@ static int suspend_prepare(suspend_state_t state) ...@@ -78,13 +78,14 @@ static int suspend_prepare(suspend_state_t state)
} }
static int suspend_enter(u32 state) static int suspend_enter(suspend_state_t state)
{ {
int error = 0; int error = 0;
unsigned long flags; unsigned long flags;
local_irq_save(flags); local_irq_save(flags);
if ((error = device_power_down(state)))
if ((error = device_power_down(PMSG_SUSPEND)))
goto Done; goto Done;
error = pm_ops->enter(state); error = pm_ops->enter(state);
device_power_up(); device_power_up();
......
...@@ -849,7 +849,7 @@ int swsusp_suspend(void) ...@@ -849,7 +849,7 @@ int swsusp_suspend(void)
* become desynchronized with the actual state of the hardware * become desynchronized with the actual state of the hardware
* at resume time, and evil weirdness ensues. * at resume time, and evil weirdness ensues.
*/ */
if ((error = device_power_down(PM_SUSPEND_DISK))) { if ((error = device_power_down(PMSG_FREEZE))) {
local_irq_enable(); local_irq_enable();
return error; return error;
} }
...@@ -878,7 +878,7 @@ int swsusp_resume(void) ...@@ -878,7 +878,7 @@ int swsusp_resume(void)
{ {
int error; int error;
local_irq_disable(); local_irq_disable();
device_power_down(PM_SUSPEND_DISK); device_power_down(PMSG_FREEZE);
/* We'll ignore saved state, but this gets preempt count (etc) right */ /* We'll ignore saved state, but this gets preempt count (etc) right */
save_processor_state(); save_processor_state();
error = swsusp_arch_resume(); error = swsusp_arch_resume();
......
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