patch-2.3.99-pre6 linux/arch/ia64/dig/iosapic.c

Next file: linux/arch/ia64/dig/setup.c
Previous file: linux/arch/ia64/dig/Makefile
Back to the patch index
Back to the overall index

diff -u --recursive --new-file v2.3.99-pre5/linux/arch/ia64/dig/iosapic.c linux/arch/ia64/dig/iosapic.c
@@ -7,16 +7,20 @@
  * Copyright (C) 1999-2000 David Mosberger-Tang <davidm@hpl.hp.com>
  * Copyright (C) 1999 VA Linux Systems
  * Copyright (C) 1999,2000 Walt Drummond <drummond@valinux.com>
+ *
+ * 00/04/19	D. Mosberger	Rewritten to mirror more closely the x86 I/O APIC code.
+ *				In particular, we now have separate handlers for edge
+ *				and level triggered interrupts.
  */
 #include <linux/config.h>
 
 #include <linux/kernel.h>
 #include <linux/init.h>
-#include <linux/irq.h>
 #include <linux/pci.h>
 #include <linux/smp.h>
 #include <linux/smp_lock.h>
 #include <linux/string.h>
+#include <linux/irq.h>
 
 #include <asm/io.h>
 #include <asm/iosapic.h>
@@ -27,172 +31,19 @@
 
 #undef DEBUG_IRQ_ROUTING
 
-/*
- * IRQ vectors 0..15 are treated as the legacy interrupts of the PC-AT
- * platform.  No new drivers should ever ask for specific irqs, but we
- * provide compatibility here in case there is an old driver that does
- * ask for specific irqs (serial, keyboard, stuff like that).  Since
- * IA-64 doesn't allow irq 0..15 to be used for external interrupts
- * anyhow, this in no way prevents us from doing the Right Thing
- * with new drivers.
- */
+static spinlock_t iosapic_lock = SPIN_LOCK_UNLOCKED;
+
 struct iosapic_vector iosapic_vector[NR_IRQS] = {
 	[0 ... NR_IRQS-1] = { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }
 };
 
-#ifndef CONFIG_IA64_IRQ_ACPI
-/*
- * Defines the default interrupt routing information for the LION platform
- * XXX - this information should be obtained from the ACPI and hardcoded since
- * we do not have ACPI AML support.
- */
-
-struct intr_routing_entry intr_routing[] = {
-      {0,0,0,2,0,0,0,0},
-      {0,0,1,1,0,0,0,0},
-      {0,0,2,0xff,0,0,0,0},
-      {0,0,3,3,0,0,0,0},
-      {0,0,4,4,0,0,0,0},
-      {0,0,5,5,0,0,0,0},
-      {0,0,6,6,0,0,0,0},
-      {0,0,7,7,0,0,0,0},
-      {0,0,8,8,0,0,0,0},
-      {0,0,9,9,0,0,0,0},
-      {0,0,10,10,0,0,0,0},
-      {0,0,11,11,0,0,0,0},
-      {0,0,12,12,0,0,0,0},
-      {0,0,13,13,0,0,0,0},
-      {0,0,14,14,0,0,0,0},
-      {0,0,15,15,0,0,0,0},
-#ifdef CONFIG_IA64_LION_HACKS
-      {1, 0, 0x04, 16, 0, 0, 1, 1},	/* bus 0, device id 1, INTA */
-      {1, 0, 0x05, 26, 0, 0, 1, 1},	/* bus 0, device id 1, INTB */
-      {1, 0, 0x06, 36, 0, 0, 1, 1},	/* bus 0, device id 1, INTC */
-      {1, 0, 0x07, 42, 0, 0, 1, 1},	/* bus 0, device id 1, INTD */
-
-      {1, 0, 0x08, 17, 0, 0, 1, 1},	/* bus 0, device id 2, INTA */
-      {1, 0, 0x09, 27, 0, 0, 1, 1},	/* bus 0, device id 2, INTB */
-      {1, 0, 0x0a, 37, 0, 0, 1, 1},	/* bus 0, device id 2, INTC */
-      {1, 0, 0x0b, 42, 0, 0, 1, 1},	/* bus 0, device id 2, INTD */
-
-      {1, 0, 0x0f, 50, 0, 0, 1, 1},	/* bus 0, device id 3, INTD */
-
-      {1, 0, 0x14, 51, 0, 0, 1, 1},	/* bus 0, device id 5, INTA */
-
-      {1, 0, 0x18, 49, 0, 0, 1, 1},	/* bus 0, device id 6, INTA */
-
-      {1, 1, 0x04, 18, 0, 0, 1, 1},	/* bus 1, device id 1, INTA */
-      {1, 1, 0x05, 28, 0, 0, 1, 1},	/* bus 1, device id 1, INTB */
-      {1, 1, 0x06, 38, 0, 0, 1, 1},	/* bus 1, device id 1, INTC */
-      {1, 1, 0x07, 43, 0, 0, 1, 1},	/* bus 1, device id 1, INTD */
-
-      {1, 1, 0x08, 48, 0, 0, 1, 1},	/* bus 1, device id 2, INTA */
-
-      {1, 1, 0x0c, 19, 0, 0, 1, 1},	/* bus 1, device id 3, INTA */
-      {1, 1, 0x0d, 29, 0, 0, 1, 1},	/* bus 1, device id 3, INTB */
-      {1, 1, 0x0e, 38, 0, 0, 1, 1},	/* bus 1, device id 3, INTC */
-      {1, 1, 0x0f, 44, 0, 0, 1, 1},	/* bus 1, device id 3, INTD */
-
-      {1, 1, 0x10, 20, 0, 0, 1, 1},	/* bus 1, device id 4, INTA */
-      {1, 1, 0x11, 30, 0, 0, 1, 1},	/* bus 1, device id 4, INTB */
-      {1, 1, 0x12, 39, 0, 0, 1, 1},	/* bus 1, device id 4, INTC */
-      {1, 1, 0x13, 45, 0, 0, 1, 1},	/* bus 1, device id 4, INTD */
-
-      {1, 2, 0x04, 21, 0, 0, 1, 1},	/* bus 2, device id 1, INTA */
-      {1, 2, 0x05, 31, 0, 0, 1, 1},	/* bus 2, device id 1, INTB */
-      {1, 2, 0x06, 39, 0, 0, 1, 1},	/* bus 2, device id 1, INTC */
-      {1, 2, 0x07, 45, 0, 0, 1, 1},	/* bus 2, device id 1, INTD */
-
-      {1, 2, 0x08, 22, 0, 0, 1, 1},	/* bus 2, device id 2, INTA */
-      {1, 2, 0x09, 32, 0, 0, 1, 1},	/* bus 2, device id 2, INTB */
-      {1, 2, 0x0a, 40, 0, 0, 1, 1},	/* bus 2, device id 2, INTC */
-      {1, 2, 0x0b, 46, 0, 0, 1, 1},	/* bus 2, device id 2, INTD */
-
-      {1, 2, 0x0c, 23, 0, 0, 1, 1},	/* bus 2, device id 3, INTA */
-      {1, 2, 0x0d, 33, 0, 0, 1, 1},	/* bus 2, device id 3, INTB */
-      {1, 2, 0x0e, 40, 0, 0, 1, 1},	/* bus 2, device id 3, INTC */
-      {1, 2, 0x0f, 46, 0, 0, 1, 1},	/* bus 2, device id 3, INTD */
-
-      {1, 3, 0x04, 24, 0, 0, 1, 1},	/* bus 3, device id 1, INTA */
-      {1, 3, 0x05, 34, 0, 0, 1, 1},	/* bus 3, device id 1, INTB */
-      {1, 3, 0x06, 41, 0, 0, 1, 1},	/* bus 3, device id 1, INTC */
-      {1, 3, 0x07, 47, 0, 0, 1, 1},	/* bus 3, device id 1, INTD */
-
-      {1, 3, 0x08, 25, 0, 0, 1, 1},	/* bus 3, device id 2, INTA */
-      {1, 3, 0x09, 35, 0, 0, 1, 1},	/* bus 3, device id 2, INTB */
-      {1, 3, 0x0a, 41, 0, 0, 1, 1},	/* bus 3, device id 2, INTC */
-      {1, 3, 0x0b, 47, 0, 0, 1, 1},	/* bus 3, device id 2, INTD */
-#else
-      /*
-       * BigSur platform, bus 0, device 1,2,4 and bus 1 device 0-3
-       */
-      {1,1,0x0,19,0,0,1,1},		/* bus 1, device id 0, INTA */
-      {1,1,0x1,18,0,0,1,1},		/* bus 1, device id 0, INTB */
-      {1,1,0x2,17,0,0,1,1},		/* bus 1, device id 0, INTC */
-      {1,1,0x3,16,0,0,1,1},		/* bus 1, device id 0, INTD */
-
-      {1,1,0x4,23,0,0,1,1},		/* bus 1, device id 1, INTA */
-      {1,1,0x5,22,0,0,1,1},		/* bus 1, device id 1, INTB */
-      {1,1,0x6,21,0,0,1,1},		/* bus 1, device id 1, INTC */
-      {1,1,0x7,20,0,0,1,1},		/* bus 1, device id 1, INTD */
-
-      {1,1,0x8,27,0,0,1,1},		/* bus 1, device id 2, INTA */
-      {1,1,0x9,26,0,0,1,1},		/* bus 1, device id 2, INTB */
-      {1,1,0xa,25,0,0,1,1},		/* bus 1, device id 2, INTC */
-      {1,1,0xb,24,0,0,1,1},		/* bus 1, device id 2, INTD */
-
-      {1,1,0xc,31,0,0,1,1},		/* bus 1, device id 3, INTA */
-      {1,1,0xd,30,0,0,1,1},		/* bus 1, device id 3, INTB */
-      {1,1,0xe,29,0,0,1,1},		/* bus 1, device id 3, INTC */
-      {1,1,0xf,28,0,0,1,1},		/* bus 1, device id 3, INTD */
-
-      {1,0,0x4,35,0,0,1,1},		/* bus 0, device id 1, INTA */
-      {1,0,0x5,34,0,0,1,1},		/* bus 0, device id 1, INTB */
-      {1,0,0x6,33,0,0,1,1},		/* bus 0, device id 1, INTC */
-      {1,0,0x7,32,0,0,1,1},		/* bus 0, device id 1, INTD */
-
-      {1,0,0x8,39,0,0,1,1},		/* bus 0, device id 2, INTA */
-      {1,0,0x9,38,0,0,1,1},		/* bus 0, device id 2, INTB */
-      {1,0,0xa,37,0,0,1,1},		/* bus 0, device id 2, INTC */
-      {1,0,0xb,36,0,0,1,1},		/* bus 0, device id 2, INTD */
-
-      {1,0,0x10,43,0,0,1,1},		/* bus 0, device id 4, INTA */
-      {1,0,0x11,42,0,0,1,1},		/* bus 0, device id 4, INTB */
-      {1,0,0x12,41,0,0,1,1},		/* bus 0, device id 4, INTC */
-      {1,0,0x13,40,0,0,1,1},		/* bus 0, device id 4, INTD */
-
-      {1,0,0x14,17,0,0,1,1},		/* bus 0, device id 5, INTA */
-      {1,0,0x18,18,0,0,1,1},		/* bus 0, device id 6, INTA */
-      {1,0,0x1c,19,0,0,1,1},		/* bus 0, device id 7, INTA */
-#endif
-      {0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff},
-};
-
-int
-iosapic_get_PCI_irq_vector(int bus, int slot, int pci_pin)
-{
-	int     i = -1;
-
-	while (intr_routing[++i].srcbus != 0xff) {
-		if (intr_routing[i].srcbus == BUS_PCI) {
-			if ((intr_routing[i].srcbusirq == ((slot << 2) | pci_pin)) 
-			    && (intr_routing[i].srcbusno == bus)) {
-				return(intr_routing[i].iosapic_pin);
-			}
-		}
-	}
-	return -1;
-}
-
-#else /* CONFIG_IA64_IRQ_ACPI */
-
 /*
  * find the IRQ in the IOSAPIC map for the PCI device on bus/slot/pin
  */
 int
-iosapic_get_PCI_irq_vector(int bus, int slot, int pci_pin)
+iosapic_get_PCI_irq_vector (int bus, int slot, int pci_pin)
 {
-	int	i;
+	int i;
 
 	for (i = 0; i < NR_IRQS; i++) {
 		if ((iosapic_bustype(i) == BUS_PCI) &&
@@ -201,17 +52,15 @@
 			return i;
 		}
 	}
-
 	return -1;
 }
-#endif /* !CONFIG_IA64_IRQ_ACPI */
 
 static void
 set_rte (unsigned long iosapic_addr, int entry, int pol, int trigger, int delivery,
 	 long dest, int vector)
 {
-	int low32;
-	int high32;
+	u32 low32;
+	u32 high32;
 
 	low32 = ((pol << IO_SAPIC_POLARITY_SHIFT) |
 		 (trigger << IO_SAPIC_TRIGGER_SHIFT) |
@@ -221,81 +70,137 @@
 	/* dest contains both id and eid */
 	high32 = (dest << IO_SAPIC_DEST_SHIFT);	
 
-	/*
-	 * program the rte 
-	 */
 	writel(IO_SAPIC_RTE_HIGH(entry), iosapic_addr + IO_SAPIC_REG_SELECT);
 	writel(high32, iosapic_addr + IO_SAPIC_WINDOW);
 	writel(IO_SAPIC_RTE_LOW(entry), iosapic_addr + IO_SAPIC_REG_SELECT);
 	writel(low32, iosapic_addr + IO_SAPIC_WINDOW);
 }
 
+static void
+nop (unsigned int irq)
+{
+	/* do nothing... */
+}
 
 static void 
-enable_pin (unsigned int pin, unsigned long iosapic_addr)
+mask_irq (unsigned int irq)
 {
-        int low32;
+	unsigned long flags, iosapic_addr = iosapic_addr(irq);
+	u32 low32;
 
-        writel(IO_SAPIC_RTE_LOW(pin), iosapic_addr + IO_SAPIC_REG_SELECT);
-        low32 = readl(iosapic_addr + IO_SAPIC_WINDOW);
+	spin_lock_irqsave(&iosapic_lock, flags);
+	{
+		writel(IO_SAPIC_RTE_LOW(iosapic_pin(irq)), iosapic_addr + IO_SAPIC_REG_SELECT);
+		low32 = readl(iosapic_addr + IO_SAPIC_WINDOW);
 
-        low32 &= ~(1 << IO_SAPIC_MASK_SHIFT);    /* Zero only the mask bit */
-        writel(low32, iosapic_addr + IO_SAPIC_WINDOW);
+		low32 |= (1 << IO_SAPIC_MASK_SHIFT);    /* Zero only the mask bit */
+		writel(low32, iosapic_addr + IO_SAPIC_WINDOW);
+	}
+	spin_unlock_irqrestore(&iosapic_lock, flags);
 }
 
-
 static void 
-disable_pin (unsigned int pin, unsigned long iosapic_addr)
+unmask_irq (unsigned int irq)
 {
-        int low32;
+	unsigned long flags, iosapic_addr = iosapic_addr(irq);
+	u32 low32;
 
-        writel(IO_SAPIC_RTE_LOW(pin), iosapic_addr + IO_SAPIC_REG_SELECT);
-        low32 = readl(iosapic_addr + IO_SAPIC_WINDOW);
+	spin_lock_irqsave(&iosapic_lock, flags);
+	{
+		writel(IO_SAPIC_RTE_LOW(iosapic_pin(irq)), iosapic_addr + IO_SAPIC_REG_SELECT);
+		low32 = readl(iosapic_addr + IO_SAPIC_WINDOW);
 
-        low32 |= (1 << IO_SAPIC_MASK_SHIFT);     /* Set only the mask bit */
-        writel(low32, iosapic_addr + IO_SAPIC_WINDOW);
+		low32 &= ~(1 << IO_SAPIC_MASK_SHIFT);    /* Zero only the mask bit */
+		writel(low32, iosapic_addr + IO_SAPIC_WINDOW);
+	}
+	spin_unlock_irqrestore(&iosapic_lock, flags);
 }
 
-#define iosapic_shutdown_irq	iosapic_disable_irq
 
-static unsigned int
-iosapic_startup_irq (unsigned int irq)
+static void
+iosapic_set_affinity (unsigned int irq, unsigned long mask)
 {
-	int pin;
+	printk("iosapic_set_affinity: not implemented yet\n");
+}
+
+/*
+ * Handlers for level-triggered interrupts.
+ */
 
-	pin = iosapic_pin(irq);
-	if (pin < 0)
-		/* happens during irq auto probing... */
-		return 0;
-	set_rte(iosapic_addr(irq), pin, iosapic_polarity(irq), iosapic_trigger(irq), 
-		iosapic_dmode(irq), (ia64_get_lid() >> 16) & 0xffff, irq);
-	enable_pin(pin, iosapic_addr(irq));
+static unsigned int
+iosapic_startup_level_irq (unsigned int irq)
+{
+	unmask_irq(irq);
 	return 0;
 }
 
 static void
-iosapic_enable_irq (unsigned int irq)
+iosapic_end_level_irq (unsigned int irq)
 {
-	int pin = iosapic_pin(irq);
+	writel(irq, iosapic_addr(irq) + IO_SAPIC_EOI);
+}
+
+#define iosapic_shutdown_level_irq	mask_irq
+#define iosapic_enable_level_irq	unmask_irq
+#define iosapic_disable_level_irq	mask_irq
+#define iosapic_ack_level_irq		nop
+
+struct hw_interrupt_type irq_type_iosapic_level = {
+	typename:	"IO-SAPIC-level",
+	startup:	iosapic_startup_level_irq,
+	shutdown:	iosapic_shutdown_level_irq,
+	enable:		iosapic_enable_level_irq,
+	disable:	iosapic_disable_level_irq,
+	ack:		iosapic_ack_level_irq,
+	end:		iosapic_end_level_irq,
+	set_affinity:	iosapic_set_affinity
+};
+
+/*
+ * Handlers for edge-triggered interrupts.
+ */
 
-	if (pin < 0)
-		/* happens during irq auto probing... */
-		return;
-	enable_pin(pin, iosapic_addr(irq));
+static unsigned int
+iosapic_startup_edge_irq (unsigned int irq)
+{
+	unmask_irq(irq);
+	/*
+	 * IOSAPIC simply drops interrupts pended while the
+	 * corresponding pin was masked, so we can't know if an
+	 * interrupt is pending already.  Let's hope not...
+	 */
+	return 0;
 }
 
 static void
-iosapic_disable_irq (unsigned int irq)
+iosapic_ack_edge_irq (unsigned int irq)
 {
-	int pin = iosapic_pin(irq);
-
-	if (pin < 0)
-		return;
-	disable_pin(pin, iosapic_addr(irq));
+	/*
+	 * Once we have recorded IRQ_PENDING already, we can mask the
+	 * interrupt for real. This prevents IRQ storms from unhandled
+	 * devices.
+	 */
+	if ((irq_desc[irq].status & (IRQ_PENDING | IRQ_DISABLED)) == (IRQ_PENDING | IRQ_DISABLED))
+		mask_irq(irq);
 }
 
+#define iosapic_enable_edge_irq		unmask_irq
+#define iosapic_disable_edge_irq	nop
+#define iosapic_end_edge_irq		nop
+
+struct hw_interrupt_type irq_type_iosapic_edge = {
+	typename:	"IO-SAPIC-edge",
+	startup:	iosapic_startup_edge_irq,
+	shutdown:	iosapic_disable_edge_irq,
+	enable:		iosapic_enable_edge_irq,
+	disable:	iosapic_disable_edge_irq,
+	ack:		iosapic_ack_edge_irq,
+	end:		iosapic_end_edge_irq,
+	set_affinity:	iosapic_set_affinity
+};
+
 unsigned int
-iosapic_version(unsigned long base_addr) 
+iosapic_version (unsigned long base_addr) 
 {
 	/*
 	 * IOSAPIC Version Register return 32 bit structure like:
@@ -310,99 +215,19 @@
 	return readl(IO_SAPIC_WINDOW + base_addr);
 }
 
-static void
-iosapic_ack_irq (unsigned int irq)
-{
-}
-
-static void
-iosapic_end_irq (unsigned int irq)
-{
-	if (iosapic_trigger(irq) == IO_SAPIC_LEVEL)	/* ACK Level trigger interrupts */
-		writel(irq, iosapic_addr(irq) + IO_SAPIC_EOI);
-}
-
-static void
-iosapic_set_affinity (unsigned int irq, unsigned long mask)
-{
-	printk("iosapic_set_affinity: not implemented yet\n");
-}
-
 void
 iosapic_init (unsigned long address)
 {
-	int	i;
-#ifdef CONFIG_IA64_IRQ_ACPI
+	struct hw_interrupt_type *irq_type;
 	struct pci_vector_struct *vectors;
-	int     irq;
-#else 
-	int     vector;
-#endif
+	int i, irq;
 
-	/*
-	 * Disable the compatibility mode interrupts (8259 style), needs IN/OUT support
-	 * enabled.
-	 */
-	outb(0xff, 0xA1);
-	outb(0xff, 0x21);
-
-#if defined(CONFIG_IA64_SOFTSDV_HACKS)
-	memset(iosapic_vector, 0x0, sizeof(iosapic_vector));
-	for (i = 0; i < NR_IRQS; i++) {
-		iosapic_pin(i) = 0xff;
-		iosapic_addr(i) = (unsigned long) ioremap(address, 0);
-	}
-	/* XXX this should come from systab or some such: */
-# if 0
-	/* this doesn't look right --davidm 00/03/07 */
-	iosapic_pin(TIMER_IRQ) = 5;	/* System Clock Interrupt */
-# endif
-	iosapic_pin(0x40) = 3;	/* Keyboard */
-	iosapic_pin(0x92) = 9;	/* COM1 Serial Port */
-	iosapic_pin(0x80) = 4;	/* Periodic Interrupt */
-	iosapic_pin(0xc0) = 2;	/* Mouse */
-	iosapic_pin(0xe0) = 1;	/* IDE Disk */
-	iosapic_pin(0xf0) = 6;	/* E-IDE CDROM */
-	iosapic_pin(0xa0) = 10;	/* Real PCI Interrupt */
-#elif !defined(CONFIG_IA64_IRQ_ACPI)
-	/*
-	 * For systems where the routing info in ACPI is
-	 * unavailable/wrong, use the intr_routing information to
-	 * initialize the iosapic array
-	 */
-	i = -1;
-	while (intr_routing[++i].srcbus != 0xff) {
-		if (intr_routing[i].srcbus == BUS_ISA) {
-			vector = isa_irq_to_vector(intr_routing[i].srcbusirq);
-		} else if (intr_routing[i].srcbus == BUS_PCI) {
-			vector = intr_routing[i].iosapic_pin;
-		} else {
-			printk("unknown bus type %d for intr_routing[%d]\n",
-                               intr_routing[i].srcbus, i);
-			continue;
-		}
-		iosapic_pin(vector) = intr_routing[i].iosapic_pin;
-		iosapic_dmode(vector) = intr_routing[i].mode;
-		iosapic_polarity(vector) = intr_routing[i].polarity;
-		iosapic_trigger(vector) = intr_routing[i].trigger;
-# ifdef DEBUG_IRQ_ROUTING
-		printk("irq[0x%x(0x%x)]:0x%x, %d, %d, %d\n", vector, intr_routing[i].srcbusirq,
-		       iosapic_pin(vector), iosapic_dmode(vector), iosapic_polarity(vector),
-		       iosapic_trigger(vector));
-# endif
-	}
-#else /* !defined(CONFIG_IA64_SOFTSDV_HACKS) && defined(CONFIG_IA64_IRQ_ACPI) */
 	/* 
-	 * Map the legacy ISA devices into the IOAPIC data; We'll override these
-	 * later with data from the ACPI Interrupt Source Override table.
-	 *
-	 * Huh, the Lion w/ FPSWA firmware has entries for _all_ of the legacy IRQs, 
-	 * including those that are not different from PC/AT standard.  I don't know
-	 * if this is a bug in the other firmware or not.  I'm going to leave this code 
-	 * here, so that this works on BigSur but will go ask Intel. --wfd 2000-Jan-19
-	 *
+	 * Map the legacy ISA devices into the IOSAPIC data.  Some of
+	 * these may get reprogrammed later on with data from the ACPI
+	 * Interrupt Source Override table.
 	 */
-	for (i =0 ; i < 16; i++) {
+	for (i = 0; i < 16; i++) {
 		irq = isa_irq_to_vector(i);
 		iosapic_pin(irq) = i; 
 		iosapic_bus(irq) = BUS_ISA;
@@ -445,41 +270,37 @@
 		       irq, iosapic_pin(irq));
 #endif
 	}
-#endif /* !CONFIG_IA64_IRQ_ACPI */
-}
 
-struct hw_interrupt_type irq_type_iosapic = {
-	typename:	"IOSAPIC",
-	startup:	iosapic_startup_irq,
-	shutdown:	iosapic_shutdown_irq,
-	enable:		iosapic_enable_irq,
-	disable:	iosapic_disable_irq,
-	ack:		iosapic_ack_irq,
-	end:		iosapic_end_irq,
-	set_affinity:	iosapic_set_affinity
-};
+	for (i = 0; i < NR_IRQS; ++i) {
+		if (iosapic_pin(i) != -1) {
+			if (iosapic_trigger(i) == IO_SAPIC_LEVEL)
+			  irq_type = &irq_type_iosapic_level;
+			else
+			  irq_type = &irq_type_iosapic_edge;
+			if (irq_desc[i].handler != &no_irq_type)
+				printk("dig_irq_init: warning: changing vector %d from %s to %s\n",
+				       i, irq_desc[i].handler->typename,
+				       irq_type->typename);
+			irq_desc[i].handler = irq_type;
+
+			/* program the IOSAPIC routing table: */
+			set_rte(iosapic_addr(i), iosapic_pin(i), iosapic_polarity(i),
+				iosapic_trigger(i), iosapic_dmode(i),
+				(ia64_get_lid() >> 16) & 0xffff, i);
+		}
+	}
+}
 
 void
 dig_irq_init (void)
 {
-	int i;
-
 	/*
-	 * Claim all non-legacy irq vectors as ours unless they're
-	 * claimed by someone else already (e.g., timer or IPI are
-	 * handled internally).
+	 * Disable the compatibility mode interrupts (8259 style), needs IN/OUT support
+	 * enabled.
 	 */
-#if 0
-	for (i = IA64_MIN_VECTORED_IRQ; i <= IA64_MAX_VECTORED_IRQ; ++i) {
-		if (irq_desc[i].handler == &no_irq_type)
-			irq_desc[i].handler = &irq_type_iosapic;
-	}
-#else
-	for (i = 0; i <= IA64_MAX_VECTORED_IRQ; ++i) {
-		if (irq_desc[i].handler == &no_irq_type)
-			irq_desc[i].handler = &irq_type_iosapic;
-	}
-#endif
+	outb(0xff, 0xA1);
+	outb(0xff, 0x21);
+
 #ifndef CONFIG_IA64_DIG
 	iosapic_init(IO_SAPIC_DEFAULT_ADDR);
 #endif

FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)