Merge branch 'master' of /home/sam/kernel/linux-2.6/
[pandora-kernel.git] / arch / powerpc / kernel / prom.c
index 6290232..4c524cb 100644 (file)
@@ -16,7 +16,6 @@
 #undef DEBUG
 
 #include <stdarg.h>
-#include <linux/config.h>
 #include <linux/kernel.h>
 #include <linux/string.h>
 #include <linux/init.h>
@@ -30,6 +29,7 @@
 #include <linux/bitops.h>
 #include <linux/module.h>
 #include <linux/kexec.h>
+#include <linux/debugfs.h>
 
 #include <asm/prom.h>
 #include <asm/rtas.h>
@@ -952,6 +952,7 @@ static struct ibm_pa_feature {
        /* put this back once we know how to test if firmware does 64k IO */
        {CPU_FTR_CI_LARGE_PAGE, 0,      1, 2, 0},
 #endif
+       {CPU_FTR_REAL_LE, PPC_FEATURE_TRUE_LE, 5, 0, 0},
 };
 
 static void __init check_cpu_pa_features(unsigned long node)
@@ -1124,24 +1125,6 @@ static int __init early_init_dt_scan_chosen(unsigned long node,
                tce_alloc_end = *lprop;
 #endif
 
-#ifdef CONFIG_PPC_RTAS
-       /* To help early debugging via the front panel, we retrieve a minimal
-        * set of RTAS infos now if available
-        */
-       {
-               u64 *basep, *entryp, *sizep;
-
-               basep = of_get_flat_dt_prop(node, "linux,rtas-base", NULL);
-               entryp = of_get_flat_dt_prop(node, "linux,rtas-entry", NULL);
-               sizep = of_get_flat_dt_prop(node, "linux,rtas-size", NULL);
-               if (basep && entryp && sizep) {
-                       rtas.base = *basep;
-                       rtas.entry = *entryp;
-                       rtas.size = *sizep;
-               }
-       }
-#endif /* CONFIG_PPC_RTAS */
-
 #ifdef CONFIG_KEXEC
        lprop = (u64*)of_get_flat_dt_prop(node, "linux,crashkernel-base", NULL);
        if (lprop)
@@ -1326,6 +1309,11 @@ void __init early_init_devtree(void *params)
        /* Setup flat device-tree pointer */
        initial_boot_params = params;
 
+#ifdef CONFIG_PPC_RTAS
+       /* Some machines might need RTAS info for debugging, grab it now. */
+       of_scan_flat_dt(early_init_dt_scan_rtas, NULL);
+#endif
+
        /* Retrieve various informations from the /chosen node of the
         * device-tree, including the platform type, initrd location and
         * size, TCE reserve, and more ...
@@ -2105,3 +2093,70 @@ int prom_update_property(struct device_node *np,
        return 0;
 }
 
+
+/* Find the device node for a given logical cpu number, also returns the cpu
+ * local thread number (index in ibm,interrupt-server#s) if relevant and
+ * asked for (non NULL)
+ */
+struct device_node *of_get_cpu_node(int cpu, unsigned int *thread)
+{
+       int hardid;
+       struct device_node *np;
+
+       hardid = get_hard_smp_processor_id(cpu);
+
+       for_each_node_by_type(np, "cpu") {
+               u32 *intserv;
+               unsigned int plen, t;
+
+               /* Check for ibm,ppc-interrupt-server#s. If it doesn't exist
+                * fallback to "reg" property and assume no threads
+                */
+               intserv = (u32 *)get_property(np, "ibm,ppc-interrupt-server#s",
+                                             &plen);
+               if (intserv == NULL) {
+                       u32 *reg = (u32 *)get_property(np, "reg", NULL);
+                       if (reg == NULL)
+                               continue;
+                       if (*reg == hardid) {
+                               if (thread)
+                                       *thread = 0;
+                               return np;
+                       }
+               } else {
+                       plen /= sizeof(u32);
+                       for (t = 0; t < plen; t++) {
+                               if (hardid == intserv[t]) {
+                                       if (thread)
+                                               *thread = t;
+                                       return np;
+                               }
+                       }
+               }
+       }
+       return NULL;
+}
+
+#ifdef DEBUG
+static struct debugfs_blob_wrapper flat_dt_blob;
+
+static int __init export_flat_device_tree(void)
+{
+       struct dentry *d;
+
+       d = debugfs_create_dir("powerpc", NULL);
+       if (!d)
+               return 1;
+
+       flat_dt_blob.data = initial_boot_params;
+       flat_dt_blob.size = initial_boot_params->totalsize;
+
+       d = debugfs_create_blob("flat-device-tree", S_IFREG | S_IRUSR,
+                               d, &flat_dt_blob);
+       if (!d)
+               return 1;
+
+       return 0;
+}
+__initcall(export_flat_device_tree);
+#endif