The patch titled swsusp resume must not device_suspend() has been added to the -mm tree. Its filename is swsusp-resume-must-not-device_suspend.patch See http://www.zip.com.au/~akpm/linux/patches/stuff/added-to-mm.txt to find out what to do about this From: David Brownell <david-b@xxxxxxxxxxx> I've noticed a bunch of problem reports that go like this: - boot system with some USB devices attached - echo disk > /sys/power/state - ... later resume ... - now those USB devices don't work right - unplug them/replug them, all is OK I recently observed this myself and tracked down one problem. The solution involves what kexec() does in much the same situation: before starting a new kernel, most hardware needs to be reset. Today, swsusp will suspend it instead, which is the root cause of the problem. This seems like something that might need to sit in the MM tree for a while, as it's a longstanding bug and the fix could shake loose driver goofs. Luckily there's a partial workaround already in wide use: link drivers as modules if they use true suspend states (like all USB HCDs), don't link them statically into the kernel image. That workaround is partial because when BIOS takes over a controller, the resume() method has to handle that nasty case too! Last I checked, all the USB HCDs do handle that case; and few drivers other than those HCDs would ever need to worry about such issues. 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(). Cc: "Rafael J. Wysocki" <rjw@xxxxxxx> Cc: Pavel Machek <pavel@xxxxxx> Signed-off-by: Andrew Morton <akpm@xxxxxxxx> --- kernel/power/swsusp.c | 13 ++++++++++--- 1 files changed, 10 insertions(+), 3 deletions(-) diff -puN kernel/power/swsusp.c~swsusp-resume-must-not-device_suspend kernel/power/swsusp.c --- devel/kernel/power/swsusp.c~swsusp-resume-must-not-device_suspend 2006-04-24 18:21:08.000000000 -0700 +++ devel-akpm/kernel/power/swsusp.c 2006-04-24 18:21:08.000000000 -0700 @@ -49,6 +49,7 @@ #include <linux/bootmem.h> #include <linux/syscalls.h> #include <linux/highmem.h> +#include <linux/reboot.h> #include "power.h" @@ -247,10 +248,16 @@ Enable_irqs: 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 _ Patches currently in -mm which might be from david-b@xxxxxxxxxxx are swsusp-resume-must-not-device_suspend.patch rtc-framework-driver-for-ds1307-and-similar-rtc-chips.patch - To unsubscribe from this list: send the line "unsubscribe mm-commits" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html