diff options
author | Alexander Shiyan <shc_work@mail.ru> | 2012-11-17 17:57:14 +0400 |
---|---|---|
committer | Olof Johansson <olof@lixom.net> | 2012-11-21 09:57:42 -0800 |
commit | 99f04c8f69753e4032059eeb0c21197948e459f7 (patch) | |
tree | 876d54413124fb63dcab9d95446a8686953d2414 | |
parent | 0d8be81c0e15ad8ebdd35bbbeb35b03f85a4b558 (diff) | |
download | lwn-99f04c8f69753e4032059eeb0c21197948e459f7.tar.gz lwn-99f04c8f69753e4032059eeb0c21197948e459f7.zip |
ARM: clps711x: Implement usage "MULTI_IRQ_HANDLER" kernel option for a platform
Signed-off-by: Alexander Shiyan <shc_work@mail.ru>
Signed-off-by: Olof Johansson <olof@lixom.net>
-rw-r--r-- | arch/arm/Kconfig | 1 | ||||
-rw-r--r-- | arch/arm/mach-clps711x/autcpu12.c | 1 | ||||
-rw-r--r-- | arch/arm/mach-clps711x/cdb89712.c | 1 | ||||
-rw-r--r-- | arch/arm/mach-clps711x/clep7312.c | 3 | ||||
-rw-r--r-- | arch/arm/mach-clps711x/common.c | 45 | ||||
-rw-r--r-- | arch/arm/mach-clps711x/common.h | 3 | ||||
-rw-r--r-- | arch/arm/mach-clps711x/edb7211.c | 1 | ||||
-rw-r--r-- | arch/arm/mach-clps711x/fortunet.c | 1 | ||||
-rw-r--r-- | arch/arm/mach-clps711x/include/mach/entry-macro.S | 51 | ||||
-rw-r--r-- | arch/arm/mach-clps711x/p720t.c | 1 |
10 files changed, 50 insertions, 58 deletions
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index 0203b1bf733d..9c2c8f3c98ec 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -371,6 +371,7 @@ config ARCH_CLPS711X select COMMON_CLK select CPU_ARM720T select GENERIC_CLOCKEVENTS + select MULTI_IRQ_HANDLER select NEED_MACH_MEMORY_H select SPARSE_IRQ help diff --git a/arch/arm/mach-clps711x/autcpu12.c b/arch/arm/mach-clps711x/autcpu12.c index b90a31659de4..3de19554d800 100644 --- a/arch/arm/mach-clps711x/autcpu12.c +++ b/arch/arm/mach-clps711x/autcpu12.c @@ -75,6 +75,7 @@ MACHINE_START(AUTCPU12, "autronix autcpu12") .init_irq = clps711x_init_irq, .timer = &clps711x_timer, .init_machine = autcpu12_init, + .handle_irq = clps711x_handle_irq, .restart = clps711x_restart, MACHINE_END diff --git a/arch/arm/mach-clps711x/cdb89712.c b/arch/arm/mach-clps711x/cdb89712.c index 133794c4b654..60900ddf97c9 100644 --- a/arch/arm/mach-clps711x/cdb89712.c +++ b/arch/arm/mach-clps711x/cdb89712.c @@ -142,5 +142,6 @@ MACHINE_START(CDB89712, "Cirrus-CDB89712") .init_irq = clps711x_init_irq, .timer = &clps711x_timer, .init_machine = cdb89712_init, + .handle_irq = clps711x_handle_irq, .restart = clps711x_restart, MACHINE_END diff --git a/arch/arm/mach-clps711x/clep7312.c b/arch/arm/mach-clps711x/clep7312.c index be776c5092dd..0b32a487183b 100644 --- a/arch/arm/mach-clps711x/clep7312.c +++ b/arch/arm/mach-clps711x/clep7312.c @@ -33,7 +33,6 @@ fixup_clep7312(struct tag *tags, char **cmdline, struct meminfo *mi) mi->bank[0].size = 0x01000000; } - MACHINE_START(CLEP7212, "Cirrus Logic 7212/7312") /* Maintainer: Nobody */ .atag_offset = 0x0100, @@ -42,6 +41,6 @@ MACHINE_START(CLEP7212, "Cirrus Logic 7212/7312") .map_io = clps711x_map_io, .init_irq = clps711x_init_irq, .timer = &clps711x_timer, + .handle_irq = clps711x_handle_irq, .restart = clps711x_restart, MACHINE_END - diff --git a/arch/arm/mach-clps711x/common.c b/arch/arm/mach-clps711x/common.c index 286d6e6d5f5a..08420244c058 100644 --- a/arch/arm/mach-clps711x/common.c +++ b/arch/arm/mach-clps711x/common.c @@ -29,6 +29,7 @@ #include <linux/clockchips.h> #include <linux/clk-provider.h> +#include <asm/exception.h> #include <asm/mach/map.h> #include <asm/mach/time.h> #include <asm/system_misc.h> @@ -134,13 +135,11 @@ static struct irq_chip int2_chip = { .irq_unmask = int2_unmask, }; -struct clps711x_irqdesc { +static struct { int nr; struct irq_chip *chip; irq_flow_handler_t handle; -}; - -static struct clps711x_irqdesc clps711x_irqdescs[] __initdata = { +} clps711x_irqdescs[] __initdata = { { IRQ_CSINT, &int1_chip, handle_fasteoi_irq, }, { IRQ_EINT1, &int1_chip, handle_level_irq, }, { IRQ_EINT2, &int1_chip, handle_level_irq, }, @@ -191,6 +190,44 @@ void __init clps711x_init_irq(void) } } +inline u32 fls16(u32 x) +{ + u32 r = 15; + + if (!(x & 0xff00)) { + x <<= 8; + r -= 8; + } + if (!(x & 0xf000)) { + x <<= 4; + r -= 4; + } + if (!(x & 0xc000)) { + x <<= 2; + r -= 2; + } + if (!(x & 0x8000)) + r--; + + return r; +} + +asmlinkage void __exception_irq_entry clps711x_handle_irq(struct pt_regs *regs) +{ + u32 irqstat; + void __iomem *base = CLPS711X_VIRT_BASE; + + irqstat = readl_relaxed(base + INTSR1) & readl_relaxed(base + INTMR1); + if (irqstat) { + handle_IRQ(fls16(irqstat), regs); + return; + } + + irqstat = readl_relaxed(base + INTSR2) & readl_relaxed(base + INTMR2); + if (likely(irqstat)) + handle_IRQ(fls16(irqstat) + 16, regs); +} + static void clps711x_clockevent_set_mode(enum clock_event_mode mode, struct clock_event_device *evt) { diff --git a/arch/arm/mach-clps711x/common.h b/arch/arm/mach-clps711x/common.h index 28b1701b7993..3c7f12cb81c1 100644 --- a/arch/arm/mach-clps711x/common.h +++ b/arch/arm/mach-clps711x/common.h @@ -12,5 +12,6 @@ struct sys_timer; extern void clps711x_map_io(void); extern void clps711x_init_irq(void); -extern struct sys_timer clps711x_timer; +extern void clps711x_handle_irq(struct pt_regs *regs); extern void clps711x_restart(char mode, const char *cmd); +extern struct sys_timer clps711x_timer; diff --git a/arch/arm/mach-clps711x/edb7211.c b/arch/arm/mach-clps711x/edb7211.c index 7b161dd40e8d..cc32a65d6982 100644 --- a/arch/arm/mach-clps711x/edb7211.c +++ b/arch/arm/mach-clps711x/edb7211.c @@ -98,5 +98,6 @@ MACHINE_START(EDB7211, "CL-EDB7211 (EP7211 eval board)") .init_irq = clps711x_init_irq, .timer = &clps711x_timer, .init_machine = edb7211_init, + .handle_irq = clps711x_handle_irq, .restart = clps711x_restart, MACHINE_END diff --git a/arch/arm/mach-clps711x/fortunet.c b/arch/arm/mach-clps711x/fortunet.c index a5c08162bff9..7d0125580366 100644 --- a/arch/arm/mach-clps711x/fortunet.c +++ b/arch/arm/mach-clps711x/fortunet.c @@ -79,5 +79,6 @@ MACHINE_START(FORTUNET, "ARM-FortuNet") .map_io = clps711x_map_io, .init_irq = clps711x_init_irq, .timer = &clps711x_timer, + .handle_irq = clps711x_handle_irq, .restart = clps711x_restart, MACHINE_END diff --git a/arch/arm/mach-clps711x/include/mach/entry-macro.S b/arch/arm/mach-clps711x/include/mach/entry-macro.S deleted file mode 100644 index 56e5c2c23504..000000000000 --- a/arch/arm/mach-clps711x/include/mach/entry-macro.S +++ /dev/null @@ -1,51 +0,0 @@ -/* - * arch/arm/mach-clps711x/include/mach/entry-macro.S - * - * Low-level IRQ helper macros for CLPS711X-based platforms - * - * This file is licensed under the terms of the GNU General Public - * License version 2. This program is licensed "as is" without any - * warranty of any kind, whether express or implied. - */ -#include <mach/hardware.h> - - .macro get_irqnr_preamble, base, tmp - .endm - -#if (INTSR2 - INTSR1) != (INTMR2 - INTMR1) -#error INTSR stride != INTMR stride -#endif - - .macro get_irqnr_and_base, irqnr, stat, base, mask - mov \base, #CLPS711X_VIRT_BASE - ldr \stat, [\base, #INTSR1] - ldr \mask, [\base, #INTMR1] - mov \irqnr, #4 - mov \mask, \mask, lsl #16 - and \stat, \stat, \mask, lsr #16 - movs \stat, \stat, lsr #4 - bne 1001f - - add \base, \base, #INTSR2 - INTSR1 - ldr \stat, [\base, #INTSR1] - ldr \mask, [\base, #INTMR1] - mov \irqnr, #16 - mov \mask, \mask, lsl #16 - and \stat, \stat, \mask, lsr #16 - -1001: tst \stat, #255 - addeq \irqnr, \irqnr, #8 - moveq \stat, \stat, lsr #8 - tst \stat, #15 - addeq \irqnr, \irqnr, #4 - moveq \stat, \stat, lsr #4 - tst \stat, #3 - addeq \irqnr, \irqnr, #2 - moveq \stat, \stat, lsr #2 - tst \stat, #1 - addeq \irqnr, \irqnr, #1 - moveq \stat, \stat, lsr #1 - tst \stat, #1 @ bit 0 should be set - .endm - - diff --git a/arch/arm/mach-clps711x/p720t.c b/arch/arm/mach-clps711x/p720t.c index fbe75527d60b..a58a0585e3e7 100644 --- a/arch/arm/mach-clps711x/p720t.c +++ b/arch/arm/mach-clps711x/p720t.c @@ -142,5 +142,6 @@ MACHINE_START(P720T, "ARM-Prospector720T") .timer = &clps711x_timer, .init_machine = p720t_init, .init_late = p720t_init_late, + .handle_irq = clps711x_handle_irq, .restart = clps711x_restart, MACHINE_END |