patch-2.1.122 linux/arch/i386/kernel/io_apic.c

Next file: linux/arch/i386/kernel/irq.c
Previous file: linux/arch/i386/kernel/init_task.c
Back to the patch index
Back to the overall index

diff -u --recursive --new-file v2.1.121/linux/arch/i386/kernel/io_apic.c linux/arch/i386/kernel/io_apic.c
@@ -905,7 +905,7 @@
 	unsigned int t1 = jiffies;
 
 	sti();
-	udelay(10*10000);
+	mdelay(100);
 
 	if (jiffies-t1>1)
 		return 1;
@@ -947,18 +947,37 @@
 }
 
 /*
- * Level triggered interrupts can just be masked.
+ * Starting up a edge-triggered IO-APIC interrupt is
+ * nasty - we need to make sure that we get the edge.
+ * If it is already asserted for some reason, we need
+ * to fake an edge by marking it IRQ_PENDING..
+ *
+ * This is not complete - we should be able to fake
+ * an edge even if it isn't on the 8259A...
  */
-static void enable_level_ioapic_irq(unsigned int irq)
-{
-	unmask_IO_APIC_irq(irq);
-}
 
-static void disable_level_ioapic_irq(unsigned int irq)
+static void startup_edge_ioapic_irq(unsigned int irq)
 {
-	mask_IO_APIC_irq(irq);
+	if (irq < 16) {
+		disable_8259A_irq(irq);
+		if (i8259A_irq_pending(irq))
+			irq_desc[irq].status |= IRQ_PENDING;
+	}
+	enable_edge_ioapic_irq(irq);
 }
 
+#define shutdown_edge_ioapic_irq	disable_edge_ioapic_irq
+
+/*
+ * Level triggered interrupts can just be masked,
+ * and shutting down and starting up the interrupt
+ * is the same as enabling and disabling them.
+ */
+#define startup_level_ioapic_irq	unmask_IO_APIC_irq
+#define shutdown_level_ioapic_irq	mask_IO_APIC_irq
+#define enable_level_ioapic_irq		unmask_IO_APIC_irq
+#define disable_level_ioapic_irq	mask_IO_APIC_irq
+
 static void do_edge_ioapic_IRQ(unsigned int irq, struct pt_regs * regs)
 {
 	irq_desc_t *desc = irq_desc + irq;
@@ -1065,6 +1084,8 @@
 
 static struct hw_interrupt_type ioapic_edge_irq_type = {
 	"IO-APIC-edge",
+	startup_edge_ioapic_irq,
+	shutdown_edge_ioapic_irq,
 	do_edge_ioapic_IRQ,
 	enable_edge_ioapic_irq,
 	disable_edge_ioapic_irq
@@ -1072,6 +1093,8 @@
 
 static struct hw_interrupt_type ioapic_level_irq_type = {
 	"IO-APIC-level",
+	startup_level_ioapic_irq,
+	shutdown_level_ioapic_irq,
 	do_level_ioapic_IRQ,
 	enable_level_ioapic_irq,
 	disable_level_ioapic_irq
@@ -1162,20 +1185,11 @@
  *   directly from the FPU to the old PIC. Linux doesn't
  *   really care, because Linux doesn't want to use IRQ13
  *   anyway (exception 16 is the proper FPU error signal)
- * - IRQ9 is broken on PIIX4 motherboards:
  *
- *		"IRQ9 cannot be re-assigned"
- *
- *		IRQ9 is not available to assign to
- *		ISA add-in cards because it is
- *		dedicated to the power
- *		management function of the PIIX4
- *		controller on the motherboard.
- *		This is true for other motherboards
- *		which use the 82371AB PIIX4
- *		component.
+ * Additionally, something is definitely wrong with irq9
+ * on PIIX4 boards.
  */
-#define PIC_IRQS	((1<<2)|(1<<9)|(1<<13))
+#define PIC_IRQS	((1<<2)|(1<<13))
 
 void __init setup_IO_APIC(void)
 {
@@ -1224,7 +1238,6 @@
 	setup_IO_APIC_irqs();
 	init_IRQ_SMP();
 	check_timer();
- 
+
 	print_IO_APIC();
 }
-

FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen, slshen@lbl.gov