[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 IXP4XX_IRQ_LEVEL, IXP4XX_IRQ_EDGE 87 }; 88 89 - static void ixp4xx_config_irq(unsigned irq, enum ixp4xx_irq_type type); 90 91 /* 92 * IRQ -> GPIO mapping table ··· 136 default: 137 return -EINVAL; 138 } 139 - ixp4xx_config_irq(irq, irq_type); 140 141 if (line >= 8) { /* pins 8-15 */ 142 line -= 8; ··· 172 *IXP4XX_ICMR &= ~(1 << irq); 173 } 174 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 static void ixp4xx_irq_ack(unsigned int irq) 184 { 185 int line = (irq < 32) ? irq2gpio[irq] : -1; ··· 184 * Level triggered interrupts on GPIO lines can only be cleared when the 185 * interrupt condition disappears. 186 */ 187 - static void ixp4xx_irq_level_unmask(unsigned int irq) 188 { 189 - ixp4xx_irq_ack(irq); 190 - ixp4xx_irq_unmask(irq); 191 } 192 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 .ack = ixp4xx_irq_ack, 202 .mask = ixp4xx_irq_mask, 203 .unmask = ixp4xx_irq_unmask, 204 .set_type = ixp4xx_set_irq_type, 205 }; 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 222 void __init ixp4xx_init_irq(void) 223 { ··· 222 } 223 224 /* Default to all level triggered */ 225 - for(i = 0; i < NR_IRQS; i++) 226 - ixp4xx_config_irq(i, IXP4XX_IRQ_LEVEL); 227 } 228 229
··· 86 IXP4XX_IRQ_LEVEL, IXP4XX_IRQ_EDGE 87 }; 88 89 + /* Each bit represents an IRQ: 1: edge-triggered, 0: level triggered */ 90 + static unsigned long long ixp4xx_irq_edge = 0; 91 92 /* 93 * IRQ -> GPIO mapping table ··· 135 default: 136 return -EINVAL; 137 } 138 + 139 + if (irq_type == IXP4XX_IRQ_EDGE) 140 + ixp4xx_irq_edge |= (1 << irq); 141 + else 142 + ixp4xx_irq_edge &= ~(1 << irq); 143 144 if (line >= 8) { /* pins 8-15 */ 145 line -= 8; ··· 167 *IXP4XX_ICMR &= ~(1 << irq); 168 } 169 170 static void ixp4xx_irq_ack(unsigned int irq) 171 { 172 int line = (irq < 32) ? irq2gpio[irq] : -1; ··· 187 * Level triggered interrupts on GPIO lines can only be cleared when the 188 * interrupt condition disappears. 189 */ 190 + static void ixp4xx_irq_unmask(unsigned int irq) 191 { 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); 199 } 200 201 + static struct irqchip ixp4xx_irq_chip = { 202 + .name = "IXP4xx", 203 .ack = ixp4xx_irq_ack, 204 .mask = ixp4xx_irq_mask, 205 .unmask = ixp4xx_irq_unmask, 206 .set_type = ixp4xx_set_irq_type, 207 }; 208 209 void __init ixp4xx_init_irq(void) 210 { ··· 241 } 242 243 /* Default to all level triggered */ 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 + } 249 } 250 251