Merge branch 'linus' into irq/numa
authorIngo Molnar <mingo@elte.hu>
Mon, 1 Jun 2009 19:06:21 +0000 (21:06 +0200)
committerIngo Molnar <mingo@elte.hu>
Mon, 1 Jun 2009 19:06:21 +0000 (21:06 +0200)
Conflicts:
arch/mips/sibyte/bcm1480/irq.c
arch/mips/sibyte/sb1250/irq.c

Merge reason: we gathered a few conflicts plus update to latest upstream fixes.

Signed-off-by: Ingo Molnar <mingo@elte.hu>
78 files changed:
Documentation/kernel-parameters.txt
arch/alpha/kernel/sys_dp264.c
arch/alpha/kernel/sys_titan.c
arch/arm/common/gic.c
arch/cris/arch-v32/kernel/irq.c
arch/ia64/hp/sim/hpsim_irq.c
arch/ia64/kernel/acpi.c
arch/ia64/kernel/iosapic.c
arch/ia64/kernel/msi_ia64.c
arch/ia64/sn/kernel/irq.c
arch/ia64/sn/kernel/msi_sn.c
arch/mips/cavium-octeon/octeon-irq.c
arch/mips/include/asm/irq.h
arch/mips/kernel/irq-gic.c
arch/mips/mti-malta/malta-smtc.c
arch/mips/sibyte/bcm1480/irq.c
arch/mips/sibyte/sb1250/irq.c
arch/parisc/kernel/irq.c
arch/powerpc/platforms/pseries/xics.c
arch/powerpc/sysdev/mpic.c
arch/powerpc/sysdev/mpic.h
arch/sparc/kernel/irq_64.c
arch/x86/Kconfig
arch/x86/configs/x86_64_defconfig
arch/x86/include/asm/apic.h
arch/x86/include/asm/apicdef.h
arch/x86/include/asm/hw_irq.h
arch/x86/include/asm/i8259.h
arch/x86/include/asm/io_apic.h
arch/x86/include/asm/irq_remapping.h
arch/x86/include/asm/irq_vectors.h
arch/x86/include/asm/mpspec.h
arch/x86/include/asm/setup.h
arch/x86/include/asm/smp.h
arch/x86/kernel/Makefile
arch/x86/kernel/acpi/boot.c
arch/x86/kernel/apic/apic.c
arch/x86/kernel/apic/apic_flat_64.c
arch/x86/kernel/apic/es7000_32.c
arch/x86/kernel/apic/io_apic.c
arch/x86/kernel/apic/probe_64.c
arch/x86/kernel/apic/summit_32.c
arch/x86/kernel/apic/x2apic_uv_x.c
arch/x86/kernel/cpu/amd.c
arch/x86/kernel/cpu/common.c
arch/x86/kernel/cpu/cpu_debug.c
arch/x86/kernel/cpu/intel.c
arch/x86/kernel/irq.c
arch/x86/kernel/irqinit.c [moved from arch/x86/kernel/irqinit_32.c with 68% similarity]
arch/x86/kernel/irqinit_64.c [deleted file]
arch/x86/kernel/mpparse.c
arch/x86/kernel/setup.c
arch/x86/kernel/smp.c
arch/x86/kernel/smpboot.c
arch/x86/kernel/traps.c
arch/x86/lguest/boot.c
arch/x86/pci/irq.c
drivers/acpi/pci_irq.c
drivers/char/hpet.c
drivers/parisc/iosapic.c
drivers/pci/hotplug/ibmphp_core.c
drivers/pci/htirq.c
drivers/pci/intel-iommu.c
drivers/pci/intr_remapping.c
drivers/pnp/pnpacpi/rsparser.c
drivers/xen/events.c
include/linux/acpi.h
include/linux/dmar.h
include/linux/interrupt.h
include/linux/irq.h
kernel/irq/Makefile
kernel/irq/chip.c
kernel/irq/handle.c
kernel/irq/internals.h
kernel/irq/manage.c
kernel/irq/migration.c
kernel/irq/numa_migrate.c
kernel/softirq.c

index fd5cac013037defc68c3ef118ed70b476debee71..11648c13a7290e48181e6f1b97c33096a621f5f6 100644 (file)
@@ -1575,6 +1575,9 @@ and is between 256 and 4096 characters. It is defined in the file
        noinitrd        [RAM] Tells the kernel not to load any configured
                        initial RAM disk.
 
+       nointremap      [X86-64, Intel-IOMMU] Do not enable interrupt
+                       remapping.
+
        nointroute      [IA-64]
 
        nojitter        [IA64] Disables jitter checking for ITC timers.
index 9c9d1fd4155fc5e736c98d89e68d034cd8f2b9ef..5bd5259324b7c8827adb237facd7bf120edd4ca2 100644 (file)
@@ -176,22 +176,26 @@ cpu_set_irq_affinity(unsigned int irq, cpumask_t affinity)
        }
 }
 
-static void
+static int
 dp264_set_affinity(unsigned int irq, const struct cpumask *affinity)
 { 
        spin_lock(&dp264_irq_lock);
        cpu_set_irq_affinity(irq, *affinity);
        tsunami_update_irq_hw(cached_irq_mask);
        spin_unlock(&dp264_irq_lock);
+
+       return 0;
 }
 
-static void
+static int
 clipper_set_affinity(unsigned int irq, const struct cpumask *affinity)
 { 
        spin_lock(&dp264_irq_lock);
        cpu_set_irq_affinity(irq - 16, *affinity);
        tsunami_update_irq_hw(cached_irq_mask);
        spin_unlock(&dp264_irq_lock);
+
+       return 0;
 }
 
 static struct hw_interrupt_type dp264_irq_type = {
index 27f840a4ad3d7ec0949ac92a55ef5c7c1a3b9280..8dd239ebdb9e2cc3489c3d128402a9da37033a29 100644 (file)
@@ -157,13 +157,15 @@ titan_cpu_set_irq_affinity(unsigned int irq, cpumask_t affinity)
 
 }
 
-static void
+static int
 titan_set_irq_affinity(unsigned int irq, const struct cpumask *affinity)
 { 
        spin_lock(&titan_irq_lock);
        titan_cpu_set_irq_affinity(irq - 16, *affinity);
        titan_update_irq_hw(titan_cached_irq_mask);
        spin_unlock(&titan_irq_lock);
+
+       return 0;
 }
 
 static void
index 3e1714c6523f06f4ab0572886edba151f21ffb8c..664c7b8b1ba87d7d5268c661808636a27b4f610c 100644 (file)
@@ -109,7 +109,7 @@ static void gic_unmask_irq(unsigned int irq)
 }
 
 #ifdef CONFIG_SMP
-static void gic_set_cpu(unsigned int irq, const struct cpumask *mask_val)
+static int gic_set_cpu(unsigned int irq, const struct cpumask *mask_val)
 {
        void __iomem *reg = gic_dist_base(irq) + GIC_DIST_TARGET + (gic_irq(irq) & ~3);
        unsigned int shift = (irq % 4) * 8;
@@ -122,6 +122,8 @@ static void gic_set_cpu(unsigned int irq, const struct cpumask *mask_val)
        val |= 1 << (cpu + shift);
        writel(val, reg);
        spin_unlock(&irq_controller_lock);
+
+       return 0;
 }
 #endif
 
index df3925cb1c7fbbcab86f8445491d0e77ebf684a9..d70b445f4a8f0fc82922e848ae4f0bbbae6a1fb5 100644 (file)
@@ -325,12 +325,14 @@ static void end_crisv32_irq(unsigned int irq)
 {
 }
 
-void set_affinity_crisv32_irq(unsigned int irq, const struct cpumask *dest)
+int set_affinity_crisv32_irq(unsigned int irq, const struct cpumask *dest)
 {
        unsigned long flags;
        spin_lock_irqsave(&irq_lock, flags);
        irq_allocations[irq - FIRST_IRQ].mask = *dest;
        spin_unlock_irqrestore(&irq_lock, flags);
+
+       return 0;
 }
 
 static struct irq_chip crisv32_irq_type = {
index cc0a3182db3c0158d246f658065a0f0f5d426a5f..acb5047ab57341d9818160f361db47c7e6e59313 100644 (file)
@@ -21,9 +21,10 @@ hpsim_irq_noop (unsigned int irq)
 {
 }
 
-static void
+static int
 hpsim_set_affinity_noop(unsigned int a, const struct cpumask *b)
 {
+       return 0;
 }
 
 static struct hw_interrupt_type irq_type_hp_sim = {
index 5510317db37b2a439711bb3fa97d6af0c7cd00bf..baec6f00f7f3feee71c5110b01f12b5c8b3f4fda 100644 (file)
@@ -636,7 +636,7 @@ void __init acpi_numa_arch_fixup(void)
  * success: return IRQ number (>=0)
  * failure: return < 0
  */
-int acpi_register_gsi(u32 gsi, int triggering, int polarity)
+int acpi_register_gsi(struct device *dev, u32 gsi, int triggering, int polarity)
 {
        if (acpi_irq_model == ACPI_IRQ_MODEL_PLATFORM)
                return gsi;
@@ -678,7 +678,8 @@ static int __init acpi_parse_fadt(struct acpi_table_header *table)
 
        fadt = (struct acpi_table_fadt *)fadt_header;
 
-       acpi_register_gsi(fadt->sci_interrupt, ACPI_LEVEL_SENSITIVE, ACPI_ACTIVE_LOW);
+       acpi_register_gsi(NULL, fadt->sci_interrupt, ACPI_LEVEL_SENSITIVE,
+                                ACPI_ACTIVE_LOW);
        return 0;
 }
 
index 166e0d839fa04d753fa3709bfe62544eee32e9ec..f92cef47bf862ed8cd3943875585535e0c412763 100644 (file)
@@ -329,7 +329,7 @@ unmask_irq (unsigned int irq)
 }
 
 
-static void
+static int
 iosapic_set_affinity(unsigned int irq, const struct cpumask *mask)
 {
 #ifdef CONFIG_SMP
@@ -343,15 +343,15 @@ iosapic_set_affinity(unsigned int irq, const struct cpumask *mask)
 
        cpu = cpumask_first_and(cpu_online_mask, mask);
        if (cpu >= nr_cpu_ids)
-               return;
+               return -1;
 
        if (irq_prepare_move(irq, cpu))
-               return;
+               return -1;
 
        dest = cpu_physical_id(cpu);
 
        if (!iosapic_intr_info[irq].count)
-               return;                 /* not an IOSAPIC interrupt */
+               return -1;                      /* not an IOSAPIC interrupt */
 
        set_irq_affinity_info(irq, dest, redir);
 
@@ -376,7 +376,9 @@ iosapic_set_affinity(unsigned int irq, const struct cpumask *mask)
                iosapic_write(iosapic, IOSAPIC_RTE_HIGH(rte_index), high32);
                iosapic_write(iosapic, IOSAPIC_RTE_LOW(rte_index), low32);
        }
+
 #endif
+       return 0;
 }
 
 /*
index 2b15e233f7fef6b016f50367c90f9c91ba096b63..0f8ade9331badf4acaf29818dcad0dc67b31fd5e 100644 (file)
@@ -12,7 +12,7 @@
 static struct irq_chip ia64_msi_chip;
 
 #ifdef CONFIG_SMP
-static void ia64_set_msi_irq_affinity(unsigned int irq,
+static int ia64_set_msi_irq_affinity(unsigned int irq,
                                      const cpumask_t *cpu_mask)
 {
        struct msi_msg msg;
@@ -20,10 +20,10 @@ static void ia64_set_msi_irq_affinity(unsigned int irq,
        int cpu = first_cpu(*cpu_mask);
 
        if (!cpu_online(cpu))
-               return;
+               return -1;
 
        if (irq_prepare_move(irq, cpu))
-               return;
+               return -1;
 
        read_msi_msg(irq, &msg);
 
@@ -39,6 +39,8 @@ static void ia64_set_msi_irq_affinity(unsigned int irq,
 
        write_msi_msg(irq, &msg);
        cpumask_copy(irq_desc[irq].affinity, cpumask_of(cpu));
+
+       return 0;
 }
 #endif /* CONFIG_SMP */
 
@@ -130,17 +132,17 @@ void arch_teardown_msi_irq(unsigned int irq)
 
 #ifdef CONFIG_DMAR
 #ifdef CONFIG_SMP
-static void dmar_msi_set_affinity(unsigned int irq, const struct cpumask *mask)
+static int dmar_msi_set_affinity(unsigned int irq, const struct cpumask *mask)
 {
        struct irq_cfg *cfg = irq_cfg + irq;
        struct msi_msg msg;
        int cpu = cpumask_first(mask);
 
        if (!cpu_online(cpu))
-               return;
+               return -1;
 
        if (irq_prepare_move(irq, cpu))
-               return;
+               return -1;
 
        dmar_msi_read(irq, &msg);
 
@@ -151,6 +153,8 @@ static void dmar_msi_set_affinity(unsigned int irq, const struct cpumask *mask)
 
        dmar_msi_write(irq, &msg);
        cpumask_copy(irq_desc[irq].affinity, mask);
+
+       return 0;
 }
 #endif /* CONFIG_SMP */
 
index 66fd705e82c09ee1e1905356cf447526461c086a..764f26abac05df5e9d7659ff7254da6fde398301 100644 (file)
@@ -227,7 +227,7 @@ finish_up:
        return new_irq_info;
 }
 
-static void sn_set_affinity_irq(unsigned int irq, const struct cpumask *mask)
+static int sn_set_affinity_irq(unsigned int irq, const struct cpumask *mask)
 {
        struct sn_irq_info *sn_irq_info, *sn_irq_info_safe;
        nasid_t nasid;
@@ -239,6 +239,8 @@ static void sn_set_affinity_irq(unsigned int irq, const struct cpumask *mask)
        list_for_each_entry_safe(sn_irq_info, sn_irq_info_safe,
                                 sn_irq_lh[irq], list)
                (void)sn_retarget_vector(sn_irq_info, nasid, slice);
+
+       return 0;
 }
 
 #ifdef CONFIG_SMP
index 81e428943d7374d01e0aef8530e39c7ecd892b30..fbbfb970120128a29df68c549895187ea3e3013e 100644 (file)
@@ -151,7 +151,7 @@ int sn_setup_msi_irq(struct pci_dev *pdev, struct msi_desc *entry)
 }
 
 #ifdef CONFIG_SMP
-static void sn_set_msi_irq_affinity(unsigned int irq,
+static int sn_set_msi_irq_affinity(unsigned int irq,
                                    const struct cpumask *cpu_mask)
 {
        struct msi_msg msg;
@@ -168,7 +168,7 @@ static void sn_set_msi_irq_affinity(unsigned int irq,
        cpu = cpumask_first(cpu_mask);
        sn_irq_info = sn_msi_info[irq].sn_irq_info;
        if (sn_irq_info == NULL || sn_irq_info->irq_int_bit >= 0)
-               return;
+               return -1;
 
        /*
         * Release XIO resources for the old MSI PCI address
@@ -189,7 +189,7 @@ static void sn_set_msi_irq_affinity(unsigned int irq,
        new_irq_info = sn_retarget_vector(sn_irq_info, nasid, slice);
        sn_msi_info[irq].sn_irq_info = new_irq_info;
        if (new_irq_info == NULL)
-               return;
+               return -1;
 
        /*
         * Map the xio address into bus space
@@ -206,6 +206,8 @@ static void sn_set_msi_irq_affinity(unsigned int irq,
 
        write_msi_msg(irq, &msg);
        cpumask_copy(irq_desc[irq].affinity, cpu_mask);
+
+       return 0;
 }
 #endif /* CONFIG_SMP */
 
index 1c19af8daa62a3f992f20ecb1a281a527bfec3cd..d3a0c8154beca80cd7cb40bc3d783fa247891941 100644 (file)
@@ -177,7 +177,7 @@ static void octeon_irq_ciu0_disable(unsigned int irq)
 }
 
 #ifdef CONFIG_SMP
-static void octeon_irq_ciu0_set_affinity(unsigned int irq, const struct cpumask *dest)
+static int octeon_irq_ciu0_set_affinity(unsigned int irq, const struct cpumask *dest)
 {
        int cpu;
        int bit = irq - OCTEON_IRQ_WORKQ0;      /* Bit 0-63 of EN0 */
@@ -199,6 +199,8 @@ static void octeon_irq_ciu0_set_affinity(unsigned int irq, const struct cpumask
         */
        cvmx_read_csr(CVMX_CIU_INTX_EN0(cvmx_get_core_num() * 2));
        write_unlock(&octeon_irq_ciu0_rwlock);
+
+       return 0;
 }
 #endif
 
@@ -292,7 +294,7 @@ static void octeon_irq_ciu1_disable(unsigned int irq)
 }
 
 #ifdef CONFIG_SMP
-static void octeon_irq_ciu1_set_affinity(unsigned int irq, const struct cpumask *dest)
+static int octeon_irq_ciu1_set_affinity(unsigned int irq, const struct cpumask *dest)
 {
        int cpu;
        int bit = irq - OCTEON_IRQ_WDOG0;       /* Bit 0-63 of EN1 */
@@ -315,6 +317,8 @@ static void octeon_irq_ciu1_set_affinity(unsigned int irq, const struct cpumask
         */
        cvmx_read_csr(CVMX_CIU_INTX_EN1(cvmx_get_core_num() * 2 + 1));
        write_unlock(&octeon_irq_ciu1_rwlock);
+
+       return 0;
 }
 #endif
 
index 3214ade02d105988937576c8425f444b08783b0e..4f1eed107b08217f8f2991ed17f92c424b6c437f 100644 (file)
@@ -49,7 +49,7 @@ static inline void smtc_im_ack_irq(unsigned int irq)
 #ifdef CONFIG_MIPS_MT_SMTC_IRQAFF
 #include <linux/cpumask.h>
 
-extern void plat_set_irq_affinity(unsigned int irq,
+extern int plat_set_irq_affinity(unsigned int irq,
                                  const struct cpumask *affinity);
 extern void smtc_forward_irq(unsigned int irq);
 
index 87deb8f6c45885e5c356df3ac4ddf1e58a6ac81c..3f43c2e3aa5a59ede8eab7ecdaee7762ea6afb68 100644 (file)
@@ -155,7 +155,7 @@ static void gic_unmask_irq(unsigned int irq)
 
 static DEFINE_SPINLOCK(gic_lock);
 
-static void gic_set_affinity(unsigned int irq, const struct cpumask *cpumask)
+static int gic_set_affinity(unsigned int irq, const struct cpumask *cpumask)
 {
        cpumask_t       tmp = CPU_MASK_NONE;
        unsigned long   flags;
@@ -166,7 +166,7 @@ static void gic_set_affinity(unsigned int irq, const struct cpumask *cpumask)
 
        cpumask_and(&tmp, cpumask, cpu_online_mask);
        if (cpus_empty(tmp))
-               return;
+               return -1;
 
        /* Assumption : cpumask refers to a single CPU */
        spin_lock_irqsave(&gic_lock, flags);
@@ -190,6 +190,7 @@ static void gic_set_affinity(unsigned int irq, const struct cpumask *cpumask)
        cpumask_copy(irq_desc[irq].affinity, cpumask);
        spin_unlock_irqrestore(&gic_lock, flags);
 
+       return 0;
 }
 #endif
 
index 5ba31888fefbbecacd123e7033ef8ddcb6c30944..499ffe5475dff4fe8254990499d13d6f5ff4a266 100644 (file)
@@ -114,7 +114,7 @@ struct plat_smp_ops msmtc_smp_ops = {
  */
 
 
-void plat_set_irq_affinity(unsigned int irq, const struct cpumask *affinity)
+int plat_set_irq_affinity(unsigned int irq, const struct cpumask *affinity)
 {
        cpumask_t tmask;
        int cpu = 0;
@@ -156,5 +156,7 @@ void plat_set_irq_affinity(unsigned int irq, const struct cpumask *affinity)
 
        /* Do any generic SMTC IRQ affinity setup */
        smtc_set_irq_affinity(irq, tmask);
+
+       return 0;
 }
 #endif /* CONFIG_MIPS_MT_SMTC_IRQAFF */
index c147c4b35d3fc6f9e1f48b81866eb36d7f882594..690de06bde902f38a49b8d1e1765ae3fd2251b48 100644 (file)
@@ -50,7 +50,7 @@ static void enable_bcm1480_irq(unsigned int irq);
 static void disable_bcm1480_irq(unsigned int irq);
 static void ack_bcm1480_irq(unsigned int irq);
 #ifdef CONFIG_SMP
-static void bcm1480_set_affinity(unsigned int irq, const struct cpumask *mask);
+static int bcm1480_set_affinity(unsigned int irq, const struct cpumask *mask);
 #endif
 
 #ifdef CONFIG_PCI
@@ -109,7 +109,7 @@ void bcm1480_unmask_irq(int cpu, int irq)
 }
 
 #ifdef CONFIG_SMP
-static void bcm1480_set_affinity(unsigned int irq, const struct cpumask *mask)
+static int bcm1480_set_affinity(unsigned int irq, const struct cpumask *mask)
 {
        int i = 0, old_cpu, cpu, int_on, k;
        u64 cur_ints;
@@ -118,7 +118,7 @@ static void bcm1480_set_affinity(unsigned int irq, const struct cpumask *mask)
 
        if (cpumask_weight(mask) != 1) {
                printk("attempted to set irq affinity for irq %d to multiple CPUs\n", irq);
-               return;
+               return -1;
        }
        i = cpumask_first(mask);
 
@@ -152,6 +152,8 @@ static void bcm1480_set_affinity(unsigned int irq, const struct cpumask *mask)
                }
        }
        spin_unlock_irqrestore(&bcm1480_imr_lock, flags);
+
+       return 0;
 }
 #endif
 
index 38cb998ade22053b8963377b70d6f7dad7fb6b94..409dec798863194f364eb378666c9e7471fd0227 100644 (file)
@@ -50,7 +50,7 @@ static void enable_sb1250_irq(unsigned int irq);
 static void disable_sb1250_irq(unsigned int irq);
 static void ack_sb1250_irq(unsigned int irq);
 #ifdef CONFIG_SMP
-static void sb1250_set_affinity(unsigned int irq, const struct cpumask *mask);
+static int sb1250_set_affinity(unsigned int irq, const struct cpumask *mask);
 #endif
 
 #ifdef CONFIG_SIBYTE_HAS_LDT
@@ -103,7 +103,7 @@ void sb1250_unmask_irq(int cpu, int irq)
 }
 
 #ifdef CONFIG_SMP
-static void sb1250_set_affinity(unsigned int irq, const struct cpumask *mask)
+static int sb1250_set_affinity(unsigned int irq, const struct cpumask *mask)
 {
        int i = 0, old_cpu, cpu, int_on;
        u64 cur_ints;
@@ -113,7 +113,7 @@ static void sb1250_set_affinity(unsigned int irq, const struct cpumask *mask)
 
        if (cpumask_weight(mask) > 1) {
                printk("attempted to set irq affinity for irq %d to multiple CPUs\n", irq);
-               return;
+               return -1;
        }
 
        /* Convert logical CPU to physical CPU */
@@ -143,6 +143,8 @@ static void sb1250_set_affinity(unsigned int irq, const struct cpumask *mask)
                                        R_IMR_INTERRUPT_MASK));
        }
        spin_unlock_irqrestore(&sb1250_imr_lock, flags);
+
+       return 0;
 }
 #endif
 
index 4ea4229d765ccc0657148d4f2268931ea3d6b8f9..8007f1e6572986559789a2520603a77336c72214 100644 (file)
@@ -130,15 +130,17 @@ int cpu_check_affinity(unsigned int irq, const struct cpumask *dest)
        return cpu_dest;
 }
 
-static void cpu_set_affinity_irq(unsigned int irq, const struct cpumask *dest)
+static int cpu_set_affinity_irq(unsigned int irq, const struct cpumask *dest)
 {
        int cpu_dest;
 
        cpu_dest = cpu_check_affinity(irq, dest);
        if (cpu_dest < 0)
-               return;
+               return -1;
 
        cpumask_copy(&irq_desc[irq].affinity, dest);
+
+       return 0;
 }
 #endif
 
index 80b513449f4c44d3c98915efe233c01caa382f4d..be3581a8c294c8de4d083b1b2c5710381a35c2d9 100644 (file)
@@ -333,7 +333,7 @@ static void xics_eoi_lpar(unsigned int virq)
        lpar_xirr_info_set((0xff << 24) | irq);
 }
 
-static void xics_set_affinity(unsigned int virq, const struct cpumask *cpumask)
+static int xics_set_affinity(unsigned int virq, const struct cpumask *cpumask)
 {
        unsigned int irq;
        int status;
@@ -342,14 +342,14 @@ static void xics_set_affinity(unsigned int virq, const struct cpumask *cpumask)
 
        irq = (unsigned int)irq_map[virq].hwirq;
        if (irq == XICS_IPI || irq == XICS_IRQ_SPURIOUS)
-               return;
+               return -1;
 
        status = rtas_call(ibm_get_xive, 1, 3, xics_status, irq);
 
        if (status) {
                printk(KERN_ERR "%s: ibm,get-xive irq=%u returns %d\n",
                        __func__, irq, status);
-               return;
+               return -1;
        }
 
        /*
@@ -363,7 +363,7 @@ static void xics_set_affinity(unsigned int virq, const struct cpumask *cpumask)
                printk(KERN_WARNING
                        "%s: No online cpus in the mask %s for irq %d\n",
                        __func__, cpulist, virq);
-               return;
+               return -1;
        }
 
        status = rtas_call(ibm_set_xive, 3, 1, NULL,
@@ -372,8 +372,10 @@ static void xics_set_affinity(unsigned int virq, const struct cpumask *cpumask)
        if (status) {
                printk(KERN_ERR "%s: ibm,set-xive irq=%u returns %d\n",
                        __func__, irq, status);
-               return;
+               return -1;
        }
+
+       return 0;
 }
 
 static struct irq_chip xics_pic_direct = {
index 0efc12d1a3d77f98716f500c5ca12f9f923e3e9d..352d8c3ef5269c97e548789edccc49c420214a71 100644 (file)
@@ -807,7 +807,7 @@ static void mpic_end_ipi(unsigned int irq)
 
 #endif /* CONFIG_SMP */
 
-void mpic_set_affinity(unsigned int irq, const struct cpumask *cpumask)
+int mpic_set_affinity(unsigned int irq, const struct cpumask *cpumask)
 {
        struct mpic *mpic = mpic_from_irq(irq);
        unsigned int src = mpic_irq_to_hw(irq);
@@ -824,6 +824,8 @@ void mpic_set_affinity(unsigned int irq, const struct cpumask *cpumask)
                mpic_irq_write(src, MPIC_INFO(IRQ_DESTINATION),
                               mpic_physmask(cpus_addr(tmp)[0]));
        }
+
+       return 0;
 }
 
 static unsigned int mpic_type_to_vecpri(struct mpic *mpic, unsigned int type)
index 3cef2af10f4254daea1ff69769117ffb1f8a23b3..eff433c322a0c55632b7d413acfddc18ed5cbaa8 100644 (file)
@@ -36,6 +36,6 @@ static inline int mpic_pasemi_msi_init(struct mpic *mpic)
 
 extern int mpic_set_irq_type(unsigned int virq, unsigned int flow_type);
 extern void mpic_set_vector(unsigned int virq, unsigned int vector);
-extern void mpic_set_affinity(unsigned int irq, const struct cpumask *cpumask);
+extern int mpic_set_affinity(unsigned int irq, const struct cpumask *cpumask);
 
 #endif /* _POWERPC_SYSDEV_MPIC_H */
index 5deabe921a47b6ebdcd5f6371faf7eaab3c135e4..e5e78f9cfc95d7104ede2ab767fdd1e5401f623c 100644 (file)
@@ -318,10 +318,12 @@ static void sun4u_irq_enable(unsigned int virt_irq)
        }
 }
 
-static void sun4u_set_affinity(unsigned int virt_irq,
+static int sun4u_set_affinity(unsigned int virt_irq,
                               const struct cpumask *mask)
 {
        sun4u_irq_enable(virt_irq);
+
+       return 0;
 }
 
 /* Don't do anything.  The desc->status check for IRQ_DISABLED in
@@ -377,7 +379,7 @@ static void sun4v_irq_enable(unsigned int virt_irq)
                       ino, err);
 }
 
-static void sun4v_set_affinity(unsigned int virt_irq,
+static int sun4v_set_affinity(unsigned int virt_irq,
                               const struct cpumask *mask)
 {
        unsigned int ino = virt_irq_table[virt_irq].dev_ino;
@@ -388,6 +390,8 @@ static void sun4v_set_affinity(unsigned int virt_irq,
        if (err != HV_EOK)
                printk(KERN_ERR "sun4v_intr_settarget(%x,%lu): "
                       "err(%d)\n", ino, cpuid, err);
+
+       return 0;
 }
 
 static void sun4v_irq_disable(unsigned int virt_irq)
@@ -445,7 +449,7 @@ static void sun4v_virq_enable(unsigned int virt_irq)
                       dev_handle, dev_ino, err);
 }
 
-static void sun4v_virt_set_affinity(unsigned int virt_irq,
+static int sun4v_virt_set_affinity(unsigned int virt_irq,
                                    const struct cpumask *mask)
 {
        unsigned long cpuid, dev_handle, dev_ino;
@@ -461,6 +465,8 @@ static void sun4v_virt_set_affinity(unsigned int virt_irq,
                printk(KERN_ERR "sun4v_vintr_set_target(%lx,%lx,%lu): "
                       "err(%d)\n",
                       dev_handle, dev_ino, cpuid, err);
+
+       return 0;
 }
 
 static void sun4v_virq_disable(unsigned int virt_irq)
index a6efe0a2e9ae613a81bedec5e4772698d16541cc..b1d3f60525c010f34da659285eabed3157a39d2f 100644 (file)
@@ -274,15 +274,9 @@ config SPARSE_IRQ
 
          If you don't know what to do here, say N.
 
-config NUMA_MIGRATE_IRQ_DESC
-       bool "Move irq desc when changing irq smp_affinity"
+config NUMA_IRQ_DESC
+       def_bool y
        depends on SPARSE_IRQ && NUMA
-       depends on BROKEN
-       default n
-       ---help---
-         This enables moving irq_desc to cpu/node that irq will use handled.
-
-         If you don't know what to do here, say N.
 
 config X86_MPPARSE
        bool "Enable MPS table" if ACPI
@@ -355,7 +349,7 @@ config X86_UV
        depends on X86_64
        depends on X86_EXTENDED_PLATFORM
        depends on NUMA
-       select X86_X2APIC
+       depends on X86_X2APIC
        ---help---
          This option is needed in order to support SGI Ultraviolet systems.
          If you don't have one of these, you should say N here.
index 9fe5d212ab4cc8291e0c55ebdc619a57c85f2d64..27b8ce0f590863dcf1901a85ba12d30a19ccb76d 100644 (file)
@@ -195,7 +195,6 @@ CONFIG_HIGH_RES_TIMERS=y
 CONFIG_GENERIC_CLOCKEVENTS_BUILD=y
 CONFIG_SMP=y
 CONFIG_SPARSE_IRQ=y
-# CONFIG_NUMA_MIGRATE_IRQ_DESC is not set
 CONFIG_X86_FIND_SMP_CONFIG=y
 CONFIG_X86_MPPARSE=y
 # CONFIG_X86_ELAN is not set
index 42f2f83774224fb7897bf848fc6b84c4bce87380..3738438a91f5595f98bcc2513798ce9264dbd5dd 100644 (file)
@@ -107,8 +107,7 @@ extern u32 native_safe_apic_wait_icr_idle(void);
 extern void native_apic_icr_write(u32 low, u32 id);
 extern u64 native_apic_icr_read(void);
 
-#define EIM_8BIT_APIC_ID       0
-#define EIM_32BIT_APIC_ID      1
+extern int x2apic_mode;
 
 #ifdef CONFIG_X86_X2APIC
 /*
@@ -166,10 +165,9 @@ static inline u64 native_x2apic_icr_read(void)
        return val;
 }
 
-extern int x2apic, x2apic_phys;
+extern int x2apic_phys;
 extern void check_x2apic(void);
 extern void enable_x2apic(void);
-extern void enable_IR_x2apic(void);
 extern void x2apic_icr_write(u32 low, u32 id);
 static inline int x2apic_enabled(void)
 {
@@ -183,6 +181,8 @@ static inline int x2apic_enabled(void)
                return 1;
        return 0;
 }
+
+#define x2apic_supported()     (cpu_has_x2apic)
 #else
 static inline void check_x2apic(void)
 {
@@ -190,28 +190,20 @@ static inline void check_x2apic(void)
 static inline void enable_x2apic(void)
 {
 }
-static inline void enable_IR_x2apic(void)
-{
-}
 static inline int x2apic_enabled(void)
 {
        return 0;
 }
 
-#define        x2apic  0
-
+#define        x2apic_preenabled 0
+#define        x2apic_supported()      0
 #endif
 
-extern int get_physical_broadcast(void);
+extern void enable_IR_x2apic(void);
 
-#ifdef CONFIG_X86_X2APIC
-static inline void ack_x2APIC_irq(void)
-{
-       /* Docs say use 0 for future compatibility */
-       native_apic_msr_write(APIC_EOI, 0);
-}
-#endif
+extern int get_physical_broadcast(void);
 
+extern void apic_disable(void);
 extern int lapic_get_maxlvt(void);
 extern void clear_local_APIC(void);
 extern void connect_bsp_APIC(void);
@@ -252,7 +244,7 @@ static inline void lapic_shutdown(void) { }
 #define local_apic_timer_c2_ok         1
 static inline void init_apic_mappings(void) { }
 static inline void disable_local_APIC(void) { }
-
+static inline void apic_disable(void) { }
 #endif /* !CONFIG_X86_LOCAL_APIC */
 
 #ifdef CONFIG_X86_64
index bc9514fb3b13f70d75b11f037546eca8e43d07fd..7ddb36ab933b97b7757c0df30732d31d40404c19 100644 (file)
@@ -22,6 +22,7 @@
 #  define      APIC_INTEGRATED(x)      (1)
 #endif
 #define                APIC_XAPIC(x)           ((x) >= 0x14)
+#define                APIC_EXT_SPACE(x)       ((x) & 0x80000000)
 #define        APIC_TASKPRI    0x80
 #define                APIC_TPRI_MASK          0xFFu
 #define        APIC_ARBPRI     0x90
 #define                APIC_TDR_DIV_32         0x8
 #define                APIC_TDR_DIV_64         0x9
 #define                APIC_TDR_DIV_128        0xA
-#define        APIC_EILVT0     0x500
+#define        APIC_EFEAT      0x400
+#define        APIC_ECTRL      0x410
+#define APIC_EILVTn(n) (0x500 + 0x10 * n)
 #define                APIC_EILVT_NR_AMD_K8    1       /* # of extended interrupts */
 #define                APIC_EILVT_NR_AMD_10H   4
 #define                APIC_EILVT_LVTOFF(x)    (((x) >> 4) & 0xF)
 #define                APIC_EILVT_MSG_NMI      0x4
 #define                APIC_EILVT_MSG_EXT      0x7
 #define                APIC_EILVT_MASKED       (1 << 16)
-#define        APIC_EILVT1     0x510
-#define        APIC_EILVT2     0x520
-#define        APIC_EILVT3     0x530
 
 #define APIC_BASE (fix_to_virt(FIX_APIC_BASE))
 #define APIC_BASE_MSR  0x800
index b762ea49bd703ab3b28958cf83b6908e825e57a4..a7d14bbae110319cc67ebe6762c0b26d92693fc4 100644 (file)
@@ -63,7 +63,26 @@ extern unsigned long io_apic_irqs;
 extern void init_VISWS_APIC_irqs(void);
 extern void setup_IO_APIC(void);
 extern void disable_IO_APIC(void);
-extern int IO_APIC_get_PCI_irq_vector(int bus, int slot, int fn);
+
+struct io_apic_irq_attr {
+       int ioapic;
+       int ioapic_pin;
+       int trigger;
+       int polarity;
+};
+
+static inline void set_io_apic_irq_attr(struct io_apic_irq_attr *irq_attr,
+                                       int ioapic, int ioapic_pin,
+                                       int trigger, int polarity)
+{
+       irq_attr->ioapic     = ioapic;
+       irq_attr->ioapic_pin = ioapic_pin;
+       irq_attr->trigger    = trigger;
+       irq_attr->polarity   = polarity;
+}
+
+extern int IO_APIC_get_PCI_irq_vector(int bus, int devfn, int pin,
+                                       struct io_apic_irq_attr *irq_attr);
 extern void setup_ioapic_dest(void);
 
 extern void enable_IO_APIC(void);
index 1a99e6c092afcfaaad1a73b95ee4ecc7249f231b..58d7091eeb1fc1e8955c87246121060fbb851d31 100644 (file)
@@ -60,8 +60,4 @@ extern struct irq_chip i8259A_chip;
 extern void mask_8259A(void);
 extern void unmask_8259A(void);
 
-#ifdef CONFIG_X86_32
-extern void init_ISA_irqs(void);
-#endif
-
 #endif /* _ASM_X86_I8259_H */
index 9d826e436010005254bb04e13bac1ee45d802b75..daf866ed0612413f3781cdf6f863e8038daebe85 100644 (file)
@@ -154,22 +154,19 @@ extern int timer_through_8259;
 extern int io_apic_get_unique_id(int ioapic, int apic_id);
 extern int io_apic_get_version(int ioapic);
 extern int io_apic_get_redir_entries(int ioapic);
-extern int io_apic_set_pci_routing(int ioapic, int pin, int irq,
-                                  int edge_level, int active_high_low);
 #endif /* CONFIG_ACPI */
 
+struct io_apic_irq_attr;
+extern int io_apic_set_pci_routing(struct device *dev, int irq,
+                struct io_apic_irq_attr *irq_attr);
 extern int (*ioapic_renumber_irq)(int ioapic, int irq);
 extern void ioapic_init_mappings(void);
 
-#ifdef CONFIG_X86_64
 extern struct IO_APIC_route_entry **alloc_ioapic_entries(void);
 extern void free_ioapic_entries(struct IO_APIC_route_entry **ioapic_entries);
 extern int save_IO_APIC_setup(struct IO_APIC_route_entry **ioapic_entries);
 extern void mask_IO_APIC_setup(struct IO_APIC_route_entry **ioapic_entries);
 extern int restore_IO_APIC_setup(struct IO_APIC_route_entry **ioapic_entries);
-extern void reinit_intr_remapped_IO_APIC(int intr_remapping,
-       struct IO_APIC_route_entry **ioapic_entries);
-#endif
 
 extern void probe_nr_irqs_gsi(void);
 
index 0396760fccb85be05de0d5666c6019316d386d55..f275e2244505b98308ca72e66e26c250d29c61a8 100644 (file)
@@ -1,6 +1,6 @@
 #ifndef _ASM_X86_IRQ_REMAPPING_H
 #define _ASM_X86_IRQ_REMAPPING_H
 
-#define IRTE_DEST(dest) ((x2apic) ? dest : dest << 8)
+#define IRTE_DEST(dest) ((x2apic_mode) ? dest : dest << 8)
 
 #endif /* _ASM_X86_IRQ_REMAPPING_H */
index 3cbd79bbb47c82613341fca01ee6e174319342fe..910b5a3d6751fea966c71553cbda17bd5469805a 100644 (file)
@@ -34,6 +34,7 @@
 
 #ifdef CONFIG_X86_32
 # define SYSCALL_VECTOR                        0x80
+# define IA32_SYSCALL_VECTOR           0x80
 #else
 # define IA32_SYSCALL_VECTOR           0x80
 #endif
index 642fc7fc8cdc3fe8aedea4ddb60cacabc7925983..e2a1bb6d71ea832f6a6dbb3fc9ad7b58c7c9e6c4 100644 (file)
@@ -61,9 +61,11 @@ extern void get_smp_config(void);
 #ifdef CONFIG_X86_MPPARSE
 extern void find_smp_config(void);
 extern void early_reserve_e820_mpc_new(void);
+extern int enable_update_mptable;
 #else
 static inline void find_smp_config(void) { }
 static inline void early_reserve_e820_mpc_new(void) { }
+#define enable_update_mptable 0
 #endif
 
 void __cpuinit generic_processor_info(int apicid, int version);
@@ -72,20 +74,13 @@ extern void mp_register_ioapic(int id, u32 address, u32 gsi_base);
 extern void mp_override_legacy_irq(u8 bus_irq, u8 polarity, u8 trigger,
                                   u32 gsi);
 extern void mp_config_acpi_legacy_irqs(void);
-extern int mp_register_gsi(u32 gsi, int edge_level, int active_high_low);
+struct device;
+extern int mp_register_gsi(struct device *dev, u32 gsi, int edge_level,
+                                int active_high_low);
 extern int acpi_probe_gsi(void);
 #ifdef CONFIG_X86_IO_APIC
-extern int mp_config_acpi_gsi(unsigned char number, unsigned int devfn, u8 pin,
-                               u32 gsi, int triggering, int polarity);
 extern int mp_find_ioapic(int gsi);
 extern int mp_find_ioapic_pin(int ioapic, int gsi);
-#else
-static inline int
-mp_config_acpi_gsi(unsigned char number, unsigned int devfn, u8 pin,
-                  u32 gsi, int triggering, int polarity)
-{
-       return 0;
-}
 #endif
 #else /* !CONFIG_ACPI: */
 static inline int acpi_probe_gsi(void)
index bdc2ada05ae06056ad95e79bd8d6434d73510f5a..4093d1ed6db2a0b3eebc2983337a1592b673d5bc 100644 (file)
@@ -33,7 +33,6 @@ struct x86_quirks {
        int (*setup_ioapic_ids)(void);
 };
 
-extern void x86_quirk_pre_intr_init(void);
 extern void x86_quirk_intr_init(void);
 
 extern void x86_quirk_trap_init(void);
index 19e0d88b966d7b9154f46d9426450765dcf3d389..6a84ed166aec136334a644cc4fbaa676368ae983 100644 (file)
@@ -180,7 +180,7 @@ extern int safe_smp_processor_id(void);
 static inline int logical_smp_processor_id(void)
 {
        /* we don't want to mark this access volatile - bad code generation */
-       return GET_APIC_LOGICAL_ID(*(u32 *)(APIC_BASE + APIC_LDR));
+       return GET_APIC_LOGICAL_ID(apic_read(APIC_LDR));
 }
 
 #endif
index 88d1bfc847d30fc6b87007648fedc9970856e1af..235f5927bb97388751a93c03e06bcfab39a21999 100644 (file)
@@ -28,7 +28,7 @@ CFLAGS_paravirt.o     := $(nostackp)
 obj-y                  := process_$(BITS).o signal.o entry_$(BITS).o
 obj-y                  += traps.o irq.o irq_$(BITS).o dumpstack_$(BITS).o
 obj-y                  += time_$(BITS).o ioport.o ldt.o dumpstack.o
-obj-y                  += setup.o i8259.o irqinit_$(BITS).o
+obj-y                  += setup.o i8259.o irqinit.o
 obj-$(CONFIG_X86_VISWS)        += visws_quirks.o
 obj-$(CONFIG_X86_32)   += probe_roms_32.o
 obj-$(CONFIG_X86_32)   += sys_i386_32.o i386_ksyms_32.o
index 723989d7f8029711c0a6fda92e8016101ac2ede7..844e5e25213baa92243ef390f6075017e4d12748 100644 (file)
@@ -33,6 +33,7 @@
 #include <linux/irq.h>
 #include <linux/bootmem.h>
 #include <linux/ioport.h>
+#include <linux/pci.h>
 
 #include <asm/pgtable.h>
 #include <asm/io_apic.h>
@@ -522,7 +523,7 @@ int acpi_gsi_to_irq(u32 gsi, unsigned int *irq)
  * success: return IRQ number (>=0)
  * failure: return < 0
  */
-int acpi_register_gsi(u32 gsi, int triggering, int polarity)
+int acpi_register_gsi(struct device *dev, u32 gsi, int trigger, int polarity)
 {
        unsigned int irq;
        unsigned int plat_gsi = gsi;
@@ -532,14 +533,14 @@ int acpi_register_gsi(u32 gsi, int triggering, int polarity)
         * Make sure all (legacy) PCI IRQs are set as level-triggered.
         */
        if (acpi_irq_model == ACPI_IRQ_MODEL_PIC) {
-               if (triggering == ACPI_LEVEL_SENSITIVE)
+               if (trigger == ACPI_LEVEL_SENSITIVE)
                        eisa_set_level_irq(gsi);
        }
 #endif
 
 #ifdef CONFIG_X86_IO_APIC
        if (acpi_irq_model == ACPI_IRQ_MODEL_IOAPIC) {
-               plat_gsi = mp_register_gsi(gsi, triggering, polarity);
+               plat_gsi = mp_register_gsi(dev, gsi, trigger, polarity);
        }
 #endif
        acpi_gsi_to_irq(plat_gsi, &irq);
@@ -903,10 +904,8 @@ extern int es7000_plat;
 #endif
 
 static struct {
-       int apic_id;
        int gsi_base;
        int gsi_end;
-       DECLARE_BITMAP(pin_programmed, MP_MAX_IOAPIC_PIN + 1);
 } mp_ioapic_routing[MAX_IO_APICS];
 
 int mp_find_ioapic(int gsi)
@@ -995,7 +994,6 @@ void __init mp_register_ioapic(int id, u32 address, u32 gsi_base)
         * Build basic GSI lookup table to facilitate gsi->io_apic lookups
         * and to prevent reprogramming of IOAPIC pins (PCI GSIs).
         */
-       mp_ioapic_routing[idx].apic_id = mp_ioapics[idx].apicid;
        mp_ioapic_routing[idx].gsi_base = gsi_base;
        mp_ioapic_routing[idx].gsi_end = gsi_base +
            io_apic_get_redir_entries(idx);
@@ -1158,26 +1156,52 @@ void __init mp_config_acpi_legacy_irqs(void)
        }
 }
 
-int mp_register_gsi(u32 gsi, int triggering, int polarity)
+static int mp_config_acpi_gsi(struct device *dev, u32 gsi, int trigger,
+                       int polarity)
 {
+#ifdef CONFIG_X86_MPPARSE
+       struct mpc_intsrc mp_irq;
+       struct pci_dev *pdev;
+       unsigned char number;
+       unsigned int devfn;
        int ioapic;
-       int ioapic_pin;
-#ifdef CONFIG_X86_32
-#define MAX_GSI_NUM    4096
-#define IRQ_COMPRESSION_START  64
+       u8 pin;
 
-       static int pci_irq = IRQ_COMPRESSION_START;
-       /*
-        * Mapping between Global System Interrupts, which
-        * represent all possible interrupts, and IRQs
-        * assigned to actual devices.
-        */
-       static int gsi_to_irq[MAX_GSI_NUM];
-#else
+       if (!acpi_ioapic)
+               return 0;
+       if (!dev)
+               return 0;
+       if (dev->bus != &pci_bus_type)
+               return 0;
+
+       pdev = to_pci_dev(dev);
+       number = pdev->bus->number;
+       devfn = pdev->devfn;
+       pin = pdev->pin;
+       /* print the entry should happen on mptable identically */
+       mp_irq.type = MP_INTSRC;
+       mp_irq.irqtype = mp_INT;
+       mp_irq.irqflag = (trigger == ACPI_EDGE_SENSITIVE ? 4 : 0x0c) |
+                               (polarity == ACPI_ACTIVE_HIGH ? 1 : 3);
+       mp_irq.srcbus = number;
+       mp_irq.srcbusirq = (((devfn >> 3) & 0x1f) << 2) | ((pin - 1) & 3);
+       ioapic = mp_find_ioapic(gsi);
+       mp_irq.dstapic = mp_ioapics[ioapic].apicid;
+       mp_irq.dstirq = mp_find_ioapic_pin(ioapic, gsi);
+
+       save_mp_irq(&mp_irq);
+#endif
+       return 0;
+}
+
+int mp_register_gsi(struct device *dev, u32 gsi, int trigger, int polarity)
+{
+       int ioapic;
+       int ioapic_pin;
+       struct io_apic_irq_attr irq_attr;
 
        if (acpi_irq_model != ACPI_IRQ_MODEL_IOAPIC)
                return gsi;
-#endif
 
        /* Don't set up the ACPI SCI because it's already set up */
        if (acpi_gbl_FADT.sci_interrupt == gsi)
@@ -1196,93 +1220,22 @@ int mp_register_gsi(u32 gsi, int triggering, int polarity)
                gsi = ioapic_renumber_irq(ioapic, gsi);
 #endif
 
-       /*
-        * Avoid pin reprogramming.  PRTs typically include entries
-        * with redundant pin->gsi mappings (but unique PCI devices);
-        * we only program the IOAPIC on the first.
-        */
        if (ioapic_pin > MP_MAX_IOAPIC_PIN) {
                printk(KERN_ERR "Invalid reference to IOAPIC pin "
-                      "%d-%d\n", mp_ioapic_routing[ioapic].apic_id,
+                      "%d-%d\n", mp_ioapics[ioapic].apicid,
                       ioapic_pin);
                return gsi;
        }
-       if (test_bit(ioapic_pin, mp_ioapic_routing[ioapic].pin_programmed)) {
-               pr_debug("Pin %d-%d already programmed\n",
-                        mp_ioapic_routing[ioapic].apic_id, ioapic_pin);
-#ifdef CONFIG_X86_32
-               return (gsi < IRQ_COMPRESSION_START ? gsi : gsi_to_irq[gsi]);
-#else
-               return gsi;
-#endif
-       }
-
-       set_bit(ioapic_pin, mp_ioapic_routing[ioapic].pin_programmed);
-#ifdef CONFIG_X86_32
-       /*
-        * For GSI >= 64, use IRQ compression
-        */
-       if ((gsi >= IRQ_COMPRESSION_START)
-           && (triggering == ACPI_LEVEL_SENSITIVE)) {
-               /*
-                * For PCI devices assign IRQs in order, avoiding gaps
-                * due to unused I/O APIC pins.
-                */
-               int irq = gsi;
-               if (gsi < MAX_GSI_NUM) {
-                       /*
-                        * Retain the VIA chipset work-around (gsi > 15), but
-                        * avoid a problem where the 8254 timer (IRQ0) is setup
-                        * via an override (so it's not on pin 0 of the ioapic),
-                        * and at the same time, the pin 0 interrupt is a PCI
-                        * type.  The gsi > 15 test could cause these two pins
-                        * to be shared as IRQ0, and they are not shareable.
-                        * So test for this condition, and if necessary, avoid
-                        * the pin collision.
-                        */
-                       gsi = pci_irq++;
-                       /*
-                        * Don't assign IRQ used by ACPI SCI
-                        */
-                       if (gsi == acpi_gbl_FADT.sci_interrupt)
-                               gsi = pci_irq++;
-                       gsi_to_irq[irq] = gsi;
-               } else {
-                       printk(KERN_ERR "GSI %u is too high\n", gsi);
-                       return gsi;
-               }
-       }
-#endif
-       io_apic_set_pci_routing(ioapic, ioapic_pin, gsi,
-                               triggering == ACPI_EDGE_SENSITIVE ? 0 : 1,
-                               polarity == ACPI_ACTIVE_HIGH ? 0 : 1);
-       return gsi;
-}
-
-int mp_config_acpi_gsi(unsigned char number, unsigned int devfn, u8 pin,
-                       u32 gsi, int triggering, int polarity)
-{
-#ifdef CONFIG_X86_MPPARSE
-       struct mpc_intsrc mp_irq;
-       int ioapic;
 
-       if (!acpi_ioapic)
-               return 0;
+       if (enable_update_mptable)
+               mp_config_acpi_gsi(dev, gsi, trigger, polarity);
 
-       /* print the entry should happen on mptable identically */
-       mp_irq.type = MP_INTSRC;
-       mp_irq.irqtype = mp_INT;
-       mp_irq.irqflag = (triggering == ACPI_EDGE_SENSITIVE ? 4 : 0x0c) |
-                               (polarity == ACPI_ACTIVE_HIGH ? 1 : 3);
-       mp_irq.srcbus = number;
-       mp_irq.srcbusirq = (((devfn >> 3) & 0x1f) << 2) | ((pin - 1) & 3);
-       ioapic = mp_find_ioapic(gsi);
-       mp_irq.dstapic = mp_ioapic_routing[ioapic].apic_id;
-       mp_irq.dstirq = mp_find_ioapic_pin(ioapic, gsi);
+       set_io_apic_irq_attr(&irq_attr, ioapic, ioapic_pin,
+                            trigger == ACPI_EDGE_SENSITIVE ? 0 : 1,
+                            polarity == ACPI_ACTIVE_HIGH ? 0 : 1);
+       io_apic_set_pci_routing(dev, gsi, &irq_attr);
 
-       save_mp_irq(&mp_irq);
-#endif
-       return 0;
+       return gsi;
 }
 
 /*
index f2870920f246a9f1d7e2075c37b65b05de27dbf1..b0fd26442c418b9c9ca4cb17cda385a11106625b 100644 (file)
@@ -98,6 +98,29 @@ early_param("lapic", parse_lapic);
 /* Local APIC was disabled by the BIOS and enabled by the kernel */
 static int enabled_via_apicbase;
 
+/*
+ * Handle interrupt mode configuration register (IMCR).
+ * This register controls whether the interrupt signals
+ * that reach the BSP come from the master PIC or from the
+ * local APIC. Before entering Symmetric I/O Mode, either
+ * the BIOS or the operating system must switch out of
+ * PIC Mode by changing the IMCR.
+ */
+static inline void imcr_pic_to_apic(void)
+{
+       /* select IMCR register */
+       outb(0x70, 0x22);
+       /* NMI and 8259 INTR go through APIC */
+       outb(0x01, 0x23);
+}
+
+static inline void imcr_apic_to_pic(void)
+{
+       /* select IMCR register */
+       outb(0x70, 0x22);
+       /* NMI and 8259 INTR go directly to BSP */
+       outb(0x00, 0x23);
+}
 #endif
 
 #ifdef CONFIG_X86_64
@@ -111,13 +134,19 @@ static __init int setup_apicpmtimer(char *s)
 __setup("apicpmtimer", setup_apicpmtimer);
 #endif
 
+int x2apic_mode;
 #ifdef CONFIG_X86_X2APIC
-int x2apic;
 /* x2apic enabled before OS handover */
 static int x2apic_preenabled;
 static int disable_x2apic;
 static __init int setup_nox2apic(char *str)
 {
+       if (x2apic_enabled()) {
+               pr_warning("Bios already enabled x2apic, "
+                          "can't enforce nox2apic");
+               return 0;
+       }
+
        disable_x2apic = 1;
        setup_clear_cpu_cap(X86_FEATURE_X2APIC);
        return 0;
@@ -209,6 +238,31 @@ static int modern_apic(void)
        return lapic_get_version() >= 0x14;
 }
 
+/*
+ * bare function to substitute write operation
+ * and it's _that_ fast :)
+ */
+static void native_apic_write_dummy(u32 reg, u32 v)
+{
+       WARN_ON_ONCE((cpu_has_apic || !disable_apic));
+}
+
+static u32 native_apic_read_dummy(u32 reg)
+{
+       WARN_ON_ONCE((cpu_has_apic || !disable_apic));
+       return 0;
+}
+
+/*
+ * right after this call apic->write/read doesn't do anything
+ * note that there is no restore operation it works one way
+ */
+void apic_disable(void)
+{
+       apic->read = native_apic_read_dummy;
+       apic->write = native_apic_write_dummy;
+}
+
 void native_apic_wait_icr_idle(void)
 {
        while (apic_read(APIC_ICR) & APIC_ICR_BUSY)
@@ -348,7 +402,7 @@ static void __setup_APIC_LVTT(unsigned int clocks, int oneshot, int irqen)
 
 static void setup_APIC_eilvt(u8 lvt_off, u8 vector, u8 msg_type, u8 mask)
 {
-       unsigned long reg = (lvt_off << 4) + APIC_EILVT0;
+       unsigned long reg = (lvt_off << 4) + APIC_EILVTn(0);
        unsigned int  v   = (mask << 16) | (msg_type << 8) | vector;
 
        apic_write(reg, v);
@@ -815,7 +869,7 @@ void clear_local_APIC(void)
        u32 v;
 
        /* APIC hasn't been mapped yet */
-       if (!x2apic && !apic_phys)
+       if (!x2apic_mode && !apic_phys)
                return;
 
        maxlvt = lapic_get_maxlvt();
@@ -1287,7 +1341,7 @@ void check_x2apic(void)
 {
        if (x2apic_enabled()) {
                pr_info("x2apic enabled by BIOS, switching to x2apic ops\n");
-               x2apic_preenabled = x2apic = 1;
+               x2apic_preenabled = x2apic_mode = 1;
        }
 }
 
@@ -1295,7 +1349,7 @@ void enable_x2apic(void)
 {
        int msr, msr2;
 
-       if (!x2apic)
+       if (!x2apic_mode)
                return;
 
        rdmsr(MSR_IA32_APICBASE, msr, msr2);
@@ -1304,6 +1358,7 @@ void enable_x2apic(void)
                wrmsr(MSR_IA32_APICBASE, msr | X2APIC_ENABLE, 0);
        }
 }
+#endif /* CONFIG_X86_X2APIC */
 
 void __init enable_IR_x2apic(void)
 {
@@ -1312,32 +1367,21 @@ void __init enable_IR_x2apic(void)
        unsigned long flags;
        struct IO_APIC_route_entry **ioapic_entries = NULL;
 
-       if (!cpu_has_x2apic)
-               return;
-
-       if (!x2apic_preenabled && disable_x2apic) {
-               pr_info("Skipped enabling x2apic and Interrupt-remapping "
-                       "because of nox2apic\n");
-               return;
+       ret = dmar_table_init();
+       if (ret) {
+               pr_debug("dmar_table_init() failed with %d:\n", ret);
+               goto ir_failed;
        }
 
-       if (x2apic_preenabled && disable_x2apic)
-               panic("Bios already enabled x2apic, can't enforce nox2apic");
-
-       if (!x2apic_preenabled && skip_ioapic_setup) {
-               pr_info("Skipped enabling x2apic and Interrupt-remapping "
-                       "because of skipping io-apic setup\n");
-               return;
+       if (!intr_remapping_supported()) {
+               pr_debug("intr-remapping not supported\n");
+               goto ir_failed;
        }
 
-       ret = dmar_table_init();
-       if (ret) {
-               pr_info("dmar_table_init() failed with %d:\n", ret);
 
-               if (x2apic_preenabled)
-                       panic("x2apic enabled by bios. But IR enabling failed");
-               else
-                       pr_info("Not enabling x2apic,Intr-remapping\n");
+       if (!x2apic_preenabled && skip_ioapic_setup) {
+               pr_info("Skipped enabling intr-remap because of skipping "
+                       "io-apic setup\n");
                return;
        }
 
@@ -1357,19 +1401,16 @@ void __init enable_IR_x2apic(void)
        mask_IO_APIC_setup(ioapic_entries);
        mask_8259A();
 
-       ret = enable_intr_remapping(EIM_32BIT_APIC_ID);
-
-       if (ret && x2apic_preenabled) {
-               local_irq_restore(flags);
-               panic("x2apic enabled by bios. But IR enabling failed");
-       }
-
+       ret = enable_intr_remapping(x2apic_supported());
        if (ret)
                goto end_restore;
 
-       if (!x2apic) {
-               x2apic = 1;
+       pr_info("Enabled Interrupt-remapping\n");
+
+       if (x2apic_supported() && !x2apic_mode) {
+               x2apic_mode = 1;
                enable_x2apic();
+               pr_info("Enabled x2apic\n");
        }
 
 end_restore:
@@ -1378,37 +1419,34 @@ end_restore:
                 * IR enabling failed
                 */
                restore_IO_APIC_setup(ioapic_entries);
-       else
-               reinit_intr_remapped_IO_APIC(x2apic_preenabled, ioapic_entries);
 
        unmask_8259A();
        local_irq_restore(flags);
 
 end:
-       if (!ret) {
-               if (!x2apic_preenabled)
-                       pr_info("Enabled x2apic and interrupt-remapping\n");
-               else
-                       pr_info("Enabled Interrupt-remapping\n");
-       } else
-               pr_err("Failed to enable Interrupt-remapping and x2apic\n");
        if (ioapic_entries)
                free_ioapic_entries(ioapic_entries);
+
+       if (!ret)
+               return;
+
+ir_failed:
+       if (x2apic_preenabled)
+               panic("x2apic enabled by bios. But IR enabling failed");
+       else if (cpu_has_x2apic)
+               pr_info("Not enabling x2apic,Intr-remapping\n");
 #else
        if (!cpu_has_x2apic)
                return;
 
        if (x2apic_preenabled)
                panic("x2apic enabled prior OS handover,"
-                     " enable CONFIG_INTR_REMAP");
-
-       pr_info("Enable CONFIG_INTR_REMAP for enabling intr-remapping "
-               " and x2apic\n");
+                     " enable CONFIG_X86_X2APIC, CONFIG_INTR_REMAP");
 #endif
 
        return;
 }
-#endif /* CONFIG_X86_X2APIC */
+
 
 #ifdef CONFIG_X86_64
 /*
@@ -1425,7 +1463,6 @@ static int __init detect_init_APIC(void)
        }
 
        mp_lapic_addr = APIC_DEFAULT_PHYS_BASE;
-       boot_cpu_physical_apicid = 0;
        return 0;
 }
 #else
@@ -1539,32 +1576,42 @@ void __init early_init_lapic_mapping(void)
  */
 void __init init_apic_mappings(void)
 {
-       if (x2apic) {
+       unsigned int new_apicid;
+
+       if (x2apic_mode) {
                boot_cpu_physical_apicid = read_apic_id();
                return;
        }
 
-       /*
-        * If no local APIC can be found then set up a fake all
-        * zeroes page to simulate the local APIC and another
-        * one for the IO-APIC.
-        */
+       /* If no local APIC can be found return early */
        if (!smp_found_config && detect_init_APIC()) {
-               apic_phys = (unsigned long) alloc_bootmem_pages(PAGE_SIZE);
-               apic_phys = __pa(apic_phys);
-       } else
+               /* lets NOP'ify apic operations */
+               pr_info("APIC: disable apic facility\n");
+               apic_disable();
+       } else {
                apic_phys = mp_lapic_addr;
 
-       set_fixmap_nocache(FIX_APIC_BASE, apic_phys);
-       apic_printk(APIC_VERBOSE, "mapped APIC to %08lx (%08lx)\n",
-                               APIC_BASE, apic_phys);
+               /*
+                * acpi lapic path already maps that address in
+                * acpi_register_lapic_address()
+                */
+               if (!acpi_lapic)
+                       set_fixmap_nocache(FIX_APIC_BASE, apic_phys);
+
+               apic_printk(APIC_VERBOSE, "mapped APIC to %08lx (%08lx)\n",
+                                       APIC_BASE, apic_phys);
+       }
 
        /*
         * Fetch the APIC ID of the BSP in case we have a
         * default configuration (or the MP table is broken).
         */
-       if (boot_cpu_physical_apicid == -1U)
-               boot_cpu_physical_apicid = read_apic_id();
+       new_apicid = read_apic_id();
+       if (boot_cpu_physical_apicid != new_apicid) {
+               boot_cpu_physical_apicid = new_apicid;
+               apic_version[new_apicid] =
+                        GET_APIC_VERSION(apic_read(APIC_LVR));
+       }
 }
 
 /*
@@ -1733,8 +1780,7 @@ void __init connect_bsp_APIC(void)
                 */
                apic_printk(APIC_VERBOSE, "leaving PIC mode, "
                                "enabling APIC mode.\n");
-               outb(0x70, 0x22);
-               outb(0x01, 0x23);
+               imcr_pic_to_apic();
        }
 #endif
        if (apic->enable_apic_mode)
@@ -1762,8 +1808,7 @@ void disconnect_bsp_APIC(int virt_wire_setup)
                 */
                apic_printk(APIC_VERBOSE, "disabling APIC mode, "
                                "entering PIC mode.\n");
-               outb(0x70, 0x22);
-               outb(0x00, 0x23);
+               imcr_apic_to_pic();
                return;
        }
 #endif
@@ -1969,10 +2014,10 @@ static int lapic_suspend(struct sys_device *dev, pm_message_t state)
 
        local_irq_save(flags);
        disable_local_APIC();
-#ifdef CONFIG_INTR_REMAP
+
        if (intr_remapping_enabled)
                disable_intr_remapping();
-#endif
+
        local_irq_restore(flags);
        return 0;
 }
@@ -1982,8 +2027,6 @@ static int lapic_resume(struct sys_device *dev)
        unsigned int l, h;
        unsigned long flags;
        int maxlvt;
-
-#ifdef CONFIG_INTR_REMAP
        int ret;
        struct IO_APIC_route_entry **ioapic_entries = NULL;
 
@@ -1991,7 +2034,7 @@ static int lapic_resume(struct sys_device *dev)
                return 0;
 
        local_irq_save(flags);
-       if (x2apic) {
+       if (intr_remapping_enabled) {
                ioapic_entries = alloc_ioapic_entries();
                if (!ioapic_entries) {
                        WARN(1, "Alloc ioapic_entries in lapic resume failed.");
@@ -2007,17 +2050,10 @@ static int lapic_resume(struct sys_device *dev)
 
                mask_IO_APIC_setup(ioapic_entries);
                mask_8259A();
-               enable_x2apic();
        }
-#else
-       if (!apic_pm_state.active)
-               return 0;
 
-       local_irq_save(flags);
-       if (x2apic)
+       if (x2apic_mode)
                enable_x2apic();
-#endif
-
        else {
                /*
                 * Make sure the APICBASE points to the right address
@@ -2055,20 +2091,15 @@ static int lapic_resume(struct sys_device *dev)
        apic_write(APIC_ESR, 0);
        apic_read(APIC_ESR);
 
-#ifdef CONFIG_INTR_REMAP
-       if (intr_remapping_enabled)
-               reenable_intr_remapping(EIM_32BIT_APIC_ID);
-
-       if (x2apic) {
+       if (intr_remapping_enabled) {
+               reenable_intr_remapping(x2apic_mode);
                unmask_8259A();
                restore_IO_APIC_setup(ioapic_entries);
                free_ioapic_entries(ioapic_entries);
        }
-#endif
 
        local_irq_restore(flags);
 
-
        return 0;
 }
 
@@ -2117,31 +2148,14 @@ static void apic_pm_activate(void) { }
 #endif /* CONFIG_PM */
 
 #ifdef CONFIG_X86_64
-/*
- * apic_is_clustered_box() -- Check if we can expect good TSC
- *
- * Thus far, the major user of this is IBM's Summit2 series:
- *
- * Clustered boxes may have unsynced TSC problems if they are
- * multi-chassis. Use available data to take a good guess.
- * If in doubt, go HPET.
- */
-__cpuinit int apic_is_clustered_box(void)
+
+static int __cpuinit apic_cluster_num(void)
 {
        int i, clusters, zeros;
        unsigned id;
        u16 *bios_cpu_apicid;
        DECLARE_BITMAP(clustermap, NUM_APIC_CLUSTERS);
 
-       /*
-        * there is not this kind of box with AMD CPU yet.
-        * Some AMD box with quadcore cpu and 8 sockets apicid
-        * will be [4, 0x23] or [8, 0x27] could be thought to
-        * vsmp box still need checking...
-        */
-       if ((boot_cpu_data.x86_vendor == X86_VENDOR_AMD) && !is_vsmp_box())
-               return 0;
-
        bios_cpu_apicid = early_per_cpu_ptr(x86_bios_cpu_apicid);
        bitmap_zero(clustermap, NUM_APIC_CLUSTERS);
 
@@ -2177,18 +2191,67 @@ __cpuinit int apic_is_clustered_box(void)
                        ++zeros;
        }
 
-       /* ScaleMP vSMPowered boxes have one cluster per board and TSCs are
-        * not guaranteed to be synced between boards
-        */
-       if (is_vsmp_box() && clusters > 1)
+       return clusters;
+}
+
+static int __cpuinitdata multi_checked;
+static int __cpuinitdata multi;
+
+static int __cpuinit set_multi(const struct dmi_system_id *d)
+{
+       if (multi)
+               return 0;
+       pr_info("APIC: %s detected, Multi Chassis\n", d->ident);
+       multi = 1;
+       return 0;
+}
+
+static const __cpuinitconst struct dmi_system_id multi_dmi_table[] = {
+       {
+               .callback = set_multi,
+               .ident = "IBM System Summit2",
+               .matches = {
+                       DMI_MATCH(DMI_SYS_VENDOR, "IBM"),
+                       DMI_MATCH(DMI_PRODUCT_NAME, "Summit2"),
+               },
+       },
+       {}
+};
+
+static void __cpuinit dmi_check_multi(void)
+{
+       if (multi_checked)
+               return;
+
+       dmi_check_system(multi_dmi_table);
+       multi_checked = 1;
+}
+
+/*
+ * apic_is_clustered_box() -- Check if we can expect good TSC
+ *
+ * Thus far, the major user of this is IBM's Summit2 series:
+ * Clustered boxes may have unsynced TSC problems if they are
+ * multi-chassis.
+ * Use DMI to check them
+ */
+__cpuinit int apic_is_clustered_box(void)
+{
+       dmi_check_multi();
+       if (multi)
                return 1;
 
+       if (!is_vsmp_box())
+               return 0;
+
        /*
-        * If clusters > 2, then should be multi-chassis.
-        * May have to revisit this when multi-core + hyperthreaded CPUs come
-        * out, but AFAIK this will work even for them.
+        * ScaleMP vSMPowered boxes have one cluster per board and TSCs are
+        * not guaranteed to be synced between boards
         */
-       return (clusters > 2);
+       if (apic_cluster_num() > 1)
+               return 1;
+
+       return 0;
 }
 #endif
 
index 306e5e88fb6f4abc9a53a3ce8638ac904a67067e..d0c99abc26c32a8f0df48d61485b1f36acb9b4b2 100644 (file)
@@ -161,7 +161,7 @@ static int flat_apic_id_registered(void)
 
 static int flat_phys_pkg_id(int initial_apic_id, int index_msb)
 {
-       return hard_smp_processor_id() >> index_msb;
+       return initial_apic_id >> index_msb;
 }
 
 struct apic apic_flat =  {
@@ -235,7 +235,7 @@ static int physflat_acpi_madt_oem_check(char *oem_id, char *oem_table_id)
         * regardless of how many processors are present (x86_64 ES7000
         * is an example).
         */
-       if (acpi_gbl_FADT.header.revision > FADT2_REVISION_ID &&
+       if (acpi_gbl_FADT.header.revision >= FADT2_REVISION_ID &&
                (acpi_gbl_FADT.flags & ACPI_FADT_APIC_PHYSICAL)) {
                printk(KERN_DEBUG "system APIC only can use physical flat");
                return 1;
index 302947775575ebb69a670a4ef10f0184b2b82ac9..69328ac8de9c86e106d30af1337a80ab0d4488b1 100644 (file)
@@ -145,7 +145,7 @@ es7000_rename_gsi(int ioapic, int gsi)
        return gsi;
 }
 
-static int wakeup_secondary_cpu_via_mip(int cpu, unsigned long eip)
+static int __cpuinit wakeup_secondary_cpu_via_mip(int cpu, unsigned long eip)
 {
        unsigned long vect = 0, psaival = 0;
 
index 30da617d18e4735de234904fdc005cf527930c89..ac7f3b6ad583e31ff997d05155888d2735da16b3 100644 (file)
@@ -129,12 +129,9 @@ struct irq_pin_list {
        struct irq_pin_list *next;
 };
 
-static struct irq_pin_list *get_one_free_irq_2_pin(int cpu)
+static struct irq_pin_list *get_one_free_irq_2_pin(int node)
 {
        struct irq_pin_list *pin;
-       int node;
-
-       node = cpu_to_node(cpu);
 
        pin = kzalloc_node(sizeof(*pin), GFP_ATOMIC, node);
 
@@ -148,9 +145,6 @@ struct irq_cfg {
        unsigned move_cleanup_count;
        u8 vector;
        u8 move_in_progress : 1;
-#ifdef CONFIG_NUMA_MIGRATE_IRQ_DESC
-       u8 move_desc_pending : 1;
-#endif
 };
 
 /* irq_cfg is indexed by the sum of all RTEs in all I/O APICs. */
@@ -212,12 +206,9 @@ static struct irq_cfg *irq_cfg(unsigned int irq)
        return cfg;
 }
 
-static struct irq_cfg *get_one_free_irq_cfg(int cpu)
+static struct irq_cfg *get_one_free_irq_cfg(int node)
 {
        struct irq_cfg *cfg;
-       int node;
-
-       node = cpu_to_node(cpu);
 
        cfg = kzalloc_node(sizeof(*cfg), GFP_ATOMIC, node);
        if (cfg) {
@@ -238,13 +229,13 @@ static struct irq_cfg *get_one_free_irq_cfg(int cpu)
        return cfg;
 }
 
-int arch_init_chip_data(struct irq_desc *desc, int cpu)
+int arch_init_chip_data(struct irq_desc *desc, int node)
 {
        struct irq_cfg *cfg;
 
        cfg = desc->chip_data;
        if (!cfg) {
-               desc->chip_data = get_one_free_irq_cfg(cpu);
+               desc->chip_data = get_one_free_irq_cfg(node);
                if (!desc->chip_data) {
                        printk(KERN_ERR "can not alloc irq_cfg\n");
                        BUG_ON(1);
@@ -254,10 +245,9 @@ int arch_init_chip_data(struct irq_desc *desc, int cpu)
        return 0;
 }
 
-#ifdef CONFIG_NUMA_MIGRATE_IRQ_DESC
-
+/* for move_irq_desc */
 static void
-init_copy_irq_2_pin(struct irq_cfg *old_cfg, struct irq_cfg *cfg, int cpu)
+init_copy_irq_2_pin(struct irq_cfg *old_cfg, struct irq_cfg *cfg, int node)
 {
        struct irq_pin_list *old_entry, *head, *tail, *entry;
 
@@ -266,7 +256,7 @@ init_copy_irq_2_pin(struct irq_cfg *old_cfg, struct irq_cfg *cfg, int cpu)
        if (!old_entry)
                return;
 
-       entry = get_one_free_irq_2_pin(cpu);
+       entry = get_one_free_irq_2_pin(node);
        if (!entry)
                return;
 
@@ -276,7 +266,7 @@ init_copy_irq_2_pin(struct irq_cfg *old_cfg, struct irq_cfg *cfg, int cpu)
        tail            = entry;
        old_entry       = old_entry->next;
        while (old_entry) {
-               entry = get_one_free_irq_2_pin(cpu);
+               entry = get_one_free_irq_2_pin(node);
                if (!entry) {
                        entry = head;
                        while (entry) {
@@ -316,12 +306,12 @@ static void free_irq_2_pin(struct irq_cfg *old_cfg, struct irq_cfg *cfg)
 }
 
 void arch_init_copy_chip_data(struct irq_desc *old_desc,
-                                struct irq_desc *desc, int cpu)
+                                struct irq_desc *desc, int node)
 {
        struct irq_cfg *cfg;
        struct irq_cfg *old_cfg;
 
-       cfg = get_one_free_irq_cfg(cpu);
+       cfg = get_one_free_irq_cfg(node);
 
        if (!cfg)
                return;
@@ -332,7 +322,7 @@ void arch_init_copy_chip_data(struct irq_desc *old_desc,
 
        memcpy(cfg, old_cfg, sizeof(struct irq_cfg));
 
-       init_copy_irq_2_pin(old_cfg, cfg, cpu);
+       init_copy_irq_2_pin(old_cfg, cfg, node);
 }
 
 static void free_irq_cfg(struct irq_cfg *old_cfg)
@@ -356,19 +346,7 @@ void arch_free_chip_data(struct irq_desc *old_desc, struct irq_desc *desc)
                old_desc->chip_data = NULL;
        }
 }
-
-static void
-set_extra_move_desc(struct irq_desc *desc, const struct cpumask *mask)
-{
-       struct irq_cfg *cfg = desc->chip_data;
-
-       if (!cfg->move_in_progress) {
-               /* it means that domain is not changed */
-               if (!cpumask_intersects(desc->affinity, mask))
-                       cfg->move_desc_pending = 1;
-       }
-}
-#endif
+/* end for move_irq_desc */
 
 #else
 static struct irq_cfg *irq_cfg(unsigned int irq)
@@ -378,13 +356,6 @@ static struct irq_cfg *irq_cfg(unsigned int irq)
 
 #endif
 
-#ifndef CONFIG_NUMA_MIGRATE_IRQ_DESC
-static inline void
-set_extra_move_desc(struct irq_desc *desc, const struct cpumask *mask)
-{
-}
-#endif
-
 struct io_apic {
        unsigned int index;
        unsigned int unused[3];
@@ -518,132 +489,18 @@ static void ioapic_mask_entry(int apic, int pin)
        spin_unlock_irqrestore(&ioapic_lock, flags);
 }
 
-#ifdef CONFIG_SMP
-static void send_cleanup_vector(struct irq_cfg *cfg)
-{
-       cpumask_var_t cleanup_mask;
-
-       if (unlikely(!alloc_cpumask_var(&cleanup_mask, GFP_ATOMIC))) {
-               unsigned int i;
-               cfg->move_cleanup_count = 0;
-               for_each_cpu_and(i, cfg->old_domain, cpu_online_mask)
-                       cfg->move_cleanup_count++;
-               for_each_cpu_and(i, cfg->old_domain, cpu_online_mask)
-                       apic->send_IPI_mask(cpumask_of(i), IRQ_MOVE_CLEANUP_VECTOR);
-       } else {
-               cpumask_and(cleanup_mask, cfg->old_domain, cpu_online_mask);
-               cfg->move_cleanup_count = cpumask_weight(cleanup_mask);
-               apic->send_IPI_mask(cleanup_mask, IRQ_MOVE_CLEANUP_VECTOR);
-               free_cpumask_var(cleanup_mask);
-       }
-       cfg->move_in_progress = 0;
-}
-
-static void __target_IO_APIC_irq(unsigned int irq, unsigned int dest, struct irq_cfg *cfg)
-{
-       int apic, pin;
-       struct irq_pin_list *entry;
-       u8 vector = cfg->vector;
-
-       entry = cfg->irq_2_pin;
-       for (;;) {
-               unsigned int reg;
-
-               if (!entry)
-                       break;
-
-               apic = entry->apic;
-               pin = entry->pin;
-               /*
-                * With interrupt-remapping, destination information comes
-                * from interrupt-remapping table entry.
-                */
-               if (!irq_remapped(irq))
-                       io_apic_write(apic, 0x11 + pin*2, dest);
-               reg = io_apic_read(apic, 0x10 + pin*2);
-               reg &= ~IO_APIC_REDIR_VECTOR_MASK;
-               reg |= vector;
-               io_apic_modify(apic, 0x10 + pin*2, reg);
-               if (!entry->next)
-                       break;
-               entry = entry->next;
-       }
-}
-
-static int
-assign_irq_vector(int irq, struct irq_cfg *cfg, const struct cpumask *mask);
-
-/*
- * Either sets desc->affinity to a valid value, and returns
- * ->cpu_mask_to_apicid of that, or returns BAD_APICID and
- * leaves desc->affinity untouched.
- */
-static unsigned int
-set_desc_affinity(struct irq_desc *desc, const struct cpumask *mask)
-{
-       struct irq_cfg *cfg;
-       unsigned int irq;
-
-       if (!cpumask_intersects(mask, cpu_online_mask))
-               return BAD_APICID;
-
-       irq = desc->irq;
-       cfg = desc->chip_data;
-       if (assign_irq_vector(irq, cfg, mask))
-               return BAD_APICID;
-
-       /* check that before desc->addinity get updated */
-       set_extra_move_desc(desc, mask);
-
-       cpumask_copy(desc->affinity, mask);
-
-       return apic->cpu_mask_to_apicid_and(desc->affinity, cfg->domain);
-}
-
-static void
-set_ioapic_affinity_irq_desc(struct irq_desc *desc, const struct cpumask *mask)
-{
-       struct irq_cfg *cfg;
-       unsigned long flags;
-       unsigned int dest;
-       unsigned int irq;
-
-       irq = desc->irq;
-       cfg = desc->chip_data;
-
-       spin_lock_irqsave(&ioapic_lock, flags);
-       dest = set_desc_affinity(desc, mask);
-       if (dest != BAD_APICID) {
-               /* Only the high 8 bits are valid. */
-               dest = SET_APIC_LOGICAL_ID(dest);
-               __target_IO_APIC_irq(irq, dest, cfg);
-       }
-       spin_unlock_irqrestore(&ioapic_lock, flags);
-}
-
-static void
-set_ioapic_affinity_irq(unsigned int irq, const struct cpumask *mask)
-{
-       struct irq_desc *desc;
-
-       desc = irq_to_desc(irq);
-
-       set_ioapic_affinity_irq_desc(desc, mask);
-}
-#endif /* CONFIG_SMP */
-
 /*
  * The common case is 1:1 IRQ<->pin mappings. Sometimes there are
  * shared ISA-space IRQs, so we have to support them. We are super
  * fast in the common case, and fast for shared ISA-space IRQs.
  */
-static void add_pin_to_irq_cpu(struct irq_cfg *cfg, int cpu, int apic, int pin)
+static void add_pin_to_irq_node(struct irq_cfg *cfg, int node, int apic, int pin)
 {
        struct irq_pin_list *entry;
 
        entry = cfg->irq_2_pin;
        if (!entry) {
-               entry = get_one_free_irq_2_pin(cpu);
+               entry = get_one_free_irq_2_pin(node);
                if (!entry) {
                        printk(KERN_ERR "can not alloc irq_2_pin to add %d - %d\n",
                                        apic, pin);
@@ -663,7 +520,7 @@ static void add_pin_to_irq_cpu(struct irq_cfg *cfg, int cpu, int apic, int pin)
                entry = entry->next;
        }
 
-       entry->next = get_one_free_irq_2_pin(cpu);
+       entry->next = get_one_free_irq_2_pin(node);
        entry = entry->next;
        entry->apic = apic;
        entry->pin = pin;
@@ -672,7 +529,7 @@ static void add_pin_to_irq_cpu(struct irq_cfg *cfg, int cpu, int apic, int pin)
 /*
  * Reroute an IRQ to a different pin.
  */
-static void __init replace_pin_at_irq_cpu(struct irq_cfg *cfg, int cpu,
+static void __init replace_pin_at_irq_node(struct irq_cfg *cfg, int node,
                                      int oldapic, int oldpin,
                                      int newapic, int newpin)
 {
@@ -692,7 +549,7 @@ static void __init replace_pin_at_irq_cpu(struct irq_cfg *cfg, int cpu,
 
        /* why? call replace before add? */
        if (!replaced)
-               add_pin_to_irq_cpu(cfg, cpu, newapic, newpin);
+               add_pin_to_irq_node(cfg, node, newapic, newpin);
 }
 
 static inline void io_apic_modify_irq(struct irq_cfg *cfg,
@@ -850,7 +707,6 @@ static int __init ioapic_pirq_setup(char *str)
 __setup("pirq=", ioapic_pirq_setup);
 #endif /* CONFIG_X86_32 */
 
-#ifdef CONFIG_INTR_REMAP
 struct IO_APIC_route_entry **alloc_ioapic_entries(void)
 {
        int apic;
@@ -948,20 +804,6 @@ int restore_IO_APIC_setup(struct IO_APIC_route_entry **ioapic_entries)
        return 0;
 }
 
-void reinit_intr_remapped_IO_APIC(int intr_remapping,
-       struct IO_APIC_route_entry **ioapic_entries)
-
-{
-       /*
-        * for now plain restore of previous settings.
-        * TBD: In the case of OS enabling interrupt-remapping,
-        * IO-APIC RTE's need to be setup to point to interrupt-remapping
-        * table entries. for now, do a plain restore, and wait for
-        * the setup_IO_APIC_irqs() to do proper initialization.
-        */
-       restore_IO_APIC_setup(ioapic_entries);
-}
-
 void free_ioapic_entries(struct IO_APIC_route_entry **ioapic_entries)
 {
        int apic;
@@ -971,7 +813,6 @@ void free_ioapic_entries(struct IO_APIC_route_entry **ioapic_entries)
 
        kfree(ioapic_entries);
 }
-#endif
 
 /*
  * Find the IRQ entry number of a certain pin.
@@ -1032,54 +873,6 @@ static int __init find_isa_irq_apic(int irq, int type)
        return -1;
 }
 
-/*
- * Find a specific PCI IRQ entry.
- * Not an __init, possibly needed by modules
- */
-static int pin_2_irq(int idx, int apic, int pin);
-
-int IO_APIC_get_PCI_irq_vector(int bus, int slot, int pin)
-{
-       int apic, i, best_guess = -1;
-
-       apic_printk(APIC_DEBUG, "querying PCI -> IRQ mapping bus:%d, slot:%d, pin:%d.\n",
-               bus, slot, pin);
-       if (test_bit(bus, mp_bus_not_pci)) {
-               apic_printk(APIC_VERBOSE, "PCI BIOS passed nonexistent PCI bus %d!\n", bus);
-               return -1;
-       }
-       for (i = 0; i < mp_irq_entries; i++) {
-               int lbus = mp_irqs[i].srcbus;
-
-               for (apic = 0; apic < nr_ioapics; apic++)
-                       if (mp_ioapics[apic].apicid == mp_irqs[i].dstapic ||
-                           mp_irqs[i].dstapic == MP_APIC_ALL)
-                               break;
-
-               if (!test_bit(lbus, mp_bus_not_pci) &&
-                   !mp_irqs[i].irqtype &&
-                   (bus == lbus) &&
-                   (slot == ((mp_irqs[i].srcbusirq >> 2) & 0x1f))) {
-                       int irq = pin_2_irq(i, apic, mp_irqs[i].dstirq);
-
-                       if (!(apic || IO_APIC_IRQ(irq)))
-                               continue;
-
-                       if (pin == (mp_irqs[i].srcbusirq & 3))
-                               return irq;
-                       /*
-                        * Use the first all-but-pin matching entry as a
-                        * best-guess fuzzy result for broken mptables.
-                        */
-                       if (best_guess < 0)
-                               best_guess = irq;
-               }
-       }
-       return best_guess;
-}
-
-EXPORT_SYMBOL(IO_APIC_get_PCI_irq_vector);
-
 #if defined(CONFIG_EISA) || defined(CONFIG_MCA)
 /*
  * EISA Edge/Level control register, ELCR
@@ -1298,6 +1091,64 @@ static int pin_2_irq(int idx, int apic, int pin)
        return irq;
 }
 
+/*
+ * Find a specific PCI IRQ entry.
+ * Not an __init, possibly needed by modules
+ */
+int IO_APIC_get_PCI_irq_vector(int bus, int slot, int pin,
+                               struct io_apic_irq_attr *irq_attr)
+{
+       int apic, i, best_guess = -1;
+
+       apic_printk(APIC_DEBUG,
+                   "querying PCI -> IRQ mapping bus:%d, slot:%d, pin:%d.\n",
+                   bus, slot, pin);
+       if (test_bit(bus, mp_bus_not_pci)) {
+               apic_printk(APIC_VERBOSE,
+                           "PCI BIOS passed nonexistent PCI bus %d!\n", bus);
+               return -1;
+       }
+       for (i = 0; i < mp_irq_entries; i++) {
+               int lbus = mp_irqs[i].srcbus;
+
+               for (apic = 0; apic < nr_ioapics; apic++)
+                       if (mp_ioapics[apic].apicid == mp_irqs[i].dstapic ||
+                           mp_irqs[i].dstapic == MP_APIC_ALL)
+                               break;
+
+               if (!test_bit(lbus, mp_bus_not_pci) &&
+                   !mp_irqs[i].irqtype &&
+                   (bus == lbus) &&
+                   (slot == ((mp_irqs[i].srcbusirq >> 2) & 0x1f))) {
+                       int irq = pin_2_irq(i, apic, mp_irqs[i].dstirq);
+
+                       if (!(apic || IO_APIC_IRQ(irq)))
+                               continue;
+
+                       if (pin == (mp_irqs[i].srcbusirq & 3)) {
+                               set_io_apic_irq_attr(irq_attr, apic,
+                                                    mp_irqs[i].dstirq,
+                                                    irq_trigger(i),
+                                                    irq_polarity(i));
+                               return irq;
+                       }
+                       /*
+                        * Use the first all-but-pin matching entry as a
+                        * best-guess fuzzy result for broken mptables.
+                        */
+                       if (best_guess < 0) {
+                               set_io_apic_irq_attr(irq_attr, apic,
+                                                    mp_irqs[i].dstirq,
+                                                    irq_trigger(i),
+                                                    irq_polarity(i));
+                               best_guess = irq;
+                       }
+               }
+       }
+       return best_guess;
+}
+EXPORT_SYMBOL(IO_APIC_get_PCI_irq_vector);
+
 void lock_vector_lock(void)
 {
        /* Used to the online set of cpus does not change
@@ -1628,58 +1479,70 @@ static void setup_IO_APIC_irq(int apic_id, int pin, unsigned int irq, struct irq
        ioapic_write_entry(apic_id, pin, entry);
 }
 
+static struct {
+       DECLARE_BITMAP(pin_programmed, MP_MAX_IOAPIC_PIN + 1);
+} mp_ioapic_routing[MAX_IO_APICS];
+
 static void __init setup_IO_APIC_irqs(void)
 {
-       int apic_id, pin, idx, irq;
+       int apic_id = 0, pin, idx, irq;
        int notcon = 0;
        struct irq_desc *desc;
        struct irq_cfg *cfg;
-       int cpu = boot_cpu_id;
+       int node = cpu_to_node(boot_cpu_id);
 
        apic_printk(APIC_VERBOSE, KERN_DEBUG "init IO_APIC IRQs\n");
 
-       for (apic_id = 0; apic_id < nr_ioapics; apic_id++) {
-               for (pin = 0; pin < nr_ioapic_registers[apic_id]; pin++) {
-
-                       idx = find_irq_entry(apic_id, pin, mp_INT);
-                       if (idx == -1) {
-                               if (!notcon) {
-                                       notcon = 1;
-                                       apic_printk(APIC_VERBOSE,
-                                               KERN_DEBUG " %d-%d",
-                                               mp_ioapics[apic_id].apicid, pin);
-                               } else
-                                       apic_printk(APIC_VERBOSE, " %d-%d",
-                                               mp_ioapics[apic_id].apicid, pin);
-                               continue;
-                       }
-                       if (notcon) {
-                               apic_printk(APIC_VERBOSE,
-                                       " (apicid-pin) not connected\n");
-                               notcon = 0;
-                       }
+#ifdef CONFIG_ACPI
+       if (!acpi_disabled && acpi_ioapic) {
+               apic_id = mp_find_ioapic(0);
+               if (apic_id < 0)
+                       apic_id = 0;
+       }
+#endif
 
-                       irq = pin_2_irq(idx, apic_id, pin);
+       for (pin = 0; pin < nr_ioapic_registers[apic_id]; pin++) {
+               idx = find_irq_entry(apic_id, pin, mp_INT);
+               if (idx == -1) {
+                       if (!notcon) {
+                               notcon = 1;
+                               apic_printk(APIC_VERBOSE,
+                                       KERN_DEBUG " %d-%d",
+                                       mp_ioapics[apic_id].apicid, pin);
+                       } else
+                               apic_printk(APIC_VERBOSE, " %d-%d",
+                                       mp_ioapics[apic_id].apicid, pin);
+                       continue;
+               }
+               if (notcon) {
+                       apic_printk(APIC_VERBOSE,
+                               " (apicid-pin) not connected\n");
+                       notcon = 0;
+               }
 
-                       /*
-                        * Skip the timer IRQ if there's a quirk handler
-                        * installed and if it returns 1:
-                        */
-                       if (apic->multi_timer_check &&
-                                       apic->multi_timer_check(apic_id, irq))
-                               continue;
+               irq = pin_2_irq(idx, apic_id, pin);
 
-                       desc = irq_to_desc_alloc_cpu(irq, cpu);
-                       if (!desc) {
-                               printk(KERN_INFO "can not get irq_desc for %d\n", irq);
-                               continue;
-                       }
-                       cfg = desc->chip_data;
-                       add_pin_to_irq_cpu(cfg, cpu, apic_id, pin);
+               /*
+                * Skip the timer IRQ if there's a quirk handler
+                * installed and if it returns 1:
+                */
+               if (apic->multi_timer_check &&
+                               apic->multi_timer_check(apic_id, irq))
+                       continue;
 
-                       setup_IO_APIC_irq(apic_id, pin, irq, desc,
-                                       irq_trigger(idx), irq_polarity(idx));
+               desc = irq_to_desc_alloc_node(irq, node);
+               if (!desc) {
+                       printk(KERN_INFO "can not get irq_desc for %d\n", irq);
+                       continue;
                }
+               cfg = desc->chip_data;
+               add_pin_to_irq_node(cfg, node, apic_id, pin);
+               /*
+                * don't mark it in pin_programmed, so later acpi could
+                * set it correctly when irq < 16
+                */
+               setup_IO_APIC_irq(apic_id, pin, irq, desc,
+                               irq_trigger(idx), irq_polarity(idx));
        }
 
        if (notcon)
@@ -1869,7 +1732,7 @@ __apicdebuginit(void) print_APIC_bitfield(int base)
 
 __apicdebuginit(void) print_local_APIC(void *dummy)
 {
-       unsigned int v, ver, maxlvt;
+       unsigned int i, v, ver, maxlvt;
        u64 icr;
 
        if (apic_verbosity == APIC_QUIET)
@@ -1957,6 +1820,18 @@ __apicdebuginit(void) print_local_APIC(void *dummy)
        printk(KERN_DEBUG "... APIC TMCCT: %08x\n", v);
        v = apic_read(APIC_TDCR);
        printk(KERN_DEBUG "... APIC TDCR: %08x\n", v);
+
+       if (boot_cpu_has(X86_FEATURE_EXTAPIC)) {
+               v = apic_read(APIC_EFEAT);
+               maxlvt = (v >> 16) & 0xff;
+               printk(KERN_DEBUG "... APIC EFEAT: %08x\n", v);
+               v = apic_read(APIC_ECTRL);
+               printk(KERN_DEBUG "... APIC ECTRL: %08x\n", v);
+               for (i = 0; i < maxlvt; i++) {
+                       v = apic_read(APIC_EILVTn(i));
+                       printk(KERN_DEBUG "... APIC EILVT%d: %08x\n", i, v);
+               }
+       }
        printk("\n");
 }
 
@@ -2005,6 +1880,11 @@ __apicdebuginit(void) print_PIC(void)
 __apicdebuginit(int) print_all_ICs(void)
 {
        print_PIC();
+
+       /* don't print out if apic is not there */
+       if (!cpu_has_apic || disable_apic)
+               return 0;
+
        print_all_local_APICs();
        print_IO_APIC();
 
@@ -2360,9 +2240,121 @@ static int ioapic_retrigger_irq(unsigned int irq)
  */
 
 #ifdef CONFIG_SMP
+static void send_cleanup_vector(struct irq_cfg *cfg)
+{
+       cpumask_var_t cleanup_mask;
+
+       if (unlikely(!alloc_cpumask_var(&cleanup_mask, GFP_ATOMIC))) {
+               unsigned int i;
+               cfg->move_cleanup_count = 0;
+               for_each_cpu_and(i, cfg->old_domain, cpu_online_mask)
+                       cfg->move_cleanup_count++;
+               for_each_cpu_and(i, cfg->old_domain, cpu_online_mask)
+                       apic->send_IPI_mask(cpumask_of(i), IRQ_MOVE_CLEANUP_VECTOR);
+       } else {
+               cpumask_and(cleanup_mask, cfg->old_domain, cpu_online_mask);
+               cfg->move_cleanup_count = cpumask_weight(cleanup_mask);
+               apic->send_IPI_mask(cleanup_mask, IRQ_MOVE_CLEANUP_VECTOR);
+               free_cpumask_var(cleanup_mask);
+       }
+       cfg->move_in_progress = 0;
+}
+
+static void __target_IO_APIC_irq(unsigned int irq, unsigned int dest, struct irq_cfg *cfg)
+{
+       int apic, pin;
+       struct irq_pin_list *entry;
+       u8 vector = cfg->vector;
+
+       entry = cfg->irq_2_pin;
+       for (;;) {
+               unsigned int reg;
+
+               if (!entry)
+                       break;
+
+               apic = entry->apic;
+               pin = entry->pin;
+               /*
+                * With interrupt-remapping, destination information comes
+                * from interrupt-remapping table entry.
+                */
+               if (!irq_remapped(irq))
+                       io_apic_write(apic, 0x11 + pin*2, dest);
+               reg = io_apic_read(apic, 0x10 + pin*2);
+               reg &= ~IO_APIC_REDIR_VECTOR_MASK;
+               reg |= vector;
+               io_apic_modify(apic, 0x10 + pin*2, reg);
+               if (!entry->next)
+                       break;
+               entry = entry->next;
+       }
+}
+
+static int
+assign_irq_vector(int irq, struct irq_cfg *cfg, const struct cpumask *mask);
+
+/*
+ * Either sets desc->affinity to a valid value, and returns
+ * ->cpu_mask_to_apicid of that, or returns BAD_APICID and
+ * leaves desc->affinity untouched.
+ */
+static unsigned int
+set_desc_affinity(struct irq_desc *desc, const struct cpumask *mask)
+{
+       struct irq_cfg *cfg;
+       unsigned int irq;
+
+       if (!cpumask_intersects(mask, cpu_online_mask))
+               return BAD_APICID;
+
+       irq = desc->irq;
+       cfg = desc->chip_data;
+       if (assign_irq_vector(irq, cfg, mask))
+               return BAD_APICID;
+
+       cpumask_copy(desc->affinity, mask);
+
+       return apic->cpu_mask_to_apicid_and(desc->affinity, cfg->domain);
+}
+
+static int
+set_ioapic_affinity_irq_desc(struct irq_desc *desc, const struct cpumask *mask)
+{
+       struct irq_cfg *cfg;
+       unsigned long flags;
+       unsigned int dest;
+       unsigned int irq;
+       int ret = -1;
+
+       irq = desc->irq;
+       cfg = desc->chip_data;
+
+       spin_lock_irqsave(&ioapic_lock, flags);
+       dest = set_desc_affinity(desc, mask);
+       if (dest != BAD_APICID) {
+               /* Only the high 8 bits are valid. */
+               dest = SET_APIC_LOGICAL_ID(dest);
+               __target_IO_APIC_irq(irq, dest, cfg);
+               ret = 0;
+       }
+       spin_unlock_irqrestore(&ioapic_lock, flags);
+
+       return ret;
+}
+
+static int
+set_ioapic_affinity_irq(unsigned int irq, const struct cpumask *mask)
+{
+       struct irq_desc *desc;
+
+       desc = irq_to_desc(irq);
+
+       return set_ioapic_affinity_irq_desc(desc, mask);
+}
+
+#ifdef CONFIG_INTR_REMAP
 
-#ifdef CONFIG_INTR_REMAP
-
 /*
  * Migrate the IO-APIC irq in the presence of intr-remapping.
  *
@@ -2374,26 +2366,25 @@ static int ioapic_retrigger_irq(unsigned int irq)
  * Real vector that is used for interrupting cpu will be coming from
  * the interrupt-remapping table entry.
  */
-static void
+static int
 migrate_ioapic_irq_desc(struct irq_desc *desc, const struct cpumask *mask)
 {
        struct irq_cfg *cfg;
        struct irte irte;
        unsigned int dest;
        unsigned int irq;
+       int ret = -1;
 
        if (!cpumask_intersects(mask, cpu_online_mask))
-               return;
+               return ret;
 
        irq = desc->irq;
        if (get_irte(irq, &irte))
-               return;
+               return ret;
 
        cfg = desc->chip_data;
        if (assign_irq_vector(irq, cfg, mask))
-               return;
-
-       set_extra_move_desc(desc, mask);
+               return ret;
 
        dest = apic->cpu_mask_to_apicid_and(cfg->domain, mask);
 
@@ -2409,27 +2400,30 @@ migrate_ioapic_irq_desc(struct irq_desc *desc, const struct cpumask *mask)
                send_cleanup_vector(cfg);
 
        cpumask_copy(desc->affinity, mask);
+
+       return 0;
 }
 
 /*
  * Migrates the IRQ destination in the process context.
  */
-static void set_ir_ioapic_affinity_irq_desc(struct irq_desc *desc,
+static int set_ir_ioapic_affinity_irq_desc(struct irq_desc *desc,
                                            const struct cpumask *mask)
 {
-       migrate_ioapic_irq_desc(desc, mask);
+       return migrate_ioapic_irq_desc(desc, mask);
 }
-static void set_ir_ioapic_affinity_irq(unsigned int irq,
+static int set_ir_ioapic_affinity_irq(unsigned int irq,
                                       const struct cpumask *mask)
 {
        struct irq_desc *desc = irq_to_desc(irq);
 
-       set_ir_ioapic_affinity_irq_desc(desc, mask);
+       return set_ir_ioapic_affinity_irq_desc(desc, mask);
 }
 #else
-static inline void set_ir_ioapic_affinity_irq_desc(struct irq_desc *desc,
+static inline int set_ir_ioapic_affinity_irq_desc(struct irq_desc *desc,
                                                   const struct cpumask *mask)
 {
+       return 0;
 }
 #endif
 
@@ -2491,86 +2485,19 @@ static void irq_complete_move(struct irq_desc **descp)
        struct irq_cfg *cfg = desc->chip_data;
        unsigned vector, me;
 
-       if (likely(!cfg->move_in_progress)) {
-#ifdef CONFIG_NUMA_MIGRATE_IRQ_DESC
-               if (likely(!cfg->move_desc_pending))
-                       return;
-
-               /* domain has not changed, but affinity did */
-               me = smp_processor_id();
-               if (cpumask_test_cpu(me, desc->affinity)) {
-                       *descp = desc = move_irq_desc(desc, me);
-                       /* get the new one */
-                       cfg = desc->chip_data;
-                       cfg->move_desc_pending = 0;
-               }
-#endif
+       if (likely(!cfg->move_in_progress))
                return;
-       }
 
        vector = ~get_irq_regs()->orig_ax;
        me = smp_processor_id();
 
-       if (vector == cfg->vector && cpumask_test_cpu(me, cfg->domain)) {
-#ifdef CONFIG_NUMA_MIGRATE_IRQ_DESC
-               *descp = desc = move_irq_desc(desc, me);
-               /* get the new one */
-               cfg = desc->chip_data;
-#endif
+       if (vector == cfg->vector && cpumask_test_cpu(me, cfg->domain))
                send_cleanup_vector(cfg);
-       }
 }
 #else
 static inline void irq_complete_move(struct irq_desc **descp) {}
 #endif
 
-static void __eoi_ioapic_irq(unsigned int irq, struct irq_cfg *cfg)
-{
-       int apic, pin;
-       struct irq_pin_list *entry;
-
-       entry = cfg->irq_2_pin;
-       for (;;) {
-
-               if (!entry)
-                       break;
-
-               apic = entry->apic;
-               pin = entry->pin;
-               io_apic_eoi(apic, pin);
-               entry = entry->next;
-       }
-}
-
-static void
-eoi_ioapic_irq(struct irq_desc *desc)
-{
-       struct irq_cfg *cfg;
-       unsigned long flags;
-       unsigned int irq;
-
-       irq = desc->irq;
-       cfg = desc->chip_data;
-
-       spin_lock_irqsave(&ioapic_lock, flags);
-       __eoi_ioapic_irq(irq, cfg);
-       spin_unlock_irqrestore(&ioapic_lock, flags);
-}
-
-#ifdef CONFIG_X86_X2APIC
-static void ack_x2apic_level(unsigned int irq)
-{
-       struct irq_desc *desc = irq_to_desc(irq);
-       ack_x2APIC_irq();
-       eoi_ioapic_irq(desc);
-}
-
-static void ack_x2apic_edge(unsigned int irq)
-{
-       ack_x2APIC_irq();
-}
-#endif
-
 static void ack_apic_edge(unsigned int irq)
 {
        struct irq_desc *desc = irq_to_desc(irq);
@@ -2634,9 +2561,6 @@ static void ack_apic_level(unsigned int irq)
         */
        ack_APIC_irq();
 
-       if (irq_remapped(irq))
-               eoi_ioapic_irq(desc);
-
        /* Now we can move and renable the irq */
        if (unlikely(do_unmask_irq)) {
                /* Only migrate the irq if the ack has been received.
@@ -2683,22 +2607,50 @@ static void ack_apic_level(unsigned int irq)
 }
 
 #ifdef CONFIG_INTR_REMAP
+static void __eoi_ioapic_irq(unsigned int irq, struct irq_cfg *cfg)
+{
+       int apic, pin;
+       struct irq_pin_list *entry;
+
+       entry = cfg->irq_2_pin;
+       for (;;) {
+
+               if (!entry)
+                       break;
+
+               apic = entry->apic;
+               pin = entry->pin;
+               io_apic_eoi(apic, pin);
+               entry = entry->next;
+       }
+}
+
+static void
+eoi_ioapic_irq(struct irq_desc *desc)
+{
+       struct irq_cfg *cfg;
+       unsigned long flags;
+       unsigned int irq;
+
+       irq = desc->irq;
+       cfg = desc->chip_data;
+
+       spin_lock_irqsave(&ioapic_lock, flags);
+       __eoi_ioapic_irq(irq, cfg);
+       spin_unlock_irqrestore(&ioapic_lock, flags);
+}
+
 static void ir_ack_apic_edge(unsigned int irq)
 {
-#ifdef CONFIG_X86_X2APIC
-       if (x2apic_enabled())
-               return ack_x2apic_edge(irq);
-#endif
-       return ack_apic_edge(irq);
+       ack_APIC_irq();
 }
 
 static void ir_ack_apic_level(unsigned int irq)
 {
-#ifdef CONFIG_X86_X2APIC
-       if (x2apic_enabled())
-               return ack_x2apic_level(irq);
-#endif
-       return ack_apic_level(irq);
+       struct irq_desc *desc = irq_to_desc(irq);
+
+       ack_APIC_irq();
+       eoi_ioapic_irq(desc);
 }
 #endif /* CONFIG_INTR_REMAP */
 
@@ -2903,7 +2855,7 @@ static inline void __init check_timer(void)
 {
        struct irq_desc *desc = irq_to_desc(0);
        struct irq_cfg *cfg = desc->chip_data;
-       int cpu = boot_cpu_id;
+       int node = cpu_to_node(boot_cpu_id);
        int apic1, pin1, apic2, pin2;
        unsigned long flags;
        int no_pin1 = 0;
@@ -2969,7 +2921,7 @@ static inline void __init check_timer(void)
                 * Ok, does IRQ0 through the IOAPIC work?
                 */
                if (no_pin1) {
-                       add_pin_to_irq_cpu(cfg, cpu, apic1, pin1);
+                       add_pin_to_irq_node(cfg, node, apic1, pin1);
                        setup_timer_IRQ0_pin(apic1, pin1, cfg->vector);
                } else {
                        /* for edge trigger, setup_IO_APIC_irq already
@@ -3006,7 +2958,7 @@ static inline void __init check_timer(void)
                /*
                 * legacy devices should be connected to IO APIC #0
                 */
-               replace_pin_at_irq_cpu(cfg, cpu, apic1, pin1, apic2, pin2);
+               replace_pin_at_irq_node(cfg, node, apic1, pin1, apic2, pin2);
                setup_timer_IRQ0_pin(apic2, pin2, cfg->vector);
                enable_8259A_irq(0);
                if (timer_irq_works()) {
@@ -3218,14 +3170,13 @@ static int nr_irqs_gsi = NR_IRQS_LEGACY;
 /*
  * Dynamic irq allocate and deallocation
  */
-unsigned int create_irq_nr(unsigned int irq_want)
+unsigned int create_irq_nr(unsigned int irq_want, int node)
 {
        /* Allocate an unused irq */
        unsigned int irq;
        unsigned int new;
        unsigned long flags;
        struct irq_cfg *cfg_new = NULL;
-       int cpu = boot_cpu_id;
        struct irq_desc *desc_new = NULL;
 
        irq = 0;
@@ -3234,7 +3185,7 @@ unsigned int create_irq_nr(unsigned int irq_want)
 
        spin_lock_irqsave(&vector_lock, flags);
        for (new = irq_want; new < nr_irqs; new++) {
-               desc_new = irq_to_desc_alloc_cpu(new, cpu);
+               desc_new = irq_to_desc_alloc_node(new, node);
                if (!desc_new) {
                        printk(KERN_INFO "can not get irq_desc for %d\n", new);
                        continue;
@@ -3243,6 +3194,9 @@ unsigned int create_irq_nr(unsigned int irq_want)
 
                if (cfg_new->vector != 0)
                        continue;
+
+               desc_new = move_irq_desc(desc_new, node);
+
                if (__assign_irq_vector(new, cfg_new, apic->target_cpus()) == 0)
                        irq = new;
                break;
@@ -3260,11 +3214,12 @@ unsigned int create_irq_nr(unsigned int irq_want)
 
 int create_irq(void)
 {
+       int node = cpu_to_node(boot_cpu_id);
        unsigned int irq_want;
        int irq;
 
        irq_want = nr_irqs_gsi;
-       irq = create_irq_nr(irq_want);
+       irq = create_irq_nr(irq_want, node);
 
        if (irq == 0)
                irq = -1;
@@ -3366,7 +3321,7 @@ static int msi_compose_msg(struct pci_dev *pdev, unsigned int irq, struct msi_ms
 }
 
 #ifdef CONFIG_SMP
-static void set_msi_irq_affinity(unsigned int irq, const struct cpumask *mask)
+static int set_msi_irq_affinity(unsigned int irq, const struct cpumask *mask)
 {
        struct irq_desc *desc = irq_to_desc(irq);
        struct irq_cfg *cfg;
@@ -3375,7 +3330,7 @@ static void set_msi_irq_affinity(unsigned int irq, const struct cpumask *mask)
 
        dest = set_desc_affinity(desc, mask);
        if (dest == BAD_APICID)
-               return;
+               return -1;
 
        cfg = desc->chip_data;
 
@@ -3387,13 +3342,15 @@ static void set_msi_irq_affinity(unsigned int irq, const struct cpumask *mask)
        msg.address_lo |= MSI_ADDR_DEST_ID(dest);
 
        write_msi_msg_desc(desc, &msg);
+
+       return 0;
 }
 #ifdef CONFIG_INTR_REMAP
 /*
  * Migrate the MSI irq to another cpumask. This migration is
  * done in the process context using interrupt-remapping hardware.
  */
-static void
+static int
 ir_set_msi_irq_affinity(unsigned int irq, const struct cpumask *mask)
 {
        struct irq_desc *desc = irq_to_desc(irq);
@@ -3402,11 +3359,11 @@ ir_set_msi_irq_affinity(unsigned int irq, const struct cpumask *mask)
        struct irte irte;
 
        if (get_irte(irq, &irte))
-               return;
+               return -1;
 
        dest = set_desc_affinity(desc, mask);
        if (dest == BAD_APICID)
-               return;
+               return -1;
 
        irte.vector = cfg->vector;
        irte.dest_id = IRTE_DEST(dest);
@@ -3423,6 +3380,8 @@ ir_set_msi_irq_affinity(unsigned int irq, const struct cpumask *mask)
         */
        if (cfg->move_in_progress)
                send_cleanup_vector(cfg);
+
+       return 0;
 }
 
 #endif
@@ -3518,15 +3477,17 @@ int arch_setup_msi_irqs(struct pci_dev *dev, int nvec, int type)
        unsigned int irq_want;
        struct intel_iommu *iommu = NULL;
        int index = 0;
+       int node;
 
        /* x86 doesn't support multiple MSI yet */
        if (type == PCI_CAP_ID_MSI && nvec > 1)
                return 1;
 
+       node = dev_to_node(&dev->dev);
        irq_want = nr_irqs_gsi;
        sub_handle = 0;
        list_for_each_entry(msidesc, &dev->msi_list, list) {
-               irq = create_irq_nr(irq_want);
+               irq = create_irq_nr(irq_want, node);
                if (irq == 0)
                        return -1;
                irq_want = irq + 1;
@@ -3576,7 +3537,7 @@ void arch_teardown_msi_irq(unsigned int irq)
 
 #if defined (CONFIG_DMAR) || defined (CONFIG_INTR_REMAP)
 #ifdef CONFIG_SMP
-static void dmar_msi_set_affinity(unsigned int irq, const struct cpumask *mask)
+static int dmar_msi_set_affinity(unsigned int irq, const struct cpumask *mask)
 {
        struct irq_desc *desc = irq_to_desc(irq);
        struct irq_cfg *cfg;
@@ -3585,7 +3546,7 @@ static void dmar_msi_set_affinity(unsigned int irq, const struct cpumask *mask)
 
        dest = set_desc_affinity(desc, mask);
        if (dest == BAD_APICID)
-               return;
+               return -1;
 
        cfg = desc->chip_data;
 
@@ -3597,6 +3558,8 @@ static void dmar_msi_set_affinity(unsigned int irq, const struct cpumask *mask)
        msg.address_lo |= MSI_ADDR_DEST_ID(dest);
 
        dmar_msi_write(irq, &msg);
+
+       return 0;
 }
 
 #endif /* CONFIG_SMP */
@@ -3630,7 +3593,7 @@ int arch_setup_dmar_msi(unsigned int irq)
 #ifdef CONFIG_HPET_TIMER
 
 #ifdef CONFIG_SMP
-static void hpet_msi_set_affinity(unsigned int irq, const struct cpumask *mask)
+static int hpet_msi_set_affinity(unsigned int irq, const struct cpumask *mask)
 {
        struct irq_desc *desc = irq_to_desc(irq);
        struct irq_cfg *cfg;
@@ -3639,7 +3602,7 @@ static void hpet_msi_set_affinity(unsigned int irq, const struct cpumask *mask)
 
        dest = set_desc_affinity(desc, mask);
        if (dest == BAD_APICID)
-               return;
+               return -1;
 
        cfg = desc->chip_data;
 
@@ -3651,6 +3614,8 @@ static void hpet_msi_set_affinity(unsigned int irq, const struct cpumask *mask)
        msg.address_lo |= MSI_ADDR_DEST_ID(dest);
 
        hpet_msi_write(irq, &msg);
+
+       return 0;
 }
 
 #endif /* CONFIG_SMP */
@@ -3707,7 +3672,7 @@ static void target_ht_irq(unsigned int irq, unsigned int dest, u8 vector)
        write_ht_irq_msg(irq, &msg);
 }
 
-static void set_ht_irq_affinity(unsigned int irq, const struct cpumask *mask)
+static int set_ht_irq_affinity(unsigned int irq, const struct cpumask *mask)
 {
        struct irq_desc *desc = irq_to_desc(irq);
        struct irq_cfg *cfg;
@@ -3715,11 +3680,13 @@ static void set_ht_irq_affinity(unsigned int irq, const struct cpumask *mask)
 
        dest = set_desc_affinity(desc, mask);
        if (dest == BAD_APICID)
-               return;
+               return -1;
 
        cfg = desc->chip_data;
 
        target_ht_irq(irq, dest, cfg->vector);
+
+       return 0;
 }
 
 #endif
@@ -3794,6 +3761,8 @@ int arch_enable_uv_irq(char *irq_name, unsigned int irq, int cpu, int mmr_blade,
        unsigned long flags;
        int err;
 
+       BUILD_BUG_ON(sizeof(struct uv_IO_APIC_route_entry) != sizeof(unsigned long));
+
        cfg = irq_cfg(irq);
 
        err = assign_irq_vector(irq, cfg, eligible_cpu);
@@ -3807,15 +3776,13 @@ int arch_enable_uv_irq(char *irq_name, unsigned int irq, int cpu, int mmr_blade,
 
        mmr_value = 0;
        entry = (struct uv_IO_APIC_route_entry *)&mmr_value;
-       BUG_ON(sizeof(struct uv_IO_APIC_route_entry) != sizeof(unsigned long));
-
-       entry->vector = cfg->vector;
-       entry->delivery_mode = apic->irq_delivery_mode;
-       entry->dest_mode = apic->irq_dest_mode;
-       entry->polarity = 0;
-       entry->trigger = 0;
-       entry->mask = 0;
-       entry->dest = apic->cpu_mask_to_apicid(eligible_cpu);
+       entry->vector           = cfg->vector;
+       entry->delivery_mode    = apic->irq_delivery_mode;
+       entry->dest_mode        = apic->irq_dest_mode;
+       entry->polarity         = 0;
+       entry->trigger          = 0;
+       entry->mask             = 0;
+       entry->dest             = apic->cpu_mask_to_apicid(eligible_cpu);
 
        mmr_pnode = uv_blade_to_pnode(mmr_blade);
        uv_write_global_mmr64(mmr_pnode, mmr_offset, mmr_value);
@@ -3833,10 +3800,10 @@ void arch_disable_uv_irq(int mmr_blade, unsigned long mmr_offset)
        struct uv_IO_APIC_route_entry *entry;
        int mmr_pnode;
 
+       BUILD_BUG_ON(sizeof(struct uv_IO_APIC_route_entry) != sizeof(unsigned long));
+
        mmr_value = 0;
        entry = (struct uv_IO_APIC_route_entry *)&mmr_value;
-       BUG_ON(sizeof(struct uv_IO_APIC_route_entry) != sizeof(unsigned long));
-
        entry->mask = 1;
 
        mmr_pnode = uv_blade_to_pnode(mmr_blade);
@@ -3900,6 +3867,71 @@ int __init arch_probe_nr_irqs(void)
 }
 #endif
 
+static int __io_apic_set_pci_routing(struct device *dev, int irq,
+                               struct io_apic_irq_attr *irq_attr)
+{
+       struct irq_desc *desc;
+       struct irq_cfg *cfg;
+       int node;
+       int ioapic, pin;
+       int trigger, polarity;
+
+       ioapic = irq_attr->ioapic;
+       if (!IO_APIC_IRQ(irq)) {
+               apic_printk(APIC_QUIET,KERN_ERR "IOAPIC[%d]: Invalid reference to IRQ 0\n",
+                       ioapic);
+               return -EINVAL;
+       }
+
+       if (dev)
+               node = dev_to_node(dev);
+       else
+               node = cpu_to_node(boot_cpu_id);
+
+       desc = irq_to_desc_alloc_node(irq, node);
+       if (!desc) {
+               printk(KERN_INFO "can not get irq_desc %d\n", irq);
+               return 0;
+       }
+
+       pin = irq_attr->ioapic_pin;
+       trigger = irq_attr->trigger;
+       polarity = irq_attr->polarity;
+
+       /*
+        * IRQs < 16 are already in the irq_2_pin[] map
+        */
+       if (irq >= NR_IRQS_LEGACY) {
+               cfg = desc->chip_data;
+               add_pin_to_irq_node(cfg, node, ioapic, pin);
+       }
+
+       setup_IO_APIC_irq(ioapic, pin, irq, desc, trigger, polarity);
+
+       return 0;
+}
+
+int io_apic_set_pci_routing(struct device *dev, int irq,
+                               struct io_apic_irq_attr *irq_attr)
+{
+       int ioapic, pin;
+       /*
+        * Avoid pin reprogramming.  PRTs typically include entries
+        * with redundant pin->gsi mappings (but unique PCI devices);
+        * we only program the IOAPIC on the first.
+        */
+       ioapic = irq_attr->ioapic;
+       pin = irq_attr->ioapic_pin;
+       if (test_bit(pin, mp_ioapic_routing[ioapic].pin_programmed)) {
+               pr_debug("Pin %d-%d already programmed\n",
+                        mp_ioapics[ioapic].apicid, pin);
+               return 0;
+       }
+       set_bit(pin, mp_ioapic_routing[ioapic].pin_programmed);
+
+       return __io_apic_set_pci_routing(dev, irq, irq_attr);
+}
+
 /* --------------------------------------------------------------------------
                           ACPI-based IOAPIC Configuration
    -------------------------------------------------------------------------- */
@@ -3994,38 +4026,6 @@ int __init io_apic_get_version(int ioapic)
 }
 #endif
 
-int io_apic_set_pci_routing (int ioapic, int pin, int irq, int triggering, int polarity)
-{
-       struct irq_desc *desc;
-       struct irq_cfg *cfg;
-       int cpu = boot_cpu_id;
-
-       if (!IO_APIC_IRQ(irq)) {
-               apic_printk(APIC_QUIET,KERN_ERR "IOAPIC[%d]: Invalid reference to IRQ 0\n",
-                       ioapic);
-               return -EINVAL;
-       }
-
-       desc = irq_to_desc_alloc_cpu(irq, cpu);
-       if (!desc) {
-               printk(KERN_INFO "can not get irq_desc %d\n", irq);
-               return 0;
-       }
-
-       /*
-        * IRQs < 16 are already in the irq_2_pin[] map
-        */
-       if (irq >= NR_IRQS_LEGACY) {
-               cfg = desc->chip_data;
-               add_pin_to_irq_cpu(cfg, cpu, ioapic, pin);
-       }
-
-       setup_IO_APIC_irq(ioapic, pin, irq, desc, triggering, polarity);
-
-       return 0;
-}
-
-
 int acpi_get_override_irq(int bus_irq, int *trigger, int *polarity)
 {
        int i;
@@ -4055,51 +4055,44 @@ int acpi_get_override_irq(int bus_irq, int *trigger, int *polarity)
 #ifdef CONFIG_SMP
 void __init setup_ioapic_dest(void)
 {
-       int pin, ioapic, irq, irq_entry;
+       int pin, ioapic = 0, irq, irq_entry;
        struct irq_desc *desc;
-       struct irq_cfg *cfg;
        const struct cpumask *mask;
 
        if (skip_ioapic_setup == 1)
                return;
 
-       for (ioapic = 0; ioapic < nr_ioapics; ioapic++) {
-               for (pin = 0; pin < nr_ioapic_registers[ioapic]; pin++) {
-                       irq_entry = find_irq_entry(ioapic, pin, mp_INT);
-                       if (irq_entry == -1)
-                               continue;
-                       irq = pin_2_irq(irq_entry, ioapic, pin);
-
-                       /* setup_IO_APIC_irqs could fail to get vector for some device
-                        * when you have too many devices, because at that time only boot
-                        * cpu is online.
-                        */
-                       desc = irq_to_desc(irq);
-                       cfg = desc->chip_data;
-                       if (!cfg->vector) {
-                               setup_IO_APIC_irq(ioapic, pin, irq, desc,
-                                                 irq_trigger(irq_entry),
-                                                 irq_polarity(irq_entry));
-                               continue;
+#ifdef CONFIG_ACPI
+       if (!acpi_disabled && acpi_ioapic) {
+               ioapic = mp_find_ioapic(0);
+               if (ioapic < 0)
+                       ioapic = 0;
+       }
+#endif
 
-                       }
+       for (pin = 0; pin < nr_ioapic_registers[ioapic]; pin++) {
+               irq_entry = find_irq_entry(ioapic, pin, mp_INT);
+               if (irq_entry == -1)
+                       continue;
+               irq = pin_2_irq(irq_entry, ioapic, pin);
 
-                       /*
-                        * Honour affinities which have been set in early boot
-                        */
-                       if (desc->status &
-                           (IRQ_NO_BALANCING | IRQ_AFFINITY_SET))
-                               mask = desc->affinity;
-                       else
-                               mask = apic->target_cpus();
+               desc = irq_to_desc(irq);
 
-                       if (intr_remapping_enabled)
-                               set_ir_ioapic_affinity_irq_desc(desc, mask);
-                       else
-                               set_ioapic_affinity_irq_desc(desc, mask);
-               }
+               /*
+                * Honour affinities which have been set in early boot
+                */
+               if (desc->status &
+                   (IRQ_NO_BALANCING | IRQ_AFFINITY_SET))
+                       mask = desc->affinity;
+               else
+                       mask = apic->target_cpus();
 
+               if (intr_remapping_enabled)
+                       set_ir_ioapic_affinity_irq_desc(desc, mask);
+               else
+                       set_ioapic_affinity_irq_desc(desc, mask);
        }
+
 }
 #endif
 
index 1783652bb0e56c8140e411a4ba5643a64ab4d0fc..bc3e880f9b82e76902b305d10920b70b05c440ac 100644 (file)
@@ -50,7 +50,7 @@ static struct apic *apic_probe[] __initdata = {
 void __init default_setup_apic_routing(void)
 {
 #ifdef CONFIG_X86_X2APIC
-       if (x2apic && (apic != &apic_x2apic_phys &&
+       if (x2apic_mode && (apic != &apic_x2apic_phys &&
 #ifdef CONFIG_X86_UV
                       apic != &apic_x2apic_uv_x &&
 #endif
index 9cfe1f415d81f3659f1f68b8f88dcb4365be3ff7..344eee4ac0a48242d64db5676ec38fbe92d42c73 100644 (file)
@@ -173,13 +173,6 @@ static inline int is_WPEG(struct rio_detail *rio){
                rio->type == LookOutAWPEG || rio->type == LookOutBWPEG);
 }
 
-
-/* In clustered mode, the high nibble of APIC ID is a cluster number.
- * The low nibble is a 4-bit bitmap. */
-#define XAPIC_DEST_CPUS_SHIFT  4
-#define XAPIC_DEST_CPUS_MASK   ((1u << XAPIC_DEST_CPUS_SHIFT) - 1)
-#define XAPIC_DEST_CLUSTER_MASK        (XAPIC_DEST_CPUS_MASK << XAPIC_DEST_CPUS_SHIFT)
-
 #define SUMMIT_APIC_DFR_VALUE  (APIC_DFR_CLUSTER)
 
 static const struct cpumask *summit_target_cpus(void)
index 2bda693529762b71f30ae2c26fa08a7692ca5cb5..780a733a5e7af0caaee7e7210d03fd12874271fb 100644 (file)
@@ -105,7 +105,7 @@ static void uv_vector_allocation_domain(int cpu, struct cpumask *retmask)
        cpumask_set_cpu(cpu, retmask);
 }
 
-static int uv_wakeup_secondary(int phys_apicid, unsigned long start_rip)
+static int __cpuinit uv_wakeup_secondary(int phys_apicid, unsigned long start_rip)
 {
 #ifdef CONFIG_SMP
        unsigned long val;
@@ -583,15 +583,18 @@ void __init uv_system_init(void)
 
        bytes = sizeof(struct uv_blade_info) * uv_num_possible_blades();
        uv_blade_info = kmalloc(bytes, GFP_KERNEL);
+       BUG_ON(!uv_blade_info);
 
        get_lowmem_redirect(&lowmem_redir_base, &lowmem_redir_size);
 
        bytes = sizeof(uv_node_to_blade[0]) * num_possible_nodes();
        uv_node_to_blade = kmalloc(bytes, GFP_KERNEL);
+       BUG_ON(!uv_node_to_blade);
        memset(uv_node_to_blade, 255, bytes);
 
        bytes = sizeof(uv_cpu_to_blade[0]) * num_possible_cpus();
        uv_cpu_to_blade = kmalloc(bytes, GFP_KERNEL);
+       BUG_ON(!uv_cpu_to_blade);
        memset(uv_cpu_to_blade, 255, bytes);
 
        blade = 0;
index 7e4a459daa644f30309f50e9ca65ece4be85fad7..728b3750a3e8ba5865aae6a551e79a94b37d27c0 100644 (file)
@@ -272,7 +272,7 @@ static void __cpuinit srat_detect_node(struct cpuinfo_x86 *c)
 #if defined(CONFIG_NUMA) && defined(CONFIG_X86_64)
        int cpu = smp_processor_id();
        int node;
-       unsigned apicid = hard_smp_processor_id();
+       unsigned apicid = cpu_has_apic ? hard_smp_processor_id() : c->apicid;
 
        node = c->phys_proc_id;
        if (apicid_to_node[apicid] != NUMA_NO_NODE)
index 77848d9fca6833fa88488adb6e22cae027a7d6c1..c2fa56a3ae13822cb686c91743aa58b83b0452f8 100644 (file)
@@ -768,6 +768,12 @@ static void __cpuinit identify_cpu(struct cpuinfo_x86 *c)
        if (this_cpu->c_identify)
                this_cpu->c_identify(c);
 
+       /* Clear/Set all flags overriden by options, after probe */
+       for (i = 0; i < NCAPINTS; i++) {
+               c->x86_capability[i] &= ~cpu_caps_cleared[i];
+               c->x86_capability[i] |= cpu_caps_set[i];
+       }
+
 #ifdef CONFIG_X86_64
        c->apicid = apic->phys_pkg_id(c->initial_apicid, 0);
 #endif
index 46e29ab96c6ac9d6765f0f1a89e7c043ed2f5cbd..2fc4f6bb9ca5116b32f654ba4e35be616712ba9f 100644 (file)
@@ -588,8 +588,20 @@ static void print_apic(void *arg)
        seq_printf(seq, " TMICT\t\t: %08x\n",  apic_read(APIC_TMICT));
        seq_printf(seq, " TMCCT\t\t: %08x\n",  apic_read(APIC_TMCCT));
        seq_printf(seq, " TDCR\t\t: %08x\n",  apic_read(APIC_TDCR));
-#endif /* CONFIG_X86_LOCAL_APIC */
+       if (boot_cpu_has(X86_FEATURE_EXTAPIC)) {
+               unsigned int i, v, maxeilvt;
+
+               v = apic_read(APIC_EFEAT);
+               maxeilvt = (v >> 16) & 0xff;
+               seq_printf(seq, " EFEAT\t\t: %08x\n", v);
+               seq_printf(seq, " ECTRL\t\t: %08x\n", apic_read(APIC_ECTRL));
 
+               for (i = 0; i < maxeilvt; i++) {
+                       v = apic_read(APIC_EILVTn(i));
+                       seq_printf(seq, " EILVT%d\t\t: %08x\n", i, v);
+               }
+       }
+#endif /* CONFIG_X86_LOCAL_APIC */
        seq_printf(seq, "\n MSR\t:\n");
 }
 
index 7437fa133c02dfdde137ca7201fb9734888a85bc..daed39ba2614dbcad31e4725b343d56d0912f05d 100644 (file)
@@ -229,12 +229,12 @@ static void __cpuinit intel_workarounds(struct cpuinfo_x86 *c)
 }
 #endif
 
-static void __cpuinit srat_detect_node(void)
+static void __cpuinit srat_detect_node(struct cpuinfo_x86 *c)
 {
 #if defined(CONFIG_NUMA) && defined(CONFIG_X86_64)
        unsigned node;
        int cpu = smp_processor_id();
-       int apicid = hard_smp_processor_id();
+       int apicid = cpu_has_apic ? hard_smp_processor_id() : c->apicid;
 
        /* Don't do the funky fallback heuristics the AMD version employs
           for now. */
@@ -400,7 +400,7 @@ static void __cpuinit init_intel(struct cpuinfo_x86 *c)
        }
 
        /* Work around errata */
-       srat_detect_node();
+       srat_detect_node(c);
 
        if (cpu_has(c, X86_FEATURE_VMX))
                detect_vmx_virtcap(c);
index c3fe010d74c8e8823793cd9ff816ee02adc8ebde..c1739ac29708cc8cd3ab9267f7b62a9e42b7ad2b 100644 (file)
@@ -24,9 +24,9 @@ void (*generic_interrupt_extension)(void) = NULL;
  */
 void ack_bad_irq(unsigned int irq)
 {
-       printk(KERN_ERR "unexpected IRQ trap at vector %02x\n", irq);
+       if (printk_ratelimit())
+               pr_err("unexpected IRQ trap at vector %02x\n", irq);
 
-#ifdef CONFIG_X86_LOCAL_APIC
        /*
         * Currently unexpected vectors happen only on SMP and APIC.
         * We _must_ ack these because every local APIC has only N
@@ -36,9 +36,7 @@ void ack_bad_irq(unsigned int irq)
         * completely.
         * But only ack when the APIC is enabled -AK
         */
-       if (cpu_has_apic)
-               ack_APIC_irq();
-#endif
+       ack_APIC_irq();
 }
 
 #define irq_stats(x)           (&per_cpu(irq_stat, x))
@@ -178,7 +176,7 @@ u64 arch_irq_stat_cpu(unsigned int cpu)
        sum += irq_stats(cpu)->irq_thermal_count;
 # ifdef CONFIG_X86_64
        sum += irq_stats(cpu)->irq_threshold_count;
-#endif
+# endif
 #endif
        return sum;
 }
@@ -213,14 +211,11 @@ unsigned int __irq_entry do_IRQ(struct pt_regs *regs)
        irq = __get_cpu_var(vector_irq)[vector];
 
        if (!handle_irq(irq, regs)) {
-#ifdef CONFIG_X86_64
-               if (!disable_apic)
-                       ack_APIC_irq();
-#endif
+               ack_APIC_irq();
 
                if (printk_ratelimit())
-                       printk(KERN_EMERG "%s: %d.%d No irq handler for vector (irq %d)\n",
-                              __func__, smp_processor_id(), vector, irq);
+                       pr_emerg("%s: %d.%d No irq handler for vector (irq %d)\n",
+                               __func__, smp_processor_id(), vector, irq);
        }
 
        irq_exit();
similarity index 68%
rename from arch/x86/kernel/irqinit_32.c
rename to arch/x86/kernel/irqinit.c
index 368b0a8836f902be69531754a72fb75e7b9a4e24..2e08b10ad51abf5be458380780242b313f160e76 100644 (file)
@@ -1,20 +1,25 @@
+#include <linux/linkage.h>
 #include <linux/errno.h>
 #include <linux/signal.h>
 #include <linux/sched.h>
 #include <linux/ioport.h>
 #include <linux/interrupt.h>
+#include <linux/timex.h>
 #include <linux/slab.h>
 #include <linux/random.h>
+#include <linux/kprobes.h>
 #include <linux/init.h>
 #include <linux/kernel_stat.h>
 #include <linux/sysdev.h>
 #include <linux/bitops.h>
+#include <linux/acpi.h>
 #include <linux/io.h>
 #include <linux/delay.h>
 
 #include <asm/atomic.h>
 #include <asm/system.h>
 #include <asm/timer.h>
+#include <asm/hw_irq.h>
 #include <asm/pgtable.h>
 #include <asm/desc.h>
 #include <asm/apic.h>
 #include <asm/i8259.h>
 #include <asm/traps.h>
 
+/*
+ * ISA PIC or low IO-APIC triggered (INTA-cycle or APIC) interrupts:
+ * (these are usually mapped to vectors 0x30-0x3f)
+ */
+
+/*
+ * The IO-APIC gives us many more interrupt sources. Most of these
+ * are unused but an SMP system is supposed to have enough memory ...
+ * sometimes (mostly wrt. hw bugs) we get corrupted vectors all
+ * across the spectrum, so we really want to be prepared to get all
+ * of these. Plus, more powerful systems might have more than 64
+ * IO-APIC registers.
+ *
+ * (these are usually mapped into the 0x30-0xff vector range)
+ */
 
+#ifdef CONFIG_X86_32
 /*
  * Note that on a 486, we don't want to do a SIGFPE on an irq13
  * as the irq is unreliable, and exception 16 works correctly
@@ -52,30 +73,7 @@ static struct irqaction fpu_irq = {
        .handler = math_error_irq,
        .name = "fpu",
 };
-
-void __init init_ISA_irqs(void)
-{
-       int i;
-
-#ifdef CONFIG_X86_LOCAL_APIC
-       init_bsp_APIC();
 #endif
-       init_8259A(0);
-
-       /*
-        * 16 old-style INTA-cycle interrupts:
-        */
-       for (i = 0; i < NR_IRQS_LEGACY; i++) {
-               struct irq_desc *desc = irq_to_desc(i);
-
-               desc->status = IRQ_DISABLED;
-               desc->action = NULL;
-               desc->depth = 1;
-
-               set_irq_chip_and_handler_name(i, &i8259A_chip,
-                                             handle_level_irq, "XT");
-       }
-}
 
 /*
  * IRQ2 is cascade interrupt to second interrupt controller
@@ -118,29 +116,37 @@ int vector_used_by_percpu_irq(unsigned int vector)
        return 0;
 }
 
-/* Overridden in paravirt.c */
-void init_IRQ(void) __attribute__((weak, alias("native_init_IRQ")));
-
-void __init native_init_IRQ(void)
+static void __init init_ISA_irqs(void)
 {
        int i;
 
-       /* Execute any quirks before the call gates are initialised: */
-       x86_quirk_pre_intr_init();
+#if defined(CONFIG_X86_64) || defined(CONFIG_X86_LOCAL_APIC)
+       init_bsp_APIC();
+#endif
+       init_8259A(0);
 
        /*
-        * Cover the whole vector space, no vector can escape
-        * us. (some of these will be overridden and become
-        * 'special' SMP interrupts)
+        * 16 old-style INTA-cycle interrupts:
         */
-       for (i =  FIRST_EXTERNAL_VECTOR; i < NR_VECTORS; i++) {
-               /* SYSCALL_VECTOR was reserved in trap_init. */
-               if (i != SYSCALL_VECTOR)
-                       set_intr_gate(i, interrupt[i-FIRST_EXTERNAL_VECTOR]);
+       for (i = 0; i < NR_IRQS_LEGACY; i++) {
+               struct irq_desc *desc = irq_to_desc(i);
+
+               desc->status = IRQ_DISABLED;
+               desc->action = NULL;
+               desc->depth = 1;
+
+               set_irq_chip_and_handler_name(i, &i8259A_chip,
+                                             handle_level_irq, "XT");
        }
+}
 
+/* Overridden in paravirt.c */
+void init_IRQ(void) __attribute__((weak, alias("native_init_IRQ")));
 
-#if defined(CONFIG_X86_LOCAL_APIC) && defined(CONFIG_SMP)
+static void __init smp_intr_init(void)
+{
+#ifdef CONFIG_SMP
+#if defined(CONFIG_X86_64) || defined(CONFIG_X86_LOCAL_APIC)
        /*
         * The reschedule interrupt is a CPU-to-CPU reschedule-helper
         * IPI, driven by wakeup.
@@ -160,16 +166,27 @@ void __init native_init_IRQ(void)
        /* IPI for generic function call */
        alloc_intr_gate(CALL_FUNCTION_VECTOR, call_function_interrupt);
 
-       /* IPI for single call function */
+       /* IPI for generic single function call */
        alloc_intr_gate(CALL_FUNCTION_SINGLE_VECTOR,
-                                call_function_single_interrupt);
+                       call_function_single_interrupt);
 
        /* Low priority IPI to cleanup after moving an irq */
        set_intr_gate(IRQ_MOVE_CLEANUP_VECTOR, irq_move_cleanup_interrupt);
        set_bit(IRQ_MOVE_CLEANUP_VECTOR, used_vectors);
 #endif
+#endif /* CONFIG_SMP */
+}
+
+static void __init apic_intr_init(void)
+{
+       smp_intr_init();
+
+#ifdef CONFIG_X86_64
+       alloc_intr_gate(THERMAL_APIC_VECTOR, thermal_interrupt);
+       alloc_intr_gate(THRESHOLD_APIC_VECTOR, threshold_interrupt);
+#endif
 
-#ifdef CONFIG_X86_LOCAL_APIC
+#if defined(CONFIG_X86_64) || defined(CONFIG_X86_LOCAL_APIC)
        /* self generated IPI for local APIC timer */
        alloc_intr_gate(LOCAL_TIMER_VECTOR, apic_timer_interrupt);
 
@@ -179,16 +196,67 @@ void __init native_init_IRQ(void)
        /* IPI vectors for APIC spurious and error interrupts */
        alloc_intr_gate(SPURIOUS_APIC_VECTOR, spurious_interrupt);
        alloc_intr_gate(ERROR_APIC_VECTOR, error_interrupt);
+
+       /* Performance monitoring interrupts: */
+# ifdef CONFIG_PERF_COUNTERS
+       alloc_intr_gate(LOCAL_PERF_VECTOR, perf_counter_interrupt);
+       alloc_intr_gate(LOCAL_PENDING_VECTOR, perf_pending_interrupt);
+# endif
+
 #endif
 
+#ifdef CONFIG_X86_32
 #if defined(CONFIG_X86_LOCAL_APIC) && defined(CONFIG_X86_MCE_P4THERMAL)
        /* thermal monitor LVT interrupt */
        alloc_intr_gate(THERMAL_APIC_VECTOR, thermal_interrupt);
 #endif
+#endif
+}
+
+/**
+ * x86_quirk_pre_intr_init - initialisation prior to setting up interrupt vectors
+ *
+ * Description:
+ *     Perform any necessary interrupt initialisation prior to setting up
+ *     the "ordinary" interrupt call gates.  For legacy reasons, the ISA
+ *     interrupts should be initialised here if the machine emulates a PC
+ *     in any way.
+ **/
+static void __init x86_quirk_pre_intr_init(void)
+{
+#ifdef CONFIG_X86_32
+       if (x86_quirks->arch_pre_intr_init) {
+               if (x86_quirks->arch_pre_intr_init())
+                       return;
+       }
+#endif
+       init_ISA_irqs();
+}
+
+void __init native_init_IRQ(void)
+{
+       int i;
+
+       /* Execute any quirks before the call gates are initialised: */
+       x86_quirk_pre_intr_init();
+
+       apic_intr_init();
+
+       /*
+        * Cover the whole vector space, no vector can escape
+        * us. (some of these will be overridden and become
+        * 'special' SMP interrupts)
+        */
+       for (i = FIRST_EXTERNAL_VECTOR; i < NR_VECTORS; i++) {
+               /* IA32_SYSCALL_VECTOR could be used in trap_init already. */
+               if (!test_bit(i, used_vectors))
+                       set_intr_gate(i, interrupt[i-FIRST_EXTERNAL_VECTOR]);
+       }
 
        if (!acpi_ioapic)
                setup_irq(2, &irq2);
 
+#ifdef CONFIG_X86_32
        /*
         * Call quirks after call gates are initialised (usually add in
         * the architecture specific gates):
@@ -203,4 +271,5 @@ void __init native_init_IRQ(void)
                setup_irq(FPU_IRQ, &fpu_irq);
 
        irq_ctx_init(smp_processor_id());
+#endif
 }
diff --git a/arch/x86/kernel/irqinit_64.c b/arch/x86/kernel/irqinit_64.c
deleted file mode 100644 (file)
index 8cd1053..0000000
+++ /dev/null
@@ -1,177 +0,0 @@
-#include <linux/linkage.h>
-#include <linux/errno.h>
-#include <linux/signal.h>
-#include <linux/sched.h>
-#include <linux/ioport.h>
-#include <linux/interrupt.h>
-#include <linux/timex.h>
-#include <linux/slab.h>
-#include <linux/random.h>
-#include <linux/init.h>
-#include <linux/kernel_stat.h>
-#include <linux/sysdev.h>
-#include <linux/bitops.h>
-#include <linux/acpi.h>
-#include <linux/io.h>
-#include <linux/delay.h>
-
-#include <asm/atomic.h>
-#include <asm/system.h>
-#include <asm/hw_irq.h>
-#include <asm/pgtable.h>
-#include <asm/desc.h>
-#include <asm/apic.h>
-#include <asm/i8259.h>
-
-/*
- * ISA PIC or low IO-APIC triggered (INTA-cycle or APIC) interrupts:
- * (these are usually mapped to vectors 0x30-0x3f)
- */
-
-/*
- * The IO-APIC gives us many more interrupt sources. Most of these
- * are unused but an SMP system is supposed to have enough memory ...
- * sometimes (mostly wrt. hw bugs) we get corrupted vectors all
- * across the spectrum, so we really want to be prepared to get all
- * of these. Plus, more powerful systems might have more than 64
- * IO-APIC registers.
- *
- * (these are usually mapped into the 0x30-0xff vector range)
- */
-
-/*
- * IRQ2 is cascade interrupt to second interrupt controller
- */
-
-static struct irqaction irq2 = {
-       .handler = no_action,
-       .name = "cascade",
-};
-DEFINE_PER_CPU(vector_irq_t, vector_irq) = {
-       [0 ... IRQ0_VECTOR - 1] = -1,
-       [IRQ0_VECTOR] = 0,
-       [IRQ1_VECTOR] = 1,
-       [IRQ2_VECTOR] = 2,
-       [IRQ3_VECTOR] = 3,
-       [IRQ4_VECTOR] = 4,
-       [IRQ5_VECTOR] = 5,
-       [IRQ6_VECTOR] = 6,
-       [IRQ7_VECTOR] = 7,
-       [IRQ8_VECTOR] = 8,
-       [IRQ9_VECTOR] = 9,
-       [IRQ10_VECTOR] = 10,
-       [IRQ11_VECTOR] = 11,
-       [IRQ12_VECTOR] = 12,
-       [IRQ13_VECTOR] = 13,
-       [IRQ14_VECTOR] = 14,
-       [IRQ15_VECTOR] = 15,
-       [IRQ15_VECTOR + 1 ... NR_VECTORS - 1] = -1
-};
-
-int vector_used_by_percpu_irq(unsigned int vector)
-{
-       int cpu;
-
-       for_each_online_cpu(cpu) {
-               if (per_cpu(vector_irq, cpu)[vector] != -1)
-                       return 1;
-       }
-
-       return 0;
-}
-
-static void __init init_ISA_irqs(void)
-{
-       int i;
-
-       init_bsp_APIC();
-       init_8259A(0);
-
-       for (i = 0; i < NR_IRQS_LEGACY; i++) {
-               struct irq_desc *desc = irq_to_desc(i);
-
-               desc->status = IRQ_DISABLED;
-               desc->action = NULL;
-               desc->depth = 1;
-
-               /*
-                * 16 old-style INTA-cycle interrupts:
-                */
-               set_irq_chip_and_handler_name(i, &i8259A_chip,
-                                                     handle_level_irq, "XT");
-       }
-}
-
-void init_IRQ(void) __attribute__((weak, alias("native_init_IRQ")));
-
-static void __init smp_intr_init(void)
-{
-#ifdef CONFIG_SMP
-       /*
-        * The reschedule interrupt is a CPU-to-CPU reschedule-helper
-        * IPI, driven by wakeup.
-        */
-       alloc_intr_gate(RESCHEDULE_VECTOR, reschedule_interrupt);
-
-       /* IPIs for invalidation */
-       alloc_intr_gate(INVALIDATE_TLB_VECTOR_START+0, invalidate_interrupt0);
-       alloc_intr_gate(INVALIDATE_TLB_VECTOR_START+1, invalidate_interrupt1);
-       alloc_intr_gate(INVALIDATE_TLB_VECTOR_START+2, invalidate_interrupt2);
-       alloc_intr_gate(INVALIDATE_TLB_VECTOR_START+3, invalidate_interrupt3);
-       alloc_intr_gate(INVALIDATE_TLB_VECTOR_START+4, invalidate_interrupt4);
-       alloc_intr_gate(INVALIDATE_TLB_VECTOR_START+5, invalidate_interrupt5);
-       alloc_intr_gate(INVALIDATE_TLB_VECTOR_START+6, invalidate_interrupt6);
-       alloc_intr_gate(INVALIDATE_TLB_VECTOR_START+7, invalidate_interrupt7);
-
-       /* IPI for generic function call */
-       alloc_intr_gate(CALL_FUNCTION_VECTOR, call_function_interrupt);
-
-       /* IPI for generic single function call */
-       alloc_intr_gate(CALL_FUNCTION_SINGLE_VECTOR,
-                       call_function_single_interrupt);
-
-       /* Low priority IPI to cleanup after moving an irq */
-       set_intr_gate(IRQ_MOVE_CLEANUP_VECTOR, irq_move_cleanup_interrupt);
-       set_bit(IRQ_MOVE_CLEANUP_VECTOR, used_vectors);
-#endif
-}
-
-static void __init apic_intr_init(void)
-{
-       smp_intr_init();
-
-       alloc_intr_gate(THERMAL_APIC_VECTOR, thermal_interrupt);
-       alloc_intr_gate(THRESHOLD_APIC_VECTOR, threshold_interrupt);
-
-       /* self generated IPI for local APIC timer */
-       alloc_intr_gate(LOCAL_TIMER_VECTOR, apic_timer_interrupt);
-
-       /* generic IPI for platform specific use */
-       alloc_intr_gate(GENERIC_INTERRUPT_VECTOR, generic_interrupt);
-
-       /* IPI vectors for APIC spurious and error interrupts */
-       alloc_intr_gate(SPURIOUS_APIC_VECTOR, spurious_interrupt);
-       alloc_intr_gate(ERROR_APIC_VECTOR, error_interrupt);
-}
-
-void __init native_init_IRQ(void)
-{
-       int i;
-
-       init_ISA_irqs();
-       /*
-        * Cover the whole vector space, no vector can escape
-        * us. (some of these will be overridden and become
-        * 'special' SMP interrupts)
-        */
-       for (i = 0; i < (NR_VECTORS - FIRST_EXTERNAL_VECTOR); i++) {
-               int vector = FIRST_EXTERNAL_VECTOR + i;
-               if (vector != IA32_SYSCALL_VECTOR)
-                       set_intr_gate(vector, interrupt[i]);
-       }
-
-       apic_intr_init();
-
-       if (!acpi_ioapic)
-               setup_irq(2, &irq2);
-}
index 70fd7e414c1544aadf5de5573e67294e88cac16c..651c93b28862a5ea04f3fdfc883533ff843b2583 100644 (file)
@@ -17,6 +17,7 @@
 #include <linux/acpi.h>
 #include <linux/module.h>
 #include <linux/smp.h>
+#include <linux/pci.h>
 
 #include <asm/mtrr.h>
 #include <asm/mpspec.h>
@@ -870,24 +871,17 @@ static
 inline void __init check_irq_src(struct mpc_intsrc *m, int *nr_m_spare) {}
 #endif /* CONFIG_X86_IO_APIC */
 
-static int check_slot(unsigned long mpc_new_phys, unsigned long mpc_new_length,
-                     int count)
+static int
+check_slot(unsigned long mpc_new_phys, unsigned long mpc_new_length, int count)
 {
-       if (!mpc_new_phys) {
-               pr_info("No spare slots, try to append...take your risk, "
-                       "new mpc_length %x\n", count);
-       } else {
-               if (count <= mpc_new_length)
-                       pr_info("No spare slots, try to append..., "
-                               "new mpc_length %x\n", count);
-               else {
-                       pr_err("mpc_new_length %lx is too small\n",
-                               mpc_new_length);
-                       return -1;
-               }
+       int ret = 0;
+
+       if (!mpc_new_phys || count <= mpc_new_length) {
+               WARN(1, "update_mptable: No spare slots (length: %x)\n", count);
+               return -1;
        }
 
-       return 0;
+       return ret;
 }
 
 static int  __init replace_intsrc_all(struct mpc_table *mpc,
@@ -946,7 +940,7 @@ static int  __init replace_intsrc_all(struct mpc_table *mpc,
                } else {
                        struct mpc_intsrc *m = (struct mpc_intsrc *)mpt;
                        count += sizeof(struct mpc_intsrc);
-                       if (!check_slot(mpc_new_phys, mpc_new_length, count))
+                       if (check_slot(mpc_new_phys, mpc_new_length, count) < 0)
                                goto out;
                        assign_to_mpc_intsrc(&mp_irqs[i], m);
                        mpc->length = count;
@@ -963,11 +957,14 @@ out:
        return 0;
 }
 
-static int __initdata enable_update_mptable;
+int enable_update_mptable;
 
 static int __init update_mptable_setup(char *str)
 {
        enable_update_mptable = 1;
+#ifdef CONFIG_PCI
+       pci_routeirq = 1;
+#endif
        return 0;
 }
 early_param("update_mptable", update_mptable_setup);
@@ -980,6 +977,9 @@ static int __initdata alloc_mptable;
 static int __init parse_alloc_mptable_opt(char *p)
 {
        enable_update_mptable = 1;
+#ifdef CONFIG_PCI
+       pci_routeirq = 1;
+#endif
        alloc_mptable = 1;
        if (!p)
                return 0;
index b4158439bf634d254852cceab2c30d26f943f7ea..523bb697120d18697addb94e2be26b0bb24dcef3 100644 (file)
@@ -996,24 +996,6 @@ void __init setup_arch(char **cmdline_p)
 
 #ifdef CONFIG_X86_32
 
-/**
- * x86_quirk_pre_intr_init - initialisation prior to setting up interrupt vectors
- *
- * Description:
- *     Perform any necessary interrupt initialisation prior to setting up
- *     the "ordinary" interrupt call gates.  For legacy reasons, the ISA
- *     interrupts should be initialised here if the machine emulates a PC
- *     in any way.
- **/
-void __init x86_quirk_pre_intr_init(void)
-{
-       if (x86_quirks->arch_pre_intr_init) {
-               if (x86_quirks->arch_pre_intr_init())
-                       return;
-       }
-       init_ISA_irqs();
-}
-
 /**
  * x86_quirk_intr_init - post gate setup interrupt initialisation
  *
index 13f33ea8ccaaf1ae8e23cc2a39f57d84d6d3c910..f6db48c405b81fca925988fa0fc408f078793722 100644 (file)
@@ -193,19 +193,19 @@ void smp_call_function_single_interrupt(struct pt_regs *regs)
 }
 
 struct smp_ops smp_ops = {
-       .smp_prepare_boot_cpu = native_smp_prepare_boot_cpu,
-       .smp_prepare_cpus = native_smp_prepare_cpus,
-       .smp_cpus_done = native_smp_cpus_done,
+       .smp_prepare_boot_cpu   = native_smp_prepare_boot_cpu,
+       .smp_prepare_cpus       = native_smp_prepare_cpus,
+       .smp_cpus_done          = native_smp_cpus_done,
 
-       .smp_send_stop = native_smp_send_stop,
-       .smp_send_reschedule = native_smp_send_reschedule,
+       .smp_send_stop          = native_smp_send_stop,
+       .smp_send_reschedule    = native_smp_send_reschedule,
 
-       .cpu_up = native_cpu_up,
-       .cpu_die = native_cpu_die,
-       .cpu_disable = native_cpu_disable,
-       .play_dead = native_play_dead,
+       .cpu_up                 = native_cpu_up,
+       .cpu_die                = native_cpu_die,
+       .cpu_disable            = native_cpu_disable,
+       .play_dead              = native_play_dead,
 
-       .send_call_func_ipi = native_send_call_func_ipi,
+       .send_call_func_ipi     = native_send_call_func_ipi,
        .send_call_func_single_ipi = native_send_call_func_single_ipi,
 };
 EXPORT_SYMBOL_GPL(smp_ops);
index 58d24ef917d8b46e7c7faedc4dd3fc79266ad0cb..d2e8de9581562a69f3d157be2bf3881c60311115 100644 (file)
@@ -504,7 +504,7 @@ void __inquire_remote_apic(int apicid)
  * INIT, INIT, STARTUP sequence will reset the chip hard for us, and this
  * won't ... remember to clear down the APIC, etc later.
  */
-int __devinit
+int __cpuinit
 wakeup_secondary_cpu_via_nmi(int logical_apicid, unsigned long start_eip)
 {
        unsigned long send_status, accept_status = 0;
@@ -538,7 +538,7 @@ wakeup_secondary_cpu_via_nmi(int logical_apicid, unsigned long start_eip)
        return (send_status | accept_status);
 }
 
-int __devinit
+static int __cpuinit
 wakeup_secondary_cpu_via_init(int phys_apicid, unsigned long start_eip)
 {
        unsigned long send_status, accept_status = 0;
@@ -822,10 +822,12 @@ do_rest:
        /* mark "stuck" area as not stuck */
        *((volatile unsigned long *)trampoline_base) = 0;
 
-       /*
-        * Cleanup possible dangling ends...
-        */
-       smpboot_restore_warm_reset_vector();
+       if (get_uv_system_type() != UV_NON_UNIQUE_APIC) {
+               /*
+                * Cleanup possible dangling ends...
+                */
+               smpboot_restore_warm_reset_vector();
+       }
 
        return boot_error;
 }
index a1d288327ff0ff0f152241bf296c742778f61e00..2310700faca5f2f491f56c7a82aefc378f9b254c 100644 (file)
@@ -969,11 +969,8 @@ void __init trap_init(void)
        for (i = 0; i < FIRST_EXTERNAL_VECTOR; i++)
                set_bit(i, used_vectors);
 
-#ifdef CONFIG_X86_64
        set_bit(IA32_SYSCALL_VECTOR, used_vectors);
-#else
-       set_bit(SYSCALL_VECTOR, used_vectors);
-#endif
+
        /*
         * Should be a barrier for any external CPU state:
         */
index ca7ec44bafc3b313aa1e3919339042f8ed53cf20..45acbcf2568332ca80d64551dac3fbb30134c490 100644 (file)
@@ -636,7 +636,7 @@ static void __init lguest_init_IRQ(void)
 
 void lguest_setup_irq(unsigned int irq)
 {
-       irq_to_desc_alloc_cpu(irq, 0);
+       irq_to_desc_alloc_node(irq, 0);
        set_irq_chip_and_handler_name(irq, &lguest_irq_controller,
                                      handle_level_irq, "level");
 }
index fecbce6e7d7c20d1f0af750e2305ef4e9a37a92c..0696d506c4ade99b0d43232128a77cea99d65ec8 100644 (file)
@@ -889,6 +889,9 @@ static int pcibios_lookup_irq(struct pci_dev *dev, int assign)
                return 0;
        }
 
+       if (io_apic_assign_pci_irqs)
+               return 0;
+
        /* Find IRQ routing entry */
 
        if (!pirq_table)
@@ -1039,56 +1042,15 @@ static void __init pcibios_fixup_irqs(void)
                pirq_penalty[dev->irq]++;
        }
 
+       if (io_apic_assign_pci_irqs)
+               return;
+
        dev = NULL;
        while ((dev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, dev)) != NULL) {
                pci_read_config_byte(dev, PCI_INTERRUPT_PIN, &pin);
                if (!pin)
                        continue;
 
-#ifdef CONFIG_X86_IO_APIC
-               /*
-                * Recalculate IRQ numbers if we use the I/O APIC.
-                */
-               if (io_apic_assign_pci_irqs) {
-                       int irq;
-
-                       /*
-                        * interrupt pins are numbered starting from 1
-                        */
-                       irq = IO_APIC_get_PCI_irq_vector(dev->bus->number,
-                               PCI_SLOT(dev->devfn), pin - 1);
-                       /*
-                        * Busses behind bridges are typically not listed in the
-                        * MP-table.  In this case we have to look up the IRQ
-                        * based on the parent bus, parent slot, and pin number.
-                        * The SMP code detects such bridged busses itself so we
-                        * should get into this branch reliably.
-                        */
-                       if (irq < 0 && dev->bus->parent) {
-                               /* go back to the bridge */
-                               struct pci_dev *bridge = dev->bus->self;
-                               int bus;
-
-                               pin = pci_swizzle_interrupt_pin(dev, pin);
-                               bus = bridge->bus->number;
-                               irq = IO_APIC_get_PCI_irq_vector(bus,
-                                               PCI_SLOT(bridge->devfn), pin - 1);
-                               if (irq >= 0)
-                                       dev_warn(&dev->dev,
-                                               "using bridge %s INT %c to "
-                                                       "get IRQ %d\n",
-                                                pci_name(bridge),
-                                                'A' + pin - 1, irq);
-                       }
-                       if (irq >= 0) {
-                               dev_info(&dev->dev,
-                                       "PCI->APIC IRQ transform: INT %c "
-                                               "-> IRQ %d\n",
-                                       'A' + pin - 1, irq);
-                               dev->irq = irq;
-                       }
-               }
-#endif
                /*
                 * Still no IRQ? Try to lookup one...
                 */
@@ -1183,6 +1145,19 @@ int __init pcibios_irq_init(void)
        pcibios_enable_irq = pirq_enable_irq;
 
        pcibios_fixup_irqs();
+
+       if (io_apic_assign_pci_irqs && pci_routeirq) {
+               struct pci_dev *dev = NULL;
+               /*
+                * PCI IRQ routing is set up by pci_enable_device(), but we
+                * also do it here in case there are still broken drivers that
+                * don't use pci_enable_device().
+                */
+               printk(KERN_INFO "PCI: Routing PCI interrupts for all devices because \"pci=routeirq\" specified\n");
+               for_each_pci_dev(dev)
+                       pirq_enable_irq(dev);
+       }
+
        return 0;
 }
 
@@ -1213,16 +1188,23 @@ void pcibios_penalize_isa_irq(int irq, int active)
 static int pirq_enable_irq(struct pci_dev *dev)
 {
        u8 pin;
-       struct pci_dev *temp_dev;
 
        pci_read_config_byte(dev, PCI_INTERRUPT_PIN, &pin);
-       if (pin && !pcibios_lookup_irq(dev, 1) && !dev->irq) {
+       if (pin && !pcibios_lookup_irq(dev, 1)) {
                char *msg = "";
 
+               if (!io_apic_assign_pci_irqs && dev->irq)
+                       return 0;
+
                if (io_apic_assign_pci_irqs) {
+#ifdef CONFIG_X86_IO_APIC
+                       struct pci_dev *temp_dev;
                        int irq;
+                       struct io_apic_irq_attr irq_attr;
 
-                       irq = IO_APIC_get_PCI_irq_vector(dev->bus->number, PCI_SLOT(dev->devfn), pin - 1);
+                       irq = IO_APIC_get_PCI_irq_vector(dev->bus->number,
+                                               PCI_SLOT(dev->devfn),
+                                               pin - 1, &irq_attr);
                        /*
                         * Busses behind bridges are typically not listed in the MP-table.
                         * In this case we have to look up the IRQ based on the parent bus,
@@ -1235,7 +1217,8 @@ static int pirq_enable_irq(struct pci_dev *dev)
 
                                pin = pci_swizzle_interrupt_pin(dev, pin);
                                irq = IO_APIC_get_PCI_irq_vector(bridge->bus->number,
-                                               PCI_SLOT(bridge->devfn), pin - 1);
+                                               PCI_SLOT(bridge->devfn),
+                                               pin - 1, &irq_attr);
                                if (irq >= 0)
                                        dev_warn(&dev->dev, "using bridge %s "
                                                 "INT %c to get IRQ %d\n",
@@ -1245,12 +1228,15 @@ static int pirq_enable_irq(struct pci_dev *dev)
                        }
                        dev = temp_dev;
                        if (irq >= 0) {
+                               io_apic_set_pci_routing(&dev->dev, irq,
+                                                        &irq_attr);
+                               dev->irq = irq;
                                dev_info(&dev->dev, "PCI->APIC IRQ transform: "
                                         "INT %c -> IRQ %d\n", 'A' + pin - 1, irq);
-                               dev->irq = irq;
                                return 0;
                        } else
                                msg = "; probably buggy MP table";
+#endif
                } else if (pci_probe & PCI_BIOS_IRQ_SCAN)
                        msg = "";
                else
index 51b9f8280f887cfd6649a39446e7e081d52fe3b6..2faa9e2ac89331b9c46c1de0de560a0225ce88e2 100644 (file)
@@ -401,7 +401,8 @@ int acpi_pci_irq_enable(struct pci_dev *dev)
                /* Interrupt Line values above 0xF are forbidden */
                if (dev->irq > 0 && (dev->irq <= 0xF)) {
                        printk(" - using IRQ %d\n", dev->irq);
-                       acpi_register_gsi(dev->irq, ACPI_LEVEL_SENSITIVE,
+                       acpi_register_gsi(&dev->dev, dev->irq,
+                                         ACPI_LEVEL_SENSITIVE,
                                          ACPI_ACTIVE_LOW);
                        return 0;
                } else {
@@ -410,7 +411,7 @@ int acpi_pci_irq_enable(struct pci_dev *dev)
                }
        }
 
-       rc = acpi_register_gsi(gsi, triggering, polarity);
+       rc = acpi_register_gsi(&dev->dev, gsi, triggering, polarity);
        if (rc < 0) {
                dev_warn(&dev->dev, "PCI INT %c: failed to register GSI\n",
                         pin_name(pin));
index 340ba4f9dc54880bd6a3f7661ebba93d9c81733b..4a9f3492b9216142333f3fa2013542b4638b9c1e 100644 (file)
@@ -224,7 +224,7 @@ static void hpet_timer_set_irq(struct hpet_dev *devp)
                        break;
                }
 
-               gsi = acpi_register_gsi(irq, ACPI_LEVEL_SENSITIVE,
+               gsi = acpi_register_gsi(NULL, irq, ACPI_LEVEL_SENSITIVE,
                                        ACPI_ACTIVE_LOW);
                if (gsi > 0)
                        break;
@@ -939,7 +939,7 @@ static acpi_status hpet_resources(struct acpi_resource *res, void *data)
                irqp = &res->data.extended_irq;
 
                for (i = 0; i < irqp->interrupt_count; i++) {
-                       irq = acpi_register_gsi(irqp->interrupts[i],
+                       irq = acpi_register_gsi(NULL, irqp->interrupts[i],
                                      irqp->triggering, irqp->polarity);
                        if (irq < 0)
                                return AE_ERROR;
index 73348c4047e98d249a9a576b87f2e8d44edaf623..4a9cc92d4d1867469dcae3efed4c468b251ff7f8 100644 (file)
@@ -702,7 +702,7 @@ static unsigned int iosapic_startup_irq(unsigned int irq)
 }
 
 #ifdef CONFIG_SMP
-static void iosapic_set_affinity_irq(unsigned int irq,
+static int iosapic_set_affinity_irq(unsigned int irq,
                                     const struct cpumask *dest)
 {
        struct vector_info *vi = iosapic_get_vector(irq);
@@ -712,7 +712,7 @@ static void iosapic_set_affinity_irq(unsigned int irq,
 
        dest_cpu = cpu_check_affinity(irq, dest);
        if (dest_cpu < 0)
-               return;
+               return -1;
 
        cpumask_copy(irq_desc[irq].affinity, cpumask_of(dest_cpu));
        vi->txn_addr = txn_affinity_addr(irq, dest_cpu);
@@ -724,6 +724,8 @@ static void iosapic_set_affinity_irq(unsigned int irq,
        iosapic_set_irt_data(vi, &dummy_d0, &d1);
        iosapic_wr_irt_entry(vi, d0, d1);
        spin_unlock_irqrestore(&iosapic_lock, flags);
+
+       return 0;
 }
 #endif
 
index dd18f857dfb042d8d5802bfbbab57c617054b3f4..42e4260c3b12311e3793102b76ec136f5f94352e 100644 (file)
@@ -153,45 +153,47 @@ int ibmphp_init_devno(struct slot **cur_slot)
                return -1;
        }
        for (loop = 0; loop < len; loop++) {
-               if ((*cur_slot)->number == rtable->slots[loop].slot) {
-               if ((*cur_slot)->bus == rtable->slots[loop].bus) {
+               if ((*cur_slot)->number == rtable->slots[loop].slot &&
+                   (*cur_slot)->bus == rtable->slots[loop].bus) {
+                       struct io_apic_irq_attr irq_attr;
+
                        (*cur_slot)->device = PCI_SLOT(rtable->slots[loop].devfn);
                        for (i = 0; i < 4; i++)
                                (*cur_slot)->irq[i] = IO_APIC_get_PCI_irq_vector((int) (*cur_slot)->bus,
-                                               (int) (*cur_slot)->device, i);
-
-                               debug("(*cur_slot)->irq[0] = %x\n",
-                                               (*cur_slot)->irq[0]);
-                               debug("(*cur_slot)->irq[1] = %x\n",
-                                               (*cur_slot)->irq[1]);
-                               debug("(*cur_slot)->irq[2] = %x\n",
-                                               (*cur_slot)->irq[2]);
-                               debug("(*cur_slot)->irq[3] = %x\n",
-                                               (*cur_slot)->irq[3]);
-
-                               debug("rtable->exlusive_irqs = %x\n",
+                                               (int) (*cur_slot)->device, i,
+                                               &irq_attr);
+
+                       debug("(*cur_slot)->irq[0] = %x\n",
+                                       (*cur_slot)->irq[0]);
+                       debug("(*cur_slot)->irq[1] = %x\n",
+                                       (*cur_slot)->irq[1]);
+                       debug("(*cur_slot)->irq[2] = %x\n",
+                                       (*cur_slot)->irq[2]);
+                       debug("(*cur_slot)->irq[3] = %x\n",
+                                       (*cur_slot)->irq[3]);
+
+                       debug("rtable->exlusive_irqs = %x\n",
                                        rtable->exclusive_irqs);
-                               debug("rtable->slots[loop].irq[0].bitmap = %x\n",
+                       debug("rtable->slots[loop].irq[0].bitmap = %x\n",
                                        rtable->slots[loop].irq[0].bitmap);
-                               debug("rtable->slots[loop].irq[1].bitmap = %x\n",
+                       debug("rtable->slots[loop].irq[1].bitmap = %x\n",
                                        rtable->slots[loop].irq[1].bitmap);
-                               debug("rtable->slots[loop].irq[2].bitmap = %x\n",
+                       debug("rtable->slots[loop].irq[2].bitmap = %x\n",
                                        rtable->slots[loop].irq[2].bitmap);
-                               debug("rtable->slots[loop].irq[3].bitmap = %x\n",
+                       debug("rtable->slots[loop].irq[3].bitmap = %x\n",
                                        rtable->slots[loop].irq[3].bitmap);
 
-                               debug("rtable->slots[loop].irq[0].link = %x\n",
+                       debug("rtable->slots[loop].irq[0].link = %x\n",
                                        rtable->slots[loop].irq[0].link);
-                               debug("rtable->slots[loop].irq[1].link = %x\n",
+                       debug("rtable->slots[loop].irq[1].link = %x\n",
                                        rtable->slots[loop].irq[1].link);
-                               debug("rtable->slots[loop].irq[2].link = %x\n",
+                       debug("rtable->slots[loop].irq[2].link = %x\n",
                                        rtable->slots[loop].irq[2].link);
-                               debug("rtable->slots[loop].irq[3].link = %x\n",
+                       debug("rtable->slots[loop].irq[3].link = %x\n",
                                        rtable->slots[loop].irq[3].link);
-                               debug("end of init_devno\n");
-                               kfree(rtable);
-                               return 0;
-                       }
+                       debug("end of init_devno\n");
+                       kfree(rtable);
+                       return 0;
                }
        }
 
index 6808d8333ecc414390590f83122f4c6602b01cef..737a1c44b07af9a8ed81ed6e2191fce7934603fd 100644 (file)
@@ -98,6 +98,7 @@ int __ht_create_irq(struct pci_dev *dev, int idx, ht_irq_update_t *update)
        int max_irq;
        int pos;
        int irq;
+       int node;
 
        pos = pci_find_ht_capability(dev, HT_CAPTYPE_IRQ);
        if (!pos)
@@ -125,7 +126,8 @@ int __ht_create_irq(struct pci_dev *dev, int idx, ht_irq_update_t *update)
        cfg->msg.address_lo = 0xffffffff;
        cfg->msg.address_hi = 0xffffffff;
 
-       irq = create_irq();
+       node = dev_to_node(&dev->dev);
+       irq = create_irq_nr(0, node);
 
        if (irq <= 0) {
                kfree(cfg);
index a563fbe559d0505b90d1f736beb3a8e8bf197717..cd389162735f3f9ff03dd596d549134ae052de5a 100644 (file)
@@ -1972,15 +1972,6 @@ static int __init init_dmars(void)
                }
        }
 
-#ifdef CONFIG_INTR_REMAP
-       if (!intr_remapping_enabled) {
-               ret = enable_intr_remapping(0);
-               if (ret)
-                       printk(KERN_ERR
-                              "IOMMU: enable interrupt remapping failed\n");
-       }
-#endif
-
        /*
         * For each rmrr
         *   for each dev attached to rmrr
index f5e0ea724a6f53a12d26443fba84b01ab898f35d..3a0cb0bb05933bd72277df67af0cfe2254a7b6e4 100644 (file)
@@ -15,6 +15,14 @@ static struct ioapic_scope ir_ioapic[MAX_IO_APICS];
 static int ir_ioapic_num;
 int intr_remapping_enabled;
 
+static int disable_intremap;
+static __init int setup_nointremap(char *str)
+{
+       disable_intremap = 1;
+       return 0;
+}
+early_param("nointremap", setup_nointremap);
+
 struct irq_2_iommu {
        struct intel_iommu *iommu;
        u16 irte_index;
@@ -23,15 +31,12 @@ struct irq_2_iommu {
 };
 
 #ifdef CONFIG_GENERIC_HARDIRQS
-static struct irq_2_iommu *get_one_free_irq_2_iommu(int cpu)
+static struct irq_2_iommu *get_one_free_irq_2_iommu(int node)
 {
        struct irq_2_iommu *iommu;
-       int node;
-
-       node = cpu_to_node(cpu);
 
        iommu = kzalloc_node(sizeof(*iommu), GFP_ATOMIC, node);
-       printk(KERN_DEBUG "alloc irq_2_iommu on cpu %d node %d\n", cpu, node);
+       printk(KERN_DEBUG "alloc irq_2_iommu on node %d\n", node);
 
        return iommu;
 }
@@ -48,7 +53,7 @@ static struct irq_2_iommu *irq_2_iommu(unsigned int irq)
        return desc->irq_2_iommu;
 }
 
-static struct irq_2_iommu *irq_2_iommu_alloc_cpu(unsigned int irq, int cpu)
+static struct irq_2_iommu *irq_2_iommu_alloc_node(unsigned int irq, int node)
 {
        struct irq_desc *desc;
        struct irq_2_iommu *irq_iommu;
@@ -56,7 +61,7 @@ static struct irq_2_iommu *irq_2_iommu_alloc_cpu(unsigned int irq, int cpu)
        /*
         * alloc irq desc if not allocated already.
         */
-       desc = irq_to_desc_alloc_cpu(irq, cpu);
+       desc = irq_to_desc_alloc_node(irq, node);
        if (!desc) {
                printk(KERN_INFO "can not get irq_desc for %d\n", irq);
                return NULL;
@@ -65,14 +70,14 @@ static struct irq_2_iommu *irq_2_iommu_alloc_cpu(unsigned int irq, int cpu)
        irq_iommu = desc->irq_2_iommu;
 
        if (!irq_iommu)
-               desc->irq_2_iommu = get_one_free_irq_2_iommu(cpu);
+               desc->irq_2_iommu = get_one_free_irq_2_iommu(node);
 
        return desc->irq_2_iommu;
 }
 
 static struct irq_2_iommu *irq_2_iommu_alloc(unsigned int irq)
 {
-       return irq_2_iommu_alloc_cpu(irq, boot_cpu_id);
+       return irq_2_iommu_alloc_node(irq, cpu_to_node(boot_cpu_id));
 }
 
 #else /* !CONFIG_SPARSE_IRQ */
@@ -423,20 +428,6 @@ static void iommu_set_intr_remapping(struct intel_iommu *iommu, int mode)
                      readl, (sts & DMA_GSTS_IRTPS), sts);
        spin_unlock_irqrestore(&iommu->register_lock, flags);
 
-       if (mode == 0) {
-               spin_lock_irqsave(&iommu->register_lock, flags);
-
-               /* enable comaptiblity format interrupt pass through */
-               cmd = iommu->gcmd | DMA_GCMD_CFI;
-               iommu->gcmd |= DMA_GCMD_CFI;
-               writel(cmd, iommu->reg + DMAR_GCMD_REG);
-
-               IOMMU_WAIT_OP(iommu, DMAR_GSTS_REG,
-                             readl, (sts & DMA_GSTS_CFIS), sts);
-
-               spin_unlock_irqrestore(&iommu->register_lock, flags);
-       }
-
        /*
         * global invalidation of interrupt entry cache before enabling
         * interrupt-remapping.
@@ -516,6 +507,23 @@ end:
        spin_unlock_irqrestore(&iommu->register_lock, flags);
 }
 
+int __init intr_remapping_supported(void)
+{
+       struct dmar_drhd_unit *drhd;
+
+       if (disable_intremap)
+               return 0;
+
+       for_each_drhd_unit(drhd) {
+               struct intel_iommu *iommu = drhd->iommu;
+
+               if (!ecap_ir_support(iommu->ecap))
+                       return 0;
+       }
+
+       return 1;
+}
+
 int __init enable_intr_remapping(int eim)
 {
        struct dmar_drhd_unit *drhd;
index adf17856bacc187a8216af9ded5ec3cf2ed2662b..7f207f335beca2c53d8120c3a4681ff139cb7282 100644 (file)
@@ -123,7 +123,7 @@ static void pnpacpi_parse_allocated_irqresource(struct pnp_dev *dev,
        }
 
        flags = irq_flags(triggering, polarity, shareable);
-       irq = acpi_register_gsi(gsi, triggering, polarity);
+       irq = acpi_register_gsi(&dev->dev, gsi, triggering, polarity);
        if (irq >= 0)
                pcibios_penalize_isa_irq(irq, 1);
        else
index 30963af5dba02960143f9ebf37b6f85d44de0dec..be437c2bc942ecb35b395b0931da0be60a14976d 100644 (file)
@@ -335,7 +335,7 @@ static int find_unbound_irq(void)
        if (irq == nr_irqs)
                panic("No available IRQ to bind to: increase nr_irqs!\n");
 
-       desc = irq_to_desc_alloc_cpu(irq, 0);
+       desc = irq_to_desc_alloc_node(irq, 0);
        if (WARN_ON(desc == NULL))
                return -1;
 
@@ -688,13 +688,13 @@ void rebind_evtchn_irq(int evtchn, int irq)
 }
 
 /* Rebind an evtchn so that it gets delivered to a specific cpu */
-static void rebind_irq_to_cpu(unsigned irq, unsigned tcpu)
+static int rebind_irq_to_cpu(unsigned irq, unsigned tcpu)
 {
        struct evtchn_bind_vcpu bind_vcpu;
        int evtchn = evtchn_from_irq(irq);
 
        if (!VALID_EVTCHN(evtchn))
-               return;
+               return -1;
 
        /* Send future instances of this interrupt to other vcpu. */
        bind_vcpu.port = evtchn;
@@ -707,13 +707,15 @@ static void rebind_irq_to_cpu(unsigned irq, unsigned tcpu)
         */
        if (HYPERVISOR_event_channel_op(EVTCHNOP_bind_vcpu, &bind_vcpu) >= 0)
                bind_evtchn_to_cpu(evtchn, tcpu);
-}
 
+       return 0;
+}
 
-static void set_affinity_irq(unsigned irq, const struct cpumask *dest)
+static int set_affinity_irq(unsigned irq, const struct cpumask *dest)
 {
        unsigned tcpu = cpumask_first(dest);
-       rebind_irq_to_cpu(irq, tcpu);
+
+       return rebind_irq_to_cpu(irq, tcpu);
 }
 
 int resend_irq_on_evtchn(unsigned int irq)
index 88be890ee3c7e402cfd398e5113d2f78bb29338b..51b4b0a5ce8cf00b00fd849ee26e0e7bc504a795 100644 (file)
@@ -119,7 +119,7 @@ extern int pci_mmcfg_config_num;
 extern int sbf_port;
 extern unsigned long acpi_realmode_flags;
 
-int acpi_register_gsi (u32 gsi, int triggering, int polarity);
+int acpi_register_gsi (struct device *dev, u32 gsi, int triggering, int polarity);
 int acpi_gsi_to_irq (u32 gsi, unsigned int *irq);
 
 #ifdef CONFIG_X86_IO_APIC
index e397dc342cdaf1eaf99b022b4523f858d9f3e886..10ff5c498824b5b8dc5e963b07563878a13c2667 100644 (file)
@@ -108,6 +108,7 @@ struct irte {
 };
 #ifdef CONFIG_INTR_REMAP
 extern int intr_remapping_enabled;
+extern int intr_remapping_supported(void);
 extern int enable_intr_remapping(int);
 extern void disable_intr_remapping(void);
 extern int reenable_intr_remapping(int);
@@ -157,6 +158,8 @@ static inline struct intel_iommu *map_ioapic_to_ir(int apic)
 }
 #define irq_remapped(irq)              (0)
 #define enable_intr_remapping(mode)    (-1)
+#define disable_intr_remapping()       (0)
+#define reenable_intr_remapping(mode)  (0)
 #define intr_remapping_enabled         (0)
 #endif
 
index 91bb76f44f14e6488e909669ba3e3e94fba1104a..ff374ceface08d55c889c5698cdf6bcfda753655 100644 (file)
@@ -566,6 +566,6 @@ struct irq_desc;
 extern int early_irq_init(void);
 extern int arch_probe_nr_irqs(void);
 extern int arch_early_irq_init(void);
-extern int arch_init_chip_data(struct irq_desc *desc, int cpu);
+extern int arch_init_chip_data(struct irq_desc *desc, int node);
 
 #endif
index b7cbeed972e425b694f1666343f6fc0558ac439e..eedbb8e5e0ccff99c79594b6485fd9259049d088 100644 (file)
@@ -117,7 +117,7 @@ struct irq_chip {
        void            (*eoi)(unsigned int irq);
 
        void            (*end)(unsigned int irq);
-       void            (*set_affinity)(unsigned int irq,
+       int             (*set_affinity)(unsigned int irq,
                                        const struct cpumask *dest);
        int             (*retrigger)(unsigned int irq);
        int             (*set_type)(unsigned int irq, unsigned int flow_type);
@@ -187,7 +187,7 @@ struct irq_desc {
        spinlock_t              lock;
 #ifdef CONFIG_SMP
        cpumask_var_t           affinity;
-       unsigned int            cpu;
+       unsigned int            node;
 #ifdef CONFIG_GENERIC_PENDING_IRQ
        cpumask_var_t           pending_mask;
 #endif
@@ -201,26 +201,23 @@ struct irq_desc {
 } ____cacheline_internodealigned_in_smp;
 
 extern void arch_init_copy_chip_data(struct irq_desc *old_desc,
-                                       struct irq_desc *desc, int cpu);
+                                       struct irq_desc *desc, int node);
 extern void arch_free_chip_data(struct irq_desc *old_desc, struct irq_desc *desc);
 
 #ifndef CONFIG_SPARSE_IRQ
 extern struct irq_desc irq_desc[NR_IRQS];
-#else /* CONFIG_SPARSE_IRQ */
-extern struct irq_desc *move_irq_desc(struct irq_desc *old_desc, int cpu);
-#endif /* CONFIG_SPARSE_IRQ */
-
-extern struct irq_desc *irq_to_desc_alloc_cpu(unsigned int irq, int cpu);
+#endif
 
-static inline struct irq_desc *
-irq_remap_to_desc(unsigned int irq, struct irq_desc *desc)
-{
-#ifdef CONFIG_NUMA_MIGRATE_IRQ_DESC
-       return irq_to_desc(irq);
+#ifdef CONFIG_NUMA_IRQ_DESC
+extern struct irq_desc *move_irq_desc(struct irq_desc *old_desc, int node);
 #else
+static inline struct irq_desc *move_irq_desc(struct irq_desc *desc, int node)
+{
        return desc;
-#endif
 }
+#endif
+
+extern struct irq_desc *irq_to_desc_alloc_node(unsigned int irq, int node);
 
 /*
  * Migration helpers for obsolete names, they will go away:
@@ -386,7 +383,7 @@ extern void set_irq_noprobe(unsigned int irq);
 extern void set_irq_probe(unsigned int irq);
 
 /* Handle dynamic irq creation and destruction */
-extern unsigned int create_irq_nr(unsigned int irq_want);
+extern unsigned int create_irq_nr(unsigned int irq_want, int node);
 extern int create_irq(void);
 extern void destroy_irq(unsigned int irq);
 
@@ -424,47 +421,48 @@ extern int set_irq_msi(unsigned int irq, struct msi_desc *entry);
 
 #ifdef CONFIG_SMP
 /**
- * init_alloc_desc_masks - allocate cpumasks for irq_desc
+ * alloc_desc_masks - allocate cpumasks for irq_desc
  * @desc:      pointer to irq_desc struct
  * @cpu:       cpu which will be handling the cpumasks
  * @boot:      true if need bootmem
  *
  * Allocates affinity and pending_mask cpumask if required.
  * Returns true if successful (or not required).
- * Side effect: affinity has all bits set, pending_mask has all bits clear.
  */
-static inline bool init_alloc_desc_masks(struct irq_desc *desc, int cpu,
+static inline bool alloc_desc_masks(struct irq_desc *desc, int node,
                                                                bool boot)
 {
-       int node;
-
+#ifdef CONFIG_CPUMASK_OFFSTACK
        if (boot) {
                alloc_bootmem_cpumask_var(&desc->affinity);
-               cpumask_setall(desc->affinity);
 
 #ifdef CONFIG_GENERIC_PENDING_IRQ
                alloc_bootmem_cpumask_var(&desc->pending_mask);
-               cpumask_clear(desc->pending_mask);
 #endif
                return true;
        }
 
-       node = cpu_to_node(cpu);
-
        if (!alloc_cpumask_var_node(&desc->affinity, GFP_ATOMIC, node))
                return false;
-       cpumask_setall(desc->affinity);
 
 #ifdef CONFIG_GENERIC_PENDING_IRQ
        if (!alloc_cpumask_var_node(&desc->pending_mask, GFP_ATOMIC, node)) {
                free_cpumask_var(desc->affinity);
                return false;
        }
-       cpumask_clear(desc->pending_mask);
+#endif
 #endif
        return true;
 }
 
+static inline void init_desc_masks(struct irq_desc *desc)
+{
+       cpumask_setall(desc->affinity);
+#ifdef CONFIG_GENERIC_PENDING_IRQ
+       cpumask_clear(desc->pending_mask);
+#endif
+}
+
 /**
  * init_copy_desc_masks - copy cpumasks for irq_desc
  * @old_desc:  pointer to old irq_desc struct
@@ -478,7 +476,7 @@ static inline bool init_alloc_desc_masks(struct irq_desc *desc, int cpu,
 static inline void init_copy_desc_masks(struct irq_desc *old_desc,
                                        struct irq_desc *new_desc)
 {
-#ifdef CONFIG_CPUMASKS_OFFSTACK
+#ifdef CONFIG_CPUMASK_OFFSTACK
        cpumask_copy(new_desc->affinity, old_desc->affinity);
 
 #ifdef CONFIG_GENERIC_PENDING_IRQ
@@ -499,12 +497,16 @@ static inline void free_desc_masks(struct irq_desc *old_desc,
 
 #else /* !CONFIG_SMP */
 
-static inline bool init_alloc_desc_masks(struct irq_desc *desc, int cpu,
+static inline bool alloc_desc_masks(struct irq_desc *desc, int node,
                                                                bool boot)
 {
        return true;
 }
 
+static inline void init_desc_masks(struct irq_desc *desc)
+{
+}
+
 static inline void init_copy_desc_masks(struct irq_desc *old_desc,
                                        struct irq_desc *new_desc)
 {
index 3394f8f52964b3d9b4433a3560ff94eb32b20cb8..7d047808419da88e273fba8cd1efd88d9aaa5bcd 100644 (file)
@@ -3,5 +3,5 @@ obj-y := handle.o manage.o spurious.o resend.o chip.o devres.o
 obj-$(CONFIG_GENERIC_IRQ_PROBE) += autoprobe.o
 obj-$(CONFIG_PROC_FS) += proc.o
 obj-$(CONFIG_GENERIC_PENDING_IRQ) += migration.o
-obj-$(CONFIG_NUMA_MIGRATE_IRQ_DESC) += numa_migrate.o
+obj-$(CONFIG_NUMA_IRQ_DESC) += numa_migrate.o
 obj-$(CONFIG_PM_SLEEP) += pm.o
index c687ba4363f2b4a95a5c3988998286a1e8ab699b..13c68e71b726c674619633de2f6e200b00adc039 100644 (file)
@@ -359,7 +359,6 @@ handle_level_irq(unsigned int irq, struct irq_desc *desc)
 
        spin_lock(&desc->lock);
        mask_ack_irq(desc, irq);
-       desc = irq_remap_to_desc(irq, desc);
 
        if (unlikely(desc->status & IRQ_INPROGRESS))
                goto out_unlock;
@@ -438,7 +437,6 @@ handle_fasteoi_irq(unsigned int irq, struct irq_desc *desc)
        desc->status &= ~IRQ_INPROGRESS;
 out:
        desc->chip->eoi(irq);
-       desc = irq_remap_to_desc(irq, desc);
 
        spin_unlock(&desc->lock);
 }
@@ -475,7 +473,6 @@ handle_edge_irq(unsigned int irq, struct irq_desc *desc)
                    !desc->action)) {
                desc->status |= (IRQ_PENDING | IRQ_MASKED);
                mask_ack_irq(desc, irq);
-               desc = irq_remap_to_desc(irq, desc);
                goto out_unlock;
        }
        kstat_incr_irqs_this_cpu(irq, desc);
@@ -483,7 +480,6 @@ handle_edge_irq(unsigned int irq, struct irq_desc *desc)
        /* Start handling the irq */
        if (desc->chip->ack)
                desc->chip->ack(irq);
-       desc = irq_remap_to_desc(irq, desc);
 
        /* Mark the IRQ currently in progress.*/
        desc->status |= IRQ_INPROGRESS;
@@ -544,10 +540,8 @@ handle_percpu_irq(unsigned int irq, struct irq_desc *desc)
        if (!noirqdebug)
                note_interrupt(irq, desc, action_ret);
 
-       if (desc->chip->eoi) {
+       if (desc->chip->eoi)
                desc->chip->eoi(irq);
-               desc = irq_remap_to_desc(irq, desc);
-       }
 }
 
 void
@@ -582,10 +576,8 @@ __set_irq_handler(unsigned int irq, irq_flow_handler_t handle, int is_chained,
 
        /* Uninstall? */
        if (handle == handle_bad_irq) {
-               if (desc->chip != &no_irq_chip) {
+               if (desc->chip != &no_irq_chip)
                        mask_ack_irq(desc, irq);
-                       desc = irq_remap_to_desc(irq, desc);
-               }
                desc->status |= IRQ_DISABLED;
                desc->depth = 1;
        }
index 26e08754744fa13dd9da3e919be6adb3976b2b04..18041a254d3246c7c95fa52918938132f2032efe 100644 (file)
@@ -11,6 +11,7 @@
  */
 
 #include <linux/irq.h>
+#include <linux/slab.h>
 #include <linux/module.h>
 #include <linux/random.h>
 #include <linux/interrupt.h>
@@ -81,45 +82,48 @@ static struct irq_desc irq_desc_init = {
        .lock       = __SPIN_LOCK_UNLOCKED(irq_desc_init.lock),
 };
 
-void init_kstat_irqs(struct irq_desc *desc, int cpu, int nr)
+void __ref init_kstat_irqs(struct irq_desc *desc, int node, int nr)
 {
-       int node;
        void *ptr;
 
-       node = cpu_to_node(cpu);
-       ptr = kzalloc_node(nr * sizeof(*desc->kstat_irqs), GFP_ATOMIC, node);
+       if (slab_is_available())
+               ptr = kzalloc_node(nr * sizeof(*desc->kstat_irqs),
+                                  GFP_ATOMIC, node);
+       else
+               ptr = alloc_bootmem_node(NODE_DATA(node),
+                               nr * sizeof(*desc->kstat_irqs));
 
        /*
         * don't overwite if can not get new one
         * init_copy_kstat_irqs() could still use old one
         */
        if (ptr) {
-               printk(KERN_DEBUG "  alloc kstat_irqs on cpu %d node %d\n",
-                        cpu, node);
+               printk(KERN_DEBUG "  alloc kstat_irqs on node %d\n", node);
                desc->kstat_irqs = ptr;
        }
 }
 
-static void init_one_irq_desc(int irq, struct irq_desc *desc, int cpu)
+static void init_one_irq_desc(int irq, struct irq_desc *desc, int node)
 {
        memcpy(desc, &irq_desc_init, sizeof(struct irq_desc));
 
        spin_lock_init(&desc->lock);
        desc->irq = irq;
 #ifdef CONFIG_SMP
-       desc->cpu = cpu;
+       desc->node = node;
 #endif
        lockdep_set_class(&desc->lock, &irq_desc_lock_class);
-       init_kstat_irqs(desc, cpu, nr_cpu_ids);
+       init_kstat_irqs(desc, node, nr_cpu_ids);
        if (!desc->kstat_irqs) {
                printk(KERN_ERR "can not alloc kstat_irqs\n");
                BUG_ON(1);
        }
-       if (!init_alloc_desc_masks(desc, cpu, false)) {
+       if (!alloc_desc_masks(desc, node, false)) {
                printk(KERN_ERR "can not alloc irq_desc cpumasks\n");
                BUG_ON(1);
        }
-       arch_init_chip_data(desc, cpu);
+       init_desc_masks(desc);
+       arch_init_chip_data(desc, node);
 }
 
 /*
@@ -169,7 +173,8 @@ int __init early_irq_init(void)
                desc[i].irq = i;
                desc[i].kstat_irqs = kstat_irqs_legacy + i * nr_cpu_ids;
                lockdep_set_class(&desc[i].lock, &irq_desc_lock_class);
-               init_alloc_desc_masks(&desc[i], 0, true);
+               alloc_desc_masks(&desc[i], 0, true);
+               init_desc_masks(&desc[i]);
                irq_desc_ptrs[i] = desc + i;
        }
 
@@ -187,11 +192,10 @@ struct irq_desc *irq_to_desc(unsigned int irq)
        return NULL;
 }
 
-struct irq_desc *irq_to_desc_alloc_cpu(unsigned int irq, int cpu)
+struct irq_desc * __ref irq_to_desc_alloc_node(unsigned int irq, int node)
 {
        struct irq_desc *desc;
        unsigned long flags;
-       int node;
 
        if (irq >= nr_irqs) {
                WARN(1, "irq (%d) >= nr_irqs (%d) in irq_to_desc_alloc\n",
@@ -210,15 +214,17 @@ struct irq_desc *irq_to_desc_alloc_cpu(unsigned int irq, int cpu)
        if (desc)
                goto out_unlock;
 
-       node = cpu_to_node(cpu);
-       desc = kzalloc_node(sizeof(*desc), GFP_ATOMIC, node);
-       printk(KERN_DEBUG "  alloc irq_desc for %d on cpu %d node %d\n",
-                irq, cpu, node);
+       if (slab_is_available())
+               desc = kzalloc_node(sizeof(*desc), GFP_ATOMIC, node);
+       else
+               desc = alloc_bootmem_node(NODE_DATA(node), sizeof(*desc));
+
+       printk(KERN_DEBUG "  alloc irq_desc for %d on node %d\n", irq, node);
        if (!desc) {
                printk(KERN_ERR "can not alloc irq_desc\n");
                BUG_ON(1);
        }
-       init_one_irq_desc(irq, desc, cpu);
+       init_one_irq_desc(irq, desc, node);
 
        irq_desc_ptrs[irq] = desc;
 
@@ -256,7 +262,8 @@ int __init early_irq_init(void)
 
        for (i = 0; i < count; i++) {
                desc[i].irq = i;
-               init_alloc_desc_masks(&desc[i], 0, true);
+               alloc_desc_masks(&desc[i], 0, true);
+               init_desc_masks(&desc[i]);
                desc[i].kstat_irqs = kstat_irqs_all[i];
        }
        return arch_early_irq_init();
@@ -267,7 +274,7 @@ struct irq_desc *irq_to_desc(unsigned int irq)
        return (irq < NR_IRQS) ? irq_desc + irq : NULL;
 }
 
-struct irq_desc *irq_to_desc_alloc_cpu(unsigned int irq, int cpu)
+struct irq_desc *irq_to_desc_alloc_node(unsigned int irq, int node)
 {
        return irq_to_desc(irq);
 }
@@ -453,11 +460,8 @@ unsigned int __do_IRQ(unsigned int irq)
                /*
                 * No locking required for CPU-local interrupts:
                 */
-               if (desc->chip->ack) {
+               if (desc->chip->ack)
                        desc->chip->ack(irq);
-                       /* get new one */
-                       desc = irq_remap_to_desc(irq, desc);
-               }
                if (likely(!(desc->status & IRQ_DISABLED))) {
                        action_ret = handle_IRQ_event(irq, desc->action);
                        if (!noirqdebug)
@@ -468,10 +472,8 @@ unsigned int __do_IRQ(unsigned int irq)
        }
 
        spin_lock(&desc->lock);
-       if (desc->chip->ack) {
+       if (desc->chip->ack)
                desc->chip->ack(irq);
-               desc = irq_remap_to_desc(irq, desc);
-       }
        /*
         * REPLAY is when Linux resends an IRQ that was dropped earlier
         * WAITING is used by probe to mark irqs that are being tested
index 01ce20eab38fed96a7b5a861940ba58d47c18fbf..73468253143ba55883072d1020791c11b1e30210 100644 (file)
@@ -16,7 +16,7 @@ extern void __disable_irq(struct irq_desc *desc, unsigned int irq, bool susp);
 extern void __enable_irq(struct irq_desc *desc, unsigned int irq, bool resume);
 
 extern struct lock_class_key irq_desc_lock_class;
-extern void init_kstat_irqs(struct irq_desc *desc, int cpu, int nr);
+extern void init_kstat_irqs(struct irq_desc *desc, int node, int nr);
 extern void clear_kstat_irqs(struct irq_desc *desc);
 extern spinlock_t sparse_irq_lock;
 
@@ -42,6 +42,9 @@ static inline void unregister_handler_proc(unsigned int irq,
 
 extern int irq_select_affinity_usr(unsigned int irq);
 
+extern void
+irq_set_thread_affinity(struct irq_desc *desc, const struct cpumask *cpumask);
+
 /*
  * Debugging printout:
  */
index 2734eca59243bd8b0783b3553622363b2ce8129e..aaf5c9d05770378b42acc2d41905ceb543f1f280 100644 (file)
@@ -80,7 +80,7 @@ int irq_can_set_affinity(unsigned int irq)
        return 1;
 }
 
-static void
+void
 irq_set_thread_affinity(struct irq_desc *desc, const struct cpumask *cpumask)
 {
        struct irqaction *action = desc->action;
@@ -109,17 +109,22 @@ int irq_set_affinity(unsigned int irq, const struct cpumask *cpumask)
        spin_lock_irqsave(&desc->lock, flags);
 
 #ifdef CONFIG_GENERIC_PENDING_IRQ
-       if (desc->status & IRQ_MOVE_PCNTXT)
-               desc->chip->set_affinity(irq, cpumask);
+       if (desc->status & IRQ_MOVE_PCNTXT) {
+               if (!desc->chip->set_affinity(irq, cpumask)) {
+                       cpumask_copy(desc->affinity, cpumask);
+                       irq_set_thread_affinity(desc, cpumask);
+               }
+       }
        else {
                desc->status |= IRQ_MOVE_PENDING;
                cpumask_copy(desc->pending_mask, cpumask);
        }
 #else
-       cpumask_copy(desc->affinity, cpumask);
-       desc->chip->set_affinity(irq, cpumask);
+       if (!desc->chip->set_affinity(irq, cpumask)) {
+               cpumask_copy(desc->affinity, cpumask);
+               irq_set_thread_affinity(desc, cpumask);
+       }
 #endif
-       irq_set_thread_affinity(desc, cpumask);
        desc->status |= IRQ_AFFINITY_SET;
        spin_unlock_irqrestore(&desc->lock, flags);
        return 0;
index e05ad9be43b7a5fa7e6d6a24f94e49828a73572a..cfe767ca154501460f9f7e757c08d881611e9c95 100644 (file)
@@ -1,5 +1,8 @@
 
 #include <linux/irq.h>
+#include <linux/interrupt.h>
+
+#include "internals.h"
 
 void move_masked_irq(int irq)
 {
@@ -39,11 +42,12 @@ void move_masked_irq(int irq)
         * masking the irqs.
         */
        if (likely(cpumask_any_and(desc->pending_mask, cpu_online_mask)
-                  < nr_cpu_ids)) {
-               cpumask_and(desc->affinity,
-                           desc->pending_mask, cpu_online_mask);
-               desc->chip->set_affinity(irq, desc->affinity);
-       }
+                  < nr_cpu_ids))
+               if (!desc->chip->set_affinity(irq, desc->pending_mask)) {
+                       cpumask_copy(desc->affinity, desc->pending_mask);
+                       irq_set_thread_affinity(desc, desc->pending_mask);
+               }
+
        cpumask_clear(desc->pending_mask);
 }
 
index 44bbdcbaf8d2c8193f2d631b54061047546d0065..2f69bee57bf21ca5a42027834ddccee96670d989 100644 (file)
@@ -15,9 +15,9 @@
 
 static void init_copy_kstat_irqs(struct irq_desc *old_desc,
                                 struct irq_desc *desc,
-                                int cpu, int nr)
+                                int node, int nr)
 {
-       init_kstat_irqs(desc, cpu, nr);
+       init_kstat_irqs(desc, node, nr);
 
        if (desc->kstat_irqs != old_desc->kstat_irqs)
                memcpy(desc->kstat_irqs, old_desc->kstat_irqs,
@@ -34,20 +34,20 @@ static void free_kstat_irqs(struct irq_desc *old_desc, struct irq_desc *desc)
 }
 
 static bool init_copy_one_irq_desc(int irq, struct irq_desc *old_desc,
-                struct irq_desc *desc, int cpu)
+                struct irq_desc *desc, int node)
 {
        memcpy(desc, old_desc, sizeof(struct irq_desc));
-       if (!init_alloc_desc_masks(desc, cpu, false)) {
+       if (!alloc_desc_masks(desc, node, false)) {
                printk(KERN_ERR "irq %d: can not get new irq_desc cpumask "
                                "for migration.\n", irq);
                return false;
        }
        spin_lock_init(&desc->lock);
-       desc->cpu = cpu;
+       desc->node = node;
        lockdep_set_class(&desc->lock, &irq_desc_lock_class);
-       init_copy_kstat_irqs(old_desc, desc, cpu, nr_cpu_ids);
+       init_copy_kstat_irqs(old_desc, desc, node, nr_cpu_ids);
        init_copy_desc_masks(old_desc, desc);
-       arch_init_copy_chip_data(old_desc, desc, cpu);
+       arch_init_copy_chip_data(old_desc, desc, node);
        return true;
 }
 
@@ -59,12 +59,11 @@ static void free_one_irq_desc(struct irq_desc *old_desc, struct irq_desc *desc)
 }
 
 static struct irq_desc *__real_move_irq_desc(struct irq_desc *old_desc,
-                                               int cpu)
+                                               int node)
 {
        struct irq_desc *desc;
        unsigned int irq;
        unsigned long flags;
-       int node;
 
        irq = old_desc->irq;
 
@@ -76,7 +75,6 @@ static struct irq_desc *__real_move_irq_desc(struct irq_desc *old_desc,
        if (desc && old_desc != desc)
                goto out_unlock;
 
-       node = cpu_to_node(cpu);
        desc = kzalloc_node(sizeof(*desc), GFP_ATOMIC, node);
        if (!desc) {
                printk(KERN_ERR "irq %d: can not get new irq_desc "
@@ -85,7 +83,7 @@ static struct irq_desc *__real_move_irq_desc(struct irq_desc *old_desc,
                desc = old_desc;
                goto out_unlock;
        }
-       if (!init_copy_one_irq_desc(irq, old_desc, desc, cpu)) {
+       if (!init_copy_one_irq_desc(irq, old_desc, desc, node)) {
                /* still use old one */
                kfree(desc);
                desc = old_desc;
@@ -97,9 +95,7 @@ static struct irq_desc *__real_move_irq_desc(struct irq_desc *old_desc,
 
        /* free the old one */
        free_one_irq_desc(old_desc, desc);
-       spin_unlock(&old_desc->lock);
        kfree(old_desc);
-       spin_lock(&desc->lock);
 
        return desc;
 
@@ -109,24 +105,14 @@ out_unlock:
        return desc;
 }
 
-struct irq_desc *move_irq_desc(struct irq_desc *desc, int cpu)
+struct irq_desc *move_irq_desc(struct irq_desc *desc, int node)
 {
-       int old_cpu;
-       int node, old_node;
-
        /* those all static, do move them */
        if (desc->irq < NR_IRQS_LEGACY)
                return desc;
 
-       old_cpu = desc->cpu;
-       if (old_cpu != cpu) {
-               node = cpu_to_node(cpu);
-               old_node = cpu_to_node(old_cpu);
-               if (old_node != node)
-                       desc = __real_move_irq_desc(desc, cpu);
-               else
-                       desc->cpu = cpu;
-       }
+       if (desc->node != node)
+               desc = __real_move_irq_desc(desc, node);
 
        return desc;
 }
index b525dd348511b0bda3b08c19ffef6df0cf053206..f674f332a02433de90bb67f4e23a66106414d53f 100644 (file)
@@ -828,7 +828,7 @@ int __init __weak arch_early_irq_init(void)
        return 0;
 }
 
-int __weak arch_init_chip_data(struct irq_desc *desc, int cpu)
+int __weak arch_init_chip_data(struct irq_desc *desc, int node)
 {
        return 0;
 }