History

Merge tag 'irqchip-mvebu-fixes-3.14' of git://git.infradead.org/linux-mvebu into irq/urgent

irqchip mvebu fixes for v3.14 - orion: - fixes for clearing bridge cause register, and clearing stale interrupts

Thomas Gleixner committed 12 years ago

Commit ec79b572 parents 2c45aad d86e9af1 file · +19 −3Browse files

Unified · Split

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