>From 551749f716c6a362ccbbfde74ef47c2cbb372805 Mon Sep 17 00:00:00 2001 From: Sebastian Hesselbarth Date: Wed, 15 Jan 2014 20:00:21 +0100 Subject: [PATCH 1/2] ARM: orion: provide C-style interrupt handler for MULTI_IRQ_HANDLER Compiling with both non-DT and DT support enabled, will break ASM irq handler used by non-DT boards. Therefore, we provide a C-style irq handler even for non-DT boards, if MULTI_IRQ_HANDLER is set. Signed-off-by: Sebastian Hesselbarth --- arch/arm/plat-orion/include/plat/irq.h | 1 + arch/arm/plat-orion/irq.c | 43 ++++++++++++++++++++++++++++++++++ 2 files changed, 44 insertions(+) diff --git a/arch/arm/plat-orion/include/plat/irq.h b/arch/arm/plat-orion/include/plat/irq.h index 50547e417936..75a38b577460 100644 --- a/arch/arm/plat-orion/include/plat/irq.h +++ b/arch/arm/plat-orion/include/plat/irq.h @@ -11,6 +11,7 @@ #ifndef __PLAT_IRQ_H #define __PLAT_IRQ_H +void orion_legacy_handle_irq(struct pt_regs *regs); void orion_irq_init(unsigned int irq_start, void __iomem *maskaddr); void __init orion_dt_init_irq(void); #endif diff --git a/arch/arm/plat-orion/irq.c b/arch/arm/plat-orion/irq.c index c492e1b3dfdb..82dd811b05c4 100644 --- a/arch/arm/plat-orion/irq.c +++ b/arch/arm/plat-orion/irq.c @@ -15,8 +15,51 @@ #include #include #include +#include #include #include +#include + +#ifdef CONFIG_MULTI_IRQ_HANDLER +/* + * Compiling with both non-DT and DT support enabled, will + * break asm irq handler used by non-DT boards. Therefore, + * we provide a C-style irq handler even for non-DT boards, + * if MULTI_IRQ_HANDLER is set. + */ + +#ifdef CONFIG_ARCH_ORION5X +/* Orion5x only has one irq cause and different macro names */ +# define IRQ_VIRT_BASE MAIN_IRQ_CAUSE +# define IRQ_CAUSE_LOW_OFF 0x00 +# define IRQ_MASK_LOW_OFF 0x04 +#endif + +static void __iomem *orion_irq_base = IRQ_VIRT_BASE; + +asmlinkage void +__exception_irq_entry orion_legacy_handle_irq(struct pt_regs *regs) +{ + u32 stat; + + stat = readl_relaxed(orion_irq_base + IRQ_CAUSE_LOW_OFF); + stat &= readl_relaxed(orion_irq_base + IRQ_MASK_LOW_OFF); + if (stat) { + int hwirq = __fls(stat); + handle_IRQ(hwirq, regs); + return; + } +#ifndef CONFIG_ARCH_ORION5X + stat = readl_relaxed(orion_irq_base + IRQ_CAUSE_HIGH_OFF); + stat &= readl_relaxed(orion_irq_base + IRQ_MASK_HIGH_OFF); + if (stat) { + int hwirq = 32 + __fls(stat); + handle_IRQ(hwirq, regs); + return; + } +#endif +} +#endif void __init orion_irq_init(unsigned int irq_start, void __iomem *maskaddr) { -- 1.8.5.2