Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/pmladek...
[linux-2.6-block.git] / arch / parisc / kernel / process.c
index 6c4585103a912e52babe30258f52d2a56223f7b9..6975a06270788cc2d3dad98ad5a385b95eb9b79b 100644 (file)
@@ -39,6 +39,7 @@
 #include <linux/kernel.h>
 #include <linux/mm.h>
 #include <linux/fs.h>
+#include <linux/cpu.h>
 #include <linux/module.h>
 #include <linux/personality.h>
 #include <linux/ptrace.h>
@@ -183,6 +184,44 @@ int dump_task_fpu (struct task_struct *tsk, elf_fpregset_t *r)
        return 1;
 }
 
+/*
+ * Idle thread support
+ *
+ * Detect when running on QEMU with SeaBIOS PDC Firmware and let
+ * QEMU idle the host too.
+ */
+
+int running_on_qemu __read_mostly;
+
+void __cpuidle arch_cpu_idle_dead(void)
+{
+       /* nop on real hardware, qemu will offline CPU. */
+       asm volatile("or %%r31,%%r31,%%r31\n":::);
+}
+
+void __cpuidle arch_cpu_idle(void)
+{
+       local_irq_enable();
+
+       /* nop on real hardware, qemu will idle sleep. */
+       asm volatile("or %%r10,%%r10,%%r10\n":::);
+}
+
+static int __init parisc_idle_init(void)
+{
+       const char *marker;
+
+       /* check QEMU/SeaBIOS marker in PAGE0 */
+       marker = (char *) &PAGE0->pad0;
+       running_on_qemu = (memcmp(marker, "SeaBIOS", 8) == 0);
+
+       if (!running_on_qemu)
+               cpu_idle_poll_ctrl(1);
+
+       return 0;
+}
+arch_initcall(parisc_idle_init);
+
 /*
  * Copy architecture-specific thread state
  */