[ARM] 3918/1: ixp4xx irq-chip rework

This is a rework of the ixp4xx irq_chip implementation. The use of
two irq_chip structures and potentially switching between them is a
violation of the intended use of the IRQ framework. The current
implementation does not work with current in-kernel spinlock debugging
or lockdep due to lock recursion problems caused by calling
set_irq_chip/handler from within the chip's set_irq_type().

This patch goes back to using one irq_chip structure and handling the
differences between edge/level, normal/GPIO interrupts inside the
ack/mask/unmask routines themselves.

Signed-off-by: Kevin Hilman <khilman@mvista.com>
Signed-off-by: Deepak Saxena <dsaxena@mvista.com>
Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>

authored by Kevin Hilman and committed by Russell King 984d115b 8f7f9435

+22 -38
+22 -38
arch/arm/mach-ixp4xx/common.c
··· 86 86 IXP4XX_IRQ_LEVEL, IXP4XX_IRQ_EDGE 87 87 }; 88 88 89 - static void ixp4xx_config_irq(unsigned irq, enum ixp4xx_irq_type type); 89 + /* Each bit represents an IRQ: 1: edge-triggered, 0: level triggered */ 90 + static unsigned long long ixp4xx_irq_edge = 0; 90 91 91 92 /* 92 93 * IRQ -> GPIO mapping table ··· 136 135 default: 137 136 return -EINVAL; 138 137 } 139 - ixp4xx_config_irq(irq, irq_type); 138 + 139 + if (irq_type == IXP4XX_IRQ_EDGE) 140 + ixp4xx_irq_edge |= (1 << irq); 141 + else 142 + ixp4xx_irq_edge &= ~(1 << irq); 140 143 141 144 if (line >= 8) { /* pins 8-15 */ 142 145 line -= 8; ··· 172 167 *IXP4XX_ICMR &= ~(1 << irq); 173 168 } 174 169 175 - static void ixp4xx_irq_unmask(unsigned int irq) 176 - { 177 - if (cpu_is_ixp46x() && irq >= 32) 178 - *IXP4XX_ICMR2 |= (1 << (irq - 32)); 179 - else 180 - *IXP4XX_ICMR |= (1 << irq); 181 - } 182 - 183 170 static void ixp4xx_irq_ack(unsigned int irq) 184 171 { 185 172 int line = (irq < 32) ? irq2gpio[irq] : -1; ··· 184 187 * Level triggered interrupts on GPIO lines can only be cleared when the 185 188 * interrupt condition disappears. 186 189 */ 187 - static void ixp4xx_irq_level_unmask(unsigned int irq) 190 + static void ixp4xx_irq_unmask(unsigned int irq) 188 191 { 189 - ixp4xx_irq_ack(irq); 190 - ixp4xx_irq_unmask(irq); 192 + if (!(ixp4xx_irq_edge & (1 << irq))) 193 + ixp4xx_irq_ack(irq); 194 + 195 + if (cpu_is_ixp46x() && irq >= 32) 196 + *IXP4XX_ICMR2 |= (1 << (irq - 32)); 197 + else 198 + *IXP4XX_ICMR |= (1 << irq); 191 199 } 192 200 193 - static struct irqchip ixp4xx_irq_level_chip = { 194 - .ack = ixp4xx_irq_mask, 195 - .mask = ixp4xx_irq_mask, 196 - .unmask = ixp4xx_irq_level_unmask, 197 - .set_type = ixp4xx_set_irq_type, 198 - }; 199 - 200 - static struct irqchip ixp4xx_irq_edge_chip = { 201 + static struct irqchip ixp4xx_irq_chip = { 202 + .name = "IXP4xx", 201 203 .ack = ixp4xx_irq_ack, 202 204 .mask = ixp4xx_irq_mask, 203 205 .unmask = ixp4xx_irq_unmask, 204 206 .set_type = ixp4xx_set_irq_type, 205 207 }; 206 - 207 - static void ixp4xx_config_irq(unsigned irq, enum ixp4xx_irq_type type) 208 - { 209 - switch (type) { 210 - case IXP4XX_IRQ_LEVEL: 211 - set_irq_chip(irq, &ixp4xx_irq_level_chip); 212 - set_irq_handler(irq, do_level_IRQ); 213 - break; 214 - case IXP4XX_IRQ_EDGE: 215 - set_irq_chip(irq, &ixp4xx_irq_edge_chip); 216 - set_irq_handler(irq, do_edge_IRQ); 217 - break; 218 - } 219 - set_irq_flags(irq, IRQF_VALID); 220 - } 221 208 222 209 void __init ixp4xx_init_irq(void) 223 210 { ··· 222 241 } 223 242 224 243 /* Default to all level triggered */ 225 - for(i = 0; i < NR_IRQS; i++) 226 - ixp4xx_config_irq(i, IXP4XX_IRQ_LEVEL); 244 + for(i = 0; i < NR_IRQS; i++) { 245 + set_irq_chip(i, &ixp4xx_irq_chip); 246 + set_irq_handler(i, do_level_IRQ); 247 + set_irq_flags(i, IRQF_VALID); 248 + } 227 249 } 228 250 229 251