diff options
Diffstat (limited to 'arch/parisc/kernel/process.c')
| -rw-r--r-- | arch/parisc/kernel/process.c | 39 | 
1 files changed, 39 insertions, 0 deletions
| diff --git a/arch/parisc/kernel/process.c b/arch/parisc/kernel/process.c index 30f92391a93e..cad3e8661cd6 100644 --- a/arch/parisc/kernel/process.c +++ b/arch/parisc/kernel/process.c @@ -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> @@ -184,6 +185,44 @@ int dump_task_fpu (struct task_struct *tsk, elf_fpregset_t *r)  }  /* + * 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   */  int |