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

Configure Feed

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

Merge git://git.kernel.org/pub/scm/linux/kernel/git/tglx/linux-2.6-genirq

* git://git.kernel.org/pub/scm/linux/kernel/git/tglx/linux-2.6-genirq:
genirq: reenable a nobody cared disabled irq when a new driver arrives

+35 -19
+1
include/linux/irq.h
··· 61 61 #define IRQ_WAKEUP 0x00100000 /* IRQ triggers system wakeup */ 62 62 #define IRQ_MOVE_PENDING 0x00200000 /* need to re-target IRQ destination */ 63 63 #define IRQ_NO_BALANCING 0x00400000 /* IRQ is excluded from balancing */ 64 + #define IRQ_SPURIOUS_DISABLED 0x00800000 /* IRQ was disabled by the spurious trap */ 64 65 65 66 #ifdef CONFIG_IRQ_PER_CPU 66 67 # define CHECK_IRQ_PER_CPU(var) ((var) & IRQ_PER_CPU)
+32 -17
kernel/irq/manage.c
··· 150 150 } 151 151 EXPORT_SYMBOL(disable_irq); 152 152 153 + static void __enable_irq(struct irq_desc *desc, unsigned int irq) 154 + { 155 + switch (desc->depth) { 156 + case 0: 157 + printk(KERN_WARNING "Unbalanced enable for IRQ %d\n", irq); 158 + WARN_ON(1); 159 + break; 160 + case 1: { 161 + unsigned int status = desc->status & ~IRQ_DISABLED; 162 + 163 + /* Prevent probing on this irq: */ 164 + desc->status = status | IRQ_NOPROBE; 165 + check_irq_resend(desc, irq); 166 + /* fall-through */ 167 + } 168 + default: 169 + desc->depth--; 170 + } 171 + } 172 + 153 173 /** 154 174 * enable_irq - enable handling of an irq 155 175 * @irq: Interrupt to enable ··· 189 169 return; 190 170 191 171 spin_lock_irqsave(&desc->lock, flags); 192 - switch (desc->depth) { 193 - case 0: 194 - printk(KERN_WARNING "Unbalanced enable for IRQ %d\n", irq); 195 - WARN_ON(1); 196 - break; 197 - case 1: { 198 - unsigned int status = desc->status & ~IRQ_DISABLED; 199 - 200 - /* Prevent probing on this irq: */ 201 - desc->status = status | IRQ_NOPROBE; 202 - check_irq_resend(desc, irq); 203 - /* fall-through */ 204 - } 205 - default: 206 - desc->depth--; 207 - } 172 + __enable_irq(desc, irq); 208 173 spin_unlock_irqrestore(&desc->lock, flags); 209 174 } 210 175 EXPORT_SYMBOL(enable_irq); ··· 370 365 compat_irq_chip_set_default_handler(desc); 371 366 372 367 desc->status &= ~(IRQ_AUTODETECT | IRQ_WAITING | 373 - IRQ_INPROGRESS); 368 + IRQ_INPROGRESS | IRQ_SPURIOUS_DISABLED); 374 369 375 370 if (!(desc->status & IRQ_NOAUTOEN)) { 376 371 desc->depth = 0; ··· 386 381 /* Reset broken irq detection when installing new handler */ 387 382 desc->irq_count = 0; 388 383 desc->irqs_unhandled = 0; 384 + 385 + /* 386 + * Check whether we disabled the irq via the spurious handler 387 + * before. Reenable it and give it another chance. 388 + */ 389 + if (shared && (desc->status & IRQ_SPURIOUS_DISABLED)) { 390 + desc->status &= ~IRQ_SPURIOUS_DISABLED; 391 + __enable_irq(desc, irq); 392 + } 393 + 389 394 spin_unlock_irqrestore(&desc->lock, flags); 390 395 391 396 new->irq = irq;
+2 -2
kernel/irq/spurious.c
··· 209 209 * Now kill the IRQ 210 210 */ 211 211 printk(KERN_EMERG "Disabling IRQ #%d\n", irq); 212 - desc->status |= IRQ_DISABLED; 213 - desc->depth = 1; 212 + desc->status |= IRQ_DISABLED | IRQ_SPURIOUS_DISABLED; 213 + desc->depth++; 214 214 desc->chip->disable(irq); 215 215 } 216 216 desc->irqs_unhandled = 0;