diff options
Diffstat (limited to 'arch/i386/kernel/irq.c')
-rw-r--r-- | arch/i386/kernel/irq.c | 18 |
1 files changed, 13 insertions, 5 deletions
diff --git a/arch/i386/kernel/irq.c b/arch/i386/kernel/irq.c index bfb2a6841..fcc0a72f5 100644 --- a/arch/i386/kernel/irq.c +++ b/arch/i386/kernel/irq.c @@ -536,7 +536,7 @@ void enable_irq(unsigned int irq) desc->depth--; break; case 0: - printk("enable_irq() unbalanced from %p\n", + printk("enable_irq(%u) unbalanced from %p\n", irq, __builtin_return_address(0)); } spin_unlock_irqrestore(&desc->lock, flags); @@ -775,6 +775,8 @@ void free_irq(unsigned int irq, void *dev_id) * disabled. */ +static DECLARE_MUTEX(probe_sem); + /** * probe_irq_on - begin an interrupt autodetect * @@ -790,6 +792,7 @@ unsigned long probe_irq_on(void) unsigned long val; unsigned long delay; + down(&probe_sem); /* * something may have generated an irq long ago and we want to * flush such a longstanding irq before considering it as spurious. @@ -868,15 +871,18 @@ unsigned long probe_irq_on(void) * Scan the ISA bus interrupt lines and return a bitmap of * active interrupts. The interrupt probe logic state is then * returned to its previous value. + * + * Note: we need to scan all the irq's even though we will + * only return ISA irq numbers - just so that we reset them + * all to a known state. */ - unsigned int probe_irq_mask(unsigned long val) { int i; unsigned int mask; mask = 0; - for (i = 0; i < 16; i++) { + for (i = 0; i < NR_IRQS; i++) { irq_desc_t *desc = irq_desc + i; unsigned int status; @@ -884,7 +890,7 @@ unsigned int probe_irq_mask(unsigned long val) status = desc->status; if (status & IRQ_AUTODETECT) { - if (!(status & IRQ_WAITING)) + if (i < 16 && !(status & IRQ_WAITING)) mask |= 1 << i; desc->status = status & ~IRQ_AUTODETECT; @@ -892,6 +898,7 @@ unsigned int probe_irq_mask(unsigned long val) } spin_unlock_irq(&desc->lock); } + up(&probe_sem); return mask & val; } @@ -943,6 +950,7 @@ int probe_irq_off(unsigned long val) } spin_unlock_irq(&desc->lock); } + up(&probe_sem); if (nr_irqs > 1) irq_found = -irq_found; @@ -998,7 +1006,7 @@ int setup_irq(unsigned int irq, struct irqaction * new) if (!shared) { desc->depth = 0; - desc->status &= ~IRQ_DISABLED; + desc->status &= ~(IRQ_DISABLED | IRQ_AUTODETECT | IRQ_WAITING); desc->handler->startup(irq); } spin_unlock_irqrestore(&desc->lock,flags); |