diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index 45df48ba0b128dd408e2275687b1757c87e0ca74..881a76c586c27e34d53693ce9810fbcb224c5baa 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -752,6 +752,7 @@ config ARCH_OMAP1 select GENERIC_IRQ_CHIP select HAVE_IDE select IRQ_DOMAIN + select MULTI_IRQ_HANDLER select NEED_MACH_IO_H if PCCARD select NEED_MACH_MEMORY_H help diff --git a/arch/arm/mach-omap1/board-ams-delta.c b/arch/arm/mach-omap1/board-ams-delta.c index 2aab761ee68db7ae8fee7fd5eaf84e82f9c80572..a95499ea87064d4f886b234f2a8eafba922fe573 100644 --- a/arch/arm/mach-omap1/board-ams-delta.c +++ b/arch/arm/mach-omap1/board-ams-delta.c @@ -626,6 +626,7 @@ MACHINE_START(AMS_DELTA, "Amstrad E3 (Delta)") .map_io = ams_delta_map_io, .init_early = omap1_init_early, .init_irq = omap1_init_irq, + .handle_irq = omap1_handle_irq, .init_machine = ams_delta_init, .init_late = ams_delta_init_late, .init_time = omap1_timer_init, diff --git a/arch/arm/mach-omap1/board-fsample.c b/arch/arm/mach-omap1/board-fsample.c index 702d58039cc1a90820232615224d2015bf7a6329..0fb51d22c8b57fd8b4de7aa5a04fdae2f8499d4b 100644 --- a/arch/arm/mach-omap1/board-fsample.c +++ b/arch/arm/mach-omap1/board-fsample.c @@ -362,6 +362,7 @@ MACHINE_START(OMAP_FSAMPLE, "OMAP730 F-Sample") .map_io = omap_fsample_map_io, .init_early = omap1_init_early, .init_irq = omap1_init_irq, + .handle_irq = omap1_handle_irq, .init_machine = omap_fsample_init, .init_late = omap1_init_late, .init_time = omap1_timer_init, diff --git a/arch/arm/mach-omap1/board-generic.c b/arch/arm/mach-omap1/board-generic.c index e1d9171774bca91eec6f2a4802c7153208822743..9708629f8c5f9c83e3db2161e7d56e1cac02b7b4 100644 --- a/arch/arm/mach-omap1/board-generic.c +++ b/arch/arm/mach-omap1/board-generic.c @@ -82,6 +82,7 @@ MACHINE_START(OMAP_GENERIC, "Generic OMAP1510/1610/1710") .map_io = omap16xx_map_io, .init_early = omap1_init_early, .init_irq = omap1_init_irq, + .handle_irq = omap1_handle_irq, .init_machine = omap_generic_init, .init_late = omap1_init_late, .init_time = omap1_timer_init, diff --git a/arch/arm/mach-omap1/board-h2.c b/arch/arm/mach-omap1/board-h2.c index 5b45d266d83e0de774c3bdea376c3f29d5193aea..8340d684d8b6003fd8da9c4b801d35f82e7c15ca 100644 --- a/arch/arm/mach-omap1/board-h2.c +++ b/arch/arm/mach-omap1/board-h2.c @@ -426,6 +426,7 @@ MACHINE_START(OMAP_H2, "TI-H2") .map_io = omap16xx_map_io, .init_early = omap1_init_early, .init_irq = omap1_init_irq, + .handle_irq = omap1_handle_irq, .init_machine = h2_init, .init_late = omap1_init_late, .init_time = omap1_timer_init, diff --git a/arch/arm/mach-omap1/board-h3.c b/arch/arm/mach-omap1/board-h3.c index bfed4f928663a52b3643a7518f35e3c8c0537800..086ff34e072b6e5e4a489a84b00f9ca2f35cc189 100644 --- a/arch/arm/mach-omap1/board-h3.c +++ b/arch/arm/mach-omap1/board-h3.c @@ -452,6 +452,7 @@ MACHINE_START(OMAP_H3, "TI OMAP1710 H3 board") .map_io = omap16xx_map_io, .init_early = omap1_init_early, .init_irq = omap1_init_irq, + .handle_irq = omap1_handle_irq, .init_machine = h3_init, .init_late = omap1_init_late, .init_time = omap1_timer_init, diff --git a/arch/arm/mach-omap1/board-htcherald.c b/arch/arm/mach-omap1/board-htcherald.c index 35a2379b986f676618a49991dcd621cbe3e6e51b..9525ef9bc6c0db1b3e706a58b4348980b8843712 100644 --- a/arch/arm/mach-omap1/board-htcherald.c +++ b/arch/arm/mach-omap1/board-htcherald.c @@ -601,6 +601,7 @@ MACHINE_START(HERALD, "HTC Herald") .map_io = htcherald_map_io, .init_early = omap1_init_early, .init_irq = omap1_init_irq, + .handle_irq = omap1_handle_irq, .init_machine = htcherald_init, .init_late = omap1_init_late, .init_time = omap1_timer_init, diff --git a/arch/arm/mach-omap1/board-innovator.c b/arch/arm/mach-omap1/board-innovator.c index c49ce83cc1ebd066abcc4200f78cd9e008dda61a..ed4e045c2ad8278b360c7b5ebba8bd0ed75f48bb 100644 --- a/arch/arm/mach-omap1/board-innovator.c +++ b/arch/arm/mach-omap1/board-innovator.c @@ -456,6 +456,7 @@ MACHINE_START(OMAP_INNOVATOR, "TI-Innovator") .map_io = innovator_map_io, .init_early = omap1_init_early, .init_irq = omap1_init_irq, + .handle_irq = omap1_handle_irq, .init_machine = innovator_init, .init_late = omap1_init_late, .init_time = omap1_timer_init, diff --git a/arch/arm/mach-omap1/board-nokia770.c b/arch/arm/mach-omap1/board-nokia770.c index 85089d821982193b2e2d79f5f5fbf050eefad464..9f6c7af3a4e71158d25f72e0cecb8fdfc59fec57 100644 --- a/arch/arm/mach-omap1/board-nokia770.c +++ b/arch/arm/mach-omap1/board-nokia770.c @@ -294,6 +294,7 @@ MACHINE_START(NOKIA770, "Nokia 770") .map_io = omap16xx_map_io, .init_early = omap1_init_early, .init_irq = omap1_init_irq, + .handle_irq = omap1_handle_irq, .init_machine = omap_nokia770_init, .init_late = omap1_init_late, .init_time = omap1_timer_init, diff --git a/arch/arm/mach-omap1/board-osk.c b/arch/arm/mach-omap1/board-osk.c index 7436d4cf659640731acaaca4a0bc352561bfd769..0efd165b82278f52626c3cf2fd2a8af230020aa4 100644 --- a/arch/arm/mach-omap1/board-osk.c +++ b/arch/arm/mach-omap1/board-osk.c @@ -610,6 +610,7 @@ MACHINE_START(OMAP_OSK, "TI-OSK") .map_io = omap16xx_map_io, .init_early = omap1_init_early, .init_irq = omap1_init_irq, + .handle_irq = omap1_handle_irq, .init_machine = osk_init, .init_late = omap1_init_late, .init_time = omap1_timer_init, diff --git a/arch/arm/mach-omap1/board-palmte.c b/arch/arm/mach-omap1/board-palmte.c index 3b8e98f4353c465675bef171a19580c1987e35ae..1142ae431fe0dc2999a85da6847c4478e8ee2ee5 100644 --- a/arch/arm/mach-omap1/board-palmte.c +++ b/arch/arm/mach-omap1/board-palmte.c @@ -235,6 +235,7 @@ MACHINE_START(OMAP_PALMTE, "OMAP310 based Palm Tungsten E") .map_io = omap15xx_map_io, .init_early = omap1_init_early, .init_irq = omap1_init_irq, + .handle_irq = omap1_handle_irq, .init_machine = omap_palmte_init, .init_late = omap1_init_late, .init_time = omap1_timer_init, diff --git a/arch/arm/mach-omap1/board-palmtt.c b/arch/arm/mach-omap1/board-palmtt.c index ca501208825fc5fb62d49701e09aaf057b44d635..54a547a96950651733677ba66ba05b58a1435aa2 100644 --- a/arch/arm/mach-omap1/board-palmtt.c +++ b/arch/arm/mach-omap1/board-palmtt.c @@ -282,6 +282,7 @@ MACHINE_START(OMAP_PALMTT, "OMAP1510 based Palm Tungsten|T") .map_io = omap15xx_map_io, .init_early = omap1_init_early, .init_irq = omap1_init_irq, + .handle_irq = omap1_handle_irq, .init_machine = omap_palmtt_init, .init_late = omap1_init_late, .init_time = omap1_timer_init, diff --git a/arch/arm/mach-omap1/board-palmz71.c b/arch/arm/mach-omap1/board-palmz71.c index 470e12d67360cd351ae41b9467dfaf406b679c64..87ec04ae40dd691f29aa3f014f3fbe4269b5a394 100644 --- a/arch/arm/mach-omap1/board-palmz71.c +++ b/arch/arm/mach-omap1/board-palmz71.c @@ -297,6 +297,7 @@ MACHINE_START(OMAP_PALMZ71, "OMAP310 based Palm Zire71") .map_io = omap15xx_map_io, .init_early = omap1_init_early, .init_irq = omap1_init_irq, + .handle_irq = omap1_handle_irq, .init_machine = omap_palmz71_init, .init_late = omap1_init_late, .init_time = omap1_timer_init, diff --git a/arch/arm/mach-omap1/board-perseus2.c b/arch/arm/mach-omap1/board-perseus2.c index 8b2f7127f716ae583fb1ba05adc2976fb0905dd9..3d76f05407f0cbe87d16f514b4b6b4c3fab1f3af 100644 --- a/arch/arm/mach-omap1/board-perseus2.c +++ b/arch/arm/mach-omap1/board-perseus2.c @@ -324,6 +324,7 @@ MACHINE_START(OMAP_PERSEUS2, "OMAP730 Perseus2") .map_io = omap_perseus2_map_io, .init_early = omap1_init_early, .init_irq = omap1_init_irq, + .handle_irq = omap1_handle_irq, .init_machine = omap_perseus2_init, .init_late = omap1_init_late, .init_time = omap1_timer_init, diff --git a/arch/arm/mach-omap1/board-sx1.c b/arch/arm/mach-omap1/board-sx1.c index 29e526235dc2e06e964e2f54631b08d01a0a5f23..939991ea33d5cab3f31713ea427cd38325618fda 100644 --- a/arch/arm/mach-omap1/board-sx1.c +++ b/arch/arm/mach-omap1/board-sx1.c @@ -343,6 +343,7 @@ MACHINE_START(SX1, "OMAP310 based Siemens SX1") .map_io = omap15xx_map_io, .init_early = omap1_init_early, .init_irq = omap1_init_irq, + .handle_irq = omap1_handle_irq, .init_machine = omap_sx1_init, .init_late = omap1_init_late, .init_time = omap1_timer_init, diff --git a/arch/arm/mach-omap1/board-voiceblue.c b/arch/arm/mach-omap1/board-voiceblue.c index 4677a9ccb3cbbb222bc50c2a59e3b66b81d73e18..e960687d0cb155465efe41ed34dcf4ca36e5d932 100644 --- a/arch/arm/mach-omap1/board-voiceblue.c +++ b/arch/arm/mach-omap1/board-voiceblue.c @@ -288,6 +288,7 @@ MACHINE_START(VOICEBLUE, "VoiceBlue OMAP5910") .map_io = omap15xx_map_io, .init_early = omap1_init_early, .init_irq = omap1_init_irq, + .handle_irq = omap1_handle_irq, .init_machine = voiceblue_init, .init_late = omap1_init_late, .init_time = omap1_timer_init, diff --git a/arch/arm/mach-omap1/common.h b/arch/arm/mach-omap1/common.h index 732f8ee2fcd2ce544a28eabda14f5fdde8250e7a..6363e0cc41f19cd73fea465faffda9937c01cb8c 100644 --- a/arch/arm/mach-omap1/common.h +++ b/arch/arm/mach-omap1/common.h @@ -30,6 +30,8 @@ #include #include +#include + #include #include @@ -73,6 +75,7 @@ static inline int omap_serial_wakeup_init(void) void omap1_init_early(void); void omap1_init_irq(void); +void __exception_irq_entry omap1_handle_irq(struct pt_regs *regs); void omap1_init_late(void); void omap1_restart(enum reboot_mode, const char *); @@ -91,8 +94,6 @@ static inline int __init omap_32k_timer_init(void) } #endif -extern u32 omap_irq_flags; - #ifdef CONFIG_ARCH_OMAP16XX extern int ocpi_enable(void); #else diff --git a/arch/arm/mach-omap1/include/mach/entry-macro.S b/arch/arm/mach-omap1/include/mach/entry-macro.S deleted file mode 100644 index 78a8c6c2476460eec32da12eaedfe997d4a3699f..0000000000000000000000000000000000000000 --- a/arch/arm/mach-omap1/include/mach/entry-macro.S +++ /dev/null @@ -1,39 +0,0 @@ -/* - * arch/arm/mach-omap1/include/mach/entry-macro.S - * - * Low-level IRQ helper macros for OMAP-based platforms - * - * Copyright (C) 2009 Texas Instruments - * - * 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 -#include - - .macro get_irqnr_preamble, base, tmp - .endm - - .macro get_irqnr_and_base, irqnr, irqstat, base, tmp - ldr \base, =OMAP1_IO_ADDRESS(OMAP_IH1_BASE) - ldr \irqnr, [\base, #IRQ_ITR_REG_OFFSET] - ldr \tmp, [\base, #IRQ_MIR_REG_OFFSET] - mov \irqstat, #0xffffffff - bic \tmp, \irqstat, \tmp - tst \irqnr, \tmp - beq 1510f - - ldr \irqnr, [\base, #IRQ_SIR_FIQ_REG_OFFSET] - ldr \tmp, =omap_irq_flags @ irq flags address - ldr \tmp, [\tmp, #0] @ irq flags value - cmp \irqnr, #0 - ldreq \irqnr, [\base, #IRQ_SIR_IRQ_REG_OFFSET] - cmpeq \irqnr, \tmp - ldreq \base, =OMAP1_IO_ADDRESS(OMAP_IH2_BASE) - ldreq \irqnr, [\base, #IRQ_SIR_IRQ_REG_OFFSET] - addeqs \irqnr, \irqnr, #32 -1510: - .endm - diff --git a/arch/arm/mach-omap1/irq.c b/arch/arm/mach-omap1/irq.c index 3651b17aeb1022657e01b236bfd2acbdb9e64689..567fba35bd9475eb5f783b167731ea96c7d333c9 100644 --- a/arch/arm/mach-omap1/irq.c +++ b/arch/arm/mach-omap1/irq.c @@ -43,6 +43,7 @@ #include #include +#include #include #include "soc.h" @@ -61,7 +62,7 @@ struct omap_irq_bank { unsigned long wake_enable; }; -u32 omap_irq_flags; +static u32 omap_l2_irq; static unsigned int irq_bank_count; static struct omap_irq_bank *irq_banks; static struct irq_domain *domain; @@ -140,6 +141,36 @@ static struct omap_irq_bank omap1610_irq_banks[] = { }; #endif +asmlinkage void __exception_irq_entry omap1_handle_irq(struct pt_regs *regs) +{ + void __iomem *l1 = irq_banks[0].va; + void __iomem *l2 = irq_banks[1].va; + u32 irqnr; + + do { + irqnr = readl_relaxed(l1 + IRQ_ITR_REG_OFFSET); + irqnr &= ~(readl_relaxed(l1 + IRQ_MIR_REG_OFFSET) & 0xffffffff); + if (!irqnr) + break; + + irqnr = readl_relaxed(l1 + IRQ_SIR_FIQ_REG_OFFSET); + if (irqnr) + goto irq; + + irqnr = readl_relaxed(l1 + IRQ_SIR_IRQ_REG_OFFSET); + if (irqnr == omap_l2_irq) { + irqnr = readl_relaxed(l2 + IRQ_SIR_IRQ_REG_OFFSET); + if (irqnr) + irqnr += 32; + } +irq: + if (irqnr) + handle_domain_irq(domain, irqnr, regs); + else + break; + } while (irqnr); +} + static __init void omap_alloc_gc(void __iomem *base, unsigned int irq_start, unsigned int num) { @@ -167,26 +198,22 @@ void __init omap1_init_irq(void) #if defined(CONFIG_ARCH_OMAP730) || defined(CONFIG_ARCH_OMAP850) if (cpu_is_omap7xx()) { - omap_irq_flags = INT_7XX_IH2_IRQ; irq_banks = omap7xx_irq_banks; irq_bank_count = ARRAY_SIZE(omap7xx_irq_banks); } #endif #ifdef CONFIG_ARCH_OMAP15XX if (cpu_is_omap1510()) { - omap_irq_flags = INT_1510_IH2_IRQ; irq_banks = omap1510_irq_banks; irq_bank_count = ARRAY_SIZE(omap1510_irq_banks); } if (cpu_is_omap310()) { - omap_irq_flags = INT_1510_IH2_IRQ; irq_banks = omap310_irq_banks; irq_bank_count = ARRAY_SIZE(omap310_irq_banks); } #endif #if defined(CONFIG_ARCH_OMAP16XX) if (cpu_is_omap16xx()) { - omap_irq_flags = INT_1510_IH2_IRQ; irq_banks = omap1610_irq_banks; irq_bank_count = ARRAY_SIZE(omap1610_irq_banks); } @@ -205,6 +232,7 @@ void __init omap1_init_irq(void) pr_warn("Couldn't allocate IRQ numbers\n"); irq_base = 0; } + omap_l2_irq = cpu_is_omap7xx() ? irq_base + 1 : irq_base; domain = irq_domain_add_legacy(NULL, nr_irqs, irq_base, 0, &irq_domain_simple_ops, NULL); @@ -239,7 +267,7 @@ void __init omap1_init_irq(void) } /* Unmask level 2 handler */ - d = irq_get_irq_data(omap_irq_flags); + d = irq_get_irq_data(irq_find_mapping(domain, omap_l2_irq)); if (d) { ct = irq_data_get_chip_type(d); ct->chip.irq_unmask(d);