From: "Barry K. Nathan" Since at least kernel 2.6.9, if not earlier, swsusp fails to properly suspend and resume all devices. The most notable effect is that resuming fails to properly reconfigure interrupt routers. In 2.6.9 this was obscured by other kernel code, but in 2.6.10 this often causes post-resume APIC errors and near-total failure of some PCI devices (e.g. network, sound and USB controllers). Even in cases where interrupt routing is unaffected, this bug causes other problems. For instance, on one of my systems I have to run "ifdown eth0;ifup eth0" after resume in order to have functional networking, if I do not apply this patch. By itself, this patch is not theoretically complete; my next patch fixes that. However, this patch is the critical one for fixing swsusp's behavior in the real world. Signed-off-by: Barry K. Nathan Acked-by: Pavel Machek Signed-off-by: Andrew Morton --- 25-akpm/kernel/power/swsusp.c | 11 +++++++++++ 1 files changed, 11 insertions(+) diff -puN kernel/power/swsusp.c~swsusp-device-power-management-fix kernel/power/swsusp.c --- 25/kernel/power/swsusp.c~swsusp-device-power-management-fix 2005-01-10 17:29:25.422022184 -0800 +++ 25-akpm/kernel/power/swsusp.c 2005-01-10 17:29:25.426021576 -0800 @@ -843,11 +843,22 @@ int swsusp_suspend(void) if ((error = arch_prepare_suspend())) return error; local_irq_disable(); + /* At this point, device_suspend() has been called, but *not* + * device_power_down(). We *must* device_power_down() now. + * Otherwise, drivers for some devices (e.g. interrupt controllers) + * become desynchronized with the actual state of the hardware + * at resume time, and evil weirdness ensues. + */ + if ((error = device_power_down(PM_SUSPEND_DISK))) { + local_irq_enable(); + return error; + } save_processor_state(); error = swsusp_arch_suspend(); /* Restore control flow magically appears here */ restore_processor_state(); restore_highmem(); + device_power_up(); local_irq_enable(); return error; } _