summaryrefslogtreecommitdiff
path: root/arch/blackfin
diff options
context:
space:
mode:
authorSonic Zhang <sonic.zhang@analog.com>2012-07-04 19:22:55 +0800
committerBob Liu <lliubbo@gmail.com>2012-07-24 13:39:52 +0800
commit06051fdefddf25e0bbf983aac40680f835829db7 (patch)
treecf8de7f13c788b7651bc03c4ad07e3d7511ae2d1 /arch/blackfin
parent2a26a2055259862e771cb922aee3d1196040c205 (diff)
downloadlinux-3.10-06051fdefddf25e0bbf983aac40680f835829db7.tar.gz
linux-3.10-06051fdefddf25e0bbf983aac40680f835829db7.tar.bz2
linux-3.10-06051fdefddf25e0bbf983aac40680f835829db7.zip
bf60x: Add double fault, hardware error and NMI SEC handler
Signed-off-by: Sonic Zhang <sonic.zhang@analog.com> Signed-off-by: Bob Liu <lliubbo@gmail.com>
Diffstat (limited to 'arch/blackfin')
-rw-r--r--arch/blackfin/include/asm/traps.h2
-rw-r--r--arch/blackfin/mach-common/ints-priority.c34
2 files changed, 35 insertions, 1 deletions
diff --git a/arch/blackfin/include/asm/traps.h b/arch/blackfin/include/asm/traps.h
index 70c4e511cae..cec771b8100 100644
--- a/arch/blackfin/include/asm/traps.h
+++ b/arch/blackfin/include/asm/traps.h
@@ -125,5 +125,7 @@
level " for Supervisor use: Supervisor only registers, all MMRs, and Supervisor\n" \
level " only instructions.\n"
+extern void double_fault_c(struct pt_regs *fp);
+
#endif /* __ASSEMBLY__ */
#endif /* _BFIN_TRAPS_H */
diff --git a/arch/blackfin/mach-common/ints-priority.c b/arch/blackfin/mach-common/ints-priority.c
index 5a109a18402..9660d5fdbed 100644
--- a/arch/blackfin/mach-common/ints-priority.c
+++ b/arch/blackfin/mach-common/ints-priority.c
@@ -26,6 +26,7 @@
#include <asm/gpio.h>
#include <asm/irq_handler.h>
#include <asm/dpmc.h>
+#include <asm/traps.h>
#ifndef SEC_GCTL
# define SIC_SYSIRQ(irq) (irq - (IRQ_CORETMR + 1))
@@ -413,6 +414,34 @@ void handle_sec_fault(unsigned int irq, struct irq_desc *desc)
raw_spin_unlock(&desc->lock);
}
+void handle_core_fault(unsigned int irq, struct irq_desc *desc)
+{
+ struct pt_regs *fp = get_irq_regs();
+
+ raw_spin_lock(&desc->lock);
+
+ switch (irq) {
+ case IRQ_C0_DBL_FAULT:
+ double_fault_c(fp);
+ break;
+ case IRQ_C0_HW_ERR:
+ dump_bfin_process(fp);
+ dump_bfin_mem(fp);
+ show_regs(fp);
+ printk(KERN_NOTICE "Kernel Stack\n");
+ show_stack(current, NULL);
+ print_modules();
+ panic("Kernel core hardware error");
+ break;
+ case IRQ_C0_NMI_L1_PARITY_ERR:
+ panic("NMI %d occurs unexpectedly");
+ break;
+ default:
+ panic("Core 1 fault %d occurs unexpectedly");
+ }
+
+ raw_spin_unlock(&desc->lock);
+}
#endif
#ifdef CONFIG_SMP
@@ -1522,9 +1551,12 @@ int __init init_arch_irq(void)
} else if (irq < BFIN_IRQ(0)) {
irq_set_chip_and_handler(irq, &bfin_internal_irqchip,
handle_simple_irq);
- } else if (irq < CORE_IRQS && irq != IRQ_CGU_EVT) {
+ } else if (irq == IRQ_SEC_ERR) {
irq_set_chip_and_handler(irq, &bfin_sec_irqchip,
handle_sec_fault);
+ } else if (irq < CORE_IRQS && irq >= IRQ_C0_DBL_FAULT) {
+ irq_set_chip_and_handler(irq, &bfin_sec_irqchip,
+ handle_core_fault);
} else if (irq >= BFIN_IRQ(21) && irq <= BFIN_IRQ(26)) {
irq_set_chip(irq, &bfin_sec_irqchip);
irq_set_chained_handler(irq, bfin_demux_gpio_irq);