diff options
Diffstat (limited to 'arch/sh/kernel/process.c')
-rw-r--r-- | arch/sh/kernel/process.c | 49 |
1 files changed, 38 insertions, 11 deletions
diff --git a/arch/sh/kernel/process.c b/arch/sh/kernel/process.c index 329b3f3051de..a11e2aa73cbc 100644 --- a/arch/sh/kernel/process.c +++ b/arch/sh/kernel/process.c @@ -15,16 +15,17 @@ #include <linux/pm.h> #include <linux/kallsyms.h> #include <linux/kexec.h> -#include <asm/kdebug.h> +#include <linux/kdebug.h> +#include <linux/tick.h> #include <asm/uaccess.h> #include <asm/mmu_context.h> +#include <asm/pgalloc.h> +#include <asm/system.h> #include <asm/ubc.h> static int hlt_counter; int ubc_usercnt = 0; -#define HARD_IDLE_TIMEOUT (HZ / 3) - void (*pm_idle)(void); void (*pm_power_off)(void); EXPORT_SYMBOL(pm_power_off); @@ -41,16 +42,39 @@ void enable_hlt(void) } EXPORT_SYMBOL(enable_hlt); +static int __init nohlt_setup(char *__unused) +{ + hlt_counter = 1; + return 1; +} +__setup("nohlt", nohlt_setup); + +static int __init hlt_setup(char *__unused) +{ + hlt_counter = 0; + return 1; +} +__setup("hlt", hlt_setup); + void default_idle(void) { - if (!hlt_counter) - cpu_sleep(); - else - cpu_relax(); + if (!hlt_counter) { + clear_thread_flag(TIF_POLLING_NRFLAG); + smp_mb__after_clear_bit(); + set_bl_bit(); + while (!need_resched()) + cpu_sleep(); + clear_bl_bit(); + set_thread_flag(TIF_POLLING_NRFLAG); + } else + while (!need_resched()) + cpu_relax(); } void cpu_idle(void) { + set_thread_flag(TIF_POLLING_NRFLAG); + /* endless idle loop with no priority at all */ while (1) { void (*idle)(void) = pm_idle; @@ -58,12 +82,15 @@ void cpu_idle(void) if (!idle) idle = default_idle; + tick_nohz_stop_sched_tick(); while (!need_resched()) idle(); + tick_nohz_restart_sched_tick(); preempt_enable_no_resched(); schedule(); preempt_disable(); + check_pgt_cache(); } } @@ -495,9 +522,9 @@ asmlinkage void debug_trap_handler(unsigned long r4, unsigned long r5, struct pt_regs *regs = RELOC_HIDE(&__regs, 0); /* Rewind */ - regs->pc -= 2; + regs->pc -= instruction_size(ctrl_inw(regs->pc - 4)); - if (notify_die(DIE_TRAP, regs, regs->tra & 0xff, + if (notify_die(DIE_TRAP, "debug trap", regs, 0, regs->tra & 0xff, SIGTRAP) == NOTIFY_STOP) return; @@ -514,9 +541,9 @@ asmlinkage void bug_trap_handler(unsigned long r4, unsigned long r5, struct pt_regs *regs = RELOC_HIDE(&__regs, 0); /* Rewind */ - regs->pc -= 2; + regs->pc -= instruction_size(ctrl_inw(regs->pc - 4)); - if (notify_die(DIE_TRAP, regs, TRAPA_BUG_OPCODE & 0xff, + if (notify_die(DIE_TRAP, "bug trap", regs, 0, TRAPA_BUG_OPCODE & 0xff, SIGTRAP) == NOTIFY_STOP) return; |