vserver 1.9.5.x5
[linux-2.6.git] / arch / ppc / syslib / prom_init.c
index e114c59..83686bc 100644 (file)
@@ -15,6 +15,7 @@
 #include <linux/ioport.h>
 #include <linux/pci.h>
 #include <linux/slab.h>
+#include <linux/bitops.h>
 
 #include <asm/sections.h>
 #include <asm/prom.h>
@@ -26,7 +27,6 @@
 #include <asm/system.h>
 #include <asm/mmu.h>
 #include <asm/pgtable.h>
-#include <asm/bitops.h>
 #include <asm/bootinfo.h>
 #include <asm/btext.h>
 #include <asm/pci-bridge.h>
@@ -111,15 +111,15 @@ static void prom_instantiate_rtas(void);
 static void * early_get_property(unsigned long base, unsigned long node,
                                char *prop);
 
-prom_entry prom __initdata = 0;
-ihandle prom_chosen __initdata = 0;
-ihandle prom_stdout __initdata = 0;
+prom_entry prom __initdata;
+ihandle prom_chosen __initdata;
+ihandle prom_stdout __initdata;
 
-char *prom_display_paths[FB_MAX] __initdata = { 0, };
-phandle prom_display_nodes[FB_MAX] __initdata;
-unsigned int prom_num_displays __initdata = 0;
-static char *of_stdout_device __initdata = 0;
-static ihandle prom_disp_node __initdata = 0;
+static char *prom_display_paths[FB_MAX] __initdata;
+static phandle prom_display_nodes[FB_MAX] __initdata;
+static unsigned int prom_num_displays __initdata;
+static ihandle prom_disp_node __initdata;
+char *of_stdout_device __initdata;
 
 unsigned int rtas_data;   /* physical pointer */
 unsigned int rtas_entry;  /* physical pointer */
@@ -161,7 +161,7 @@ call_prom(const char *service, int nargs, int nret, ...)
                prom_args.args[i] = va_arg(list, void *);
        va_end(list);
        for (i = 0; i < nret; ++i)
-               prom_args.args[i + nargs] = 0;
+               prom_args.args[i + nargs] = NULL;
        prom(&prom_args);
        return prom_args.args[nargs];
 }
@@ -181,7 +181,7 @@ call_prom_ret(const char *service, int nargs, int nret, void **rets, ...)
                prom_args.args[i] = va_arg(list, void *);
        va_end(list);
        for (i = 0; i < nret; ++i)
-               prom_args.args[i + nargs] = 0;
+               prom_args.args[i + nargs] = NULL;
        prom(&prom_args);
        for (i = 1; i < nret; ++i)
                rets[i-1] = prom_args.args[nargs + i];
@@ -363,9 +363,9 @@ check_display(unsigned long mem)
        };
        const unsigned char *clut;
 
-       prom_disp_node = 0;
+       prom_disp_node = NULL;
 
-       for (node = 0; prom_next_node(&node); ) {
+       for (node = NULL; prom_next_node(&node); ) {
                type[0] = 0;
                call_prom("getprop", 4, 1, node, "device_type",
                          type, sizeof(type));
@@ -403,6 +403,7 @@ check_display(unsigned long mem)
 
        for (j=0; j<prom_num_displays; j++) {
                path = prom_display_paths[j];
+               node = prom_display_nodes[j];
                prom_print("opening display ");
                prom_print(path);
                ih = call_prom("open", 1, 1, path);
@@ -420,6 +421,8 @@ check_display(unsigned long mem)
                        continue;
                } else {
                        prom_print("... ok\n");
+                       call_prom("setprop", 4, 1, node, "linux,opened", 0, NULL);
+
                        /*
                         * Setup a usable color table when the appropriate
                         * method is available.
@@ -441,6 +444,19 @@ check_display(unsigned long mem)
 #endif /* CONFIG_LOGO_LINUX_CLUT224 */
                }
        }
+       
+       if (prom_stdout) {
+               phandle p;
+               p = call_prom("instance-to-package", 1, 1, prom_stdout);
+               if (p && (int)p != -1) {
+                       type[0] = 0;
+                       call_prom("getprop", 4, 1, p, "device_type",
+                                 type, sizeof(type));
+                       if (strcmp(type, "display") == 0)
+                               call_prom("setprop", 4, 1, p, "linux,boot-display",
+                                         0, NULL);
+               }
+       }
 
        return ALIGNUL(mem);
 }
@@ -546,8 +562,8 @@ copy_device_tree(unsigned long mem_start, unsigned long mem_end)
        }
        allnextp = &allnodes;
        mem_start = ALIGNUL(mem_start);
-       new_start = inspect_node(root, 0, mem_start, mem_end, &allnextp);
-       *allnextp = 0;
+       new_start = inspect_node(root, NULL, mem_start, mem_end, &allnextp);
+       *allnextp = NULL;
        return new_start;
 }
 
@@ -695,7 +711,7 @@ prom_hold_cpus(unsigned long mem)
        /* look for cpus */
        *(unsigned long *)(0x0) = 0;
        asm volatile("dcbf 0,%0": : "r" (0) : "memory");
-       for (node = 0; prom_next_node(&node); ) {
+       for (node = NULL; prom_next_node(&node); ) {
                type[0] = 0;
                call_prom("getprop", 4, 1, node, "device_type",
                          type, sizeof(type));
@@ -794,14 +810,16 @@ prom_init(int r3, int r4, prom_entry pp)
        char *p, *d;
        unsigned long phys;
        void *result[3];
+       char model[32];
+       phandle node;
+       int rc;
 
        /* Default */
        phys = (unsigned long) &_stext;
 
        /* First get a handle for the stdout device */
        prom = pp;
-       prom_chosen = call_prom("finddevice", 1, 1,
-                                      "/chosen");
+       prom_chosen = call_prom("finddevice", 1, 1, "/chosen");
        if (prom_chosen == (void *)-1)
                prom_exit();
        if ((int) call_prom("getprop", 4, 1, prom_chosen,
@@ -851,11 +869,20 @@ prom_init(int r3, int r4, prom_entry pp)
 
        klimit = (char *) (mem - offset);
 
-       /* If we are already running at 0xc0000000, we assume we were
-        * loaded by an OF bootloader which did set a BAT for us.
-        * This breaks OF translate so we force phys to be 0.
-        */
-       if (offset == 0) {
+       node = call_prom("finddevice", 1, 1, "/");
+       rc = call_prom("getprop", 4, 1, node, "model", model, sizeof(model));
+       if (rc > 0 && !strncmp (model, "Pegasos", 7)
+               && strncmp (model, "Pegasos2", 8)) {
+               /* Pegasos 1 has a broken translate method in the OF,
+                * and furthermore the BATs are mapped 1:1 so the phys
+                * address calculated above is correct, so let's use
+                * it directly.
+                */
+       } else if (offset == 0) {
+               /* If we are already running at 0xc0000000, we assume we were
+                * loaded by an OF bootloader which did set a BAT for us.
+                * This breaks OF translate so we force phys to be 0.
+                */
                prom_print("(already at 0xc0000000) phys=0\n");
                phys = 0;
        } else if ((int) call_prom("getprop", 4, 1, prom_chosen, "mmu",
@@ -881,10 +908,15 @@ prom_init(int r3, int r4, prom_entry pp)
        for (i = 0; i < prom_num_displays; ++i)
                prom_display_paths[i] = PTRUNRELOC(prom_display_paths[i]);
 
+#ifdef CONFIG_SERIAL_CORE_CONSOLE
+       /* Relocate the of stdout for console autodetection */
+       of_stdout_device = PTRUNRELOC(of_stdout_device);
+#endif
+
        prom_print("returning 0x");
        prom_print_hex(phys);
        prom_print("from prom_init\n");
-       prom_stdout = 0;
+       prom_stdout = NULL;
 
        return phys;
 }
@@ -906,7 +938,7 @@ early_get_property(unsigned long base, unsigned long node, char *prop)
                        return (void *)((unsigned long)pp->value + base);
                }
        }
-       return 0;
+       return NULL;
 }
 
 /* Is boot-info compatible ? */
@@ -924,7 +956,7 @@ bootx_init(unsigned long r4, unsigned long phys)
 
        boot_infos = PTRUNRELOC(bi);
        if (!BOOT_INFO_IS_V2_COMPATIBLE(bi))
-               bi->logicalDisplayBase = 0;
+               bi->logicalDisplayBase = NULL;
 
 #ifdef CONFIG_BOOTX_TEXT
        btext_init(bi);