Commit 3482a6f1 authored by Linus Torvalds's avatar Linus Torvalds
parents 59d42c0e 1adb0850
...@@ -61,6 +61,7 @@ typedef void (*irq_flow_handler_t)(unsigned int irq, ...@@ -61,6 +61,7 @@ typedef void (*irq_flow_handler_t)(unsigned int irq,
#define IRQ_WAKEUP 0x00100000 /* IRQ triggers system wakeup */ #define IRQ_WAKEUP 0x00100000 /* IRQ triggers system wakeup */
#define IRQ_MOVE_PENDING 0x00200000 /* need to re-target IRQ destination */ #define IRQ_MOVE_PENDING 0x00200000 /* need to re-target IRQ destination */
#define IRQ_NO_BALANCING 0x00400000 /* IRQ is excluded from balancing */ #define IRQ_NO_BALANCING 0x00400000 /* IRQ is excluded from balancing */
#define IRQ_SPURIOUS_DISABLED 0x00800000 /* IRQ was disabled by the spurious trap */
#ifdef CONFIG_IRQ_PER_CPU #ifdef CONFIG_IRQ_PER_CPU
# define CHECK_IRQ_PER_CPU(var) ((var) & IRQ_PER_CPU) # define CHECK_IRQ_PER_CPU(var) ((var) & IRQ_PER_CPU)
......
...@@ -150,6 +150,26 @@ void disable_irq(unsigned int irq) ...@@ -150,6 +150,26 @@ void disable_irq(unsigned int irq)
} }
EXPORT_SYMBOL(disable_irq); EXPORT_SYMBOL(disable_irq);
static void __enable_irq(struct irq_desc *desc, unsigned int irq)
{
switch (desc->depth) {
case 0:
printk(KERN_WARNING "Unbalanced enable for IRQ %d\n", irq);
WARN_ON(1);
break;
case 1: {
unsigned int status = desc->status & ~IRQ_DISABLED;
/* Prevent probing on this irq: */
desc->status = status | IRQ_NOPROBE;
check_irq_resend(desc, irq);
/* fall-through */
}
default:
desc->depth--;
}
}
/** /**
* enable_irq - enable handling of an irq * enable_irq - enable handling of an irq
* @irq: Interrupt to enable * @irq: Interrupt to enable
...@@ -169,22 +189,7 @@ void enable_irq(unsigned int irq) ...@@ -169,22 +189,7 @@ void enable_irq(unsigned int irq)
return; return;
spin_lock_irqsave(&desc->lock, flags); spin_lock_irqsave(&desc->lock, flags);
switch (desc->depth) { __enable_irq(desc, irq);
case 0:
printk(KERN_WARNING "Unbalanced enable for IRQ %d\n", irq);
WARN_ON(1);
break;
case 1: {
unsigned int status = desc->status & ~IRQ_DISABLED;
/* Prevent probing on this irq: */
desc->status = status | IRQ_NOPROBE;
check_irq_resend(desc, irq);
/* fall-through */
}
default:
desc->depth--;
}
spin_unlock_irqrestore(&desc->lock, flags); spin_unlock_irqrestore(&desc->lock, flags);
} }
EXPORT_SYMBOL(enable_irq); EXPORT_SYMBOL(enable_irq);
...@@ -365,7 +370,7 @@ int setup_irq(unsigned int irq, struct irqaction *new) ...@@ -365,7 +370,7 @@ int setup_irq(unsigned int irq, struct irqaction *new)
compat_irq_chip_set_default_handler(desc); compat_irq_chip_set_default_handler(desc);
desc->status &= ~(IRQ_AUTODETECT | IRQ_WAITING | desc->status &= ~(IRQ_AUTODETECT | IRQ_WAITING |
IRQ_INPROGRESS); IRQ_INPROGRESS | IRQ_SPURIOUS_DISABLED);
if (!(desc->status & IRQ_NOAUTOEN)) { if (!(desc->status & IRQ_NOAUTOEN)) {
desc->depth = 0; desc->depth = 0;
...@@ -381,6 +386,16 @@ int setup_irq(unsigned int irq, struct irqaction *new) ...@@ -381,6 +386,16 @@ int setup_irq(unsigned int irq, struct irqaction *new)
/* Reset broken irq detection when installing new handler */ /* Reset broken irq detection when installing new handler */
desc->irq_count = 0; desc->irq_count = 0;
desc->irqs_unhandled = 0; desc->irqs_unhandled = 0;
/*
* Check whether we disabled the irq via the spurious handler
* before. Reenable it and give it another chance.
*/
if (shared && (desc->status & IRQ_SPURIOUS_DISABLED)) {
desc->status &= ~IRQ_SPURIOUS_DISABLED;
__enable_irq(desc, irq);
}
spin_unlock_irqrestore(&desc->lock, flags); spin_unlock_irqrestore(&desc->lock, flags);
new->irq = irq; new->irq = irq;
......
...@@ -209,8 +209,8 @@ void note_interrupt(unsigned int irq, struct irq_desc *desc, ...@@ -209,8 +209,8 @@ void note_interrupt(unsigned int irq, struct irq_desc *desc,
* Now kill the IRQ * Now kill the IRQ
*/ */
printk(KERN_EMERG "Disabling IRQ #%d\n", irq); printk(KERN_EMERG "Disabling IRQ #%d\n", irq);
desc->status |= IRQ_DISABLED; desc->status |= IRQ_DISABLED | IRQ_SPURIOUS_DISABLED;
desc->depth = 1; desc->depth++;
desc->chip->disable(irq); desc->chip->disable(irq);
} }
desc->irqs_unhandled = 0; desc->irqs_unhandled = 0;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment