Merge branch 'master' of git://git.kernel.org/pub/scm/fs/xfs/xfs
[pandora-kernel.git] / arch / powerpc / platforms / pseries / xics.c
index e190477..80b5134 100644 (file)
@@ -153,9 +153,10 @@ static int get_irq_server(unsigned int virq, unsigned int strict_check)
 {
        int server;
        /* For the moment only implement delivery to all cpus or one cpu */
-       cpumask_t cpumask = irq_desc[virq].affinity;
+       cpumask_t cpumask;
        cpumask_t tmp = CPU_MASK_NONE;
 
+       cpumask_copy(&cpumask, irq_desc[virq].affinity);
        if (!distribute_irqs)
                return default_server;
 
@@ -332,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, cpumask_t cpumask)
+static void xics_set_affinity(unsigned int virq, const struct cpumask *cpumask)
 {
        unsigned int irq;
        int status;
@@ -579,7 +580,7 @@ static void xics_update_irq_servers(void)
        int i, j;
        struct device_node *np;
        u32 ilen;
-       const u32 *ireg, *isize;
+       const u32 *ireg;
        u32 hcpuid;
 
        /* Find the server numbers for the boot cpu. */
@@ -607,11 +608,6 @@ static void xics_update_irq_servers(void)
                }
        }
 
-       /* get the bit size of server numbers */
-       isize = of_get_property(np, "ibm,interrupt-server#-size", NULL);
-       if (isize)
-               interrupt_server_size = *isize;
-
        of_node_put(np);
 }
 
@@ -682,6 +678,7 @@ void __init xics_init_IRQ(void)
        struct device_node *np;
        u32 indx = 0;
        int found = 0;
+       const u32 *isize;
 
        ppc64_boot_msg(0x20, "XICS Init");
 
@@ -701,6 +698,26 @@ void __init xics_init_IRQ(void)
        if (found == 0)
                return;
 
+       /* get the bit size of server numbers */
+       found = 0;
+
+       for_each_compatible_node(np, NULL, "ibm,ppc-xics") {
+               isize = of_get_property(np, "ibm,interrupt-server#-size", NULL);
+
+               if (!isize)
+                       continue;
+
+               if (!found) {
+                       interrupt_server_size = *isize;
+                       found = 1;
+               } else if (*isize != interrupt_server_size) {
+                       printk(KERN_WARNING "XICS: "
+                              "mismatched ibm,interrupt-server#-size\n");
+                       interrupt_server_size = max(*isize,
+                                                   interrupt_server_size);
+               }
+       }
+
        xics_update_irq_servers();
        xics_init_host();
 
@@ -728,9 +745,18 @@ static void xics_set_cpu_priority(unsigned char cppr)
 /* Have the calling processor join or leave the specified global queue */
 static void xics_set_cpu_giq(unsigned int gserver, unsigned int join)
 {
-       int status = rtas_set_indicator_fast(GLOBAL_INTERRUPT_QUEUE,
-               (1UL << interrupt_server_size) - 1 - gserver, join);
-       WARN_ON(status < 0);
+       int index;
+       int status;
+
+       if (!rtas_indicator_present(GLOBAL_INTERRUPT_QUEUE, NULL))
+               return;
+
+       index = (1UL << interrupt_server_size) - 1 - gserver;
+
+       status = rtas_set_indicator_fast(GLOBAL_INTERRUPT_QUEUE, index, join);
+
+       WARN(status < 0, "set-indicator(%d, %d, %u) returned %d\n",
+            GLOBAL_INTERRUPT_QUEUE, index, join, status);
 }
 
 void xics_setup_cpu(void)
@@ -844,8 +870,8 @@ void xics_migrate_irqs_away(void)
                       virq, cpu);
 
                /* Reset affinity to all cpus */
-               irq_desc[virq].affinity = CPU_MASK_ALL;
-               desc->chip->set_affinity(virq, CPU_MASK_ALL);
+               cpumask_setall(irq_desc[virq].affinity);
+               desc->chip->set_affinity(virq, cpu_all_mask);
 unlock:
                spin_unlock_irqrestore(&desc->lock, flags);
        }