diff options
author | Daniel Thompson <daniel.thompson@linaro.org> | 2015-01-13 15:36:56 +0000 |
---|---|---|
committer | Daniel Thompson <daniel.thompson@linaro.org> | 2015-01-21 17:02:54 +0000 |
commit | 73ff7c8248d13dc9288b905d9c04e0e703ca2d00 (patch) | |
tree | e8a0c90dcd27e1b4c1abc75e5895813215c2e17f /arch | |
parent | 51d0de72371ef91361e57e245748f09f9a561bb7 (diff) | |
download | linux-73ff7c8248d13dc9288b905d9c04e0e703ca2d00.tar.gz |
irq: gic: Add support for NMI routing
This patch provides an implementation of irq_set_nmi_routing by
allowing SPIs to be switched between group 1 (IRQ) and group 0 (FIQ).
It also repaces the interface used between the default FIQ handler and
the GIC. These extensions are required in order to allow SPIs to be
acknowledged and completed.
Signed-off-by: Daniel Thompson <daniel.thompson@linaro.org>
Diffstat (limited to 'arch')
-rw-r--r-- | arch/arm/kernel/traps.c | 29 |
1 files changed, 24 insertions, 5 deletions
diff --git a/arch/arm/kernel/traps.c b/arch/arm/kernel/traps.c index 5645f81ac4cc..445fdf26b1af 100644 --- a/arch/arm/kernel/traps.c +++ b/arch/arm/kernel/traps.c @@ -26,6 +26,7 @@ #include <linux/init.h> #include <linux/sched.h> #include <linux/irq.h> +#include <linux/interrupt.h> #include <linux/irqchip/arm-gic.h> #include <linux/atomic.h> @@ -462,6 +463,23 @@ die_sig: arm_notify_die("Oops - undefined instruction", regs, &info, 0, 6); } +int arch_filter_nmi_handler(irq_handler_t handler) +{ + irq_handler_t whitelist[] = { + }; + int i; + + for (i = 0; i < ARRAY_SIZE(whitelist); i++) + if (handler == whitelist[i]) { + pr_debug("%pS accepted for use as NMI handler\n", + handler); + return 0; + } + + pr_err("%pS cannot be used as an NMI handler\n", handler); + return -EPERM; +} + /* * Handle FIQ similarly to NMI on x86 systems. * @@ -478,19 +496,20 @@ asmlinkage void __exception_irq_entry handle_fiq_as_nmi(struct pt_regs *regs) { unsigned int cpu = smp_processor_id(); struct pt_regs *old_regs = set_irq_regs(regs); + enum irqreturn irqret = 0; __inc_irq_stat(cpu, __nmi_count); nmi_enter(); -#ifdef CONFIG_ARM_GIC - gic_handle_fiq_ipi(); -#endif + irqret = gic_handle_fiq(); + + if (irqret == IRQ_NONE) { #ifdef CONFIG_SMP - ipi_cpu_backtrace(regs); + ipi_cpu_backtrace(regs); #endif + } nmi_exit(); - set_irq_regs(old_regs); } |