|
@@ -123,4 +123,96 @@ static void __init omap_irq_bank_init_one(struct omap_irq_bank *bank)
|
|
}
|
|
}
|
|
|
|
|
|
int omap_irq_pending(void)
|
|
int omap_irq_pending(void)
|
|
|
|
+{
|
|
|
|
+ int i;
|
|
|
|
+
|
|
|
|
+ for (i = 0; i < ARRAY_SIZE(irq_banks); i++) {
|
|
|
|
+ struct omap_irq_bank *bank = irq_banks + i;
|
|
|
|
+ int irq;
|
|
|
|
+
|
|
|
|
+ for (irq = 0; irq < bank->nr_irqs; irq += 32)
|
|
|
|
+ if (intc_bank_read_reg(bank, INTC_PENDING_IRQ0 +
|
|
|
|
+ ((irq >> 5) << 5)))
|
|
|
|
+ return 1;
|
|
|
|
+ }
|
|
|
|
+ return 0;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+static __init void
|
|
|
|
+omap_alloc_gc(void __iomem *base, unsigned int irq_start, unsigned int num)
|
|
|
|
+{
|
|
|
|
+ struct irq_chip_generic *gc;
|
|
|
|
+ struct irq_chip_type *ct;
|
|
|
|
+
|
|
|
|
+ gc = irq_alloc_generic_chip("INTC", 1, irq_start, base,
|
|
|
|
+ handle_level_irq);
|
|
|
|
+ ct = gc->chip_types;
|
|
|
|
+ ct->chip.irq_ack = omap_mask_ack_irq;
|
|
|
|
+ ct->chip.irq_mask = irq_gc_mask_disable_reg;
|
|
|
|
+ ct->chip.irq_unmask = irq_gc_unmask_enable_reg;
|
|
|
|
+ ct->chip.flags |= IRQCHIP_SKIP_SET_WAKE;
|
|
|
|
+
|
|
|
|
+ ct->regs.enable = INTC_MIR_CLEAR0;
|
|
|
|
+ ct->regs.disable = INTC_MIR_SET0;
|
|
|
|
+ irq_setup_generic_chip(gc, IRQ_MSK(num), IRQ_GC_INIT_MASK_CACHE,
|
|
|
|
+ IRQ_NOREQUEST | IRQ_NOPROBE, 0);
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+static void __init omap_init_irq(u32 base, int nr_irqs,
|
|
|
|
+ struct device_node *node)
|
|
|
|
+{
|
|
|
|
+ void __iomem *omap_irq_base;
|
|
|
|
+ unsigned long nr_of_irqs = 0;
|
|
|
|
+ unsigned int nr_banks = 0;
|
|
|
|
+ int i, j, irq_base;
|
|
|
|
+
|
|
|
|
+ omap_irq_base = ioremap(base, SZ_4K);
|
|
|
|
+ if (WARN_ON(!omap_irq_base))
|
|
|
|
+ return;
|
|
|
|
+
|
|
|
|
+ irq_base = irq_alloc_descs(-1, 0, nr_irqs, 0);
|
|
|
|
+ if (irq_base < 0) {
|
|
|
|
+ pr_warn("Couldn't allocate IRQ numbers\n");
|
|
|
|
+ irq_base = 0;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ domain = irq_domain_add_legacy(node, nr_irqs, irq_base, 0,
|
|
|
|
+ &irq_domain_simple_ops, NULL);
|
|
|
|
+
|
|
|
|
+ for (i = 0; i < ARRAY_SIZE(irq_banks); i++) {
|
|
|
|
+ struct omap_irq_bank *bank = irq_banks + i;
|
|
|
|
+
|
|
|
|
+ bank->nr_irqs = nr_irqs;
|
|
|
|
+
|
|
|
|
+ /* Static mapping, never released */
|
|
|
|
+ bank->base_reg = ioremap(base, SZ_4K);
|
|
|
|
+ if (!bank->base_reg) {
|
|
|
|
+ pr_err("Could not ioremap irq bank%i\n", i);
|
|
|
|
+ continue;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ omap_irq_bank_init_one(bank);
|
|
|
|
+
|
|
|
|
+ for (j = 0; j < bank->nr_irqs; j += 32)
|
|
|
|
+ omap_alloc_gc(bank->base_reg + j, j + irq_base, 32);
|
|
|
|
+
|
|
|
|
+ nr_of_irqs += bank->nr_irqs;
|
|
|
|
+ nr_banks++;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ pr_info("Total of %ld interrupts on %d active controller%s\n",
|
|
|
|
+ nr_of_irqs, nr_banks, nr_banks > 1 ? "s" : "");
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+void __init omap2_init_irq(void)
|
|
|
|
+{
|
|
|
|
+ omap_init_irq(OMAP24XX_IC_BASE, 96, NULL);
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+void __init omap3_init_irq(void)
|
|
|
|
+{
|
|
|
|
+ omap_init_irq(OMAP34XX_IC_BASE, 96, NULL);
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+void __init ti81xx_init_irq(void)
|
|
{
|
|
{
|