]> err.no Git - linux-2.6/blobdiff - arch/powerpc/platforms/pseries/xics.c
Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/sparc-2.6
[linux-2.6] / arch / powerpc / platforms / pseries / xics.c
index 9ecf75fe9b1485a9f710011effc8ee018243ceec..a977f200db895c6bbdfd4f98cc60a69af65912df 100644 (file)
@@ -160,6 +160,46 @@ static inline void lpar_qirr_info(int n_cpu , u8 value)
 
 /* High level handlers and init code */
 
+static void xics_update_irq_servers(void)
+{
+       int i, j;
+       struct device_node *np;
+       u32 ilen;
+       const u32 *ireg, *isize;
+       u32 hcpuid;
+
+       /* Find the server numbers for the boot cpu. */
+       np = of_get_cpu_node(boot_cpuid, NULL);
+       BUG_ON(!np);
+
+       ireg = of_get_property(np, "ibm,ppc-interrupt-gserver#s", &ilen);
+       if (!ireg) {
+               of_node_put(np);
+               return;
+       }
+
+       i = ilen / sizeof(int);
+       hcpuid = get_hard_smp_processor_id(boot_cpuid);
+
+       /* Global interrupt distribution server is specified in the last
+        * entry of "ibm,ppc-interrupt-gserver#s" property. Get the last
+        * entry fom this property for current boot cpu id and use it as
+        * default distribution server
+        */
+       for (j = 0; j < i; j += 2) {
+               if (ireg[j] == hcpuid) {
+                       default_server = hcpuid;
+                       default_distrib_server = ireg[j+1];
+
+                       isize = of_get_property(np,
+                                       "ibm,interrupt-server#-size", NULL);
+                       if (isize)
+                               interrupt_server_size = *isize;
+               }
+       }
+
+       of_node_put(np);
+}
 
 #ifdef CONFIG_SMP
 static int get_irq_server(unsigned int virq, unsigned int strict_check)
@@ -169,6 +209,9 @@ static int get_irq_server(unsigned int virq, unsigned int strict_check)
        cpumask_t cpumask = irq_desc[virq].affinity;
        cpumask_t tmp = CPU_MASK_NONE;
 
+       if (! cpu_isset(default_server, cpu_online_map))
+               xics_update_irq_servers();
+
        if (!distribute_irqs)
                return default_server;
 
@@ -660,12 +703,9 @@ static void __init xics_setup_8259_cascade(void)
 
 void __init xics_init_IRQ(void)
 {
-       int i, j;
        struct device_node *np;
-       u32 ilen, indx = 0;
-       const u32 *ireg, *isize;
+       u32 indx = 0;
        int found = 0;
-       u32 hcpuid;
 
        ppc64_boot_msg(0x20, "XICS Init");
 
@@ -684,34 +724,7 @@ void __init xics_init_IRQ(void)
                return;
 
        xics_init_host();
-
-       /* Find the server numbers for the boot cpu. */
-       np = of_get_cpu_node(boot_cpuid, NULL);
-       BUG_ON(!np);
-       ireg = of_get_property(np, "ibm,ppc-interrupt-gserver#s", &ilen);
-       if (!ireg)
-               goto skip_gserver_check;
-       i = ilen / sizeof(int);
-       hcpuid = get_hard_smp_processor_id(boot_cpuid);
-
-       /* Global interrupt distribution server is specified in the last
-        * entry of "ibm,ppc-interrupt-gserver#s" property. Get the last
-        * entry fom this property for current boot cpu id and use it as
-        * default distribution server
-        */
-       for (j = 0; j < i; j += 2) {
-               if (ireg[j] == hcpuid) {
-                       default_server = hcpuid;
-                       default_distrib_server = ireg[j+1];
-
-                       isize = of_get_property(np,
-                                       "ibm,interrupt-server#-size", NULL);
-                       if (isize)
-                               interrupt_server_size = *isize;
-               }
-       }
-skip_gserver_check:
-       of_node_put(np);
+       xics_update_irq_servers();
 
        if (firmware_has_feature(FW_FEATURE_LPAR))
                ppc_md.get_irq = xics_get_irq_lpar;
@@ -750,7 +763,7 @@ void xics_request_IPIs(void)
 }
 #endif /* CONFIG_SMP */
 
-void xics_teardown_cpu()
+void xics_teardown_cpu(void)
 {
        int cpu = smp_processor_id();