[POWERPC] Fix various offb and BootX-related issues

This patch fixes various issues with offb (the default fbdev used on
powerpc when no proper fbdev is supported). It was broken when using
BootX under some circumstances and would fail to properly get the
framebuffer base address in others.

Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Signed-off-by: Paul Mackerras <paulus@samba.org>
diff --git a/arch/powerpc/kernel/btext.c b/arch/powerpc/kernel/btext.c
index a692091..f4e5e14e 100644
--- a/arch/powerpc/kernel/btext.c
+++ b/arch/powerpc/kernel/btext.c
@@ -111,7 +111,7 @@
 	logicalDisplayBase = (unsigned char *)address;
 	dispDeviceBase = (unsigned char *)address;
 	dispDeviceRowBytes = pitch;
-	dispDeviceDepth = depth;
+	dispDeviceDepth = depth == 15 ? 16 : depth;
 	dispDeviceRect[0] = dispDeviceRect[1] = 0;
 	dispDeviceRect[2] = width;
 	dispDeviceRect[3] = height;
@@ -160,20 +160,28 @@
 	unsigned long address = 0;
 	u32 *prop;
 
-	prop = (u32 *)get_property(np, "width", NULL);
+	prop = (u32 *)get_property(np, "linux,bootx-width", NULL);
+	if (prop == NULL)
+		prop = (u32 *)get_property(np, "width", NULL);
 	if (prop == NULL)
 		return -EINVAL;
 	width = *prop;
-	prop = (u32 *)get_property(np, "height", NULL);
+	prop = (u32 *)get_property(np, "linux,bootx-height", NULL);
+	if (prop == NULL)
+		prop = (u32 *)get_property(np, "height", NULL);
 	if (prop == NULL)
 		return -EINVAL;
 	height = *prop;
-	prop = (u32 *)get_property(np, "depth", NULL);
+	prop = (u32 *)get_property(np, "linux,bootx-depth", NULL);
+	if (prop == NULL)
+		prop = (u32 *)get_property(np, "depth", NULL);
 	if (prop == NULL)
 		return -EINVAL;
 	depth = *prop;
 	pitch = width * ((depth + 7) / 8);
-	prop = (u32 *)get_property(np, "linebytes", NULL);
+	prop = (u32 *)get_property(np, "linux,bootx-linebytes", NULL);
+	if (prop == NULL)
+		prop = (u32 *)get_property(np, "linebytes", NULL);
 	if (prop)
 		pitch = *prop;
 	if (pitch == 1)
@@ -194,7 +202,7 @@
 	g_max_loc_Y = height / 16;
 	dispDeviceBase = (unsigned char *)address;
 	dispDeviceRowBytes = pitch;
-	dispDeviceDepth = depth;
+	dispDeviceDepth = depth == 15 ? 16 : depth;
 	dispDeviceRect[0] = dispDeviceRect[1] = 0;
 	dispDeviceRect[2] = width;
 	dispDeviceRect[3] = height;
diff --git a/arch/powerpc/kernel/setup_32.c b/arch/powerpc/kernel/setup_32.c
index ba7cd50..0c21de3 100644
--- a/arch/powerpc/kernel/setup_32.c
+++ b/arch/powerpc/kernel/setup_32.c
@@ -51,7 +51,6 @@
 
 extern void bootx_init(unsigned long r4, unsigned long phys);
 
-boot_infos_t *boot_infos;
 struct ide_machdep_calls ppc_ide_md;
 
 int boot_cpuid;
diff --git a/arch/powerpc/platforms/powermac/bootx_init.c b/arch/powerpc/platforms/powermac/bootx_init.c
index cb257ae..5685ad9 100644
--- a/arch/powerpc/platforms/powermac/bootx_init.c
+++ b/arch/powerpc/platforms/powermac/bootx_init.c
@@ -181,8 +181,25 @@
 static void __init bootx_add_display_props(unsigned long base,
 					   unsigned long *mem_end)
 {
+	boot_infos_t *bi = bootx_info;
+	u32 tmp;
+
 	bootx_dt_add_prop("linux,boot-display", NULL, 0, mem_end);
 	bootx_dt_add_prop("linux,opened", NULL, 0, mem_end);
+	tmp = bi->dispDeviceDepth;
+	bootx_dt_add_prop("linux,bootx-depth", &tmp, 4, mem_end);
+	tmp = bi->dispDeviceRect[2] - bi->dispDeviceRect[0];
+	bootx_dt_add_prop("linux,bootx-width", &tmp, 4, mem_end);
+	tmp = bi->dispDeviceRect[3] - bi->dispDeviceRect[1];
+	bootx_dt_add_prop("linux,bootx-height", &tmp, 4, mem_end);
+	tmp = bi->dispDeviceRowBytes;
+	bootx_dt_add_prop("linux,bootx-linebytes", &tmp, 4, mem_end);
+	tmp = (u32)bi->dispDeviceBase;
+	if (tmp == 0)
+		tmp = (u32)bi->logicalDisplayBase;
+	tmp += bi->dispDeviceRect[1] * bi->dispDeviceRowBytes;
+	tmp += bi->dispDeviceRect[0] * ((bi->dispDeviceDepth + 7) / 8);
+	bootx_dt_add_prop("linux,bootx-addr", &tmp, 4, mem_end);
 }
 
 static void __init bootx_dt_add_string(char *s, unsigned long *mem_end)
@@ -222,6 +239,11 @@
 		DBG(" detected display ! adding properties names !\n");
 		bootx_dt_add_string("linux,boot-display", mem_end);
 		bootx_dt_add_string("linux,opened", mem_end);
+		bootx_dt_add_string("linux,bootx-depth", mem_end);
+		bootx_dt_add_string("linux,bootx-width", mem_end);
+		bootx_dt_add_string("linux,bootx-height", mem_end);
+		bootx_dt_add_string("linux,bootx-linebytes", mem_end);
+		bootx_dt_add_string("linux,bootx-addr", mem_end);
 		strncpy(bootx_disp_path, namep, 255);
 	}
 
@@ -443,7 +465,14 @@
 	if (!BOOT_INFO_IS_V2_COMPATIBLE(bi))
 		bi->logicalDisplayBase = bi->dispDeviceBase;
 
+	/* Fixup depth 16 -> 15 as that's what MacOS calls 16bpp */
+	if (bi->dispDeviceDepth == 16)
+		bi->dispDeviceDepth = 15;
+
 #ifdef CONFIG_BOOTX_TEXT
+	ptr = (unsigned long)bi->logicalDisplayBase;
+	ptr += bi->dispDeviceRect[1] * bi->dispDeviceRowBytes;
+	ptr += bi->dispDeviceRect[0] * ((bi->dispDeviceDepth + 7) / 8);
 	btext_setup_display(bi->dispDeviceRect[2] - bi->dispDeviceRect[0],
 			    bi->dispDeviceRect[3] - bi->dispDeviceRect[1],
 			    bi->dispDeviceDepth, bi->dispDeviceRowBytes,