From: Philippe Bergheaud <felix@linux.vnet.ibm.com>
Subject: powerpc: Check return value of instance-to-package OF call
Git-commit: 10348f5976830e5d8f74e8abb04a9a057a5e8478
Patch-mainline: v3.13-rc3
References: bnc#863310, fate#315275, LTC#92305

Summary:     ## powerpc: add little-endian support
Description: ## Add little-endian support for POWER8.

Upstream-Description:

    On PA-Semi firmware, the instance-to-package callback doesn't seem
    to be implemented. We didn't check for error, however, thus
    subsequently passed the -1 value returned into stdout_node to
    thins like prom_getprop etc...
    
    Thus caused the firmware to load values around 0 (physical) internally
    as node structures. It somewhat "worked" as long as we had a NULL in the
    right place (address 8) at the beginning of the kernel, we didn't "see"
    the bug. But commit 5c0484e25ec03243d4c2f2d4416d4a13efc77f6a
    "powerpc: Endian safe trampoline" changed the kernel entry point causing
    that old bug to now cause a crash early during boot.
    
    This fixes booting on PA-Semi board by properly checking the return
    value from instance-to-package.
    
Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Tested-by: Olof Johansson <olof@lixom.net>

Signed-off-by: Philippe Bergheaud <felix@linux.vnet.ibm.com>
Acked-by: Torsten Duwe <duwe@suse.de>
---
 arch/powerpc/kernel/prom_init.c |   22 +++++++++++++---------
 1 file changed, 13 insertions(+), 9 deletions(-)

diff --git a/arch/powerpc/kernel/prom_init.c b/arch/powerpc/kernel/prom_init.c
index cb64a6e..078145a 100644
--- a/arch/powerpc/kernel/prom_init.c
+++ b/arch/powerpc/kernel/prom_init.c
@@ -1986,19 +1986,23 @@ static void __init prom_init_stdout(void)
 	/* Get the full OF pathname of the stdout device */
 	memset(path, 0, 256);
 	call_prom("instance-to-path", 3, 1, prom.stdout, path, 255);
-	stdout_node = call_prom("instance-to-package", 1, 1, prom.stdout);
-	val = cpu_to_be32(stdout_node);
-	prom_setprop(prom.chosen, "/chosen", "linux,stdout-package",
-		     &val, sizeof(val));
 	prom_printf("OF stdout device is: %s\n", of_stdout_device);
 	prom_setprop(prom.chosen, "/chosen", "linux,stdout-path",
 		     path, strlen(path) + 1);
 
-	/* If it's a display, note it */
-	memset(type, 0, sizeof(type));
-	prom_getprop(stdout_node, "device_type", type, sizeof(type));
-	if (strcmp(type, "display") == 0)
-		prom_setprop(stdout_node, path, "linux,boot-display", NULL, 0);
+	/* instance-to-package fails on PA-Semi */
+	stdout_node = call_prom("instance-to-package", 1, 1, prom.stdout);
+	if (stdout_node != PROM_ERROR) {
+		val = cpu_to_be32(stdout_node);
+		prom_setprop(prom.chosen, "/chosen", "linux,stdout-package",
+			     &val, sizeof(val));
+
+		/* If it's a display, note it */
+		memset(type, 0, sizeof(type));
+		prom_getprop(stdout_node, "device_type", type, sizeof(type));
+		if (strcmp(type, "display") == 0)
+			prom_setprop(stdout_node, path, "linux,boot-display", NULL, 0);
+	}
 }
 
 static int __init prom_find_machine_type(void)
-- 
1.7.10.4

