*/
void spurious_interrupt(struct cpu_user_regs *regs)
{
- unsigned long v;
-
/*
* Check if this is a vectored interrupt (most likely, as this is probably
* a request to dump local CPU state). Vectored interrupts are ACKed;
* spurious interrupts are not.
*/
- v = apic_read(APIC_ISR + ((SPURIOUS_APIC_VECTOR & ~0x1f) >> 1));
- if (v & (1 << (SPURIOUS_APIC_VECTOR & 0x1f))) {
+ if (apic_isr_read(SPURIOUS_APIC_VECTOR)) {
ack_APIC_irq();
if (this_cpu(state_dump_pending)) {
this_cpu(state_dump_pending) = 0;
void check_for_unexpected_msi(unsigned int vector)
{
- unsigned long v = apic_read(APIC_ISR + ((vector & ~0x1f) >> 1));
- BUG_ON(v & (1 << (vector & 0x1f)));
+ BUG_ON(apic_isr_read(vector));
}
static DEFINE_SPINLOCK(i8259A_lock);
-static void mask_and_ack_8259A_irq(struct irq_desc *);
+static void _mask_and_ack_8259A_irq(unsigned int irq);
+
+void (*__read_mostly bogus_8259A_irq)(unsigned int irq) =
+ _mask_and_ack_8259A_irq;
+
+static void mask_and_ack_8259A_irq(struct irq_desc *desc)
+{
+ _mask_and_ack_8259A_irq(desc->irq);
+}
static unsigned int startup_8259A_irq(struct irq_desc *desc)
{
*/
unsigned int __read_mostly io_apic_irqs;
-void disable_8259A_irq(struct irq_desc *desc)
+static void _disable_8259A_irq(unsigned int irq)
{
- unsigned int mask = 1 << desc->irq;
+ unsigned int mask = 1 << irq;
unsigned long flags;
spin_lock_irqsave(&i8259A_lock, flags);
cached_irq_mask |= mask;
- if (desc->irq & 8)
+ if (irq & 8)
outb(cached_A1,0xA1);
else
outb(cached_21,0x21);
+ per_cpu(vector_irq, 0)[LEGACY_VECTOR(irq)] = -1;
spin_unlock_irqrestore(&i8259A_lock, flags);
}
+void disable_8259A_irq(struct irq_desc *desc)
+{
+ _disable_8259A_irq(desc->irq);
+}
+
void enable_8259A_irq(struct irq_desc *desc)
{
unsigned int mask = ~(1 << desc->irq);
spin_lock_irqsave(&i8259A_lock, flags);
cached_irq_mask &= mask;
+ per_cpu(vector_irq, 0)[LEGACY_VECTOR(desc->irq)] = desc->irq;
if (desc->irq & 8)
outb(cached_A1,0xA1);
else
* first, _then_ send the EOI, and the order of EOI
* to the two 8259s is important!
*/
-static void mask_and_ack_8259A_irq(struct irq_desc *desc)
+static void _mask_and_ack_8259A_irq(unsigned int irq)
{
- unsigned int irqmask = 1 << desc->irq;
+ unsigned int irqmask = 1 << irq;
unsigned long flags;
spin_lock_irqsave(&i8259A_lock, flags);
cached_irq_mask |= irqmask;
handle_real_irq:
- if (desc->irq & 8) {
+ if (irq & 8) {
inb(0xA1); /* DUMMY - (do we need this?) */
outb(cached_A1,0xA1);
- outb(0x60 + (desc->irq & 7), 0xA0);/* 'Specific EOI' to slave */
+ 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 + desc->irq, 0x20);/* 'Specific EOI' to master */
+ outb(0x60 + irq, 0x20);/* 'Specific EOI' to master */
}
spin_unlock_irqrestore(&i8259A_lock, flags);
return;
/*
* this is the slow path - should happen rarely.
*/
- if (i8259A_irq_real(desc->irq))
+ if (i8259A_irq_real(irq))
/*
* oops, the IRQ _is_ in service according to the
* 8259A - not spurious, go handle it.
* lets ACK and report it. [once per IRQ]
*/
if (!(spurious_irq_mask & irqmask)) {
- printk("spurious 8259A interrupt: IRQ%d.\n", desc->irq);
+ printk("spurious 8259A interrupt: IRQ%d.\n", irq);
spurious_irq_mask |= irqmask;
}
/*
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 */
if (direct_apic_vector[vector] != NULL) {
(*direct_apic_vector[vector])(regs);
} else {
- ack_APIC_irq();
- printk("%s: %d.%d No irq handler for vector (irq %d)\n",
- __func__, smp_processor_id(), vector, irq);
+ const char *kind = ", LAPIC";
+
+ if ( apic_isr_read(vector) )
+ 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);
TRACE_1D(TRC_HW_IRQ_UNMAPPED_VECTOR, vector);
}
goto out_no_unlock;