Subject: [PATCH] powerpc: XICS - fix getting the server number size

From: Sebastien Dugue <[email-masked]>
Date: Wed, 22 Oct 2008 16:36:32 +0200

The 'ibm,interrupt-server#-size' properties are not cpu nodes properties,
but rather live under the interrupt source controller nodes (compatible
ibm,ppc-xics).

  Therefore, this patch moves the detection of this property outside of
xics_update_irq_servers() and into xics_init_IRQ().

  Also this adds a check for mismatched sizes across the interrupt source
controller nodes. Not sure this is necessary as in this case the firmware
might be seriously busted.

Signed-off-by: Sebastien Dugue <[email-masked]>
Cc: Benjamin Herrenschmidt <[email-masked]>
Cc: Milton Miller <[email-masked]>
---
 arch/powerpc/platforms/pseries/xics.c |   28 ++++++++++++++++++++++------
 1 files changed, 22 insertions(+), 6 deletions(-)

diff --git a/arch/powerpc/platforms/pseries/xics.c b/arch/powerpc/platforms/pseries/xics.c
index e190477..75a289b 100644
--- a/arch/powerpc/platforms/pseries/xics.c
+++ b/arch/powerpc/platforms/pseries/xics.c
@@ -579,7 +579,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 +607,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 +677,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 +697,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();
 
-- 
1.6.0.1.308.gede4c