Commit 55601c9f24670ba926ebdd4d712ac3b177232330

Authored by Felipe Balbi
Committed by Tony Lindgren
1 parent d6a7c5c84f

arm: omap: intc: switch over to linear irq domain

now that we don't need to support legacy board-files,
we can completely switch over to a linear irq domain
and make use of irq_alloc_domain_generic_chips() to
allocate all generic irq chips for us.

Signed-off-by: Felipe Balbi <balbi@ti.com>
Signed-off-by: Tony Lindgren <tony@atomide.com>

Showing 1 changed file with 79 additions and 9 deletions Side-by-side Diff

arch/arm/mach-omap2/irq.c
... ... @@ -188,14 +188,51 @@
188 188 omap_ack_irq(NULL);
189 189 }
190 190  
191   -static __init void
192   -omap_alloc_gc(void __iomem *base, unsigned int irq_start, unsigned int num)
  191 +static int __init omap_alloc_gc_of(struct irq_domain *d, void __iomem *base)
193 192 {
  193 + int ret;
  194 + int i;
  195 +
  196 + ret = irq_alloc_domain_generic_chips(d, 32, 1, "INTC",
  197 + handle_level_irq, IRQ_NOREQUEST | IRQ_NOPROBE,
  198 + IRQ_LEVEL, 0);
  199 + if (ret) {
  200 + pr_warn("Failed to allocate irq chips\n");
  201 + return ret;
  202 + }
  203 +
  204 + for (i = 0; i < omap_nr_pending; i++) {
  205 + struct irq_chip_generic *gc;
  206 + struct irq_chip_type *ct;
  207 +
  208 + gc = irq_get_domain_generic_chip(d, 32 * i);
  209 + gc->reg_base = base;
  210 + ct = gc->chip_types;
  211 +
  212 + ct->type = IRQ_TYPE_LEVEL_MASK;
  213 + ct->handler = handle_level_irq;
  214 +
  215 + ct->chip.irq_ack = omap_mask_ack_irq;
  216 + ct->chip.irq_mask = irq_gc_mask_disable_reg;
  217 + ct->chip.irq_unmask = irq_gc_unmask_enable_reg;
  218 +
  219 + ct->chip.flags |= IRQCHIP_SKIP_SET_WAKE;
  220 +
  221 + ct->regs.enable = INTC_MIR_CLEAR0 + 32 * i;
  222 + ct->regs.disable = INTC_MIR_SET0 + 32 * i;
  223 + }
  224 +
  225 + return 0;
  226 +}
  227 +
  228 +static void __init omap_alloc_gc_legacy(void __iomem *base,
  229 + unsigned int irq_start, unsigned int num)
  230 +{
194 231 struct irq_chip_generic *gc;
195 232 struct irq_chip_type *ct;
196 233  
197 234 gc = irq_alloc_generic_chip("INTC", 1, irq_start, base,
198   - handle_level_irq);
  235 + handle_level_irq);
199 236 ct = gc->chip_types;
200 237 ct->chip.irq_ack = omap_mask_ack_irq;
201 238 ct->chip.irq_mask = irq_gc_mask_disable_reg;
202 239  
203 240  
204 241  
... ... @@ -205,16 +242,36 @@
205 242 ct->regs.enable = INTC_MIR_CLEAR0;
206 243 ct->regs.disable = INTC_MIR_SET0;
207 244 irq_setup_generic_chip(gc, IRQ_MSK(num), IRQ_GC_INIT_MASK_CACHE,
208   - IRQ_NOREQUEST | IRQ_NOPROBE, 0);
  245 + IRQ_NOREQUEST | IRQ_NOPROBE, 0);
209 246 }
210 247  
211   -static void __init omap_init_irq(u32 base, struct device_node *node)
  248 +static int __init omap_init_irq_of(struct device_node *node)
212 249 {
  250 + int ret;
  251 +
  252 + omap_irq_base = of_iomap(node, 0);
  253 + if (WARN_ON(!omap_irq_base))
  254 + return -ENOMEM;
  255 +
  256 + domain = irq_domain_add_linear(node, omap_nr_irqs,
  257 + &irq_generic_chip_ops, NULL);
  258 +
  259 + omap_irq_soft_reset();
  260 +
  261 + ret = omap_alloc_gc_of(domain, omap_irq_base);
  262 + if (ret < 0)
  263 + irq_domain_remove(domain);
  264 +
  265 + return ret;
  266 +}
  267 +
  268 +static int __init omap_init_irq_legacy(u32 base)
  269 +{
213 270 int j, irq_base;
214 271  
215 272 omap_irq_base = ioremap(base, SZ_4K);
216 273 if (WARN_ON(!omap_irq_base))
217   - return;
  274 + return -ENOMEM;
218 275  
219 276 irq_base = irq_alloc_descs(-1, 0, omap_nr_irqs, 0);
220 277 if (irq_base < 0) {
221 278  
222 279  
... ... @@ -222,15 +279,25 @@
222 279 irq_base = 0;
223 280 }
224 281  
225   - domain = irq_domain_add_legacy(node, omap_nr_irqs, irq_base, 0,
  282 + domain = irq_domain_add_legacy(NULL, omap_nr_irqs, irq_base, 0,
226 283 &irq_domain_simple_ops, NULL);
227 284  
228 285 omap_irq_soft_reset();
229 286  
230 287 for (j = 0; j < omap_nr_irqs; j += 32)
231   - omap_alloc_gc(omap_irq_base + j, j + irq_base, 32);
  288 + omap_alloc_gc_legacy(omap_irq_base + j, j + irq_base, 32);
  289 +
  290 + return 0;
232 291 }
233 292  
  293 +static int __init omap_init_irq(u32 base, struct device_node *node)
  294 +{
  295 + if (node)
  296 + return omap_init_irq_of(node);
  297 + else
  298 + return omap_init_irq_legacy(base);
  299 +}
  300 +
234 301 static asmlinkage void __exception_irq_entry
235 302 omap_intc_handle_irq(struct pt_regs *regs)
236 303 {
... ... @@ -294,6 +361,7 @@
294 361 struct device_node *parent)
295 362 {
296 363 struct resource res;
  364 + int ret;
297 365  
298 366 omap_nr_pending = 3;
299 367 omap_nr_irqs = 96;
... ... @@ -311,7 +379,9 @@
311 379 omap_nr_pending = 4;
312 380 }
313 381  
314   - omap_init_irq(res.start, of_node_get(node));
  382 + ret = omap_init_irq(-1, of_node_get(node));
  383 + if (ret < 0)
  384 + return ret;
315 385  
316 386 set_handle_irq(omap_intc_handle_irq);
317 387