]> err.no Git - linux-2.6/blobdiff - arch/x86/kernel/io_apic_64.c
x86: use bitmap library for pin_programmed
[linux-2.6] / arch / x86 / kernel / io_apic_64.c
index 3e471d0fb150125117f412271cf4e0b3e3f58786..9ba11d07920f794c71e11de98d51d8430e129cf2 100644 (file)
@@ -32,6 +32,7 @@
 #include <linux/msi.h>
 #include <linux/htirq.h>
 #include <linux/dmar.h>
+#include <linux/jiffies.h>
 #ifdef CONFIG_ACPI
 #include <acpi/acpi_bus.h>
 #endif
 #include <asm/smp.h>
 #include <asm/desc.h>
 #include <asm/proto.h>
-#include <asm/mach_apic.h>
 #include <asm/acpi.h>
 #include <asm/dma.h>
 #include <asm/nmi.h>
 #include <asm/msidef.h>
 #include <asm/hypertransport.h>
 
+#include <mach_ipi.h>
+#include <mach_apic.h>
+
 struct irq_cfg {
        cpumask_t domain;
        cpumask_t old_domain;
@@ -100,6 +103,16 @@ DEFINE_SPINLOCK(vector_lock);
  */
 int nr_ioapic_registers[MAX_IO_APICS];
 
+/* I/O APIC entries */
+struct mpc_config_ioapic mp_ioapics[MAX_IO_APICS];
+int nr_ioapics;
+
+/* MP IRQ source entries */
+struct mpc_config_intsrc mp_irqs[MAX_IRQ_SOURCES];
+
+/* # of MP IRQ source entries */
+int mp_irq_entries;
+
 /*
  * Rough estimation of how many shared IRQs there are, can
  * be changed anytime.
@@ -154,11 +167,10 @@ static inline void io_apic_modify(unsigned int apic, unsigned int value)
        writel(value, &io_apic->data);
 }
 
-static int io_apic_level_ack_pending(unsigned int irq)
+static bool io_apic_level_ack_pending(unsigned int irq)
 {
        struct irq_pin_list *entry;
        unsigned long flags;
-       int pending = 0;
 
        spin_lock_irqsave(&ioapic_lock, flags);
        entry = irq_2_pin + irq;
@@ -171,13 +183,17 @@ static int io_apic_level_ack_pending(unsigned int irq)
                        break;
                reg = io_apic_read(entry->apic, 0x10 + pin*2);
                /* Is the remote IRR bit set? */
-               pending |= (reg >> 14) & 1;
+               if ((reg >> 14) & 1) {
+                       spin_unlock_irqrestore(&ioapic_lock, flags);
+                       return true;
+               }
                if (!entry->next)
                        break;
                entry = irq_2_pin + entry->next;
        }
        spin_unlock_irqrestore(&ioapic_lock, flags);
-       return pending;
+
+       return false;
 }
 
 /*
@@ -769,7 +785,7 @@ static void __clear_irq_vector(int irq)
                per_cpu(vector_irq, cpu)[vector] = -1;
 
        cfg->vector = 0;
-       cfg->domain = CPU_MASK_NONE;
+       cpus_clear(cfg->domain);
 }
 
 void __setup_vector_irq(int cpu)
@@ -901,9 +917,8 @@ static void __init setup_IO_APIC_irqs(void)
 static void __init setup_ExtINT_IRQ0_pin(unsigned int apic, unsigned int pin, int vector)
 {
        struct IO_APIC_route_entry entry;
-       unsigned long flags;
 
-       memset(&entry,0,sizeof(entry));
+       memset(&entry, 0, sizeof(entry));
 
        disable_8259A_irq(0);
 
@@ -931,10 +946,7 @@ static void __init setup_ExtINT_IRQ0_pin(unsigned int apic, unsigned int pin, in
        /*
         * Add it to the IO-APIC irq-routing table:
         */
-       spin_lock_irqsave(&ioapic_lock, flags);
-       io_apic_write(apic, 0x11+2*pin, *(((int *)&entry)+1));
-       io_apic_write(apic, 0x10+2*pin, *(((int *)&entry)+0));
-       spin_unlock_irqrestore(&ioapic_lock, flags);
+       ioapic_write_entry(apic, pin, entry);
 
        enable_8259A_irq(0);
 }
@@ -1065,8 +1077,7 @@ void __apicdebuginit print_local_APIC(void * dummy)
 
        printk("\n" KERN_DEBUG "printing local APIC contents on CPU#%d/%d:\n",
                smp_processor_id(), hard_smp_processor_id());
-       v = apic_read(APIC_ID);
-       printk(KERN_INFO "... APIC ID:      %08x (%01x)\n", v, GET_APIC_ID(v));
+       printk(KERN_INFO "... APIC ID:      %08x (%01x)\n", v, GET_APIC_ID(read_apic_id()));
        v = apic_read(APIC_LVR);
        printk(KERN_INFO "... APIC VERSION: %08x\n", v);
        ver = GET_APIC_VERSION(v);
@@ -1172,7 +1183,7 @@ void __apicdebuginit print_PIC(void)
 
 #endif  /*  0  */
 
-static void __init enable_IO_APIC(void)
+void __init enable_IO_APIC(void)
 {
        union IO_APIC_reg_01 reg_01;
        int i8259_apic, i8259_pin;
@@ -1260,7 +1271,7 @@ void disable_IO_APIC(void)
                entry.dest_mode       = 0; /* Physical */
                entry.delivery_mode   = dest_ExtINT; /* ExtInt */
                entry.vector          = 0;
-               entry.dest          = GET_APIC_ID(apic_read(APIC_ID));
+               entry.dest          = GET_APIC_ID(read_apic_id());
 
                /*
                 * Add it to the IO-APIC irq-routing table:
@@ -1299,7 +1310,7 @@ static int __init timer_irq_works(void)
         */
 
        /* jiffies wrap? */
-       if (jiffies - t1 > 4)
+       if (time_after(jiffies, t1 + 4))
                return 1;
        return 0;
 }
@@ -1351,9 +1362,7 @@ static int ioapic_retrigger_irq(unsigned int irq)
        unsigned long flags;
 
        spin_lock_irqsave(&vector_lock, flags);
-       cpus_clear(mask);
-       cpu_set(first_cpu(cfg->domain), mask);
-
+       mask = cpumask_of_cpu(first_cpu(cfg->domain));
        send_IPI_mask(mask, cfg->vector);
        spin_unlock_irqrestore(&vector_lock, flags);
 
@@ -1412,7 +1421,7 @@ static void irq_complete_move(unsigned int irq)
        if (likely(!cfg->move_in_progress))
                return;
 
-       vector = ~get_irq_regs()->orig_rax;
+       vector = ~get_irq_regs()->orig_ax;
        me = smp_processor_id();
        if ((vector == cfg->vector) && cpu_isset(me, cfg->domain)) {
                cpumask_t cleanup_mask;
@@ -1516,8 +1525,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_cfg[tmp].vector) {
+               if (IO_APIC_IRQ(irq) && !irq_cfg[irq].vector) {
                        /*
                         * Hmm.. We don't have an entry for this,
                         * so default to an old-fashioned 8259
@@ -1566,7 +1574,7 @@ static struct hw_interrupt_type lapic_irq_type __read_mostly = {
        .end = end_lapic_irq,
 };
 
-static void setup_nmi (void)
+static void __init setup_nmi(void)
 {
        /*
         * Dirty trick to enable the NMI watchdog ...
@@ -1579,7 +1587,7 @@ static void setup_nmi (void)
         */ 
        printk(KERN_INFO "activating NMI Watchdog ...");
 
-       enable_NMI_through_LVT0(NULL);
+       enable_NMI_through_LVT0();
 
        printk(" done.\n");
 }
@@ -1596,17 +1604,14 @@ static inline void unlock_ExtINT_logic(void)
        int apic, pin, i;
        struct IO_APIC_route_entry entry0, entry1;
        unsigned char save_control, save_freq_select;
-       unsigned long flags;
 
        pin  = find_isa_irq_pin(8, mp_INT);
        apic = find_isa_irq_apic(8, mp_INT);
        if (pin == -1)
                return;
 
-       spin_lock_irqsave(&ioapic_lock, flags);
-       *(((int *)&entry0) + 1) = io_apic_read(apic, 0x11 + 2 * pin);
-       *(((int *)&entry0) + 0) = io_apic_read(apic, 0x10 + 2 * pin);
-       spin_unlock_irqrestore(&ioapic_lock, flags);
+       entry0 = ioapic_read_entry(apic, pin);
+
        clear_IO_APIC_pin(apic, pin);
 
        memset(&entry1, 0, sizeof(entry1));
@@ -1619,10 +1624,7 @@ static inline void unlock_ExtINT_logic(void)
        entry1.trigger = 0;
        entry1.vector = 0;
 
-       spin_lock_irqsave(&ioapic_lock, flags);
-       io_apic_write(apic, 0x11 + 2 * pin, *(((int *)&entry1) + 1));
-       io_apic_write(apic, 0x10 + 2 * pin, *(((int *)&entry1) + 0));
-       spin_unlock_irqrestore(&ioapic_lock, flags);
+       ioapic_write_entry(apic, pin, entry1);
 
        save_control = CMOS_READ(RTC_CONTROL);
        save_freq_select = CMOS_READ(RTC_FREQ_SELECT);
@@ -1641,10 +1643,7 @@ static inline void unlock_ExtINT_logic(void)
        CMOS_WRITE(save_freq_select, RTC_FREQ_SELECT);
        clear_IO_APIC_pin(apic, pin);
 
-       spin_lock_irqsave(&ioapic_lock, flags);
-       io_apic_write(apic, 0x11 + 2 * pin, *(((int *)&entry0) + 1));
-       io_apic_write(apic, 0x10 + 2 * pin, *(((int *)&entry0) + 0));
-       spin_unlock_irqrestore(&ioapic_lock, flags);
+       ioapic_write_entry(apic, pin, entry0);
 }
 
 /*
@@ -1655,7 +1654,7 @@ static inline void unlock_ExtINT_logic(void)
  *
  * FIXME: really need to revamp this for modern platforms only.
  */
-static inline void check_timer(void)
+static inline void __init check_timer(void)
 {
        struct irq_cfg *cfg = irq_cfg + 0;
        int apic1, pin1, apic2, pin2;
@@ -1789,7 +1788,10 @@ __setup("no_timer_check", notimercheck);
 
 void __init setup_IO_APIC(void)
 {
-       enable_IO_APIC();
+
+       /*
+        * calling enable_IO_APIC() is moved to setup_local_APIC for BP
+        */
 
        if (acpi_ioapic)
                io_apic_irqs = ~0;      /* all IRQs go through IOAPIC */
@@ -2310,7 +2312,6 @@ static struct resource * __init ioapic_setup_resources(void)
        res = (void *)mem;
 
        if (mem != NULL) {
-               memset(mem, 0, n);
                mem += sizeof(struct resource) * nr_ioapics;
 
                for (i = 0; i < nr_ioapics; i++) {