patch-2.1.120 linux/arch/i386/kernel/irq.c
Next file: linux/arch/i386/kernel/irq.h
Previous file: linux/arch/i386/kernel/io_apic.c
Back to the patch index
Back to the overall index
- Lines: 179
- Date:
Wed Sep 2 16:18:32 1998
- Orig file:
v2.1.119/linux/arch/i386/kernel/irq.c
- Orig date:
Thu Aug 27 19:56:28 1998
diff -u --recursive --new-file v2.1.119/linux/arch/i386/kernel/irq.c linux/arch/i386/kernel/irq.c
@@ -105,8 +105,8 @@
};
irq_desc_t irq_desc[NR_IRQS] = {
- [0 ... 15] = { 0, 0, 0, &i8259A_irq_type, }, /* default to standard ISA IRQs */
- [16 ... 63] = { 0, 0, 0, &no_irq_type, }, /* 'high' PCI IRQs filled in on demand */
+ [0 ... 15] = { 0, &i8259A_irq_type, }, /* default to standard ISA IRQs */
+ [16 ... 63] = { 0, &no_irq_type, }, /* 'high' PCI IRQs filled in on demand */
};
int irq_vector[NR_IRQS] = { IRQ0_TRAP_VECTOR , 0 };
@@ -663,7 +663,8 @@
if (handle_IRQ_event(irq, regs)) {
spin_lock(&irq_controller_lock);
- if (!(irq_desc[irq].status &= IRQ_DISABLED))
+ irq_desc[irq].status &= ~IRQ_INPROGRESS;
+ if (!(irq_desc[irq].status & IRQ_DISABLED))
enable_8259A_irq(irq);
spin_unlock(&irq_controller_lock);
}
@@ -683,10 +684,6 @@
unsigned long flags;
spin_lock_irqsave(&irq_controller_lock, flags);
- /*
- * At this point we may actually have a pending interrupt being active
- * on another CPU. So don't touch the IRQ_INPROGRESS bit..
- */
irq_desc[irq].status |= IRQ_DISABLED;
irq_desc[irq].handler->disable(irq);
spin_unlock_irqrestore(&irq_controller_lock, flags);
@@ -793,6 +790,7 @@
*p = new;
if (!shared) {
+ irq_desc[irq].status = 0;
#ifdef __SMP__
if (IO_APIC_IRQ(irq)) {
/*
@@ -803,11 +801,10 @@
if (irq < 16) {
disable_8259A_irq(irq);
if (i8259A_irq_pending(irq))
- irq_desc[irq].events = 1;
+ irq_desc[irq].status = IRQ_PENDING;
}
}
#endif
- irq_desc[irq].status = 0;
irq_desc[irq].handler->enable(irq);
}
spin_unlock_irqrestore(&irq_controller_lock,flags);
@@ -863,8 +860,10 @@
/* Found it - now free it */
*p = action->next;
kfree(action);
- if (!irq_desc[irq].action)
+ if (!irq_desc[irq].action) {
+ irq_desc[irq].status |= IRQ_DISABLED;
irq_desc[irq].handler->disable(irq);
+ }
goto out;
}
printk("Trying to free free IRQ%d\n",irq);
@@ -880,9 +879,9 @@
* with "IRQ_INPROGRESS" asserted and the interrupt
* disabled.
*/
-unsigned long probe_irq_on (void)
+unsigned long probe_irq_on(void)
{
- unsigned int i, irqs = 0;
+ unsigned int i;
unsigned long delay;
/*
@@ -891,51 +890,68 @@
spin_lock_irq(&irq_controller_lock);
for (i = NR_IRQS-1; i > 0; i--) {
if (!irq_desc[i].action) {
- irq_desc[i].status = 0;
+ unsigned int status = irq_desc[i].status | IRQ_AUTODETECT;
+ irq_desc[i].status = status & ~(IRQ_INPROGRESS | IRQ_PENDING);
irq_desc[i].handler->enable(i);
- irqs |= (1 << i);
}
}
spin_unlock_irq(&irq_controller_lock);
/*
- * wait for spurious interrupts to increase counters
+ * Wait for spurious interrupts to trigger
*/
for (delay = jiffies + HZ/10; delay > jiffies; )
/* about 100ms delay */ synchronize_irq();
/*
- * now filter out any obviously spurious interrupts
+ * Now filter out any obviously spurious interrupts
*/
spin_lock_irq(&irq_controller_lock);
for (i=0; i<NR_IRQS; i++) {
- if (irq_desc[i].status & IRQ_INPROGRESS)
- irqs &= ~(1UL << i);
+ unsigned int status = irq_desc[i].status;
+
+ if (!(status & IRQ_AUTODETECT))
+ continue;
+
+ /* It triggered already - consider it spurious. */
+ if (status & IRQ_INPROGRESS) {
+ irq_desc[i].status = status & ~IRQ_AUTODETECT;
+ irq_desc[i].handler->disable(i);
+ }
}
spin_unlock_irq(&irq_controller_lock);
- return irqs;
+ return 0x12345678;
}
-int probe_irq_off (unsigned long irqs)
+int probe_irq_off(unsigned long unused)
{
- int i, irq_found = -1;
+ int i, irq_found, nr_irqs;
+
+ if (unused != 0x12345678)
+ printk("Bad IRQ probe from %lx\n", (&unused)[-1]);
+ nr_irqs = 0;
+ irq_found = 0;
spin_lock_irq(&irq_controller_lock);
for (i=0; i<NR_IRQS; i++) {
- if ((irqs & 1) && (irq_desc[i].status & IRQ_INPROGRESS)) {
- if (irq_found != -1) {
- irq_found = -irq_found;
- goto out;
- }
- irq_found = i;
+ unsigned int status = irq_desc[i].status;
+
+ if (!(status & IRQ_AUTODETECT))
+ continue;
+
+ if (status & IRQ_INPROGRESS) {
+ if (!nr_irqs)
+ irq_found = i;
+ nr_irqs++;
}
- irqs >>= 1;
+ irq_desc[i].status = status & ~IRQ_AUTODETECT;
+ irq_desc[i].handler->disable(i);
}
- if (irq_found == -1)
- irq_found = 0;
-out:
spin_unlock_irq(&irq_controller_lock);
+
+ if (nr_irqs > 1)
+ irq_found = -irq_found;
return irq_found;
}
@@ -948,10 +964,9 @@
outb_p(LATCH & 0xff , 0x40); /* LSB */
outb(LATCH >> 8 , 0x40); /* MSB */
- for (i=0; i<NR_IRQS; i++) {
- irq_desc[i].events = 0;
- irq_desc[i].status = 0;
- }
+ for (i=0; i<NR_IRQS; i++)
+ irq_desc[i].status = IRQ_DISABLED;
+
/*
* 16 old-style INTA-cycle interrupt gates:
*/
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen, slshen@lbl.gov