diff options
Diffstat (limited to 'arch/arm/mach-omap1/irq.c')
-rw-r--r-- | arch/arm/mach-omap1/irq.c | 40 |
1 files changed, 34 insertions, 6 deletions
diff --git a/arch/arm/mach-omap1/irq.c b/arch/arm/mach-omap1/irq.c index 3651b17aeb10..567fba35bd94 100644 --- a/arch/arm/mach-omap1/irq.c +++ b/arch/arm/mach-omap1/irq.c | |||
@@ -43,6 +43,7 @@ | |||
43 | #include <linux/io.h> | 43 | #include <linux/io.h> |
44 | 44 | ||
45 | #include <asm/irq.h> | 45 | #include <asm/irq.h> |
46 | #include <asm/exception.h> | ||
46 | #include <asm/mach/irq.h> | 47 | #include <asm/mach/irq.h> |
47 | 48 | ||
48 | #include "soc.h" | 49 | #include "soc.h" |
@@ -61,7 +62,7 @@ struct omap_irq_bank { | |||
61 | unsigned long wake_enable; | 62 | unsigned long wake_enable; |
62 | }; | 63 | }; |
63 | 64 | ||
64 | u32 omap_irq_flags; | 65 | static u32 omap_l2_irq; |
65 | static unsigned int irq_bank_count; | 66 | static unsigned int irq_bank_count; |
66 | static struct omap_irq_bank *irq_banks; | 67 | static struct omap_irq_bank *irq_banks; |
67 | static struct irq_domain *domain; | 68 | static struct irq_domain *domain; |
@@ -140,6 +141,36 @@ static struct omap_irq_bank omap1610_irq_banks[] = { | |||
140 | }; | 141 | }; |
141 | #endif | 142 | #endif |
142 | 143 | ||
144 | asmlinkage void __exception_irq_entry omap1_handle_irq(struct pt_regs *regs) | ||
145 | { | ||
146 | void __iomem *l1 = irq_banks[0].va; | ||
147 | void __iomem *l2 = irq_banks[1].va; | ||
148 | u32 irqnr; | ||
149 | |||
150 | do { | ||
151 | irqnr = readl_relaxed(l1 + IRQ_ITR_REG_OFFSET); | ||
152 | irqnr &= ~(readl_relaxed(l1 + IRQ_MIR_REG_OFFSET) & 0xffffffff); | ||
153 | if (!irqnr) | ||
154 | break; | ||
155 | |||
156 | irqnr = readl_relaxed(l1 + IRQ_SIR_FIQ_REG_OFFSET); | ||
157 | if (irqnr) | ||
158 | goto irq; | ||
159 | |||
160 | irqnr = readl_relaxed(l1 + IRQ_SIR_IRQ_REG_OFFSET); | ||
161 | if (irqnr == omap_l2_irq) { | ||
162 | irqnr = readl_relaxed(l2 + IRQ_SIR_IRQ_REG_OFFSET); | ||
163 | if (irqnr) | ||
164 | irqnr += 32; | ||
165 | } | ||
166 | irq: | ||
167 | if (irqnr) | ||
168 | handle_domain_irq(domain, irqnr, regs); | ||
169 | else | ||
170 | break; | ||
171 | } while (irqnr); | ||
172 | } | ||
173 | |||
143 | static __init void | 174 | static __init void |
144 | omap_alloc_gc(void __iomem *base, unsigned int irq_start, unsigned int num) | 175 | omap_alloc_gc(void __iomem *base, unsigned int irq_start, unsigned int num) |
145 | { | 176 | { |
@@ -167,26 +198,22 @@ void __init omap1_init_irq(void) | |||
167 | 198 | ||
168 | #if defined(CONFIG_ARCH_OMAP730) || defined(CONFIG_ARCH_OMAP850) | 199 | #if defined(CONFIG_ARCH_OMAP730) || defined(CONFIG_ARCH_OMAP850) |
169 | if (cpu_is_omap7xx()) { | 200 | if (cpu_is_omap7xx()) { |
170 | omap_irq_flags = INT_7XX_IH2_IRQ; | ||
171 | irq_banks = omap7xx_irq_banks; | 201 | irq_banks = omap7xx_irq_banks; |
172 | irq_bank_count = ARRAY_SIZE(omap7xx_irq_banks); | 202 | irq_bank_count = ARRAY_SIZE(omap7xx_irq_banks); |
173 | } | 203 | } |
174 | #endif | 204 | #endif |
175 | #ifdef CONFIG_ARCH_OMAP15XX | 205 | #ifdef CONFIG_ARCH_OMAP15XX |
176 | if (cpu_is_omap1510()) { | 206 | if (cpu_is_omap1510()) { |
177 | omap_irq_flags = INT_1510_IH2_IRQ; | ||
178 | irq_banks = omap1510_irq_banks; | 207 | irq_banks = omap1510_irq_banks; |
179 | irq_bank_count = ARRAY_SIZE(omap1510_irq_banks); | 208 | irq_bank_count = ARRAY_SIZE(omap1510_irq_banks); |
180 | } | 209 | } |
181 | if (cpu_is_omap310()) { | 210 | if (cpu_is_omap310()) { |
182 | omap_irq_flags = INT_1510_IH2_IRQ; | ||
183 | irq_banks = omap310_irq_banks; | 211 | irq_banks = omap310_irq_banks; |
184 | irq_bank_count = ARRAY_SIZE(omap310_irq_banks); | 212 | irq_bank_count = ARRAY_SIZE(omap310_irq_banks); |
185 | } | 213 | } |
186 | #endif | 214 | #endif |
187 | #if defined(CONFIG_ARCH_OMAP16XX) | 215 | #if defined(CONFIG_ARCH_OMAP16XX) |
188 | if (cpu_is_omap16xx()) { | 216 | if (cpu_is_omap16xx()) { |
189 | omap_irq_flags = INT_1510_IH2_IRQ; | ||
190 | irq_banks = omap1610_irq_banks; | 217 | irq_banks = omap1610_irq_banks; |
191 | irq_bank_count = ARRAY_SIZE(omap1610_irq_banks); | 218 | irq_bank_count = ARRAY_SIZE(omap1610_irq_banks); |
192 | } | 219 | } |
@@ -205,6 +232,7 @@ void __init omap1_init_irq(void) | |||
205 | pr_warn("Couldn't allocate IRQ numbers\n"); | 232 | pr_warn("Couldn't allocate IRQ numbers\n"); |
206 | irq_base = 0; | 233 | irq_base = 0; |
207 | } | 234 | } |
235 | omap_l2_irq = cpu_is_omap7xx() ? irq_base + 1 : irq_base; | ||
208 | 236 | ||
209 | domain = irq_domain_add_legacy(NULL, nr_irqs, irq_base, 0, | 237 | domain = irq_domain_add_legacy(NULL, nr_irqs, irq_base, 0, |
210 | &irq_domain_simple_ops, NULL); | 238 | &irq_domain_simple_ops, NULL); |
@@ -239,7 +267,7 @@ void __init omap1_init_irq(void) | |||
239 | } | 267 | } |
240 | 268 | ||
241 | /* Unmask level 2 handler */ | 269 | /* Unmask level 2 handler */ |
242 | d = irq_get_irq_data(omap_irq_flags); | 270 | d = irq_get_irq_data(irq_find_mapping(domain, omap_l2_irq)); |
243 | if (d) { | 271 | if (d) { |
244 | ct = irq_data_get_chip_type(d); | 272 | ct = irq_data_get_chip_type(d); |
245 | ct->chip.irq_unmask(d); | 273 | ct->chip.irq_unmask(d); |