--- /dev/null
+* ARM CPUs binding description
+
+The device tree allows to describe the layout of CPUs in a system through
+the "cpus" node, which in turn contains a number of subnodes (ie "cpu")
+defining properties for every cpu.
+
+Bindings for CPU nodes follow the ePAPR standard, available from:
+
+http://devicetree.org
+
+For the ARM architecture every CPU node must contain the following properties:
+
+- device_type: must be "cpu"
+- reg:         property matching the CPU MPIDR[23:0] register bits
+               reg[31:24] bits must be set to 0
+- compatible:  should be one of:
+               "arm,arm1020"
+               "arm,arm1020e"
+               "arm,arm1022"
+               "arm,arm1026"
+               "arm,arm720"
+               "arm,arm740"
+               "arm,arm7tdmi"
+               "arm,arm920"
+               "arm,arm922"
+               "arm,arm925"
+               "arm,arm926"
+               "arm,arm940"
+               "arm,arm946"
+               "arm,arm9tdmi"
+               "arm,cortex-a5"
+               "arm,cortex-a7"
+               "arm,cortex-a8"
+               "arm,cortex-a9"
+               "arm,cortex-a15"
+               "arm,arm1136"
+               "arm,arm1156"
+               "arm,arm1176"
+               "arm,arm11mpcore"
+               "faraday,fa526"
+               "intel,sa110"
+               "intel,sa1100"
+               "marvell,feroceon"
+               "marvell,mohawk"
+               "marvell,xsc3"
+               "marvell,xscale"
+
+Example:
+
+       cpus {
+               #size-cells = <0>;
+               #address-cells = <1>;
+
+               CPU0: cpu@0 {
+                       device_type = "cpu";
+                       compatible = "arm,cortex-a15";
+                       reg = <0x0>;
+               };
+
+               CPU1: cpu@1 {
+                       device_type = "cpu";
+                       compatible = "arm,cortex-a15";
+                       reg = <0x1>;
+               };
+
+               CPU2: cpu@100 {
+                       device_type = "cpu";
+                       compatible = "arm,cortex-a7";
+                       reg = <0x100>;
+               };
+
+               CPU3: cpu@101 {
+                       device_type = "cpu";
+                       compatible = "arm,cortex-a7";
+                       reg = <0x101>;
+               };
+       };
 
 #include <linux/of_irq.h>
 #include <linux/of_platform.h>
 
+#include <asm/cputype.h>
 #include <asm/setup.h>
 #include <asm/page.h>
+#include <asm/smp_plat.h>
 #include <asm/mach/arch.h>
 #include <asm/mach-types.h>
 
        }
 }
 
+/*
+ * arm_dt_init_cpu_maps - Function retrieves cpu nodes from the device tree
+ * and builds the cpu logical map array containing MPIDR values related to
+ * logical cpus
+ *
+ * Updates the cpu possible mask with the number of parsed cpu nodes
+ */
+void __init arm_dt_init_cpu_maps(void)
+{
+       /*
+        * Temp logical map is initialized with UINT_MAX values that are
+        * considered invalid logical map entries since the logical map must
+        * contain a list of MPIDR[23:0] values where MPIDR[31:24] must
+        * read as 0.
+        */
+       struct device_node *cpu, *cpus;
+       u32 i, j, cpuidx = 1;
+       u32 mpidr = is_smp() ? read_cpuid_mpidr() & MPIDR_HWID_BITMASK : 0;
+
+       u32 tmp_map[NR_CPUS] = { [0 ... NR_CPUS-1] = UINT_MAX };
+       bool bootcpu_valid = false;
+       cpus = of_find_node_by_path("/cpus");
+
+       if (!cpus)
+               return;
+
+       for_each_child_of_node(cpus, cpu) {
+               u32 hwid;
+
+               pr_debug(" * %s...\n", cpu->full_name);
+               /*
+                * A device tree containing CPU nodes with missing "reg"
+                * properties is considered invalid to build the
+                * cpu_logical_map.
+                */
+               if (of_property_read_u32(cpu, "reg", &hwid)) {
+                       pr_debug(" * %s missing reg property\n",
+                                    cpu->full_name);
+                       return;
+               }
+
+               /*
+                * 8 MSBs must be set to 0 in the DT since the reg property
+                * defines the MPIDR[23:0].
+                */
+               if (hwid & ~MPIDR_HWID_BITMASK)
+                       return;
+
+               /*
+                * Duplicate MPIDRs are a recipe for disaster.
+                * Scan all initialized entries and check for
+                * duplicates. If any is found just bail out.
+                * temp values were initialized to UINT_MAX
+                * to avoid matching valid MPIDR[23:0] values.
+                */
+               for (j = 0; j < cpuidx; j++)
+                       if (WARN(tmp_map[j] == hwid, "Duplicate /cpu reg "
+                                                    "properties in the DT\n"))
+                               return;
+
+               /*
+                * Build a stashed array of MPIDR values. Numbering scheme
+                * requires that if detected the boot CPU must be assigned
+                * logical id 0. Other CPUs get sequential indexes starting
+                * from 1. If a CPU node with a reg property matching the
+                * boot CPU MPIDR is detected, this is recorded so that the
+                * logical map built from DT is validated and can be used
+                * to override the map created in smp_setup_processor_id().
+                */
+               if (hwid == mpidr) {
+                       i = 0;
+                       bootcpu_valid = true;
+               } else {
+                       i = cpuidx++;
+               }
+
+               tmp_map[i] = hwid;
+
+               if (cpuidx > nr_cpu_ids)
+                       break;
+       }
+
+       if (WARN(!bootcpu_valid, "DT missing boot CPU MPIDR[23:0], "
+                                "fall back to default cpu_logical_map\n"))
+               return;
+
+       /*
+        * Since the boot CPU node contains proper data, and all nodes have
+        * a reg property, the DT CPU list can be considered valid and the
+        * logical map created in smp_setup_processor_id() can be overridden
+        */
+       for (i = 0; i < cpuidx; i++) {
+               set_cpu_possible(i, true);
+               cpu_logical_map(i) = tmp_map[i];
+               pr_debug("cpu logical map 0x%x\n", cpu_logical_map(i));
+       }
+}
+
 /**
  * setup_machine_fdt - Machine setup when an dtb was passed to the kernel
  * @dt_phys: physical address of dt blob