|
@@ -633,8 +633,8 @@ next:
|
|
}
|
|
}
|
|
|
|
|
|
extern void (*interrupt[NR_IRQS])(void);
|
|
extern void (*interrupt[NR_IRQS])(void);
|
|
-static struct hw_interrupt_type ioapic_level_type;
|
|
|
|
-static struct hw_interrupt_type ioapic_edge_type;
|
|
|
|
|
|
+
|
|
|
|
+static struct irq_chip ioapic_chip;
|
|
|
|
|
|
#define IOAPIC_AUTO -1
|
|
#define IOAPIC_AUTO -1
|
|
#define IOAPIC_EDGE 0
|
|
#define IOAPIC_EDGE 0
|
|
@@ -648,9 +648,11 @@ static void ioapic_register_intr(int irq, int vector, unsigned long trigger)
|
|
|
|
|
|
if ((trigger == IOAPIC_AUTO && IO_APIC_irq_trigger(irq)) ||
|
|
if ((trigger == IOAPIC_AUTO && IO_APIC_irq_trigger(irq)) ||
|
|
trigger == IOAPIC_LEVEL)
|
|
trigger == IOAPIC_LEVEL)
|
|
- irq_desc[idx].chip = &ioapic_level_type;
|
|
|
|
|
|
+ set_irq_chip_and_handler(idx, &ioapic_chip,
|
|
|
|
+ handle_fasteoi_irq);
|
|
else
|
|
else
|
|
- irq_desc[idx].chip = &ioapic_edge_type;
|
|
|
|
|
|
+ set_irq_chip_and_handler(idx, &ioapic_chip,
|
|
|
|
+ handle_edge_irq);
|
|
set_intr_gate(vector, interrupt[idx]);
|
|
set_intr_gate(vector, interrupt[idx]);
|
|
}
|
|
}
|
|
|
|
|
|
@@ -752,7 +754,7 @@ static void __init setup_ExtINT_IRQ0_pin(unsigned int apic, unsigned int pin, in
|
|
* The timer IRQ doesn't have to know that behind the
|
|
* The timer IRQ doesn't have to know that behind the
|
|
* scene we have a 8259A-master in AEOI mode ...
|
|
* scene we have a 8259A-master in AEOI mode ...
|
|
*/
|
|
*/
|
|
- irq_desc[0].chip = &ioapic_edge_type;
|
|
|
|
|
|
+ set_irq_chip_and_handler(0, &ioapic_chip, handle_edge_irq);
|
|
|
|
|
|
/*
|
|
/*
|
|
* Add it to the IO-APIC irq-routing table:
|
|
* Add it to the IO-APIC irq-routing table:
|
|
@@ -1185,7 +1187,7 @@ static int __init timer_irq_works(void)
|
|
* an edge even if it isn't on the 8259A...
|
|
* an edge even if it isn't on the 8259A...
|
|
*/
|
|
*/
|
|
|
|
|
|
-static unsigned int startup_edge_ioapic_irq(unsigned int irq)
|
|
|
|
|
|
+static unsigned int startup_ioapic_irq(unsigned int irq)
|
|
{
|
|
{
|
|
int was_pending = 0;
|
|
int was_pending = 0;
|
|
unsigned long flags;
|
|
unsigned long flags;
|
|
@@ -1202,86 +1204,21 @@ static unsigned int startup_edge_ioapic_irq(unsigned int irq)
|
|
return was_pending;
|
|
return was_pending;
|
|
}
|
|
}
|
|
|
|
|
|
-/*
|
|
|
|
- * Once we have recorded IRQ_PENDING already, we can mask the
|
|
|
|
- * interrupt for real. This prevents IRQ storms from unhandled
|
|
|
|
- * devices.
|
|
|
|
- */
|
|
|
|
-static void ack_edge_ioapic_irq(unsigned int irq)
|
|
|
|
-{
|
|
|
|
- move_irq(irq);
|
|
|
|
- if ((irq_desc[irq].status & (IRQ_PENDING | IRQ_DISABLED))
|
|
|
|
- == (IRQ_PENDING | IRQ_DISABLED))
|
|
|
|
- mask_IO_APIC_irq(irq);
|
|
|
|
- ack_APIC_irq();
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
-/*
|
|
|
|
- * Level triggered interrupts can just be masked,
|
|
|
|
- * and shutting down and starting up the interrupt
|
|
|
|
- * is the same as enabling and disabling them -- except
|
|
|
|
- * with a startup need to return a "was pending" value.
|
|
|
|
- *
|
|
|
|
- * Level triggered interrupts are special because we
|
|
|
|
- * do not touch any IO-APIC register while handling
|
|
|
|
- * them. We ack the APIC in the end-IRQ handler, not
|
|
|
|
- * in the start-IRQ-handler. Protection against reentrance
|
|
|
|
- * from the same interrupt is still provided, both by the
|
|
|
|
- * generic IRQ layer and by the fact that an unacked local
|
|
|
|
- * APIC does not accept IRQs.
|
|
|
|
- */
|
|
|
|
-static unsigned int startup_level_ioapic_irq (unsigned int irq)
|
|
|
|
-{
|
|
|
|
- unmask_IO_APIC_irq(irq);
|
|
|
|
-
|
|
|
|
- return 0; /* don't check for pending */
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
-static void end_level_ioapic_irq (unsigned int irq)
|
|
|
|
-{
|
|
|
|
- move_irq(irq);
|
|
|
|
- ack_APIC_irq();
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
-#ifdef CONFIG_PCI_MSI
|
|
|
|
-static unsigned int startup_edge_ioapic_vector(unsigned int vector)
|
|
|
|
|
|
+static unsigned int startup_ioapic_vector(unsigned int vector)
|
|
{
|
|
{
|
|
int irq = vector_to_irq(vector);
|
|
int irq = vector_to_irq(vector);
|
|
|
|
|
|
- return startup_edge_ioapic_irq(irq);
|
|
|
|
|
|
+ return startup_ioapic_irq(irq);
|
|
}
|
|
}
|
|
|
|
|
|
-static void ack_edge_ioapic_vector(unsigned int vector)
|
|
|
|
-{
|
|
|
|
- int irq = vector_to_irq(vector);
|
|
|
|
-
|
|
|
|
- move_native_irq(vector);
|
|
|
|
- ack_edge_ioapic_irq(irq);
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
-static unsigned int startup_level_ioapic_vector (unsigned int vector)
|
|
|
|
-{
|
|
|
|
- int irq = vector_to_irq(vector);
|
|
|
|
-
|
|
|
|
- return startup_level_ioapic_irq (irq);
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
-static void end_level_ioapic_vector (unsigned int vector)
|
|
|
|
-{
|
|
|
|
- int irq = vector_to_irq(vector);
|
|
|
|
-
|
|
|
|
- move_native_irq(vector);
|
|
|
|
- end_level_ioapic_irq(irq);
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
-static void mask_IO_APIC_vector (unsigned int vector)
|
|
|
|
|
|
+static void mask_ioapic_vector (unsigned int vector)
|
|
{
|
|
{
|
|
int irq = vector_to_irq(vector);
|
|
int irq = vector_to_irq(vector);
|
|
|
|
|
|
mask_IO_APIC_irq(irq);
|
|
mask_IO_APIC_irq(irq);
|
|
}
|
|
}
|
|
|
|
|
|
-static void unmask_IO_APIC_vector (unsigned int vector)
|
|
|
|
|
|
+static void unmask_ioapic_vector (unsigned int vector)
|
|
{
|
|
{
|
|
int irq = vector_to_irq(vector);
|
|
int irq = vector_to_irq(vector);
|
|
|
|
|
|
@@ -1298,10 +1235,11 @@ static void set_ioapic_affinity_vector (unsigned int vector,
|
|
set_ioapic_affinity_irq(irq, cpu_mask);
|
|
set_ioapic_affinity_irq(irq, cpu_mask);
|
|
}
|
|
}
|
|
#endif // CONFIG_SMP
|
|
#endif // CONFIG_SMP
|
|
-#endif // CONFIG_PCI_MSI
|
|
|
|
|
|
|
|
-static int ioapic_retrigger(unsigned int irq)
|
|
|
|
|
|
+static int ioapic_retrigger_vector(unsigned int vector)
|
|
{
|
|
{
|
|
|
|
+ int irq = vector_to_irq(vector);
|
|
|
|
+
|
|
send_IPI_self(IO_APIC_VECTOR(irq));
|
|
send_IPI_self(IO_APIC_VECTOR(irq));
|
|
|
|
|
|
return 1;
|
|
return 1;
|
|
@@ -1316,32 +1254,22 @@ static int ioapic_retrigger(unsigned int irq)
|
|
* races.
|
|
* races.
|
|
*/
|
|
*/
|
|
|
|
|
|
-static struct hw_interrupt_type ioapic_edge_type __read_mostly = {
|
|
|
|
- .typename = "IO-APIC-edge",
|
|
|
|
- .startup = startup_edge_ioapic,
|
|
|
|
- .shutdown = shutdown_edge_ioapic,
|
|
|
|
- .enable = enable_edge_ioapic,
|
|
|
|
- .disable = disable_edge_ioapic,
|
|
|
|
- .ack = ack_edge_ioapic,
|
|
|
|
- .end = end_edge_ioapic,
|
|
|
|
-#ifdef CONFIG_SMP
|
|
|
|
- .set_affinity = set_ioapic_affinity,
|
|
|
|
-#endif
|
|
|
|
- .retrigger = ioapic_retrigger,
|
|
|
|
-};
|
|
|
|
|
|
+static void ack_apic(unsigned int vector)
|
|
|
|
+{
|
|
|
|
+ ack_APIC_irq();
|
|
|
|
+}
|
|
|
|
|
|
-static struct hw_interrupt_type ioapic_level_type __read_mostly = {
|
|
|
|
- .typename = "IO-APIC-level",
|
|
|
|
- .startup = startup_level_ioapic,
|
|
|
|
- .shutdown = shutdown_level_ioapic,
|
|
|
|
- .enable = enable_level_ioapic,
|
|
|
|
- .disable = disable_level_ioapic,
|
|
|
|
- .ack = mask_and_ack_level_ioapic,
|
|
|
|
- .end = end_level_ioapic,
|
|
|
|
|
|
+static struct irq_chip ioapic_chip __read_mostly = {
|
|
|
|
+ .name = "IO-APIC",
|
|
|
|
+ .startup = startup_ioapic_vector,
|
|
|
|
+ .mask = mask_ioapic_vector,
|
|
|
|
+ .unmask = unmask_ioapic_vector,
|
|
|
|
+ .ack = ack_apic,
|
|
|
|
+ .eoi = ack_apic,
|
|
#ifdef CONFIG_SMP
|
|
#ifdef CONFIG_SMP
|
|
- .set_affinity = set_ioapic_affinity,
|
|
|
|
|
|
+ .set_affinity = set_ioapic_affinity_vector,
|
|
#endif
|
|
#endif
|
|
- .retrigger = ioapic_retrigger,
|
|
|
|
|
|
+ .retrigger = ioapic_retrigger_vector,
|
|
};
|
|
};
|
|
|
|
|
|
static inline void init_IO_APIC_traps(void)
|
|
static inline void init_IO_APIC_traps(void)
|
|
@@ -1376,7 +1304,7 @@ static inline void init_IO_APIC_traps(void)
|
|
make_8259A_irq(irq);
|
|
make_8259A_irq(irq);
|
|
else
|
|
else
|
|
/* Strange. Oh, well.. */
|
|
/* Strange. Oh, well.. */
|
|
- irq_desc[irq].chip = &no_irq_type;
|
|
|
|
|
|
+ irq_desc[irq].chip = &no_irq_chip;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|