summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--arch/blackfin/Kconfig46
-rw-r--r--arch/blackfin/kernel/irqchip.c3
-rw-r--r--arch/blackfin/mach-bf533/head.S10
-rw-r--r--arch/blackfin/mach-bf537/head.S10
-rw-r--r--arch/blackfin/mach-bf548/head.S10
-rw-r--r--arch/blackfin/mach-bf561/head.S10
-rw-r--r--arch/blackfin/mach-common/entry.S18
-rw-r--r--arch/blackfin/mach-common/interrupt.S28
-rw-r--r--arch/blackfin/mach-common/ints-priority-dc.c6
-rw-r--r--arch/blackfin/mach-common/ints-priority-sc.c6
-rw-r--r--include/asm-blackfin/irq_handler.h5
11 files changed, 107 insertions, 45 deletions
diff --git a/arch/blackfin/Kconfig b/arch/blackfin/Kconfig
index cdce8cc5b7b3..26ebb0e8c431 100644
--- a/arch/blackfin/Kconfig
+++ b/arch/blackfin/Kconfig
@@ -521,6 +521,52 @@ config BFIN_IDLE_LED_NUM
help
Select the LED (marked on the board) for you to blink.
+choice
+ prompt "Blackfin Exception Scratch Register"
+ default BFIN_SCRATCH_REG_RETN
+ help
+ Select the resource to reserve for the Exception handler:
+ - RETN: Non-Maskable Interrupt (NMI)
+ - RETE: Exception Return (JTAG/ICE)
+ - CYCLES: Performance counter
+
+ If you are unsure, please select "RETN".
+
+config BFIN_SCRATCH_REG_RETN
+ bool "RETN"
+ help
+ Use the RETN register in the Blackfin exception handler
+ as a stack scratch register. This means you cannot
+ safely use NMI on the Blackfin while running Linux, but
+ you can debug the system with a JTAG ICE and use the
+ CYCLES performance registers.
+
+ If you are unsure, please select "RETN".
+
+config BFIN_SCRATCH_REG_RETE
+ bool "RETE"
+ help
+ Use the RETE register in the Blackfin exception handler
+ as a stack scratch register. This means you cannot
+ safely use a JTAG ICE while debugging a Blackfin board,
+ but you can safely use the CYCLES performance registers
+ and the NMI.
+
+ If you are unsure, please select "RETN".
+
+config BFIN_SCRATCH_REG_CYCLES
+ bool "CYCLES"
+ help
+ Use the CYCLES register in the Blackfin exception handler
+ as a stack scratch register. This means you cannot
+ safely use the CYCLES performance registers on a Blackfin
+ board at anytime, but you can debug the system with a JTAG
+ ICE and use the NMI.
+
+ If you are unsure, please select "RETN".
+
+endchoice
+
#
# Sorry - but you need to put the hex address here -
#
diff --git a/arch/blackfin/kernel/irqchip.c b/arch/blackfin/kernel/irqchip.c
index 462ae41144c7..73647c158774 100644
--- a/arch/blackfin/kernel/irqchip.c
+++ b/arch/blackfin/kernel/irqchip.c
@@ -98,9 +98,8 @@ int show_interrupts(struct seq_file *p, void *v)
*/
#ifdef CONFIG_DO_IRQ_L1
-asmlinkage void asm_do_IRQ(unsigned int irq, struct pt_regs *regs)__attribute__((l1_text));
+__attribute__((l1_text))
#endif
-
asmlinkage void asm_do_IRQ(unsigned int irq, struct pt_regs *regs)
{
struct pt_regs *old_regs;
diff --git a/arch/blackfin/mach-bf533/head.S b/arch/blackfin/mach-bf533/head.S
index 1d5b9dbbbaa7..3be6feefa8a9 100644
--- a/arch/blackfin/mach-bf533/head.S
+++ b/arch/blackfin/mach-bf533/head.S
@@ -53,10 +53,12 @@ __INIT
ENTRY(__start)
/* R0: argument of command line string, passed from uboot, save it */
R7 = R0;
- /* Set the SYSCFG register:
- * Enable Cycle Counter and Nesting Of Interrupts (3rd Bit)
- */
- R0 = 0x36;
+ /* Enable Cycle Counter and Nesting Of Interrupts */
+#ifdef CONFIG_BFIN_SCRATCH_REG_CYCLES
+ R0 = SYSCFG_SNEN;
+#else
+ R0 = SYSCFG_SNEN | SYSCFG_CCEN;
+#endif
SYSCFG = R0;
R0 = 0;
diff --git a/arch/blackfin/mach-bf537/head.S b/arch/blackfin/mach-bf537/head.S
index 6dbcb77c8d36..0836bfdcc6c5 100644
--- a/arch/blackfin/mach-bf537/head.S
+++ b/arch/blackfin/mach-bf537/head.S
@@ -51,10 +51,12 @@ __INIT
ENTRY(__start)
/* R0: argument of command line string, passed from uboot, save it */
R7 = R0;
- /* Set the SYSCFG register:
- * Enable Cycle Counter and Nesting Of Interrupts (3rd Bit)
- */
- R0 = 0x36;
+ /* Enable Cycle Counter and Nesting Of Interrupts */
+#ifdef CONFIG_BFIN_SCRATCH_REG_CYCLES
+ R0 = SYSCFG_SNEN;
+#else
+ R0 = SYSCFG_SNEN | SYSCFG_CCEN;
+#endif
SYSCFG = R0;
R0 = 0;
diff --git a/arch/blackfin/mach-bf548/head.S b/arch/blackfin/mach-bf548/head.S
index 4c7d49f41187..937fbef26a51 100644
--- a/arch/blackfin/mach-bf548/head.S
+++ b/arch/blackfin/mach-bf548/head.S
@@ -50,9 +50,13 @@ ENTRY(__start)
ENTRY(__stext)
/* R0: argument of command line string, passed from uboot, save it */
R7 = R0;
- /* Set the SYSCFG register */
- R0 = 0x36;
- SYSCFG = R0; /*Enable Cycle Counter and Nesting Of Interrupts(3rd Bit)*/
+ /* Enable Cycle Counter and Nesting Of Interrupts */
+#ifdef CONFIG_BFIN_SCRATCH_REG_CYCLES
+ R0 = SYSCFG_SNEN;
+#else
+ R0 = SYSCFG_SNEN | SYSCFG_CCEN;
+#endif
+ SYSCFG = R0;
R0 = 0;
/* Clear Out All the data and pointer Registers*/
diff --git a/arch/blackfin/mach-bf561/head.S b/arch/blackfin/mach-bf561/head.S
index 8c9f73b8e579..139f4cff801b 100644
--- a/arch/blackfin/mach-bf561/head.S
+++ b/arch/blackfin/mach-bf561/head.S
@@ -51,10 +51,12 @@ __INIT
ENTRY(__start)
/* R0: argument of command line string, passed from uboot, save it */
R7 = R0;
- /* Set the SYSCFG register:
- * Enable Cycle Counter and Nesting Of Interrupts (3rd Bit)
- */
- R0 = 0x36;
+ /* Enable Cycle Counter and Nesting Of Interrupts */
+#ifdef CONFIG_BFIN_SCRATCH_REG_CYCLES
+ R0 = SYSCFG_SNEN;
+#else
+ R0 = SYSCFG_SNEN | SYSCFG_CCEN;
+#endif
SYSCFG = R0;
R0 = 0;
diff --git a/arch/blackfin/mach-common/entry.S b/arch/blackfin/mach-common/entry.S
index ab278a72f282..2188f81c6456 100644
--- a/arch/blackfin/mach-common/entry.S
+++ b/arch/blackfin/mach-common/entry.S
@@ -58,6 +58,14 @@
#include <asm/mach-common/context.S>
+#if defined(CONFIG_BFIN_SCRATCH_REG_RETN)
+# define EX_SCRATCH_REG RETN
+#elif defined(CONFIG_BFIN_SCRATCH_REG_RETE)
+# define EX_SCRATCH_REG RETE
+#else
+# define EX_SCRATCH_REG CYCLES
+#endif
+
#ifdef CONFIG_EXCPT_IRQ_SYSC_L1
.section .l1.text
#else
@@ -93,7 +101,7 @@ ENTRY(_ex_icplb)
call __cplb_hdr;
DEBUG_START_HWTRACE(p5, r7)
RESTORE_ALL_SYS
- SP = RETN;
+ SP = EX_SCRATCH_REG;
rtx;
ENDPROC(_ex_icplb)
@@ -102,7 +110,7 @@ ENTRY(_ex_syscall)
(R7:6,P5:4) = [sp++];
ASTAT = [sp++];
raise 15; /* invoked by TRAP #0, for sys call */
- sp = retn;
+ sp = EX_SCRATCH_REG;
rtx
ENDPROC(_ex_syscall)
@@ -145,7 +153,7 @@ _return_from_exception:
#endif
(R7:6,P5:4) = [sp++];
ASTAT = [sp++];
- sp = retn;
+ sp = EX_SCRATCH_REG;
rtx;
ENDPROC(_ex_soft_bp)
@@ -204,7 +212,7 @@ ENTRY(_ex_trap_c)
DEBUG_START_HWTRACE(p5, r7)
(R7:6,P5:4) = [sp++];
ASTAT = [sp++];
- SP = RETN;
+ SP = EX_SCRATCH_REG;
raise 5;
rtx;
ENDPROC(_ex_trap_c)
@@ -279,7 +287,7 @@ ENTRY(_trap) /* Exception: 4th entry into system event table(supervisor mode)*/
* covered by a CPLB. Switch to an exception stack; use RETN as a
* scratch register (for want of a better option).
*/
- retn = sp;
+ EX_SCRATCH_REG = sp;
sp.l = _exception_stack_top;
sp.h = _exception_stack_top;
/* Try to deal with syscalls quickly. */
diff --git a/arch/blackfin/mach-common/interrupt.S b/arch/blackfin/mach-common/interrupt.S
index 1d5ba5e3d91c..c6b32fe0f6e9 100644
--- a/arch/blackfin/mach-common/interrupt.S
+++ b/arch/blackfin/mach-common/interrupt.S
@@ -177,27 +177,15 @@ ENTRY(_evt_ivhw)
jump .Lcommon_restore_context;
#endif
-/* interrupt routine for evt2 - 2. This is NMI. */
-ENTRY(_evt_evt2)
- SAVE_CONTEXT
-#ifdef CONFIG_FRAME_POINTER
- fp = 0;
-#endif
-#if ANOMALY_05000283
- cc = r7 == r7;
- p5.h = 0xffc0;
- p5.l = 0x0014;
- if cc jump 1f;
- r7.l = W[p5];
-1:
-#endif
- r0 = IRQ_NMI;
- r1 = sp;
- SP += -12;
- call _asm_do_IRQ;
- SP += 12;
- RESTORE_CONTEXT
+/* Interrupt routine for evt2 (NMI).
+ * We don't actually use this, so just return.
+ * For inner circle type details, please see:
+ * http://docs.blackfin.uclinux.org/doku.php?id=linux:nmi
+ */
+ENTRY(_evt_nmi)
+.weak _evt_nmi
rtn;
+ENDPROC(_evt_nmi)
/* interrupt routine for core timer - 6 */
ENTRY(_evt_timer)
diff --git a/arch/blackfin/mach-common/ints-priority-dc.c b/arch/blackfin/mach-common/ints-priority-dc.c
index 684d306ab6bb..2db3546fc874 100644
--- a/arch/blackfin/mach-common/ints-priority-dc.c
+++ b/arch/blackfin/mach-common/ints-priority-dc.c
@@ -362,7 +362,11 @@ void __init init_exception_vectors(void)
{
SSYNC();
- bfin_write_EVT2(evt_evt2);
+ /* cannot program in software:
+ * evt0 - emulation (jtag)
+ * evt1 - reset
+ */
+ bfin_write_EVT2(evt_nmi);
bfin_write_EVT3(trap);
bfin_write_EVT5(evt_ivhw);
bfin_write_EVT6(evt_timer);
diff --git a/arch/blackfin/mach-common/ints-priority-sc.c b/arch/blackfin/mach-common/ints-priority-sc.c
index a2016af65eb0..d3b7672b2b94 100644
--- a/arch/blackfin/mach-common/ints-priority-sc.c
+++ b/arch/blackfin/mach-common/ints-priority-sc.c
@@ -721,7 +721,11 @@ void __init init_exception_vectors(void)
{
SSYNC();
- bfin_write_EVT2(evt_evt2);
+ /* cannot program in software:
+ * evt0 - emulation (jtag)
+ * evt1 - reset
+ */
+ bfin_write_EVT2(evt_nmi);
bfin_write_EVT3(trap);
bfin_write_EVT5(evt_ivhw);
bfin_write_EVT6(evt_timer);
diff --git a/include/asm-blackfin/irq_handler.h b/include/asm-blackfin/irq_handler.h
index 6a768315bbf7..f13cd73b0966 100644
--- a/include/asm-blackfin/irq_handler.h
+++ b/include/asm-blackfin/irq_handler.h
@@ -1,12 +1,15 @@
#ifndef _IRQ_HANDLER_H
#define _IRQ_HANDLER_H
+#include <linux/types.h>
+#include <linux/linkage.h>
+
/* BASE LEVEL interrupt handler routines */
asmlinkage void evt_exception(void);
asmlinkage void trap(void);
asmlinkage void evt_ivhw(void);
asmlinkage void evt_timer(void);
-asmlinkage void evt_evt2(void);
+asmlinkage void evt_nmi(void);
asmlinkage void evt_evt7(void);
asmlinkage void evt_evt8(void);
asmlinkage void evt_evt9(void);