#! /bin/sh -e ## swsusp-platform-devices.dpatch by ## ## All lines beginning with `## DP:' are a description of the patch. ## DP: Description: Make sure swsusp suspends and resumes platform devices ## DP: Patch author: Barry K. Nathan ## DP: Upstream status: submitted . $(dirname $0)/DPATCH @DPATCH@ --- linux-2.6.10-mm1/kernel/power/swsusp.c 2005-01-03 02:16:15.175265255 -0800 +++ linux-2.6.10-mm1-bkn3/kernel/power/swsusp.c 2005-01-03 06:27:07.753344731 -0800 @@ -843,11 +843,22 @@ 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; } --- linux-2.6.10-mm1-bkn3/kernel/power/swsusp.c 2005-01-03 06:27:07.753344731 -0800 +++ linux-2.6.10-mm1-bkn4/kernel/power/swsusp.c 2005-01-03 20:19:06.737439106 -0800 @@ -878,6 +878,7 @@ { int error; local_irq_disable(); + device_power_down(PM_SUSPEND_DISK); /* We'll ignore saved state, but this gets preempt count (etc) right */ save_processor_state(); error = swsusp_arch_resume(); @@ -887,6 +888,7 @@ BUG_ON(!error); restore_processor_state(); restore_highmem(); + device_power_up(); local_irq_enable(); return error; }