Currently the swsusp resume path puts devices into a bogus suspend state before switching to the new kernel. It's neither the suspend state that the driver left the device in, nor a "device lost power" reset state. Instead, it's a semi-functional state from the kernel which loaded the snapshot. There's no way that a driver can properly resume from that. Some drivers issue resets in their resume methods, but that's wrong for every driver which uses more power states than just "on" and "reset". This patch shuts down (resets) the devices, just like kexec() does, so that non-modular drivers will know they must fully re-initialize even when they wouldn't ordinarily do so during resume(). --- linux.orig/kernel/power/swsusp.c 2006-04-23 08:41:22.000000000 -0700 +++ linux/kernel/power/swsusp.c 2006-04-24 13:20:17.000000000 -0700 @@ -49,6 +49,7 @@ #include #include #include +#include #include "power.h" @@ -249,10 +250,16 @@ int swsusp_resume(void) { int error; - local_irq_disable(); - if (device_power_down(PMSG_FREEZE)) - printk(KERN_ERR "Some devices failed to power down, very bad\n"); + + /* We need to shutdown/reset devices so that drivers which use + * non-powerdown suspend() states will see sane states in their + * resume() methods. At this point "reset" is the only option, + * since we clobbered any valid suspend state a long time ago. + */ + kernel_restart_prepare(NULL); + /* We'll ignore saved state, but this gets preempt count (etc) right */ + local_irq_disable(); save_processor_state(); error = swsusp_arch_resume(); /* Code below is only ever reached in case of failure. Otherwise