Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
fork

Configure Feed

Select the types of activity you want to include in your feed.

Merge branch 'irq-urgent-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip

Pull irq fixes from Thomas Gleixner:
"Another four fixlets to tame the ARM orion irq chip"

* 'irq-urgent-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip:
irqchip: orion: Fix getting generic chip pointer.
irqchip: orion: clear stale interrupts in irq_startup
irqchip: orion: use handle_edge_irq on bridge irqs
irqchip: orion: clear bridge cause register on init

+19 -3
+19 -3
drivers/irqchip/irq-orion.c
··· 111 111 static void orion_bridge_irq_handler(unsigned int irq, struct irq_desc *desc) 112 112 { 113 113 struct irq_domain *d = irq_get_handler_data(irq); 114 - struct irq_chip_generic *gc = irq_get_domain_generic_chip(d, irq); 114 + 115 + struct irq_chip_generic *gc = irq_get_domain_generic_chip(d, 0); 115 116 u32 stat = readl_relaxed(gc->reg_base + ORION_BRIDGE_IRQ_CAUSE) & 116 117 gc->mask_cache; 117 118 ··· 122 121 generic_handle_irq(irq_find_mapping(d, gc->irq_base + hwirq)); 123 122 stat &= ~(1 << hwirq); 124 123 } 124 + } 125 + 126 + /* 127 + * Bridge IRQ_CAUSE is asserted regardless of IRQ_MASK register. 128 + * To avoid interrupt events on stale irqs, we clear them before unmask. 129 + */ 130 + static unsigned int orion_bridge_irq_startup(struct irq_data *d) 131 + { 132 + struct irq_chip_type *ct = irq_data_get_chip_type(d); 133 + 134 + ct->chip.irq_ack(d); 135 + ct->chip.irq_unmask(d); 136 + return 0; 125 137 } 126 138 127 139 static int __init orion_bridge_irq_init(struct device_node *np, ··· 157 143 } 158 144 159 145 ret = irq_alloc_domain_generic_chips(domain, nrirqs, 1, np->name, 160 - handle_level_irq, clr, 0, IRQ_GC_INIT_MASK_CACHE); 146 + handle_edge_irq, clr, 0, IRQ_GC_INIT_MASK_CACHE); 161 147 if (ret) { 162 148 pr_err("%s: unable to alloc irq domain gc\n", np->name); 163 149 return ret; ··· 190 176 191 177 gc->chip_types[0].regs.ack = ORION_BRIDGE_IRQ_CAUSE; 192 178 gc->chip_types[0].regs.mask = ORION_BRIDGE_IRQ_MASK; 179 + gc->chip_types[0].chip.irq_startup = orion_bridge_irq_startup; 193 180 gc->chip_types[0].chip.irq_ack = irq_gc_ack_clr_bit; 194 181 gc->chip_types[0].chip.irq_mask = irq_gc_mask_clr_bit; 195 182 gc->chip_types[0].chip.irq_unmask = irq_gc_mask_set_bit; 196 183 197 - /* mask all interrupts */ 184 + /* mask and clear all interrupts */ 198 185 writel(0, gc->reg_base + ORION_BRIDGE_IRQ_MASK); 186 + writel(0, gc->reg_base + ORION_BRIDGE_IRQ_CAUSE); 199 187 200 188 irq_set_handler_data(irq, domain); 201 189 irq_set_chained_handler(irq, orion_bridge_irq_handler);