aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86_64/kernel/io_apic.c
diff options
context:
space:
mode:
authorIngo Molnar <mingo@elte.hu>2006-10-04 05:16:25 -0400
committerLinus Torvalds <torvalds@g5.osdl.org>2006-10-04 10:55:25 -0400
commitf29bd1ba68c8c6a0f50bd678bbd5a26674018f7c (patch)
tree5a2f6086397b94e9094fa065a344bcb7e6a05ac0 /arch/x86_64/kernel/io_apic.c
parent0271eb947db2704a0ff8be68d72915ab021d1ead (diff)
[PATCH] genirq: convert the x86_64 architecture to irq-chips
This patch converts all the x86_64 PIC controllers layers to the new and simpler irq-chip interrupt handling layer. [mingo@elte.hu: The patch also enables the fasteoi handler for x86_64] Signed-off-by: Ingo Molnar <mingo@elte.hu> Signed-off-by: Thomas Gleixner <tglx@linutronix.de> Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org> Cc: Roland Dreier <rolandd@cisco.com> Cc: Andi Kleen <ak@suse.de> Signed-off-by: Andrew Morton <akpm@osdl.org> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Diffstat (limited to 'arch/x86_64/kernel/io_apic.c')
-rw-r--r--arch/x86_64/kernel/io_apic.c130
1 files changed, 29 insertions, 101 deletions
diff --git a/arch/x86_64/kernel/io_apic.c b/arch/x86_64/kernel/io_apic.c
index 0491019d4c8d..e1d1b4217cb2 100644
--- a/arch/x86_64/kernel/io_apic.c
+++ b/arch/x86_64/kernel/io_apic.c
@@ -633,8 +633,8 @@ next:
633} 633}
634 634
635extern void (*interrupt[NR_IRQS])(void); 635extern void (*interrupt[NR_IRQS])(void);
636static struct hw_interrupt_type ioapic_level_type; 636
637static struct hw_interrupt_type ioapic_edge_type; 637static struct irq_chip ioapic_chip;
638 638
639#define IOAPIC_AUTO -1 639#define IOAPIC_AUTO -1
640#define IOAPIC_EDGE 0 640#define IOAPIC_EDGE 0
@@ -648,9 +648,11 @@ static void ioapic_register_intr(int irq, int vector, unsigned long trigger)
648 648
649 if ((trigger == IOAPIC_AUTO && IO_APIC_irq_trigger(irq)) || 649 if ((trigger == IOAPIC_AUTO && IO_APIC_irq_trigger(irq)) ||
650 trigger == IOAPIC_LEVEL) 650 trigger == IOAPIC_LEVEL)
651 irq_desc[idx].chip = &ioapic_level_type; 651 set_irq_chip_and_handler(idx, &ioapic_chip,
652 handle_fasteoi_irq);
652 else 653 else
653 irq_desc[idx].chip = &ioapic_edge_type; 654 set_irq_chip_and_handler(idx, &ioapic_chip,
655 handle_edge_irq);
654 set_intr_gate(vector, interrupt[idx]); 656 set_intr_gate(vector, interrupt[idx]);
655} 657}
656 658
@@ -752,7 +754,7 @@ static void __init setup_ExtINT_IRQ0_pin(unsigned int apic, unsigned int pin, in
752 * The timer IRQ doesn't have to know that behind the 754 * The timer IRQ doesn't have to know that behind the
753 * scene we have a 8259A-master in AEOI mode ... 755 * scene we have a 8259A-master in AEOI mode ...
754 */ 756 */
755 irq_desc[0].chip = &ioapic_edge_type; 757 set_irq_chip_and_handler(0, &ioapic_chip, handle_edge_irq);
756 758
757 /* 759 /*
758 * Add it to the IO-APIC irq-routing table: 760 * Add it to the IO-APIC irq-routing table:
@@ -1185,7 +1187,7 @@ static int __init timer_irq_works(void)
1185 * an edge even if it isn't on the 8259A... 1187 * an edge even if it isn't on the 8259A...
1186 */ 1188 */
1187 1189
1188static unsigned int startup_edge_ioapic_irq(unsigned int irq) 1190static unsigned int startup_ioapic_irq(unsigned int irq)
1189{ 1191{
1190 int was_pending = 0; 1192 int was_pending = 0;
1191 unsigned long flags; 1193 unsigned long flags;
@@ -1202,86 +1204,21 @@ static unsigned int startup_edge_ioapic_irq(unsigned int irq)
1202 return was_pending; 1204 return was_pending;
1203} 1205}
1204 1206
1205/* 1207static unsigned int startup_ioapic_vector(unsigned int vector)
1206 * Once we have recorded IRQ_PENDING already, we can mask the
1207 * interrupt for real. This prevents IRQ storms from unhandled
1208 * devices.
1209 */
1210static void ack_edge_ioapic_irq(unsigned int irq)
1211{
1212 move_irq(irq);
1213 if ((irq_desc[irq].status & (IRQ_PENDING | IRQ_DISABLED))
1214 == (IRQ_PENDING | IRQ_DISABLED))
1215 mask_IO_APIC_irq(irq);
1216 ack_APIC_irq();
1217}
1218
1219/*
1220 * Level triggered interrupts can just be masked,
1221 * and shutting down and starting up the interrupt
1222 * is the same as enabling and disabling them -- except
1223 * with a startup need to return a "was pending" value.
1224 *
1225 * Level triggered interrupts are special because we
1226 * do not touch any IO-APIC register while handling
1227 * them. We ack the APIC in the end-IRQ handler, not
1228 * in the start-IRQ-handler. Protection against reentrance
1229 * from the same interrupt is still provided, both by the
1230 * generic IRQ layer and by the fact that an unacked local
1231 * APIC does not accept IRQs.
1232 */
1233static unsigned int startup_level_ioapic_irq (unsigned int irq)
1234{
1235 unmask_IO_APIC_irq(irq);
1236
1237 return 0; /* don't check for pending */
1238}
1239
1240static void end_level_ioapic_irq (unsigned int irq)
1241{
1242 move_irq(irq);
1243 ack_APIC_irq();
1244}
1245
1246#ifdef CONFIG_PCI_MSI
1247static unsigned int startup_edge_ioapic_vector(unsigned int vector)
1248{ 1208{
1249 int irq = vector_to_irq(vector); 1209 int irq = vector_to_irq(vector);
1250 1210
1251 return startup_edge_ioapic_irq(irq); 1211 return startup_ioapic_irq(irq);
1252} 1212}
1253 1213
1254static void ack_edge_ioapic_vector(unsigned int vector) 1214static void mask_ioapic_vector (unsigned int vector)
1255{
1256 int irq = vector_to_irq(vector);
1257
1258 move_native_irq(vector);
1259 ack_edge_ioapic_irq(irq);
1260}
1261
1262static unsigned int startup_level_ioapic_vector (unsigned int vector)
1263{
1264 int irq = vector_to_irq(vector);
1265
1266 return startup_level_ioapic_irq (irq);
1267}
1268
1269static void end_level_ioapic_vector (unsigned int vector)
1270{
1271 int irq = vector_to_irq(vector);
1272
1273 move_native_irq(vector);
1274 end_level_ioapic_irq(irq);
1275}
1276
1277static void mask_IO_APIC_vector (unsigned int vector)
1278{ 1215{
1279 int irq = vector_to_irq(vector); 1216 int irq = vector_to_irq(vector);
1280 1217
1281 mask_IO_APIC_irq(irq); 1218 mask_IO_APIC_irq(irq);
1282} 1219}
1283 1220
1284static void unmask_IO_APIC_vector (unsigned int vector) 1221static void unmask_ioapic_vector (unsigned int vector)
1285{ 1222{
1286 int irq = vector_to_irq(vector); 1223 int irq = vector_to_irq(vector);
1287 1224
@@ -1298,10 +1235,11 @@ static void set_ioapic_affinity_vector (unsigned int vector,
1298 set_ioapic_affinity_irq(irq, cpu_mask); 1235 set_ioapic_affinity_irq(irq, cpu_mask);
1299} 1236}
1300#endif // CONFIG_SMP 1237#endif // CONFIG_SMP
1301#endif // CONFIG_PCI_MSI
1302 1238
1303static int ioapic_retrigger(unsigned int irq) 1239static int ioapic_retrigger_vector(unsigned int vector)
1304{ 1240{
1241 int irq = vector_to_irq(vector);
1242
1305 send_IPI_self(IO_APIC_VECTOR(irq)); 1243 send_IPI_self(IO_APIC_VECTOR(irq));
1306 1244
1307 return 1; 1245 return 1;
@@ -1316,32 +1254,22 @@ static int ioapic_retrigger(unsigned int irq)
1316 * races. 1254 * races.
1317 */ 1255 */
1318 1256
1319static struct hw_interrupt_type ioapic_edge_type __read_mostly = { 1257static void ack_apic(unsigned int vector)
1320 .typename = "IO-APIC-edge", 1258{
1321 .startup = startup_edge_ioapic, 1259 ack_APIC_irq();
1322 .shutdown = shutdown_edge_ioapic, 1260}
1323 .enable = enable_edge_ioapic,
1324 .disable = disable_edge_ioapic,
1325 .ack = ack_edge_ioapic,
1326 .end = end_edge_ioapic,
1327#ifdef CONFIG_SMP
1328 .set_affinity = set_ioapic_affinity,
1329#endif
1330 .retrigger = ioapic_retrigger,
1331};
1332 1261
1333static struct hw_interrupt_type ioapic_level_type __read_mostly = { 1262static struct irq_chip ioapic_chip __read_mostly = {
1334 .typename = "IO-APIC-level", 1263 .name = "IO-APIC",
1335 .startup = startup_level_ioapic, 1264 .startup = startup_ioapic_vector,
1336 .shutdown = shutdown_level_ioapic, 1265 .mask = mask_ioapic_vector,
1337 .enable = enable_level_ioapic, 1266 .unmask = unmask_ioapic_vector,
1338 .disable = disable_level_ioapic, 1267 .ack = ack_apic,
1339 .ack = mask_and_ack_level_ioapic, 1268 .eoi = ack_apic,
1340 .end = end_level_ioapic,
1341#ifdef CONFIG_SMP 1269#ifdef CONFIG_SMP
1342 .set_affinity = set_ioapic_affinity, 1270 .set_affinity = set_ioapic_affinity_vector,
1343#endif 1271#endif
1344 .retrigger = ioapic_retrigger, 1272 .retrigger = ioapic_retrigger_vector,
1345}; 1273};
1346 1274
1347static inline void init_IO_APIC_traps(void) 1275static inline void init_IO_APIC_traps(void)
@@ -1376,7 +1304,7 @@ static inline void init_IO_APIC_traps(void)
1376 make_8259A_irq(irq); 1304 make_8259A_irq(irq);
1377 else 1305 else
1378 /* Strange. Oh, well.. */ 1306 /* Strange. Oh, well.. */
1379 irq_desc[irq].chip = &no_irq_type; 1307 irq_desc[irq].chip = &no_irq_chip;
1380 } 1308 }
1381 } 1309 }
1382} 1310}