vserver 1.9.5.x5
[linux-2.6.git] / arch / ia64 / kernel / iosapic.c
index 9db13ac..111dad9 100644 (file)
@@ -32,6 +32,8 @@
  * 03/02/19    B. Helgaas      Make pcat_compat system-wide, not per-IOSAPIC.
  *                             Remove iosapic_address & gsi_base from external interfaces.
  *                             Rationalize __init/__devinit attributes.
+ * 04/12/04 Ashok Raj  <ashok.raj@intel.com> Intel Corporation 2004
+ *                             Updated to work with irq migration necessary for CPU Hotplug
  */
 /*
  * Here is what the interrupt logic between a PCI device and the kernel looks like:
 #define DBG(fmt...)
 #endif
 
-static spinlock_t iosapic_lock = SPIN_LOCK_UNLOCKED;
+static DEFINE_SPINLOCK(iosapic_lock);
 
 /* These tables map IA-64 vectors to the IOSAPIC pin that generates this vector. */
 
 static struct iosapic_intr_info {
-       char            *addr;          /* base address of IOSAPIC */
+       char __iomem    *addr;          /* base address of IOSAPIC */
        u32             low32;          /* current value of low word of Redirection table entry */
        unsigned int    gsi_base;       /* first GSI assigned to this IOSAPIC */
        char            rte_index;      /* IOSAPIC RTE index (-1 => not an IOSAPIC interrupt) */
        unsigned char   dmode   : 3;    /* delivery mode (see iosapic.h) */
        unsigned char   polarity: 1;    /* interrupt polarity (see iosapic.h) */
        unsigned char   trigger : 1;    /* trigger mode (see iosapic.h) */
+       int             refcnt;         /* reference counter */
 } iosapic_intr_info[IA64_NUM_VECTORS];
 
 static struct iosapic {
-       char            *addr;          /* base address of IOSAPIC */
+       char __iomem    *addr;          /* base address of IOSAPIC */
        unsigned int    gsi_base;       /* first GSI assigned to this IOSAPIC */
        unsigned short  num_rte;        /* number of RTE in this IOSAPIC */
+#ifdef CONFIG_NUMA
+       unsigned short  node;           /* numa node association via pxm */
+#endif
 } iosapic_lists[NR_IOSAPICS];
 
 static int num_iosapic;
@@ -172,9 +178,9 @@ gsi_to_irq (unsigned int gsi)
 static void
 set_rte (unsigned int vector, unsigned int dest, int mask)
 {
-       unsigned long pol, trigger, dmode, flags;
+       unsigned long pol, trigger, dmode;
        u32 low32, high32;
-       char *addr;
+       char __iomem *addr;
        int rte_index;
        char redir;
 
@@ -188,8 +194,10 @@ set_rte (unsigned int vector, unsigned int dest, int mask)
        pol     = iosapic_intr_info[vector].polarity;
        trigger = iosapic_intr_info[vector].trigger;
        dmode   = iosapic_intr_info[vector].dmode;
+       vector &= (~IA64_IRQ_REDIRECTED);
 
        redir = (dmode == IOSAPIC_LOWEST_PRIORITY) ? 1 : 0;
+
 #ifdef CONFIG_SMP
        {
                unsigned int irq;
@@ -211,15 +219,9 @@ set_rte (unsigned int vector, unsigned int dest, int mask)
        /* dest contains both id and eid */
        high32 = (dest << IOSAPIC_DEST_SHIFT);
 
-       spin_lock_irqsave(&iosapic_lock, flags);
-       {
-               writel(IOSAPIC_RTE_HIGH(rte_index), addr + IOSAPIC_REG_SELECT);
-               writel(high32, addr + IOSAPIC_WINDOW);
-               writel(IOSAPIC_RTE_LOW(rte_index), addr + IOSAPIC_REG_SELECT);
-               writel(low32, addr + IOSAPIC_WINDOW);
-               iosapic_intr_info[vector].low32 = low32;
-       }
-       spin_unlock_irqrestore(&iosapic_lock, flags);
+       iosapic_write(addr, IOSAPIC_RTE_HIGH(rte_index), high32);
+       iosapic_write(addr, IOSAPIC_RTE_LOW(rte_index), low32);
+       iosapic_intr_info[vector].low32 = low32;
 }
 
 static void
@@ -232,7 +234,7 @@ static void
 mask_irq (unsigned int irq)
 {
        unsigned long flags;
-       char *addr;
+       char __iomem *addr;
        u32 low32;
        int rte_index;
        ia64_vector vec = irq_to_vector(irq);
@@ -245,12 +247,9 @@ mask_irq (unsigned int irq)
 
        spin_lock_irqsave(&iosapic_lock, flags);
        {
-               writel(IOSAPIC_RTE_LOW(rte_index), addr + IOSAPIC_REG_SELECT);
-
                /* set only the mask bit */
                low32 = iosapic_intr_info[vec].low32 |= IOSAPIC_MASK;
-
-               writel(low32, addr + IOSAPIC_WINDOW);
+               iosapic_write(addr, IOSAPIC_RTE_LOW(rte_index), low32);
        }
        spin_unlock_irqrestore(&iosapic_lock, flags);
 }
@@ -259,7 +258,7 @@ static void
 unmask_irq (unsigned int irq)
 {
        unsigned long flags;
-       char *addr;
+       char __iomem *addr;
        u32 low32;
        int rte_index;
        ia64_vector vec = irq_to_vector(irq);
@@ -271,9 +270,8 @@ unmask_irq (unsigned int irq)
 
        spin_lock_irqsave(&iosapic_lock, flags);
        {
-               writel(IOSAPIC_RTE_LOW(rte_index), addr + IOSAPIC_REG_SELECT);
                low32 = iosapic_intr_info[vec].low32 &= ~IOSAPIC_MASK;
-               writel(low32, addr + IOSAPIC_WINDOW);
+               iosapic_write(addr, IOSAPIC_RTE_LOW(rte_index), low32);
        }
        spin_unlock_irqrestore(&iosapic_lock, flags);
 }
@@ -286,7 +284,7 @@ iosapic_set_affinity (unsigned int irq, cpumask_t mask)
        unsigned long flags;
        u32 high32, low32;
        int dest, rte_index;
-       char *addr;
+       char __iomem *addr;
        int redir = (irq & IA64_IRQ_REDIRECTED) ? 1 : 0;
        ia64_vector vec;
 
@@ -311,9 +309,8 @@ iosapic_set_affinity (unsigned int irq, cpumask_t mask)
 
        spin_lock_irqsave(&iosapic_lock, flags);
        {
-               /* get current delivery mode by reading the low32 */
-               writel(IOSAPIC_RTE_LOW(rte_index), addr + IOSAPIC_REG_SELECT);
                low32 = iosapic_intr_info[vec].low32 & ~(7 << IOSAPIC_DELIVERY_SHIFT);
+
                if (redir)
                        /* change delivery mode to lowest priority */
                        low32 |= (IOSAPIC_LOWEST_PRIORITY << IOSAPIC_DELIVERY_SHIFT);
@@ -322,10 +319,8 @@ iosapic_set_affinity (unsigned int irq, cpumask_t mask)
                        low32 |= (IOSAPIC_FIXED << IOSAPIC_DELIVERY_SHIFT);
 
                iosapic_intr_info[vec].low32 = low32;
-               writel(IOSAPIC_RTE_HIGH(rte_index), addr + IOSAPIC_REG_SELECT);
-               writel(high32, addr + IOSAPIC_WINDOW);
-               writel(IOSAPIC_RTE_LOW(rte_index), addr + IOSAPIC_REG_SELECT);
-               writel(low32, addr + IOSAPIC_WINDOW);
+               iosapic_write(addr, IOSAPIC_RTE_HIGH(rte_index), high32);
+               iosapic_write(addr, IOSAPIC_RTE_LOW(rte_index), low32);
        }
        spin_unlock_irqrestore(&iosapic_lock, flags);
 #endif
@@ -347,7 +342,8 @@ iosapic_end_level_irq (unsigned int irq)
 {
        ia64_vector vec = irq_to_vector(irq);
 
-       writel(vec, iosapic_intr_info[vec].addr + IOSAPIC_EOI);
+       move_irq(irq);
+       iosapic_eoi(iosapic_intr_info[vec].addr, vec);
 }
 
 #define iosapic_shutdown_level_irq     mask_irq
@@ -386,6 +382,8 @@ static void
 iosapic_ack_edge_irq (unsigned int irq)
 {
        irq_desc_t *idesc = irq_descp(irq);
+
+       move_irq(irq);
        /*
         * Once we have recorded IRQ_PENDING already, we can mask the
         * interrupt for real. This prevents IRQ storms from unhandled
@@ -411,7 +409,7 @@ struct hw_interrupt_type irq_type_iosapic_edge = {
 };
 
 unsigned int
-iosapic_version (char *addr)
+iosapic_version (char __iomem *addr)
 {
        /*
         * IOSAPIC Version Register return 32 bit structure like:
@@ -422,8 +420,7 @@ iosapic_version (char *addr)
         *      unsigned int reserved2 : 8;
         * }
         */
-       writel(IOSAPIC_VERSION, addr + IOSAPIC_REG_SELECT);
-       return readl(IOSAPIC_WINDOW + addr);
+       return iosapic_read(addr, IOSAPIC_VERSION);
 }
 
 /*
@@ -457,11 +454,11 @@ register_intr (unsigned int gsi, int vector, unsigned char delivery,
        int rte_index;
        int index;
        unsigned long gsi_base;
-       char *iosapic_address;
+       void __iomem *iosapic_address;
 
        index = find_iosapic(gsi);
        if (index < 0) {
-               printk(KERN_WARNING "%s: No IOSAPIC for GSI 0x%x\n", __FUNCTION__, gsi);
+               printk(KERN_WARNING "%s: No IOSAPIC for GSI %u\n", __FUNCTION__, gsi);
                return;
        }
 
@@ -475,6 +472,7 @@ register_intr (unsigned int gsi, int vector, unsigned char delivery,
        iosapic_intr_info[vector].addr     = iosapic_address;
        iosapic_intr_info[vector].gsi_base = gsi_base;
        iosapic_intr_info[vector].trigger  = trigger;
+       iosapic_intr_info[vector].refcnt++;
 
        if (trigger == IOSAPIC_EDGE)
                irq_type = &irq_type_iosapic_edge;
@@ -490,6 +488,75 @@ register_intr (unsigned int gsi, int vector, unsigned char delivery,
        }
 }
 
+static unsigned int
+get_target_cpu (unsigned int gsi, int vector)
+{
+#ifdef CONFIG_SMP
+       static int cpu = -1;
+
+       /*
+        * If the platform supports redirection via XTP, let it
+        * distribute interrupts.
+        */
+       if (smp_int_redirect & SMP_IRQ_REDIRECTION)
+               return hard_smp_processor_id();
+
+       /*
+        * Some interrupts (ACPI SCI, for instance) are registered
+        * before the BSP is marked as online.
+        */
+       if (!cpu_online(smp_processor_id()))
+               return hard_smp_processor_id();
+
+#ifdef CONFIG_NUMA
+       {
+               int num_cpus, cpu_index, iosapic_index, numa_cpu, i = 0;
+               cpumask_t cpu_mask;
+
+               iosapic_index = find_iosapic(gsi);
+               if (iosapic_index < 0 ||
+                   iosapic_lists[iosapic_index].node == MAX_NUMNODES)
+                       goto skip_numa_setup;
+
+               cpu_mask = node_to_cpumask(iosapic_lists[iosapic_index].node);
+
+               for_each_cpu_mask(numa_cpu, cpu_mask) {
+                       if (!cpu_online(numa_cpu))
+                               cpu_clear(numa_cpu, cpu_mask);
+               }
+
+               num_cpus = cpus_weight(cpu_mask);
+
+               if (!num_cpus)
+                       goto skip_numa_setup;
+
+               /* Use vector assigment to distribute across cpus in node */
+               cpu_index = vector % num_cpus;
+
+               for (numa_cpu = first_cpu(cpu_mask) ; i < cpu_index ; i++)
+                       numa_cpu = next_cpu(numa_cpu, cpu_mask);
+
+               if (numa_cpu != NR_CPUS)
+                       return cpu_physical_id(numa_cpu);
+       }
+skip_numa_setup:
+#endif
+       /*
+        * Otherwise, round-robin interrupt vectors across all the
+        * processors.  (It'd be nice if we could be smarter in the
+        * case of NUMA.)
+        */
+       do {
+               if (++cpu >= NR_CPUS)
+                       cpu = 0;
+       } while (!cpu_online(cpu));
+
+       return cpu_physical_id(cpu);
+#else
+       return hard_smp_processor_id();
+#endif
+}
+
 /*
  * ACPI can describe IOSAPIC interrupts via static tables and namespace
  * methods.  This provides an interface to register those interrupts and
@@ -500,24 +567,118 @@ iosapic_register_intr (unsigned int gsi,
                       unsigned long polarity, unsigned long trigger)
 {
        int vector;
-       unsigned int dest = (ia64_getreg(_IA64_REG_CR_LID) >> 16) & 0xffff;
+       unsigned int dest;
+       unsigned long flags;
+
+       /*
+        * If this GSI has already been registered (i.e., it's a
+        * shared interrupt, or we lost a race to register it),
+        * don't touch the RTE.
+        */
+       spin_lock_irqsave(&iosapic_lock, flags);
+       {
+               vector = gsi_to_vector(gsi);
+               if (vector > 0) {
+                       iosapic_intr_info[vector].refcnt++;
+                       spin_unlock_irqrestore(&iosapic_lock, flags);
+                       return vector;
+               }
 
-       vector = gsi_to_vector(gsi);
-       if (vector < 0)
                vector = assign_irq_vector(AUTO_ASSIGN);
+               dest = get_target_cpu(gsi, vector);
+               register_intr(gsi, vector, IOSAPIC_LOWEST_PRIORITY,
+                       polarity, trigger);
 
-       register_intr(gsi, vector, IOSAPIC_LOWEST_PRIORITY,
-                     polarity, trigger);
+               set_rte(vector, dest, 1);
+       }
+       spin_unlock_irqrestore(&iosapic_lock, flags);
 
-       printk(KERN_INFO "GSI 0x%x(%s,%s) -> CPU 0x%04x vector %d\n",
-              gsi, (polarity == IOSAPIC_POL_HIGH ? "high" : "low"),
-              (trigger == IOSAPIC_EDGE ? "edge" : "level"), dest, vector);
+       printk(KERN_INFO "GSI %u (%s, %s) -> CPU %d (0x%04x) vector %d\n",
+              gsi, (trigger == IOSAPIC_EDGE ? "edge" : "level"),
+              (polarity == IOSAPIC_POL_HIGH ? "high" : "low"),
+              cpu_logical_id(dest), dest, vector);
 
-       /* program the IOSAPIC routing table */
-       set_rte(vector, dest, 0);
        return vector;
 }
 
+#ifdef CONFIG_ACPI_DEALLOCATE_IRQ
+void
+iosapic_unregister_intr (unsigned int gsi)
+{
+       unsigned long flags;
+       int irq, vector;
+       irq_desc_t *idesc;
+       int rte_index;
+       unsigned long trigger, polarity;
+
+       /*
+        * If the irq associated with the gsi is not found,
+        * iosapic_unregister_intr() is unbalanced. We need to check
+        * this again after getting locks.
+        */
+       irq = gsi_to_irq(gsi);
+       if (irq < 0) {
+               printk(KERN_ERR "iosapic_unregister_intr(%u) unbalanced\n", gsi);
+               WARN_ON(1);
+               return;
+       }
+       vector = irq_to_vector(irq);
+
+       idesc = irq_descp(irq);
+       spin_lock_irqsave(&idesc->lock, flags);
+       spin_lock(&iosapic_lock);
+       {
+               rte_index = iosapic_intr_info[vector].rte_index;
+               if (rte_index < 0) {
+                       spin_unlock(&iosapic_lock);
+                       spin_unlock_irqrestore(&idesc->lock, flags);
+                       printk(KERN_ERR "iosapic_unregister_intr(%u) unbalanced\n", gsi);
+                       WARN_ON(1);
+                       return;
+               }
+
+               if (--iosapic_intr_info[vector].refcnt > 0) {
+                       spin_unlock(&iosapic_lock);
+                       spin_unlock_irqrestore(&idesc->lock, flags);
+                       return;
+               }
+
+               /*
+                * If interrupt handlers still exist on the irq
+                * associated with the gsi, don't unregister the
+                * interrupt.
+                */
+               if (idesc->action) {
+                       iosapic_intr_info[vector].refcnt++;
+                       spin_unlock(&iosapic_lock);
+                       spin_unlock_irqrestore(&idesc->lock, flags);
+                       printk(KERN_WARNING "Cannot unregister GSI. IRQ %u is still in use.\n", irq);
+                       return;
+               }
+
+               /* Clear the interrupt controller descriptor. */
+               idesc->handler = &no_irq_type;
+
+               trigger  = iosapic_intr_info[vector].trigger;
+               polarity = iosapic_intr_info[vector].polarity;
+
+               /* Clear the interrupt information. */
+               memset(&iosapic_intr_info[vector], 0, sizeof(struct iosapic_intr_info));
+               iosapic_intr_info[vector].rte_index = -1;       /* mark as unused */
+       }
+       spin_unlock(&iosapic_lock);
+       spin_unlock_irqrestore(&idesc->lock, flags);
+
+       /* Free the interrupt vector */
+       free_irq_vector(vector);
+
+       printk(KERN_INFO "GSI %u (%s, %s) -> vector %d unregisterd.\n",
+              gsi, (trigger == IOSAPIC_EDGE ? "edge" : "level"),
+              (polarity == IOSAPIC_POL_HIGH ? "high" : "low"),
+              vector);
+}
+#endif /* CONFIG_ACPI_DEALLOCATE_IRQ */
+
 /*
  * ACPI calls this when it finds an entry for a platform interrupt.
  * Note that the irq_base and IOSAPIC address must be set in iosapic_init().
@@ -527,8 +688,9 @@ iosapic_register_platform_intr (u32 int_type, unsigned int gsi,
                                int iosapic_vector, u16 eid, u16 id,
                                unsigned long polarity, unsigned long trigger)
 {
+       static const char * const name[] = {"unknown", "PMI", "INIT", "CPEI"};
        unsigned char delivery;
-       int vector;
+       int vector, mask = 0;
        unsigned int dest = ((id << 8) | eid) & 0xffff;
 
        switch (int_type) {
@@ -548,21 +710,22 @@ iosapic_register_platform_intr (u32 int_type, unsigned int gsi,
              case ACPI_INTERRUPT_CPEI:
                vector = IA64_CPE_VECTOR;
                delivery = IOSAPIC_LOWEST_PRIORITY;
+               mask = 1;
                break;
              default:
-               printk(KERN_ERR "iosapic_register_platform_irq(): invalid int type\n");
+               printk(KERN_ERR "iosapic_register_platform_irq(): invalid int type 0x%x\n", int_type);
                return -1;
        }
 
-       register_intr(gsi, vector, delivery, polarity,
-                     trigger);
+       register_intr(gsi, vector, delivery, polarity, trigger);
 
-       printk(KERN_INFO "PLATFORM int 0x%x: GSI 0x%x(%s,%s) -> CPU 0x%04x vector %d\n",
-              int_type, gsi, (polarity == IOSAPIC_POL_HIGH ? "high" : "low"),
-              (trigger == IOSAPIC_EDGE ? "edge" : "level"), dest, vector);
+       printk(KERN_INFO "PLATFORM int %s (0x%x): GSI %u (%s, %s) -> CPU %d (0x%04x) vector %d\n",
+              int_type < ARRAY_SIZE(name) ? name[int_type] : "unknown",
+              int_type, gsi, (trigger == IOSAPIC_EDGE ? "edge" : "level"),
+              (polarity == IOSAPIC_POL_HIGH ? "high" : "low"),
+              cpu_logical_id(dest), dest, vector);
 
-       /* program the IOSAPIC routing table */
-       set_rte(vector, dest, 0);
+       set_rte(vector, dest, mask);
        return vector;
 }
 
@@ -577,18 +740,18 @@ iosapic_override_isa_irq (unsigned int isa_irq, unsigned int gsi,
                          unsigned long trigger)
 {
        int vector;
-       unsigned int dest = (ia64_getreg(_IA64_REG_CR_LID) >> 16) & 0xffff;
+       unsigned int dest = hard_smp_processor_id();
 
        vector = isa_irq_to_vector(isa_irq);
 
        register_intr(gsi, vector, IOSAPIC_LOWEST_PRIORITY, polarity, trigger);
 
-       DBG("ISA: IRQ %u -> GSI 0x%x (%s,%s) -> CPU 0x%04x vector %d\n",
-           isa_irq, gsi, polarity == IOSAPIC_POL_HIGH ? "high" : "low",
-           trigger == IOSAPIC_EDGE ? "edge" : "level", dest, vector);
+       DBG("ISA: IRQ %u -> GSI %u (%s,%s) -> CPU %d (0x%04x) vector %d\n",
+           isa_irq, gsi, trigger == IOSAPIC_EDGE ? "edge" : "level",
+           polarity == IOSAPIC_POL_HIGH ? "high" : "low",
+           cpu_logical_id(dest), dest, vector);
 
-       /* program the IOSAPIC routing table */
-       set_rte(vector, dest, 0);
+       set_rte(vector, dest, 1);
 }
 
 void __init
@@ -616,7 +779,7 @@ iosapic_init (unsigned long phys_addr, unsigned int gsi_base)
 {
        int num_rte;
        unsigned int isa_irq, ver;
-       char *addr;
+       char __iomem *addr;
 
        addr = ioremap(phys_addr, 0);
        ver = iosapic_version(addr);
@@ -631,6 +794,9 @@ iosapic_init (unsigned long phys_addr, unsigned int gsi_base)
        iosapic_lists[num_iosapic].addr = addr;
        iosapic_lists[num_iosapic].gsi_base = gsi_base;
        iosapic_lists[num_iosapic].num_rte = num_rte;
+#ifdef CONFIG_NUMA
+       iosapic_lists[num_iosapic].node = MAX_NUMNODES;
+#endif
        num_iosapic++;
 
        if ((gsi_base == 0) && pcat_compat) {
@@ -644,103 +810,19 @@ iosapic_init (unsigned long phys_addr, unsigned int gsi_base)
        }
 }
 
-void
-iosapic_enable_intr (unsigned int vector)
-{
-       unsigned int dest;
-       irq_desc_t *desc;
-
-       /*
-        * In the case of a shared interrupt, do not re-route the vector, and
-        * especially do not mask a running interrupt (startup will not get
-        * called for a shared interrupt).
-        */
-       desc = irq_descp(vector);
-       if (desc->action)
-               return;
-
-#ifdef CONFIG_SMP
-       /*
-        * For platforms that do not support interrupt redirect via the XTP interface, we
-        * can round-robin the PCI device interrupts to the processors
-        */
-       if (!(smp_int_redirect & SMP_IRQ_REDIRECTION)) {
-               static int cpu_index = -1;
-
-               do
-                       if (++cpu_index >= NR_CPUS)
-                               cpu_index = 0;
-               while (!cpu_online(cpu_index));
-
-               dest = cpu_physical_id(cpu_index) & 0xffff;
-       } else {
-               /*
-                * Direct the interrupt vector to the current cpu, platform redirection
-                * will distribute them.
-                */
-               dest = (ia64_getreg(_IA64_REG_CR_LID) >> 16) & 0xffff;
-       }
-#else
-       /* direct the interrupt vector to the running cpu id */
-       dest = (ia64_getreg(_IA64_REG_CR_LID) >> 16) & 0xffff;
-#endif
-       set_rte(vector, dest, 1);
-
-       printk(KERN_INFO "IOSAPIC: vector %d -> CPU 0x%04x, enabled\n",
-              vector, dest);
-}
-
-#ifdef CONFIG_ACPI_PCI
-
+#ifdef CONFIG_NUMA
 void __init
-iosapic_parse_prt (void)
+map_iosapic_to_node(unsigned int gsi_base, int node)
 {
-       struct acpi_prt_entry *entry;
-       struct list_head *node;
-       unsigned int gsi;
-       int vector;
-       char pci_id[16];
-       struct hw_interrupt_type *irq_type = &irq_type_iosapic_level;
-       irq_desc_t *idesc;
-
-       list_for_each(node, &acpi_prt.entries) {
-               entry = list_entry(node, struct acpi_prt_entry, node);
-
-               /* We're only interested in static (non-link) entries.  */
-               if (entry->link.handle)
-                       continue;
-
-               gsi = entry->link.index;
-
-               vector = gsi_to_vector(gsi);
-               if (vector < 0) {
-                       if (find_iosapic(gsi) < 0)
-                               continue;
-
-                       /* allocate a vector for this interrupt line */
-                       if (pcat_compat && (gsi < 16))
-                               vector = isa_irq_to_vector(gsi);
-                       else
-                               /* new GSI; allocate a vector for it */
-                               vector = assign_irq_vector(AUTO_ASSIGN);
-
-                       register_intr(gsi, vector, IOSAPIC_LOWEST_PRIORITY, IOSAPIC_POL_LOW,
-                                     IOSAPIC_LEVEL);
-               }
-               entry->irq = vector;
-               snprintf(pci_id, sizeof(pci_id), "%02x:%02x:%02x[%c]",
-                        entry->id.segment, entry->id.bus, entry->id.device, 'A' + entry->pin);
-
-               /*
-                * If vector was previously initialized to a different
-                * handler, re-initialize.
-                */
-               idesc = irq_descp(vector);
-               if (idesc->handler != irq_type)
-                       register_intr(gsi, vector, IOSAPIC_LOWEST_PRIORITY, IOSAPIC_POL_LOW,
-                                     IOSAPIC_LEVEL);
+       int index;
 
+       index = find_iosapic(gsi_base);
+       if (index < 0) {
+               printk(KERN_WARNING "%s: No IOSAPIC for GSI %u\n",
+                      __FUNCTION__, gsi_base);
+               return;
        }
+       iosapic_lists[index].node = node;
+       return;
 }
-
-#endif /* CONFIG_ACPI */
+#endif