In the DTB tree created by firmware on Maple 64bit target, host bridge parent<br><div class="gmail_quote">
node has specified both of these two properties to be 2. However, the actual<br>
"cell" value for host bridge node is 1. we have to provide one fixup function.<br>
<br>
Signed-off-by: Tiejun Chen <<a href="mailto:tiejun.china@gmail.com">tiejun.china@gmail.com</a>><br>
---<br>
arch/powerpc/kernel/prom_init.c | 42 +++++++++++++++++++++++++++++++++++++++<br>
1 files changed, 42 insertions(+), 0 deletions(-)<br>
<br>
diff --git a/arch/powerpc/kernel/prom_init.c b/arch/powerpc/kernel/prom_init.c<br>
index 2445945..9cd23b6 100644<br>
--- a/arch/powerpc/kernel/prom_init.c<br>
+++ b/arch/powerpc/kernel/prom_init.c<br>
@@ -1948,8 +1948,49 @@ static void __init fixup_device_tree_maple(void)<br>
prom_setprop(isa, name, "ranges",<br>
isa_ranges, sizeof(isa_ranges));<br>
}<br>
+<br>
+/* On Maple 64bit target host bridge parent node has specified address and<br>
+ * size properties to be 2. But the actual "cell" value for host bridge node<br>
+ * is 1 since early MOTLoad internal bug. */<br>
+static void __init fixup_device_tree_maple_hb(void)<br>
+{<br>
+ phandle hb;<br>
+ u32 hb_ranges[4];<br>
+ u32 size_cell, addr_cell;<br>
+ struct prom_t *_prom = &RELOC(prom);<br>
+ char *name;<br>
+<br>
+ name = "/hostbridge@f8000000";<br>
+ hb = call_prom("finddevice", 1, 1, ADDR(name));<br>
+ if (!PHANDLE_VALID(hb))<br>
+ return;<br>
+<br>
+ if (prom_getproplen(hb, "reg") != 8)<br>
+ return;<br>
+<br>
+ if (prom_getprop(hb, "reg", hb_ranges, (sizeof(hb_ranges))/2)<br>
+ == PROM_ERROR)<br>
+ return;<br>
+<br>
+ prom_getprop(_prom->root, "#address-cells", &addr_cell, sizeof(addr_cell));<br>
+ prom_getprop(_prom->root, "#size-cells", &size_cell, sizeof(size_cell));<br>
+<br>
+ if ((addr_cell != 2) || (size_cell != 2) ||<br>
+ (hb_ranges[0] != 0xf8000000))<br>
+ return;<br>
+<br>
+ prom_printf("Fixing up bogus HOSTBRIDGE reg on Maple/Apache...\n");<br>
+<br>
+ hb_ranges[3] = hb_ranges[1];<br>
+ hb_ranges[1] = hb_ranges[0];<br>
+ hb_ranges[0] = hb_ranges[2] = 0;<br>
+ prom_setprop(hb, name, "reg",<br>
+ hb_ranges, sizeof(hb_ranges));<br>
+}<br>
+<br>
#else<br>
#define fixup_device_tree_maple()<br>
+#define fixup_device_tree_maple_hb()<br>
#endif<br>
<br>
#ifdef CONFIG_PPC_CHRP<br>
@@ -2190,6 +2231,7 @@ static void __init fixup_device_tree_efika(void)<br>
static void __init fixup_device_tree(void)<br>
{<br>
fixup_device_tree_maple();<br>
+ fixup_device_tree_maple_hb();<br>
fixup_device_tree_chrp();<br>
fixup_device_tree_pmac();<br>
fixup_device_tree_efika();<br>
<font color="#888888">--<br>
1.5.6<br>
<br>
</font></div><br>