sysrq-o is supposed to power off the machine.  But if it calls into ACPI (at
least) it does lots of sleepy things, so we best not do this from interrupt
context.


---

 kernel/power/poweroff.c |   22 +++++++++++-----------
 1 files changed, 11 insertions(+), 11 deletions(-)

diff -puN kernel/power/poweroff.c~poweroff-atomicity-fix kernel/power/poweroff.c
--- 25/kernel/power/poweroff.c~poweroff-atomicity-fix	2004-02-26 05:13:59.000000000 -0800
+++ 25-akpm/kernel/power/poweroff.c	2004-02-26 05:18:31.000000000 -0800
@@ -8,33 +8,33 @@
 #include <linux/sysrq.h>
 #include <linux/init.h>
 #include <linux/pm.h>
+#include <linux/workqueue.h>
 
-
-/**
- * handle_poweroff	-	sysrq callback for power down
- * @key: key pressed (unused)
- * @pt_regs: register state (unused)
- * @kbd: keyboard state (unused)
- * @tty: tty involved (unused)
- *
+/*
  * When the user hits Sys-Rq o to power down the machine this is the
  * callback we use.
  */
 
-static void handle_poweroff (int key, struct pt_regs *pt_regs,
-			     struct tty_struct *tty)
+static void do_poweroff(void *dummy)
 {
 	if (pm_power_off)
 		pm_power_off();
 }
 
+static DECLARE_WORK(poweroff_work, do_poweroff, 0);
+
+static void handle_poweroff(int key, struct pt_regs *pt_regs,
+				struct tty_struct *tty)
+{
+	schedule_work(&poweroff_work);
+}
+
 static struct sysrq_key_op	sysrq_poweroff_op = {
 	.handler        = handle_poweroff,
 	.help_msg       = "powerOff",
 	.action_msg     = "Power Off\n"
 };
 
-
 static int pm_sysrq_init(void)
 {
 	register_sysrq_key('o', &sysrq_poweroff_op);

_