All chips have the same register layout and just differ by their base address. Further this chip is pretty much a VIC, it just lacks the PL190 registers. So there is further consolidation possible. Signed-off-by: Thomas Gleixner --- arch/arm/mach-bcmring/irq.c | 98 +++++++++----------------------------------- 1 file changed, 21 insertions(+), 77 deletions(-) Index: linux-2.6/arch/arm/mach-bcmring/irq.c =================================================================== --- linux-2.6.orig/arch/arm/mach-bcmring/irq.c +++ linux-2.6/arch/arm/mach-bcmring/irq.c @@ -30,77 +30,22 @@ #include #include -static void bcmring_mask_irq0(struct irq_data *d) +static void vic_init(const char *name, void __iomem *base, + unsigned int irq_start, u32 vic_sources) { - writel(1 << (d->irq - IRQ_INTC0_START), - MM_IO_BASE_INTC0 + INTCHW_INTENCLEAR); -} + struct irq_chip_generic *gc; + struct irq_chip_type *ct; -static void bcmring_unmask_irq0(struct irq_data *d) -{ - writel(1 << (d->irq - IRQ_INTC0_START), - MM_IO_BASE_INTC0 + INTCHW_INTENABLE); -} + gc = irq_alloc_generic_chip(name, 1, irq_start, base, handle_level_irq); + ct = gc->chip_types; + ct->chip.irq_mask_ack = irq_gc_mask_disable_reg_and_ack; + ct->chip.irq_unmask = irq_gc_unmask_enable_reg; + ct->regs.ack = INTCHW_SOFTINTCLEAR; + ct->regs.disable = INTCHW_INTENCLEAR; + ct->regs.enable = INTCHW_INTENABLE; -static void bcmring_mask_irq1(struct irq_data *d) -{ - writel(1 << (d->irq - IRQ_INTC1_START), - MM_IO_BASE_INTC1 + INTCHW_INTENCLEAR); -} + irq_setup_generic_chip(gc, vic_sources, IRQ_NOREQUEST | IRQ_NOPROBE, IRQ_LEVEL); -static void bcmring_unmask_irq1(struct irq_data *d) -{ - writel(1 << (d->irq - IRQ_INTC1_START), - MM_IO_BASE_INTC1 + INTCHW_INTENABLE); -} - -static void bcmring_mask_irq2(struct irq_data *d) -{ - writel(1 << (d->irq - IRQ_SINTC_START), - MM_IO_BASE_SINTC + INTCHW_INTENCLEAR); -} - -static void bcmring_unmask_irq2(struct irq_data *d) -{ - writel(1 << (d->irq - IRQ_SINTC_START), - MM_IO_BASE_SINTC + INTCHW_INTENABLE); -} - -static struct irq_chip bcmring_irq0_chip = { - .name = "ARM-INTC0", - .irq_ack = bcmring_mask_irq0, - .irq_mask = bcmring_mask_irq0, /* mask a specific interrupt, blocking its delivery. */ - .irq_unmask = bcmring_unmask_irq0, /* unmaks an interrupt */ -}; - -static struct irq_chip bcmring_irq1_chip = { - .name = "ARM-INTC1", - .irq_ack = bcmring_mask_irq1, - .irq_mask = bcmring_mask_irq1, - .irq_unmask = bcmring_unmask_irq1, -}; - -static struct irq_chip bcmring_irq2_chip = { - .name = "ARM-SINTC", - .irq_ack = bcmring_mask_irq2, - .irq_mask = bcmring_mask_irq2, - .irq_unmask = bcmring_unmask_irq2, -}; - -static void vic_init(void __iomem *base, struct irq_chip *chip, - unsigned int irq_start, unsigned int vic_sources) -{ - unsigned int i; - for (i = 0; i < 32; i++) { - unsigned int irq = irq_start + i; - irq_set_chip(irq, chip); - irq_set_chip_data(irq, base); - - if (vic_sources & (1 << i)) { - irq_set_handler(irq, handle_level_irq); - set_irq_flags(irq, IRQF_VALID | IRQF_PROBE); - } - } writel(0, base + INTCHW_INTSELECT); writel(0, base + INTCHW_INTENABLE); writel(~0, base + INTCHW_INTENCLEAR); @@ -110,18 +55,17 @@ static void vic_init(void __iomem *base, void __init bcmring_init_irq(void) { - vic_init((void __iomem *)MM_IO_BASE_INTC0, &bcmring_irq0_chip, - IRQ_INTC0_START, IRQ_INTC0_VALID_MASK); - vic_init((void __iomem *)MM_IO_BASE_INTC1, &bcmring_irq1_chip, - IRQ_INTC1_START, IRQ_INTC1_VALID_MASK); - vic_init((void __iomem *)MM_IO_BASE_SINTC, &bcmring_irq2_chip, - IRQ_SINTC_START, IRQ_SINTC_VALID_MASK); + vic_init("ARM-INTC0", (void __iomem *)MM_IO_BASE_INTC0, IRQ_INTC0_START, + IRQ_INTC0_VALID_MASK); + vic_init("ARM-INTC1", (void __iomem *)MM_IO_BASE_INTC1, IRQ_INTC1_START, + IRQ_INTC1_VALID_MASK); + vic_init("ARM-SINTC", (void __iomem *)MM_IO_BASE_SINTC, IRQ_SINTC_START, + IRQ_SINTC_VALID_MASK); /* special cases */ - if (INTCHW_INTC1_GPIO0 & IRQ_INTC1_VALID_MASK) { + if (INTCHW_INTC1_GPIO0 & IRQ_INTC1_VALID_MASK) irq_set_handler(IRQ_GPIO0, handle_simple_irq); - } - if (INTCHW_INTC1_GPIO1 & IRQ_INTC1_VALID_MASK) { + + if (INTCHW_INTC1_GPIO1 & IRQ_INTC1_VALID_MASK) irq_set_handler(IRQ_GPIO1, handle_simple_irq); - } }