--- zzzz-none-000/linux-3.10.107/drivers/irqchip/irq-sirfsoc.c 2017-06-27 09:49:32.000000000 +0000 +++ scorpion-7490-727/linux-3.10.107/drivers/irqchip/irq-sirfsoc.c 2021-02-04 17:41:59.000000000 +0000 @@ -11,61 +11,65 @@ #include #include #include +#include #include #include #include #include -#include "irqchip.h" -#define SIRFSOC_INT_RISC_MASK0 0x0018 -#define SIRFSOC_INT_RISC_MASK1 0x001C -#define SIRFSOC_INT_RISC_LEVEL0 0x0020 -#define SIRFSOC_INT_RISC_LEVEL1 0x0024 +#define SIRFSOC_INT_RISC_MASK0 0x0018 +#define SIRFSOC_INT_RISC_MASK1 0x001C +#define SIRFSOC_INT_RISC_LEVEL0 0x0020 +#define SIRFSOC_INT_RISC_LEVEL1 0x0024 #define SIRFSOC_INIT_IRQ_ID 0x0038 +#define SIRFSOC_INT_BASE_OFFSET 0x0004 -#define SIRFSOC_NUM_IRQS 128 +#define SIRFSOC_NUM_IRQS 64 +#define SIRFSOC_NUM_BANKS (SIRFSOC_NUM_IRQS / 32) static struct irq_domain *sirfsoc_irqdomain; -static __init void -sirfsoc_alloc_gc(void __iomem *base, unsigned int irq_start, unsigned int num) +static __init void sirfsoc_alloc_gc(void __iomem *base) { + unsigned int clr = IRQ_NOREQUEST | IRQ_NOPROBE | IRQ_NOAUTOEN; + unsigned int set = IRQ_LEVEL; struct irq_chip_generic *gc; struct irq_chip_type *ct; + int i; - gc = irq_alloc_generic_chip("SIRFINTC", 1, irq_start, base, handle_level_irq); - ct = gc->chip_types; - - ct->chip.irq_mask = irq_gc_mask_clr_bit; - ct->chip.irq_unmask = irq_gc_mask_set_bit; - ct->regs.mask = SIRFSOC_INT_RISC_MASK0; - - irq_setup_generic_chip(gc, IRQ_MSK(num), IRQ_GC_INIT_MASK_CACHE, IRQ_NOREQUEST, 0); + irq_alloc_domain_generic_chips(sirfsoc_irqdomain, 32, 1, "irq_sirfsoc", + handle_level_irq, clr, set, + IRQ_GC_INIT_MASK_CACHE); + + for (i = 0; i < SIRFSOC_NUM_BANKS; i++) { + gc = irq_get_domain_generic_chip(sirfsoc_irqdomain, i * 32); + gc->reg_base = base + i * SIRFSOC_INT_BASE_OFFSET; + ct = gc->chip_types; + ct->chip.irq_mask = irq_gc_mask_clr_bit; + ct->chip.irq_unmask = irq_gc_mask_set_bit; + ct->regs.mask = SIRFSOC_INT_RISC_MASK0; + } } -static asmlinkage void __exception_irq_entry sirfsoc_handle_irq(struct pt_regs *regs) +static void __exception_irq_entry sirfsoc_handle_irq(struct pt_regs *regs) { void __iomem *base = sirfsoc_irqdomain->host_data; - u32 irqstat, irqnr; + u32 irqstat; irqstat = readl_relaxed(base + SIRFSOC_INIT_IRQ_ID); - irqnr = irq_find_mapping(sirfsoc_irqdomain, irqstat & 0xff); - - handle_IRQ(irqnr, regs); + handle_domain_irq(sirfsoc_irqdomain, irqstat & 0xff, regs); } -static int __init sirfsoc_irq_init(struct device_node *np, struct device_node *parent) +static int __init sirfsoc_irq_init(struct device_node *np, + struct device_node *parent) { void __iomem *base = of_iomap(np, 0); if (!base) panic("unable to map intc cpu registers\n"); - /* using legacy because irqchip_generic does not work with linear */ - sirfsoc_irqdomain = irq_domain_add_legacy(np, SIRFSOC_NUM_IRQS, 0, 0, - &irq_domain_simple_ops, base); - - sirfsoc_alloc_gc(base, 0, 32); - sirfsoc_alloc_gc(base + 4, 32, SIRFSOC_NUM_IRQS - 32); + sirfsoc_irqdomain = irq_domain_add_linear(np, SIRFSOC_NUM_IRQS, + &irq_generic_chip_ops, base); + sirfsoc_alloc_gc(base); writel_relaxed(0, base + SIRFSOC_INT_RISC_LEVEL0); writel_relaxed(0, base + SIRFSOC_INT_RISC_LEVEL1);