summaryrefslogtreecommitdiffstats
path: root/arch/sh/kernel/process.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/sh/kernel/process.c')
-rw-r--r--arch/sh/kernel/process.c24
1 files changed, 20 insertions, 4 deletions
diff --git a/arch/sh/kernel/process.c b/arch/sh/kernel/process.c
index e7607366ac4..6b4f5748d0b 100644
--- a/arch/sh/kernel/process.c
+++ b/arch/sh/kernel/process.c
@@ -7,7 +7,7 @@
*
* SuperH version: Copyright (C) 1999, 2000 Niibe Yutaka & Kaz Kojima
* Copyright (C) 2006 Lineo Solutions Inc. support SH4A UBC
- * Copyright (C) 2002 - 2006 Paul Mundt
+ * Copyright (C) 2002 - 2007 Paul Mundt
*/
#include <linux/module.h>
#include <linux/mm.h>
@@ -15,8 +15,12 @@
#include <linux/pm.h>
#include <linux/kallsyms.h>
#include <linux/kexec.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;
@@ -57,12 +61,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();
}
}
@@ -299,7 +306,8 @@ static void ubc_set_tracing(int asid, unsigned long pc)
ctrl_outl(0, UBC_BAMRA);
if (current_cpu_data.type == CPU_SH7729 ||
- current_cpu_data.type == CPU_SH7710) {
+ current_cpu_data.type == CPU_SH7710 ||
+ current_cpu_data.type == CPU_SH7712) {
ctrl_outw(BBR_INST | BBR_READ | BBR_CPU, UBC_BBRA);
ctrl_outl(BRCR_PCBA | BRCR_PCTE, UBC_BRCR);
} else {
@@ -493,7 +501,11 @@ 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, "debug trap", regs, 0, regs->tra & 0xff,
+ SIGTRAP) == NOTIFY_STOP)
+ return;
force_sig(SIGTRAP, current);
}
@@ -508,7 +520,11 @@ 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, "bug trap", regs, 0, TRAPA_BUG_OPCODE & 0xff,
+ SIGTRAP) == NOTIFY_STOP)
+ return;
#ifdef CONFIG_BUG
if (__kernel_text_address(instruction_pointer(regs))) {