static DEFINE_SPINLOCK(i8259A_lock);
-static void _mask_and_ack_8259A_irq(unsigned int irq);
+static bool_t _mask_and_ack_8259A_irq(unsigned int irq);
-void (*__read_mostly bogus_8259A_irq)(unsigned int irq) =
- _mask_and_ack_8259A_irq;
+bool_t bogus_8259A_irq(unsigned int irq)
+{
+ return _mask_and_ack_8259A_irq(irq);
+}
static void mask_and_ack_8259A_irq(struct irq_desc *desc)
{
* Careful! The 8259A is a fragile beast, it pretty
* much _has_ to be done exactly like this (mask it
* first, _then_ send the EOI, and the order of EOI
- * to the two 8259s is important!
+ * to the two 8259s is important! Return a boolean
+ * indicating whether the irq was genuine or spurious.
*/
-static void _mask_and_ack_8259A_irq(unsigned int irq)
+static bool_t _mask_and_ack_8259A_irq(unsigned int irq)
{
unsigned int irqmask = 1 << irq;
unsigned long flags;
+ bool_t real_irq = 1; /* Assume real unless spurious */
+ bool_t need_eoi = i8259A_irq_type.ack != disable_8259A_irq;
spin_lock_irqsave(&i8259A_lock, flags);
/*
if (irq & 8) {
inb(0xA1); /* DUMMY - (do we need this?) */
outb(cached_A1,0xA1);
- outb(0x60 + (irq & 7), 0xA0);/* 'Specific EOI' to slave */
- outb(0x62,0x20); /* 'Specific EOI' to master-IRQ2 */
+ if ( need_eoi )
+ {
+ outb(0x60 + (irq & 7), 0xA0);/* 'Specific EOI' to slave */
+ outb(0x62,0x20); /* 'Specific EOI' to master-IRQ2 */
+ }
} else {
inb(0x21); /* DUMMY - (do we need this?) */
outb(cached_21,0x21);
- outb(0x60 + irq, 0x20);/* 'Specific EOI' to master */
+ if ( need_eoi )
+ outb(0x60 + irq, 0x20);/* 'Specific EOI' to master */
}
spin_unlock_irqrestore(&i8259A_lock, flags);
- return;
+ return real_irq;
spurious_8259A_irq:
/*
{
static int spurious_irq_mask;
+ real_irq = 0;
/*
* At this point we can be sure the IRQ is spurious,
* lets ACK and report it. [once per IRQ]
is to be investigated) */
if (auto_eoi)
- {
/*
* in AEOI mode we just have to mask the interrupt
* when acking.
*/
i8259A_irq_type.ack = disable_8259A_irq;
- bogus_8259A_irq = _disable_8259A_irq;
- }
else
- {
i8259A_irq_type.ack = mask_and_ack_8259A_irq;
- bogus_8259A_irq = _mask_and_ack_8259A_irq;
- }
udelay(100); /* wait for 8259A to initialize */
ack_APIC_irq();
else
kind = "";
- if ( vector >= FIRST_LEGACY_VECTOR &&
- vector <= LAST_LEGACY_VECTOR )
- bogus_8259A_irq(vector - FIRST_LEGACY_VECTOR);
- printk("CPU%u: No irq handler for vector %02x (IRQ %d%s)\n",
- smp_processor_id(), vector, irq, kind);
+ if ( ! ( vector >= FIRST_LEGACY_VECTOR &&
+ vector <= LAST_LEGACY_VECTOR &&
+ bogus_8259A_irq(vector - FIRST_LEGACY_VECTOR) ) )
+ printk("CPU%u: No irq handler for vector %02x (IRQ %d%s)\n",
+ smp_processor_id(), vector, irq, kind);
TRACE_1D(TRC_HW_IRQ_UNMAPPED_VECTOR, vector);
}
goto out_no_unlock;