linux 2.6.16.38 w/ vs2.0.3-rc1
[linux-2.6.git] / arch / powerpc / kernel / prom.c
index 9a07f97..6dbd217 100644 (file)
@@ -62,7 +62,7 @@ static int __initdata dt_root_addr_cells;
 static int __initdata dt_root_size_cells;
 
 #ifdef CONFIG_PPC64
-int __initdata iommu_is_off;
+static int __initdata iommu_is_off;
 int __initdata iommu_force_on;
 unsigned long tce_alloc_start, tce_alloc_end;
 #endif
@@ -383,14 +383,14 @@ static int __devinit finish_node_interrupts(struct device_node *np,
                        /* Apple uses bits in there in a different way, let's
                         * only keep the real sense bit on macs
                         */
-                       if (machine_is(powermac))
+                       if (_machine == PLATFORM_POWERMAC)
                                sense &= 0x1;
                        np->intrs[intrcount].sense = map_mpic_senses[sense];
                }
 
 #ifdef CONFIG_PPC64
                /* We offset irq numbers for the u3 MPIC by 128 in PowerMac */
-               if (machine_is(powermac) && ic && ic->parent) {
+               if (_machine == PLATFORM_POWERMAC && ic && ic->parent) {
                        char *name = get_property(ic->parent, "name", NULL);
                        if (name && !strcmp(name, "u3"))
                                np->intrs[intrcount].line += 128;
@@ -570,18 +570,6 @@ int __init of_scan_flat_dt(int (*it)(unsigned long node,
        return rc;
 }
 
-unsigned long __init of_get_flat_dt_root(void)
-{
-       unsigned long p = ((unsigned long)initial_boot_params) +
-               initial_boot_params->off_dt_struct;
-
-       while(*((u32 *)p) == OF_DT_NOP)
-               p += 4;
-       BUG_ON (*((u32 *)p) != OF_DT_BEGIN_NODE);
-       p += 4;
-       return _ALIGN(p + strlen((char *)p) + 1, 4);
-}
-
 /**
  * This  function can be used within scan_flattened_dt callback to get
  * access to properties
@@ -624,25 +612,6 @@ void* __init of_get_flat_dt_prop(unsigned long node, const char *name,
        } while(1);
 }
 
-int __init of_flat_dt_is_compatible(unsigned long node, const char *compat)
-{
-       const char* cp;
-       unsigned long cplen, l;
-
-       cp = of_get_flat_dt_prop(node, "compatible", &cplen);
-       if (cp == NULL)
-               return 0;
-       while (cplen > 0) {
-               if (strncasecmp(cp, compat, strlen(compat)) == 0)
-                       return 1;
-               l = strlen(cp) + 1;
-               cp += l;
-               cplen -= l;
-       }
-
-       return 0;
-}
-
 static void *__init unflatten_dt_alloc(unsigned long *mem, unsigned long size,
                                       unsigned long align)
 {
@@ -717,7 +686,7 @@ static unsigned long __init unflatten_dt_node(unsigned long mem,
 #ifdef DEBUG
                                if ((strlen(p) + l + 1) != allocl) {
                                        DBG("%s: p: %d, l: %d, a: %d\n",
-                                           pathp, (int)strlen(p), l, allocl);
+                                           pathp, strlen(p), l, allocl);
                                }
 #endif
                                p += strlen(p);
@@ -860,6 +829,10 @@ void __init unflatten_device_tree(void)
 
        /* Allocate memory for the expanded device tree */
        mem = lmb_alloc(size + 4, __alignof__(struct device_node));
+       if (!mem) {
+               DBG("Couldn't allocate memory with lmb_alloc()!\n");
+               panic("Couldn't allocate memory with lmb_alloc()!\n");
+       }
        mem = (unsigned long) __va(mem);
 
        ((u32 *)mem)[size / 4] = 0xdeadbeef;
@@ -885,141 +858,35 @@ void __init unflatten_device_tree(void)
        DBG(" <- unflatten_device_tree()\n");
 }
 
-/*
- * ibm,pa-features is a per-cpu property that contains a string of
- * attribute descriptors, each of which has a 2 byte header plus up
- * to 254 bytes worth of processor attribute bits.  First header
- * byte specifies the number of bytes following the header.
- * Second header byte is an "attribute-specifier" type, of which
- * zero is the only currently-defined value.
- * Implementation:  Pass in the byte and bit offset for the feature
- * that we are interested in.  The function will return -1 if the
- * pa-features property is missing, or a 1/0 to indicate if the feature
- * is supported/not supported.  Note that the bit numbers are
- * big-endian to match the definition in PAPR.
- */
-static struct ibm_pa_feature {
-       unsigned long   cpu_features;   /* CPU_FTR_xxx bit */
-       unsigned int    cpu_user_ftrs;  /* PPC_FEATURE_xxx bit */
-       unsigned char   pabyte;         /* byte number in ibm,pa-features */
-       unsigned char   pabit;          /* bit number (big-endian) */
-       unsigned char   invert;         /* if 1, pa bit set => clear feature */
-} ibm_pa_features[] __initdata = {
-       {0, PPC_FEATURE_HAS_MMU,        0, 0, 0},
-       {0, PPC_FEATURE_HAS_FPU,        0, 1, 0},
-       {CPU_FTR_SLB, 0,                0, 2, 0},
-       {CPU_FTR_CTRL, 0,               0, 3, 0},
-       {CPU_FTR_NOEXECUTE, 0,          0, 6, 0},
-       {CPU_FTR_NODSISRALIGN, 0,       1, 1, 1},
-       {CPU_FTR_CI_LARGE_PAGE, 0,      1, 2, 0},
-};
-
-static void __init check_cpu_pa_features(unsigned long node)
-{
-       unsigned char *pa_ftrs;
-       unsigned long len, tablelen, i, bit;
-
-       pa_ftrs = of_get_flat_dt_prop(node, "ibm,pa-features", &tablelen);
-       if (pa_ftrs == NULL)
-               return;
-
-       /* find descriptor with type == 0 */
-       for (;;) {
-               if (tablelen < 3)
-                       return;
-               len = 2 + pa_ftrs[0];
-               if (tablelen < len)
-                       return;         /* descriptor 0 not found */
-               if (pa_ftrs[1] == 0)
-                       break;
-               tablelen -= len;
-               pa_ftrs += len;
-       }
-
-       /* loop over bits we know about */
-       for (i = 0; i < ARRAY_SIZE(ibm_pa_features); ++i) {
-               struct ibm_pa_feature *fp = &ibm_pa_features[i];
-
-               if (fp->pabyte >= pa_ftrs[0])
-                       continue;
-               bit = (pa_ftrs[2 + fp->pabyte] >> (7 - fp->pabit)) & 1;
-               if (bit ^ fp->invert) {
-                       cur_cpu_spec->cpu_features |= fp->cpu_features;
-                       cur_cpu_spec->cpu_user_features |= fp->cpu_user_ftrs;
-               } else {
-                       cur_cpu_spec->cpu_features &= ~fp->cpu_features;
-                       cur_cpu_spec->cpu_user_features &= ~fp->cpu_user_ftrs;
-               }
-       }
-}
 
 static int __init early_init_dt_scan_cpus(unsigned long node,
-                                         const char *uname, int depth,
-                                         void *data)
+                                         const char *uname, int depth, void *data)
 {
-       static int logical_cpuid = 0;
-       char *type = of_get_flat_dt_prop(node, "device_type", NULL);
-#ifdef CONFIG_ALTIVEC
        u32 *prop;
-#endif
-       u32 *intserv;
-       int i, nthreads;
-       unsigned long len;
-       int found = 0;
+       unsigned long size;
+       char *type = of_get_flat_dt_prop(node, "device_type", &size);
 
        /* We are scanning "cpu" nodes only */
        if (type == NULL || strcmp(type, "cpu") != 0)
                return 0;
 
-       /* Get physical cpuid */
-       intserv = of_get_flat_dt_prop(node, "ibm,ppc-interrupt-server#s", &len);
-       if (intserv) {
-               nthreads = len / sizeof(int);
-       } else {
-               intserv = of_get_flat_dt_prop(node, "reg", NULL);
-               nthreads = 1;
-       }
-
-       /*
-        * Now see if any of these threads match our boot cpu.
-        * NOTE: This must match the parsing done in smp_setup_cpu_maps.
-        */
-       for (i = 0; i < nthreads; i++) {
-               /*
-                * version 2 of the kexec param format adds the phys cpuid of
-                * booted proc.
+       boot_cpuid = 0;
+       boot_cpuid_phys = 0;
+       if (initial_boot_params && initial_boot_params->version >= 2) {
+               /* version 2 of the kexec param format adds the phys cpuid
+                * of booted proc.
                 */
-               if (initial_boot_params && initial_boot_params->version >= 2) {
-                       if (intserv[i] ==
-                                       initial_boot_params->boot_cpuid_phys) {
-                               found = 1;
-                               break;
-                       }
-               } else {
-                       /*
-                        * Check if it's the boot-cpu, set it's hw index now,
-                        * unfortunately this format did not support booting
-                        * off secondary threads.
-                        */
-                       if (of_get_flat_dt_prop(node,
+               boot_cpuid_phys = initial_boot_params->boot_cpuid_phys;
+       } else {
+               /* Check if it's the boot-cpu, set it's hw index now */
+               if (of_get_flat_dt_prop(node,
                                        "linux,boot-cpu", NULL) != NULL) {
-                               found = 1;
-                               break;
-                       }
+                       prop = of_get_flat_dt_prop(node, "reg", NULL);
+                       if (prop != NULL)
+                               boot_cpuid_phys = *prop;
                }
-
-#ifdef CONFIG_SMP
-               /* logical cpu id is always 0 on UP kernels */
-               logical_cpuid++;
-#endif
-       }
-
-       if (found) {
-               DBG("boot cpu: logical %d physical %d\n", logical_cpuid,
-                       intserv[i]);
-               boot_cpuid = logical_cpuid;
-               set_hard_smp_processor_id(boot_cpuid, intserv[i]);
        }
+       set_hard_smp_processor_id(0, boot_cpuid_phys);
 
 #ifdef CONFIG_ALTIVEC
        /* Check if we have a VMX and eventually update CPU features */
@@ -1037,13 +904,17 @@ static int __init early_init_dt_scan_cpus(unsigned long node,
        }
 #endif /* CONFIG_ALTIVEC */
 
-       check_cpu_pa_features(node);
-
 #ifdef CONFIG_PPC_PSERIES
-       if (nthreads > 1)
+       /*
+        * Check for an SMT capable CPU and set the CPU feature. We do
+        * this by looking at the size of the ibm,ppc-interrupt-server#s
+        * property
+        */
+       prop = (u32 *)of_get_flat_dt_prop(node, "ibm,ppc-interrupt-server#s",
+                                      &size);
+       cur_cpu_spec->cpu_features &= ~CPU_FTR_SMT;
+       if (prop && ((size / sizeof(u32)) > 1))
                cur_cpu_spec->cpu_features |= CPU_FTR_SMT;
-       else
-               cur_cpu_spec->cpu_features &= ~CPU_FTR_SMT;
 #endif
 
        return 0;
@@ -1052,6 +923,7 @@ static int __init early_init_dt_scan_cpus(unsigned long node,
 static int __init early_init_dt_scan_chosen(unsigned long node,
                                            const char *uname, int depth, void *data)
 {
+       u32 *prop;
        unsigned long *lprop;
        unsigned long l;
        char *p;
@@ -1062,6 +934,14 @@ static int __init early_init_dt_scan_chosen(unsigned long node,
            (strcmp(uname, "chosen") != 0 && strcmp(uname, "chosen@0") != 0))
                return 0;
 
+       /* get platform type */
+       prop = (u32 *)of_get_flat_dt_prop(node, "linux,platform", NULL);
+       if (prop == NULL)
+               return 0;
+#ifdef CONFIG_PPC_MULTIPLATFORM
+       _machine = *prop;
+#endif
+
 #ifdef CONFIG_PPC64
        /* check if iommu is forced on or off */
        if (of_get_flat_dt_prop(node, "linux,iommu-off", NULL) != NULL)
@@ -1088,15 +968,15 @@ static int __init early_init_dt_scan_chosen(unsigned long node,
         * set of RTAS infos now if available
         */
        {
-               u64 *basep, *entryp, *sizep;
+               u64 *basep, *entryp;
 
                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) {
+               prop = of_get_flat_dt_prop(node, "linux,rtas-size", NULL);
+               if (basep && entryp && prop) {
                        rtas.base = *basep;
                        rtas.entry = *entryp;
-                       rtas.size = *sizep;
+                       rtas.size = *prop;
                }
        }
 #endif /* CONFIG_PPC_RTAS */
@@ -1125,13 +1005,25 @@ static int __init early_init_dt_scan_chosen(unsigned long node,
 
        if (strstr(cmd_line, "mem=")) {
                char *p, *q;
+               unsigned long maxmem = 0;
 
                for (q = cmd_line; (p = strstr(q, "mem=")) != 0; ) {
                        q = p + 4;
                        if (p > cmd_line && p[-1] != ' ')
                                continue;
-                       memory_limit = memparse(q, &q);
+                       maxmem = simple_strtoul(q, &q, 0);
+                       if (*q == 'k' || *q == 'K') {
+                               maxmem <<= 10;
+                               ++q;
+                       } else if (*q == 'm' || *q == 'M') {
+                               maxmem <<= 20;
+                               ++q;
+                       } else if (*q == 'g' || *q == 'G') {
+                               maxmem <<= 30;
+                               ++q;
+                       }
                }
+               memory_limit = maxmem;
        }
 
        /* break now */
@@ -1867,7 +1759,7 @@ static int of_finish_dynamic_node(struct device_node *node)
        /* We don't support that function on PowerMac, at least
         * not yet
         */
-       if (machine_is(powermac))
+       if (_machine == PLATFORM_POWERMAC)
                return -ENODEV;
 
        /* fix up new node's linux_phandle field */