]> err.no Git - linux-2.6/blobdiff - arch/x86/kernel/io_apic_32.c
Merge branch 'linus' into tmp.x86.mpparse.new
[linux-2.6] / arch / x86 / kernel / io_apic_32.c
index 2e01b69a46e0e09bcaa91a1fbeff72e500480c5a..0662817d61bfdd61f189fb7576ada934fdbfbedb 100644 (file)
@@ -72,9 +72,21 @@ int sis_apic_bug = -1;
 int nr_ioapic_registers[MAX_IO_APICS];
 
 /* I/O APIC entries */
-struct mpc_config_ioapic mp_ioapics[MAX_IO_APICS];
+struct mp_config_ioapic mp_ioapics[MAX_IO_APICS];
 int nr_ioapics;
 
+/* MP IRQ source entries */
+struct mp_config_intsrc mp_irqs[MAX_IRQ_SOURCES];
+
+/* # of MP IRQ source entries */
+int mp_irq_entries;
+
+#if defined (CONFIG_MCA) || defined (CONFIG_EISA)
+int mp_bus_id_to_type[MAX_MP_BUSSES];
+#endif
+
+DECLARE_BITMAP(mp_bus_not_pci, MAX_MP_BUSSES);
+
 static int disable_timer_pin_1 __initdata;
 
 /*
@@ -104,7 +116,7 @@ struct io_apic {
 static __attribute_const__ struct io_apic __iomem *io_apic_base(int idx)
 {
        return (void __iomem *) __fix_to_virt(FIX_IO_APIC_BASE_0 + idx)
-               + (mp_ioapics[idx].mpc_apicaddr & ~PAGE_MASK);
+               + (mp_ioapics[idx].mp_apicaddr & ~PAGE_MASK);
 }
 
 static inline unsigned int io_apic_read(unsigned int apic, unsigned int reg)
@@ -795,10 +807,10 @@ static int find_irq_entry(int apic, int pin, int type)
        int i;
 
        for (i = 0; i < mp_irq_entries; i++)
-               if (mp_irqs[i].mpc_irqtype == type &&
-                   (mp_irqs[i].mpc_dstapic == mp_ioapics[apic].mpc_apicid ||
-                    mp_irqs[i].mpc_dstapic == MP_APIC_ALL) &&
-                   mp_irqs[i].mpc_dstirq == pin)
+               if (mp_irqs[i].mp_irqtype == type &&
+                   (mp_irqs[i].mp_dstapic == mp_ioapics[apic].mp_apicid ||
+                    mp_irqs[i].mp_dstapic == MP_APIC_ALL) &&
+                   mp_irqs[i].mp_dstirq == pin)
                        return i;
 
        return -1;
@@ -812,13 +824,13 @@ static int __init find_isa_irq_pin(int irq, int type)
        int i;
 
        for (i = 0; i < mp_irq_entries; i++) {
-               int lbus = mp_irqs[i].mpc_srcbus;
+               int lbus = mp_irqs[i].mp_srcbus;
 
                if (test_bit(lbus, mp_bus_not_pci) &&
-                   (mp_irqs[i].mpc_irqtype == type) &&
-                   (mp_irqs[i].mpc_srcbusirq == irq))
+                   (mp_irqs[i].mp_irqtype == type) &&
+                   (mp_irqs[i].mp_srcbusirq == irq))
 
-                       return mp_irqs[i].mpc_dstirq;
+                       return mp_irqs[i].mp_dstirq;
        }
        return -1;
 }
@@ -828,17 +840,17 @@ static int __init find_isa_irq_apic(int irq, int type)
        int i;
 
        for (i = 0; i < mp_irq_entries; i++) {
-               int lbus = mp_irqs[i].mpc_srcbus;
+               int lbus = mp_irqs[i].mp_srcbus;
 
                if (test_bit(lbus, mp_bus_not_pci) &&
-                   (mp_irqs[i].mpc_irqtype == type) &&
-                   (mp_irqs[i].mpc_srcbusirq == irq))
+                   (mp_irqs[i].mp_irqtype == type) &&
+                   (mp_irqs[i].mp_srcbusirq == irq))
                        break;
        }
        if (i < mp_irq_entries) {
                int apic;
                for(apic = 0; apic < nr_ioapics; apic++) {
-                       if (mp_ioapics[apic].mpc_apicid == mp_irqs[i].mpc_dstapic)
+                       if (mp_ioapics[apic].mp_apicid == mp_irqs[i].mp_dstapic)
                                return apic;
                }
        }
@@ -858,28 +870,28 @@ int IO_APIC_get_PCI_irq_vector(int bus, int slot, int pin)
 
        apic_printk(APIC_DEBUG, "querying PCI -> IRQ mapping bus:%d, "
                "slot:%d, pin:%d.\n", bus, slot, pin);
-       if (mp_bus_id_to_pci_bus[bus] == -1) {
+       if (test_bit(bus, mp_bus_not_pci)) {
                printk(KERN_WARNING "PCI BIOS passed nonexistent PCI bus %d!\n", bus);
                return -1;
        }
        for (i = 0; i < mp_irq_entries; i++) {
-               int lbus = mp_irqs[i].mpc_srcbus;
+               int lbus = mp_irqs[i].mp_srcbus;
 
                for (apic = 0; apic < nr_ioapics; apic++)
-                       if (mp_ioapics[apic].mpc_apicid == mp_irqs[i].mpc_dstapic ||
-                           mp_irqs[i].mpc_dstapic == MP_APIC_ALL)
+                       if (mp_ioapics[apic].mp_apicid == mp_irqs[i].mp_dstapic ||
+                           mp_irqs[i].mp_dstapic == MP_APIC_ALL)
                                break;
 
                if (!test_bit(lbus, mp_bus_not_pci) &&
-                   !mp_irqs[i].mpc_irqtype &&
+                   !mp_irqs[i].mp_irqtype &&
                    (bus == lbus) &&
-                   (slot == ((mp_irqs[i].mpc_srcbusirq >> 2) & 0x1f))) {
-                       int irq = pin_2_irq(i,apic,mp_irqs[i].mpc_dstirq);
+                   (slot == ((mp_irqs[i].mp_srcbusirq >> 2) & 0x1f))) {
+                       int irq = pin_2_irq(i,apic,mp_irqs[i].mp_dstirq);
 
                        if (!(apic || IO_APIC_IRQ(irq)))
                                continue;
 
-                       if (pin == (mp_irqs[i].mpc_srcbusirq & 3))
+                       if (pin == (mp_irqs[i].mp_srcbusirq & 3))
                                return irq;
                        /*
                         * Use the first all-but-pin matching entry as a
@@ -946,7 +958,7 @@ static int EISA_ELCR(unsigned int irq)
  * EISA conforming in the MP table, that means its trigger type must
  * be read in from the ELCR */
 
-#define default_EISA_trigger(idx)      (EISA_ELCR(mp_irqs[idx].mpc_srcbusirq))
+#define default_EISA_trigger(idx)      (EISA_ELCR(mp_irqs[idx].mp_srcbusirq))
 #define default_EISA_polarity(idx)     default_ISA_polarity(idx)
 
 /* PCI interrupts are always polarity one level triggered,
@@ -963,13 +975,13 @@ static int EISA_ELCR(unsigned int irq)
 
 static int MPBIOS_polarity(int idx)
 {
-       int bus = mp_irqs[idx].mpc_srcbus;
+       int bus = mp_irqs[idx].mp_srcbus;
        int polarity;
 
        /*
         * Determine IRQ line polarity (high active or low active):
         */
-       switch (mp_irqs[idx].mpc_irqflag & 3)
+       switch (mp_irqs[idx].mp_irqflag & 3)
        {
                case 0: /* conforms, ie. bus-type dependent polarity */
                {
@@ -1006,13 +1018,13 @@ static int MPBIOS_polarity(int idx)
 
 static int MPBIOS_trigger(int idx)
 {
-       int bus = mp_irqs[idx].mpc_srcbus;
+       int bus = mp_irqs[idx].mp_srcbus;
        int trigger;
 
        /*
         * Determine IRQ trigger mode (edge or level sensitive):
         */
-       switch ((mp_irqs[idx].mpc_irqflag>>2) & 3)
+       switch ((mp_irqs[idx].mp_irqflag>>2) & 3)
        {
                case 0: /* conforms, ie. bus-type dependent */
                {
@@ -1091,16 +1103,16 @@ static inline int irq_trigger(int idx)
 static int pin_2_irq(int idx, int apic, int pin)
 {
        int irq, i;
-       int bus = mp_irqs[idx].mpc_srcbus;
+       int bus = mp_irqs[idx].mp_srcbus;
 
        /*
         * Debugging check, we are in big trouble if this message pops up!
         */
-       if (mp_irqs[idx].mpc_dstirq != pin)
+       if (mp_irqs[idx].mp_dstirq != pin)
                printk(KERN_ERR "broken BIOS or MPTABLE parser, ayiee!!\n");
 
        if (test_bit(bus, mp_bus_not_pci))
-               irq = mp_irqs[idx].mpc_srcbusirq;
+               irq = mp_irqs[idx].mp_srcbusirq;
        else {
                /*
                 * PCI IRQs are mapped in order
@@ -1222,7 +1234,6 @@ static void __init setup_IO_APIC_irqs(void)
 {
        struct IO_APIC_route_entry entry;
        int apic, pin, idx, irq, first_notcon = 1, vector;
-       unsigned long flags;
 
        apic_printk(APIC_VERBOSE, KERN_DEBUG "init IO_APIC IRQs\n");
 
@@ -1245,12 +1256,12 @@ static void __init setup_IO_APIC_irqs(void)
                        if (first_notcon) {
                                apic_printk(APIC_VERBOSE, KERN_DEBUG
                                                " IO-APIC (apicid-pin) %d-%d",
-                                               mp_ioapics[apic].mpc_apicid,
+                                               mp_ioapics[apic].mp_apicid,
                                                pin);
                                first_notcon = 0;
                        } else
                                apic_printk(APIC_VERBOSE, ", %d-%d",
-                                       mp_ioapics[apic].mpc_apicid, pin);
+                                       mp_ioapics[apic].mp_apicid, pin);
                        continue;
                }
 
@@ -1288,9 +1299,7 @@ static void __init setup_IO_APIC_irqs(void)
                        if (!apic && (irq < 16))
                                disable_8259A_irq(irq);
                }
-               spin_lock_irqsave(&ioapic_lock, flags);
-               __ioapic_write_entry(apic, pin, entry);
-               spin_unlock_irqrestore(&ioapic_lock, flags);
+               ioapic_write_entry(apic, pin, entry);
        }
        }
 
@@ -1354,7 +1363,7 @@ void __init print_IO_APIC(void)
        printk(KERN_DEBUG "number of MP IRQ sources: %d.\n", mp_irq_entries);
        for (i = 0; i < nr_ioapics; i++)
                printk(KERN_DEBUG "number of IO-APIC #%d registers: %d.\n",
-                      mp_ioapics[i].mpc_apicid, nr_ioapic_registers[i]);
+                      mp_ioapics[i].mp_apicid, nr_ioapic_registers[i]);
 
        /*
         * We are a bit conservative about what we expect.  We have to
@@ -1373,7 +1382,7 @@ void __init print_IO_APIC(void)
                reg_03.raw = io_apic_read(apic, 3);
        spin_unlock_irqrestore(&ioapic_lock, flags);
 
-       printk(KERN_DEBUG "IO APIC #%d......\n", mp_ioapics[apic].mpc_apicid);
+       printk(KERN_DEBUG "IO APIC #%d......\n", mp_ioapics[apic].mp_apicid);
        printk(KERN_DEBUG ".... register #00: %08X\n", reg_00.raw);
        printk(KERN_DEBUG ".......    : physical APIC id: %02X\n", reg_00.bits.ID);
        printk(KERN_DEBUG ".......    : Delivery Type: %X\n", reg_00.bits.delivery_type);
@@ -1713,7 +1722,6 @@ void disable_IO_APIC(void)
  * by Matt Domsch <Matt_Domsch@dell.com>  Tue Dec 21 12:25:05 CST 1999
  */
 
-#ifndef CONFIG_X86_NUMAQ
 static void __init setup_ioapic_ids_from_mpc(void)
 {
        union IO_APIC_reg_00 reg_00;
@@ -1723,6 +1731,11 @@ static void __init setup_ioapic_ids_from_mpc(void)
        unsigned char old_id;
        unsigned long flags;
 
+#ifdef CONFIG_X86_NUMAQ
+       if (found_numaq)
+               return;
+#endif
+
        /*
         * Don't check I/O APIC IDs for xAPIC systems.  They have
         * no meaning without the serial APIC bus.
@@ -1746,14 +1759,14 @@ static void __init setup_ioapic_ids_from_mpc(void)
                reg_00.raw = io_apic_read(apic, 0);
                spin_unlock_irqrestore(&ioapic_lock, flags);
                
-               old_id = mp_ioapics[apic].mpc_apicid;
+               old_id = mp_ioapics[apic].mp_apicid;
 
-               if (mp_ioapics[apic].mpc_apicid >= get_physical_broadcast()) {
+               if (mp_ioapics[apic].mp_apicid >= get_physical_broadcast()) {
                        printk(KERN_ERR "BIOS bug, IO-APIC#%d ID is %d in the MPC table!...\n",
-                               apic, mp_ioapics[apic].mpc_apicid);
+                               apic, mp_ioapics[apic].mp_apicid);
                        printk(KERN_ERR "... fixing up to %d. (tell your hw vendor)\n",
                                reg_00.bits.ID);
-                       mp_ioapics[apic].mpc_apicid = reg_00.bits.ID;
+                       mp_ioapics[apic].mp_apicid = reg_00.bits.ID;
                }
 
                /*
@@ -1762,9 +1775,9 @@ static void __init setup_ioapic_ids_from_mpc(void)
                 * 'stuck on smp_invalidate_needed IPI wait' messages.
                 */
                if (check_apicid_used(phys_id_present_map,
-                                       mp_ioapics[apic].mpc_apicid)) {
+                                       mp_ioapics[apic].mp_apicid)) {
                        printk(KERN_ERR "BIOS bug, IO-APIC#%d ID %d is already used!...\n",
-                               apic, mp_ioapics[apic].mpc_apicid);
+                               apic, mp_ioapics[apic].mp_apicid);
                        for (i = 0; i < get_physical_broadcast(); i++)
                                if (!physid_isset(i, phys_id_present_map))
                                        break;
@@ -1773,13 +1786,13 @@ static void __init setup_ioapic_ids_from_mpc(void)
                        printk(KERN_ERR "... fixing up to %d. (tell your hw vendor)\n",
                                i);
                        physid_set(i, phys_id_present_map);
-                       mp_ioapics[apic].mpc_apicid = i;
+                       mp_ioapics[apic].mp_apicid = i;
                } else {
                        physid_mask_t tmp;
-                       tmp = apicid_to_cpu_present(mp_ioapics[apic].mpc_apicid);
+                       tmp = apicid_to_cpu_present(mp_ioapics[apic].mp_apicid);
                        apic_printk(APIC_VERBOSE, "Setting %d in the "
                                        "phys_id_present_map\n",
-                                       mp_ioapics[apic].mpc_apicid);
+                                       mp_ioapics[apic].mp_apicid);
                        physids_or(phys_id_present_map, phys_id_present_map, tmp);
                }
 
@@ -1788,11 +1801,11 @@ static void __init setup_ioapic_ids_from_mpc(void)
                 * We need to adjust the IRQ routing table
                 * if the ID changed.
                 */
-               if (old_id != mp_ioapics[apic].mpc_apicid)
+               if (old_id != mp_ioapics[apic].mp_apicid)
                        for (i = 0; i < mp_irq_entries; i++)
-                               if (mp_irqs[i].mpc_dstapic == old_id)
-                                       mp_irqs[i].mpc_dstapic
-                                               = mp_ioapics[apic].mpc_apicid;
+                               if (mp_irqs[i].mp_dstapic == old_id)
+                                       mp_irqs[i].mp_dstapic
+                                               = mp_ioapics[apic].mp_apicid;
 
                /*
                 * Read the right value from the MPC table and
@@ -1800,9 +1813,9 @@ static void __init setup_ioapic_ids_from_mpc(void)
                 */
                apic_printk(APIC_VERBOSE, KERN_INFO
                        "...changing IO-APIC physical APIC ID to %d ...",
-                       mp_ioapics[apic].mpc_apicid);
+                       mp_ioapics[apic].mp_apicid);
 
-               reg_00.bits.ID = mp_ioapics[apic].mpc_apicid;
+               reg_00.bits.ID = mp_ioapics[apic].mp_apicid;
                spin_lock_irqsave(&ioapic_lock, flags);
                io_apic_write(apic, 0, reg_00.raw);
                spin_unlock_irqrestore(&ioapic_lock, flags);
@@ -1813,15 +1826,12 @@ static void __init setup_ioapic_ids_from_mpc(void)
                spin_lock_irqsave(&ioapic_lock, flags);
                reg_00.raw = io_apic_read(apic, 0);
                spin_unlock_irqrestore(&ioapic_lock, flags);
-               if (reg_00.bits.ID != mp_ioapics[apic].mpc_apicid)
+               if (reg_00.bits.ID != mp_ioapics[apic].mp_apicid)
                        printk("could not set ID!\n");
                else
                        apic_printk(APIC_VERBOSE, " ok.\n");
        }
 }
-#else
-static void __init setup_ioapic_ids_from_mpc(void) { }
-#endif
 
 int no_timer_check __initdata;
 
@@ -1993,8 +2003,7 @@ static inline void init_IO_APIC_traps(void)
         * 0x80, because int 0x80 is hm, kind of importantish. ;)
         */
        for (irq = 0; irq < NR_IRQS ; irq++) {
-               int tmp = irq;
-               if (IO_APIC_IRQ(tmp) && !irq_vector[tmp]) {
+               if (IO_APIC_IRQ(irq) && !irq_vector[irq]) {
                        /*
                         * Hmm.. We don't have an entry for this,
                         * so default to an old-fashioned 8259
@@ -2066,7 +2075,7 @@ static void __init setup_nmi(void)
  * cycles as some i82489DX-based boards have glue logic that keeps the
  * 8259A interrupt line asserted until INTA.  --macro
  */
-static inline void unlock_ExtINT_logic(void)
+static inline void __init unlock_ExtINT_logic(void)
 {
        int apic, pin, i;
        struct IO_APIC_route_entry entry0, entry1;
@@ -2128,14 +2137,10 @@ static inline void __init check_timer(void)
 {
        int apic1, pin1, apic2, pin2;
        int vector;
-       unsigned int ver;
        unsigned long flags;
 
        local_irq_save(flags);
 
-       ver = apic_read(APIC_LVR);
-       ver = GET_APIC_VERSION(ver);
-
        /*
         * get/set the timer IRQ vector:
         */
@@ -2148,15 +2153,11 @@ static inline void __init check_timer(void)
         * mode for the 8259A whenever interrupts are routed
         * through I/O APICs.  Also IRQ0 has to be enabled in
         * the 8259A which implies the virtual wire has to be
-        * disabled in the local APIC.  Finally timer interrupts
-        * need to be acknowledged manually in the 8259A for
-        * timer_interrupt() and for the i82489DX when using
-        * the NMI watchdog.
+        * disabled in the local APIC.
         */
        apic_write_around(APIC_LVT0, APIC_LVT_MASKED | APIC_DM_EXTINT);
        init_8259A(1);
-       timer_ack = !cpu_has_tsc;
-       timer_ack |= (nmi_watchdog == NMI_IO_APIC && !APIC_INTEGRATED(ver));
+       timer_ack = 1;
        if (timer_over_8254 > 0)
                enable_8259A_irq(0);
 
@@ -2353,8 +2354,8 @@ static int ioapic_resume(struct sys_device *dev)
 
        spin_lock_irqsave(&ioapic_lock, flags);
        reg_00.raw = io_apic_read(dev->id, 0);
-       if (reg_00.bits.ID != mp_ioapics[dev->id].mpc_apicid) {
-               reg_00.bits.ID = mp_ioapics[dev->id].mpc_apicid;
+       if (reg_00.bits.ID != mp_ioapics[dev->id].mp_apicid) {
+               reg_00.bits.ID = mp_ioapics[dev->id].mp_apicid;
                io_apic_write(dev->id, 0, reg_00.raw);
        }
        spin_unlock_irqrestore(&ioapic_lock, flags);
@@ -2442,6 +2443,7 @@ void destroy_irq(unsigned int irq)
        dynamic_irq_cleanup(irq);
 
        spin_lock_irqsave(&vector_lock, flags);
+       clear_bit(irq_vector[irq], used_vectors);
        irq_vector[irq] = 0;
        spin_unlock_irqrestore(&vector_lock, flags);
 }
@@ -2754,7 +2756,6 @@ int __init io_apic_get_redir_entries (int ioapic)
 int io_apic_set_pci_routing (int ioapic, int pin, int irq, int edge_level, int active_high_low)
 {
        struct IO_APIC_route_entry entry;
-       unsigned long flags;
 
        if (!IO_APIC_IRQ(irq)) {
                printk(KERN_ERR "IOAPIC[%d]: Invalid reference to IRQ 0\n",
@@ -2787,7 +2788,7 @@ int io_apic_set_pci_routing (int ioapic, int pin, int irq, int edge_level, int a
 
        apic_printk(APIC_DEBUG, KERN_DEBUG "IOAPIC[%d]: Set PCI routing entry "
                "(%d-%d -> 0x%x -> IRQ %d Mode:%i Active:%i)\n", ioapic,
-               mp_ioapics[ioapic].mpc_apicid, pin, entry.vector, irq,
+               mp_ioapics[ioapic].mp_apicid, pin, entry.vector, irq,
                edge_level, active_high_low);
 
        ioapic_register_intr(irq, entry.vector, edge_level);
@@ -2795,9 +2796,7 @@ int io_apic_set_pci_routing (int ioapic, int pin, int irq, int edge_level, int a
        if (!ioapic && (irq < 16))
                disable_8259A_irq(irq);
 
-       spin_lock_irqsave(&ioapic_lock, flags);
-       __ioapic_write_entry(ioapic, pin, entry);
-       spin_unlock_irqrestore(&ioapic_lock, flags);
+       ioapic_write_entry(ioapic, pin, entry);
 
        return 0;
 }
@@ -2810,8 +2809,8 @@ int acpi_get_override_irq(int bus_irq, int *trigger, int *polarity)
                return -1;
 
        for (i = 0; i < mp_irq_entries; i++)
-               if (mp_irqs[i].mpc_irqtype == mp_INT &&
-                   mp_irqs[i].mpc_srcbusirq == bus_irq)
+               if (mp_irqs[i].mp_irqtype == mp_INT &&
+                   mp_irqs[i].mp_srcbusirq == bus_irq)
                        break;
        if (i >= mp_irq_entries)
                return -1;