]> Pileus Git - ~andy/linux/commitdiff
Merge tag 'devicetree-for-linus' of git://git.secretlab.ca/git/linux
authorLinus Torvalds <torvalds@linux-foundation.org>
Tue, 10 Sep 2013 20:53:52 +0000 (13:53 -0700)
committerLinus Torvalds <torvalds@linux-foundation.org>
Tue, 10 Sep 2013 20:53:52 +0000 (13:53 -0700)
Pull device tree core updates from Grant Likely:
 "Generally minor changes.  A bunch of bug fixes, particularly for
  initialization and some refactoring.  Most notable change if feeding
  the entire flattened tree into the random pool at boot.  May not be
  significant, but shouldn't hurt either"

Tim Bird questions whether the boot time cost of the random feeding may
be noticeable.  And "add_device_randomness()" is definitely not some
speed deamon of a function.

* tag 'devicetree-for-linus' of git://git.secretlab.ca/git/linux:
  of/platform: add error reporting to of_amba_device_create()
  irq/of: Fix comment typo for irq_of_parse_and_map
  of: Feed entire flattened device tree into the random pool
  of/fdt: Clean up casting in unflattening path
  of/fdt: Remove duplicate memory clearing on FDT unflattening
  gpio: implement gpio-ranges binding document fix
  of: call __of_parse_phandle_with_args from of_parse_phandle
  of: introduce of_parse_phandle_with_fixed_args
  of: move of_parse_phandle()
  of: move documentation of of_parse_phandle_with_args
  of: Fix missing memory initialization on FDT unflattening
  of: consolidate definition of early_init_dt_alloc_memory_arch()
  of: Make of_get_phy_mode() return int i.s.o. const int
  include: dt-binding: input: create a DT header defining key codes.
  of/platform: Staticize of_platform_device_create_pdata()
  of: Specify initrd location using 64-bit
  dt: Typo fix
  OF: make of_property_for_each_{u32|string}() use parameters if OF is not enabled

1  2 
arch/arm/mm/init.c
arch/arm64/kernel/setup.c
arch/powerpc/kernel/prom.c
drivers/gpio/gpiolib-of.c
drivers/of/base.c
drivers/of/fdt.c
drivers/of/platform.c
include/linux/of.h
include/linux/of_fdt.h

diff --combined arch/arm/mm/init.c
index 93cbf566a97244aa5e773a9cc52250afd24ce18c,81484177c9b86f571efd9e88cd91a402306c7d9a..febaee7ca57be76487290a2ac45c6cf74e53759c
@@@ -17,7 -17,6 +17,7 @@@
  #include <linux/nodemask.h>
  #include <linux/initrd.h>
  #include <linux/of_fdt.h>
 +#include <linux/of_reserved_mem.h>
  #include <linux/highmem.h>
  #include <linux/gfp.h>
  #include <linux/memblock.h>
@@@ -78,7 -77,7 +78,7 @@@ static int __init parse_tag_initrd2(con
  __tagtable(ATAG_INITRD2, parse_tag_initrd2);
  
  #ifdef CONFIG_OF_FLATTREE
- void __init early_init_dt_setup_initrd_arch(unsigned long start, unsigned long end)
+ void __init early_init_dt_setup_initrd_arch(u64 start, u64 end)
  {
        phys_initrd_start = start;
        phys_initrd_size = end - start;
@@@ -208,7 -207,7 +208,7 @@@ static void __init arm_bootmem_init(uns
  
  #ifdef CONFIG_ZONE_DMA
  
 -unsigned long arm_dma_zone_size __read_mostly;
 +phys_addr_t arm_dma_zone_size __read_mostly;
  EXPORT_SYMBOL(arm_dma_zone_size);
  
  /*
@@@ -232,7 -231,7 +232,7 @@@ static void __init arm_adjust_dma_zone(
  }
  #endif
  
 -void __init setup_dma_zone(struct machine_desc *mdesc)
 +void __init setup_dma_zone(const struct machine_desc *mdesc)
  {
  #ifdef CONFIG_ZONE_DMA
        if (mdesc->dma_zone_size) {
@@@ -336,8 -335,7 +336,8 @@@ phys_addr_t __init arm_memblock_steal(p
        return phys;
  }
  
 -void __init arm_memblock_init(struct meminfo *mi, struct machine_desc *mdesc)
 +void __init arm_memblock_init(struct meminfo *mi,
 +      const struct machine_desc *mdesc)
  {
        int i;
  
        if (mdesc->reserve)
                mdesc->reserve();
  
 +      early_init_dt_scan_reserved_mem();
 +
        /*
         * reserve memory for DMA contigouos allocations,
         * must come from DMA area inside low memory
index bca4c1c2052ad87af9d883bef4a4e70b2524a128,0f9856a2afa42efedb9ad653c3da5bb7ec17aeae..12ad8f3d0cfd32c4f5409a0b8f29b499b7f5cf80
@@@ -190,11 -190,6 +190,6 @@@ void __init early_init_dt_add_memory_ar
        memblock_add(base, size);
  }
  
- void * __init early_init_dt_alloc_memory_arch(u64 size, u64 align)
- {
-       return __va(memblock_alloc(size, align));
- }
  /*
   * Limit the memory size that was specified via FDT.
   */
@@@ -328,6 -323,9 +323,6 @@@ static int c_show(struct seq_file *m, v
  #ifdef CONFIG_SMP
                seq_printf(m, "processor\t: %d\n", i);
  #endif
 -              seq_printf(m, "BogoMIPS\t: %lu.%02lu\n\n",
 -                         loops_per_jiffy / (500000UL/HZ),
 -                         loops_per_jiffy / (5000UL/HZ) % 100);
        }
  
        /* dump out the processor features */
index 6bfcab97c981a9b7978dac1491d5362247b24006,3fa349efc4a6e1e9ad55f151a5d05bab12d19912..b7634ce41dbc92bd67cd5ed1c6c7cd584924ccc4
@@@ -215,16 -215,16 +215,16 @@@ static void __init check_cpu_pa_feature
  #ifdef CONFIG_PPC_STD_MMU_64
  static void __init check_cpu_slb_size(unsigned long node)
  {
 -      u32 *slb_size_ptr;
 +      __be32 *slb_size_ptr;
  
        slb_size_ptr = of_get_flat_dt_prop(node, "slb-size", NULL);
        if (slb_size_ptr != NULL) {
 -              mmu_slb_size = *slb_size_ptr;
 +              mmu_slb_size = be32_to_cpup(slb_size_ptr);
                return;
        }
        slb_size_ptr = of_get_flat_dt_prop(node, "ibm,slb-size", NULL);
        if (slb_size_ptr != NULL) {
 -              mmu_slb_size = *slb_size_ptr;
 +              mmu_slb_size = be32_to_cpup(slb_size_ptr);
        }
  }
  #else
@@@ -279,11 -279,11 +279,11 @@@ static void __init check_cpu_feature_pr
  {
        unsigned long i;
        struct feature_property *fp = feature_properties;
 -      const u32 *prop;
 +      const __be32 *prop;
  
        for (i = 0; i < ARRAY_SIZE(feature_properties); ++i, ++fp) {
                prop = of_get_flat_dt_prop(node, fp->name, NULL);
 -              if (prop && *prop >= fp->min_value) {
 +              if (prop && be32_to_cpup(prop) >= fp->min_value) {
                        cur_cpu_spec->cpu_features |= fp->cpu_feature;
                        cur_cpu_spec->cpu_user_features |= fp->cpu_user_ftr;
                }
@@@ -295,8 -295,8 +295,8 @@@ static int __init early_init_dt_scan_cp
                                          void *data)
  {
        char *type = of_get_flat_dt_prop(node, "device_type", NULL);
 -      const u32 *prop;
 -      const u32 *intserv;
 +      const __be32 *prop;
 +      const __be32 *intserv;
        int i, nthreads;
        unsigned long len;
        int found = -1;
                 * version 2 of the kexec param format adds the phys cpuid of
                 * booted proc.
                 */
 -              if (initial_boot_params->version >= 2) {
 -                      if (intserv[i] == initial_boot_params->boot_cpuid_phys) {
 +              if (be32_to_cpu(initial_boot_params->version) >= 2) {
 +                      if (be32_to_cpu(intserv[i]) ==
 +                          be32_to_cpu(initial_boot_params->boot_cpuid_phys)) {
                                found = boot_cpu_count;
                                found_thread = i;
                        }
  
        if (found >= 0) {
                DBG("boot cpu: logical %d physical %d\n", found,
 -                      intserv[found_thread]);
 +                      be32_to_cpu(intserv[found_thread]));
                boot_cpuid = found;
 -              set_hard_smp_processor_id(found, intserv[found_thread]);
 +              set_hard_smp_processor_id(found,
 +                      be32_to_cpu(intserv[found_thread]));
  
                /*
                 * PAPR defines "logical" PVR values for cpus that
                 * it uses 0x0f000001.
                 */
                prop = of_get_flat_dt_prop(node, "cpu-version", NULL);
 -              if (prop && (*prop & 0xff000000) == 0x0f000000)
 -                      identify_cpu(0, *prop);
 +              if (prop && (be32_to_cpup(prop) & 0xff000000) == 0x0f000000)
 +                      identify_cpu(0, be32_to_cpup(prop));
  
                identical_pvr_fixup(node);
        }
  int __init early_init_dt_scan_chosen_ppc(unsigned long node, const char *uname,
                                         int depth, void *data)
  {
 -      unsigned long *lprop;
 +      unsigned long *lprop; /* All these set by kernel, so no need to convert endian */
  
        /* Use common scan routine to determine if this is the chosen node */
        if (early_init_dt_scan_chosen(node, uname, depth, data) == 0)
@@@ -456,7 -454,7 +456,7 @@@ static int __init early_init_dt_scan_dr
        if (dm == NULL || l < sizeof(__be32))
                return 0;
  
 -      n = *dm++;      /* number of entries */
 +      n = of_read_number(dm++, 1);    /* number of entries */
        if (l < (n * (dt_root_addr_cells + 4) + 1) * sizeof(__be32))
                return 0;
  
  
        for (; n != 0; --n) {
                base = dt_mem_next_cell(dt_root_addr_cells, &dm);
 -              flags = dm[3];
 +              flags = of_read_number(&dm[3], 1);
                /* skip DRC index, pad, assoc. list index, flags */
                dm += 4;
                /* skip this block if the reserved bit is set in flags (0x80)
@@@ -546,14 -544,8 +546,8 @@@ void __init early_init_dt_add_memory_ar
        memblock_add(base, size);
  }
  
- void * __init early_init_dt_alloc_memory_arch(u64 size, u64 align)
- {
-       return __va(memblock_alloc(size, align));
- }
  #ifdef CONFIG_BLK_DEV_INITRD
- void __init early_init_dt_setup_initrd_arch(unsigned long start,
-               unsigned long end)
+ void __init early_init_dt_setup_initrd_arch(u64 start, u64 end)
  {
        initrd_start = (unsigned long)__va(start);
        initrd_end = (unsigned long)__va(end);
@@@ -593,16 -585,16 +587,16 @@@ static void __init early_reserve_mem_dt
  static void __init early_reserve_mem(void)
  {
        u64 base, size;
 -      u64 *reserve_map;
 +      __be64 *reserve_map;
        unsigned long self_base;
        unsigned long self_size;
  
 -      reserve_map = (u64 *)(((unsigned long)initial_boot_params) +
 -                                      initial_boot_params->off_mem_rsvmap);
 +      reserve_map = (__be64 *)(((unsigned long)initial_boot_params) +
 +                      be32_to_cpu(initial_boot_params->off_mem_rsvmap));
  
        /* before we do anything, lets reserve the dt blob */
        self_base = __pa((unsigned long)initial_boot_params);
 -      self_size = initial_boot_params->totalsize;
 +      self_size = be32_to_cpu(initial_boot_params->totalsize);
        memblock_reserve(self_base, self_size);
  
        /* Look for the new "reserved-regions" property in the DT */
         * Handle the case where we might be booting from an old kexec
         * image that setup the mem_rsvmap as pairs of 32-bit values
         */
 -      if (*reserve_map > 0xffffffffull) {
 +      if (be64_to_cpup(reserve_map) > 0xffffffffull) {
                u32 base_32, size_32;
 -              u32 *reserve_map_32 = (u32 *)reserve_map;
 +              __be32 *reserve_map_32 = (__be32 *)reserve_map;
  
                DBG("Found old 32-bit reserve map\n");
  
                while (1) {
 -                      base_32 = *(reserve_map_32++);
 -                      size_32 = *(reserve_map_32++);
 +                      base_32 = be32_to_cpup(reserve_map_32++);
 +                      size_32 = be32_to_cpup(reserve_map_32++);
                        if (size_32 == 0)
                                break;
                        /* skip if the reservation is for the blob */
  
        /* Handle the reserve map in the fdt blob if it exists */
        while (1) {
 -              base = *(reserve_map++);
 -              size = *(reserve_map++);
 +              base = be64_to_cpup(reserve_map++);
 +              size = be64_to_cpup(reserve_map++);
                if (size == 0)
                        break;
                DBG("reserving: %llx -> %llx\n", base, size);
@@@ -797,32 -789,6 +791,32 @@@ struct device_node *of_find_next_cache_
        return NULL;
  }
  
 +/**
 + * of_get_ibm_chip_id - Returns the IBM "chip-id" of a device
 + * @np: device node of the device
 + *
 + * This looks for a property "ibm,chip-id" in the node or any
 + * of its parents and returns its content, or -1 if it cannot
 + * be found.
 + */
 +int of_get_ibm_chip_id(struct device_node *np)
 +{
 +      of_node_get(np);
 +      while(np) {
 +              struct device_node *old = np;
 +              const __be32 *prop;
 +
 +              prop = of_get_property(np, "ibm,chip-id", NULL);
 +              if (prop) {
 +                      of_node_put(np);
 +                      return be32_to_cpup(prop);
 +              }
 +              np = of_get_parent(np);
 +              of_node_put(old);
 +      }
 +      return -1;
 +}
 +
  #ifdef CONFIG_PPC_PSERIES
  /*
   * Fix up the uninitialized fields in a new device node:
@@@ -893,10 -859,49 +887,10 @@@ static int __init prom_reconfig_setup(v
  __initcall(prom_reconfig_setup);
  #endif
  
 -/* 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)
 +bool arch_match_cpu_phys_id(int cpu, u64 phys_id)
  {
 -      int hardid;
 -      struct device_node *np;
 -
 -      hardid = get_hard_smp_processor_id(cpu);
 -
 -      for_each_node_by_type(np, "cpu") {
 -              const 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 = of_get_property(np, "ibm,ppc-interrupt-server#s",
 -                              &plen);
 -              if (intserv == NULL) {
 -                      const u32 *reg = of_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;
 +      return (int)phys_id == get_hard_smp_processor_id(cpu);
  }
 -EXPORT_SYMBOL(of_get_cpu_node);
  
  #if defined(CONFIG_DEBUG_FS) && defined(DEBUG)
  static struct debugfs_blob_wrapper flat_dt_blob;
@@@ -906,7 -911,7 +900,7 @@@ static int __init export_flat_device_tr
        struct dentry *d;
  
        flat_dt_blob.data = initial_boot_params;
 -      flat_dt_blob.size = initial_boot_params->totalsize;
 +      flat_dt_blob.size = be32_to_cpu(initial_boot_params->totalsize);
  
        d = debugfs_create_blob("flat-device-tree", S_IFREG | S_IRUSR,
                                powerpc_debugfs_root, &flat_dt_blob);
index ba9876ffb017ba3c8874512e73acbbf9c97d0cbb,48cda3c9ee94abc832b0fa72c24cb974a37accb0..0dfaf20e4dad4175fc7d5f49e6989d609876b123
@@@ -76,8 -76,7 +76,8 @@@ int of_get_named_gpio_flags(struct devi
        ret = of_parse_phandle_with_args(np, propname, "#gpio-cells", index,
                                         &gg_data.gpiospec);
        if (ret) {
 -              pr_debug("%s: can't parse gpios property\n", __func__);
 +              pr_debug("%s: can't parse gpios property of node '%s[%d]'\n",
 +                      __func__, np->full_name, index);
                return ret;
        }
  
@@@ -195,8 -194,8 +195,8 @@@ static void of_gpiochip_add_pin_range(s
                return;
  
        for (;; index++) {
-               ret = of_parse_phandle_with_args(np, "gpio-ranges",
-                               "#gpio-range-cells", index, &pinspec);
+               ret = of_parse_phandle_with_fixed_args(np, "gpio-ranges", 3,
+                               index, &pinspec);
                if (ret)
                        break;
  
diff --combined drivers/of/base.c
index e486e416d5a08303271e5af402218a26f1f93779,7c75d7551eb921645498516d570e7d8c6d3d6de3..865d3f66c86b2735810e1f6d4d7a219dfd9b350e
@@@ -18,7 -18,6 +18,7 @@@
   *      2 of the License, or (at your option) any later version.
   */
  #include <linux/ctype.h>
 +#include <linux/cpu.h>
  #include <linux/module.h>
  #include <linux/of.h>
  #include <linux/spinlock.h>
@@@ -33,7 -32,6 +33,7 @@@ struct device_node *of_allnodes
  EXPORT_SYMBOL(of_allnodes);
  struct device_node *of_chosen;
  struct device_node *of_aliases;
 +static struct device_node *of_stdout;
  
  DEFINE_MUTEX(of_aliases_mutex);
  
@@@ -232,100 -230,6 +232,100 @@@ const void *of_get_property(const struc
  }
  EXPORT_SYMBOL(of_get_property);
  
 +/*
 + * arch_match_cpu_phys_id - Match the given logical CPU and physical id
 + *
 + * @cpu: logical cpu index of a core/thread
 + * @phys_id: physical identifier of a core/thread
 + *
 + * CPU logical to physical index mapping is architecture specific.
 + * However this __weak function provides a default match of physical
 + * id to logical cpu index. phys_id provided here is usually values read
 + * from the device tree which must match the hardware internal registers.
 + *
 + * Returns true if the physical identifier and the logical cpu index
 + * correspond to the same core/thread, false otherwise.
 + */
 +bool __weak arch_match_cpu_phys_id(int cpu, u64 phys_id)
 +{
 +      return (u32)phys_id == cpu;
 +}
 +
 +/**
 + * Checks if the given "prop_name" property holds the physical id of the
 + * core/thread corresponding to the logical cpu 'cpu'. If 'thread' is not
 + * NULL, local thread number within the core is returned in it.
 + */
 +static bool __of_find_n_match_cpu_property(struct device_node *cpun,
 +                      const char *prop_name, int cpu, unsigned int *thread)
 +{
 +      const __be32 *cell;
 +      int ac, prop_len, tid;
 +      u64 hwid;
 +
 +      ac = of_n_addr_cells(cpun);
 +      cell = of_get_property(cpun, prop_name, &prop_len);
 +      if (!cell)
 +              return false;
 +      prop_len /= sizeof(*cell);
 +      for (tid = 0; tid < prop_len; tid++) {
 +              hwid = of_read_number(cell, ac);
 +              if (arch_match_cpu_phys_id(cpu, hwid)) {
 +                      if (thread)
 +                              *thread = tid;
 +                      return true;
 +              }
 +              cell += ac;
 +      }
 +      return false;
 +}
 +
 +/**
 + * of_get_cpu_node - Get device node associated with the given logical CPU
 + *
 + * @cpu: CPU number(logical index) for which device node is required
 + * @thread: if not NULL, local thread number within the physical core is
 + *          returned
 + *
 + * The main purpose of this function is to retrieve the device node for the
 + * given logical CPU index. It should be used to initialize the of_node in
 + * cpu device. Once of_node in cpu device is populated, all the further
 + * references can use that instead.
 + *
 + * CPU logical to physical index mapping is architecture specific and is built
 + * before booting secondary cores. This function uses arch_match_cpu_phys_id
 + * which can be overridden by architecture specific implementation.
 + *
 + * Returns a node pointer for the logical cpu if found, else NULL.
 + */
 +struct device_node *of_get_cpu_node(int cpu, unsigned int *thread)
 +{
 +      struct device_node *cpun, *cpus;
 +
 +      cpus = of_find_node_by_path("/cpus");
 +      if (!cpus) {
 +              pr_warn("Missing cpus node, bailing out\n");
 +              return NULL;
 +      }
 +
 +      for_each_child_of_node(cpus, cpun) {
 +              if (of_node_cmp(cpun->type, "cpu"))
 +                      continue;
 +              /* Check for non-standard "ibm,ppc-interrupt-server#s" property
 +               * for thread ids on PowerPC. If it doesn't exist fallback to
 +               * standard "reg" property.
 +               */
 +              if (IS_ENABLED(CONFIG_PPC) &&
 +                      __of_find_n_match_cpu_property(cpun,
 +                              "ibm,ppc-interrupt-server#s", cpu, thread))
 +                      return cpun;
 +              if (__of_find_n_match_cpu_property(cpun, "reg", cpu, thread))
 +                      return cpun;
 +      }
 +      return NULL;
 +}
 +EXPORT_SYMBOL(of_get_cpu_node);
 +
  /** Checks if the given "compat" string matches one of the strings in
   * the device's "compatible" property
   */
@@@ -1176,65 -1080,10 +1176,10 @@@ int of_property_count_strings(struct de
  }
  EXPORT_SYMBOL_GPL(of_property_count_strings);
  
- /**
-  * of_parse_phandle - Resolve a phandle property to a device_node pointer
-  * @np: Pointer to device node holding phandle property
-  * @phandle_name: Name of property holding a phandle value
-  * @index: For properties holding a table of phandles, this is the index into
-  *         the table
-  *
-  * Returns the device_node pointer with refcount incremented.  Use
-  * of_node_put() on it when done.
-  */
- struct device_node *of_parse_phandle(const struct device_node *np,
-                                    const char *phandle_name, int index)
- {
-       const __be32 *phandle;
-       int size;
-       phandle = of_get_property(np, phandle_name, &size);
-       if ((!phandle) || (size < sizeof(*phandle) * (index + 1)))
-               return NULL;
-       return of_find_node_by_phandle(be32_to_cpup(phandle + index));
- }
- EXPORT_SYMBOL(of_parse_phandle);
- /**
-  * of_parse_phandle_with_args() - Find a node pointed by phandle in a list
-  * @np:               pointer to a device tree node containing a list
-  * @list_name:        property name that contains a list
-  * @cells_name:       property name that specifies phandles' arguments count
-  * @index:    index of a phandle to parse out
-  * @out_args: optional pointer to output arguments structure (will be filled)
-  *
-  * This function is useful to parse lists of phandles and their arguments.
-  * Returns 0 on success and fills out_args, on error returns appropriate
-  * errno value.
-  *
-  * Caller is responsible to call of_node_put() on the returned out_args->node
-  * pointer.
-  *
-  * Example:
-  *
-  * phandle1: node1 {
-  *    #list-cells = <2>;
-  * }
-  *
-  * phandle2: node2 {
-  *    #list-cells = <1>;
-  * }
-  *
-  * node3 {
-  *    list = <&phandle1 1 2 &phandle2 3>;
-  * }
-  *
-  * To get a device_node of the `node2' node you may call this:
-  * of_parse_phandle_with_args(node3, "list", "#list-cells", 1, &args);
-  */
  static int __of_parse_phandle_with_args(const struct device_node *np,
                                        const char *list_name,
-                                       const char *cells_name, int index,
+                                       const char *cells_name,
+                                       int cell_count, int index,
                                        struct of_phandle_args *out_args)
  {
        const __be32 *list, *list_end;
                if (phandle) {
                        /*
                         * Find the provider node and parse the #*-cells
-                        * property to determine the argument length
+                        * property to determine the argument length.
+                        *
+                        * This is not needed if the cell count is hard-coded
+                        * (i.e. cells_name not set, but cell_count is set),
+                        * except when we're going to return the found node
+                        * below.
                         */
-                       node = of_find_node_by_phandle(phandle);
-                       if (!node) {
-                               pr_err("%s: could not find phandle\n",
-                                        np->full_name);
-                               goto err;
+                       if (cells_name || cur_index == index) {
+                               node = of_find_node_by_phandle(phandle);
+                               if (!node) {
+                                       pr_err("%s: could not find phandle\n",
+                                               np->full_name);
+                                       goto err;
+                               }
                        }
-                       if (of_property_read_u32(node, cells_name, &count)) {
-                               pr_err("%s: could not get %s for %s\n",
-                                        np->full_name, cells_name,
-                                        node->full_name);
-                               goto err;
+                       if (cells_name) {
+                               if (of_property_read_u32(node, cells_name,
+                                                        &count)) {
+                                       pr_err("%s: could not get %s for %s\n",
+                                               np->full_name, cells_name,
+                                               node->full_name);
+                                       goto err;
+                               }
+                       } else {
+                               count = cell_count;
                        }
  
                        /*
        return rc;
  }
  
+ /**
+  * of_parse_phandle - Resolve a phandle property to a device_node pointer
+  * @np: Pointer to device node holding phandle property
+  * @phandle_name: Name of property holding a phandle value
+  * @index: For properties holding a table of phandles, this is the index into
+  *         the table
+  *
+  * Returns the device_node pointer with refcount incremented.  Use
+  * of_node_put() on it when done.
+  */
+ struct device_node *of_parse_phandle(const struct device_node *np,
+                                    const char *phandle_name, int index)
+ {
+       struct of_phandle_args args;
+       if (index < 0)
+               return NULL;
+       if (__of_parse_phandle_with_args(np, phandle_name, NULL, 0,
+                                        index, &args))
+               return NULL;
+       return args.np;
+ }
+ EXPORT_SYMBOL(of_parse_phandle);
+ /**
+  * of_parse_phandle_with_args() - Find a node pointed by phandle in a list
+  * @np:               pointer to a device tree node containing a list
+  * @list_name:        property name that contains a list
+  * @cells_name:       property name that specifies phandles' arguments count
+  * @index:    index of a phandle to parse out
+  * @out_args: optional pointer to output arguments structure (will be filled)
+  *
+  * This function is useful to parse lists of phandles and their arguments.
+  * Returns 0 on success and fills out_args, on error returns appropriate
+  * errno value.
+  *
+  * Caller is responsible to call of_node_put() on the returned out_args->node
+  * pointer.
+  *
+  * Example:
+  *
+  * phandle1: node1 {
+  *    #list-cells = <2>;
+  * }
+  *
+  * phandle2: node2 {
+  *    #list-cells = <1>;
+  * }
+  *
+  * node3 {
+  *    list = <&phandle1 1 2 &phandle2 3>;
+  * }
+  *
+  * To get a device_node of the `node2' node you may call this:
+  * of_parse_phandle_with_args(node3, "list", "#list-cells", 1, &args);
+  */
  int of_parse_phandle_with_args(const struct device_node *np, const char *list_name,
                                const char *cells_name, int index,
                                struct of_phandle_args *out_args)
  {
        if (index < 0)
                return -EINVAL;
-       return __of_parse_phandle_with_args(np, list_name, cells_name, index, out_args);
+       return __of_parse_phandle_with_args(np, list_name, cells_name, 0,
+                                           index, out_args);
  }
  EXPORT_SYMBOL(of_parse_phandle_with_args);
  
+ /**
+  * of_parse_phandle_with_fixed_args() - Find a node pointed by phandle in a list
+  * @np:               pointer to a device tree node containing a list
+  * @list_name:        property name that contains a list
+  * @cell_count: number of argument cells following the phandle
+  * @index:    index of a phandle to parse out
+  * @out_args: optional pointer to output arguments structure (will be filled)
+  *
+  * This function is useful to parse lists of phandles and their arguments.
+  * Returns 0 on success and fills out_args, on error returns appropriate
+  * errno value.
+  *
+  * Caller is responsible to call of_node_put() on the returned out_args->node
+  * pointer.
+  *
+  * Example:
+  *
+  * phandle1: node1 {
+  * }
+  *
+  * phandle2: node2 {
+  * }
+  *
+  * node3 {
+  *    list = <&phandle1 0 2 &phandle2 2 3>;
+  * }
+  *
+  * To get a device_node of the `node2' node you may call this:
+  * of_parse_phandle_with_fixed_args(node3, "list", 2, 1, &args);
+  */
+ int of_parse_phandle_with_fixed_args(const struct device_node *np,
+                               const char *list_name, int cell_count,
+                               int index, struct of_phandle_args *out_args)
+ {
+       if (index < 0)
+               return -EINVAL;
+       return __of_parse_phandle_with_args(np, list_name, NULL, cell_count,
+                                          index, out_args);
+ }
+ EXPORT_SYMBOL(of_parse_phandle_with_fixed_args);
  /**
   * of_count_phandle_with_args() - Find the number of phandles references in a property
   * @np:               pointer to a device tree node containing a list
  int of_count_phandle_with_args(const struct device_node *np, const char *list_name,
                                const char *cells_name)
  {
-       return __of_parse_phandle_with_args(np, list_name, cells_name, -1, NULL);
+       return __of_parse_phandle_with_args(np, list_name, cells_name, 0, -1,
+                                           NULL);
  }
  EXPORT_SYMBOL(of_count_phandle_with_args);
  
@@@ -1691,15 -1654,6 +1750,15 @@@ void of_alias_scan(void * (*dt_alloc)(u
        of_chosen = of_find_node_by_path("/chosen");
        if (of_chosen == NULL)
                of_chosen = of_find_node_by_path("/chosen@0");
 +
 +      if (of_chosen) {
 +              const char *name;
 +
 +              name = of_get_property(of_chosen, "linux,stdout-path", NULL);
 +              if (name)
 +                      of_stdout = of_find_node_by_path(name);
 +      }
 +
        of_aliases = of_find_node_by_path("/aliases");
        if (!of_aliases)
                return;
                ap = dt_alloc(sizeof(*ap) + len + 1, 4);
                if (!ap)
                        continue;
+               memset(ap, 0, sizeof(*ap) + len + 1);
                ap->alias = start;
                of_alias_add(ap, np, id, start, len);
        }
@@@ -1808,19 -1763,3 +1868,19 @@@ const char *of_prop_next_string(struct 
        return curv;
  }
  EXPORT_SYMBOL_GPL(of_prop_next_string);
 +
 +/**
 + * of_device_is_stdout_path - check if a device node matches the
 + *                            linux,stdout-path property
 + *
 + * Check if this device node matches the linux,stdout-path property
 + * in the chosen node. return true if yes, false otherwise.
 + */
 +int of_device_is_stdout_path(struct device_node *dn)
 +{
 +      if (!of_stdout)
 +              return false;
 +
 +      return of_stdout == dn;
 +}
 +EXPORT_SYMBOL_GPL(of_device_is_stdout_path);
diff --combined drivers/of/fdt.c
index 4fb06f3e7b3c852a9939c8daab0fe1e25db5d8d1,543c5002831ec8a433e8ebf348487ae69cfedc93..229dd9d69e180529cc7e3135d71001421ab9deea
  
  #include <linux/kernel.h>
  #include <linux/initrd.h>
+ #include <linux/memblock.h>
  #include <linux/module.h>
  #include <linux/of.h>
  #include <linux/of_fdt.h>
  #include <linux/string.h>
  #include <linux/errno.h>
  #include <linux/slab.h>
+ #include <linux/random.h>
  
  #include <asm/setup.h>  /* for COMMAND_LINE_SIZE */
  #ifdef CONFIG_PPC
@@@ -125,13 -127,13 +127,13 @@@ int of_fdt_match(struct boot_param_head
        return score;
  }
  
- static void *unflatten_dt_alloc(unsigned long *mem, unsigned long size,
+ static void *unflatten_dt_alloc(void **mem, unsigned long size,
                                       unsigned long align)
  {
        void *res;
  
-       *mem = ALIGN(*mem, align);
-       res = (void *)*mem;
+       *mem = PTR_ALIGN(*mem, align);
+       res = *mem;
        *mem += size;
  
        return res;
   * @allnextpp: pointer to ->allnext from last allocated device_node
   * @fpsize: Size of the node path up at the current depth.
   */
- static unsigned long unflatten_dt_node(struct boot_param_header *blob,
-                               unsigned long mem,
-                               unsigned long *p,
+ static void * unflatten_dt_node(struct boot_param_header *blob,
+                               void *mem,
+                               void **p,
                                struct device_node *dad,
                                struct device_node ***allnextpp,
                                unsigned long fpsize)
        int has_name = 0;
        int new_format = 0;
  
-       tag = be32_to_cpup((__be32 *)(*p));
+       tag = be32_to_cpup(*p);
        if (tag != OF_DT_BEGIN_NODE) {
                pr_err("Weird tag at start of node: %x\n", tag);
                return mem;
        }
        *p += 4;
-       pathp = (char *)*p;
+       pathp = *p;
        l = allocl = strlen(pathp) + 1;
-       *p = ALIGN(*p + l, 4);
+       *p = PTR_ALIGN(*p + l, 4);
  
        /* version 0x10 has a more compact unit name here instead of the full
         * path. we accumulate the full path size using "fpsize", we'll rebuild
                                __alignof__(struct device_node));
        if (allnextpp) {
                char *fn;
-               memset(np, 0, sizeof(*np));
                np->full_name = fn = ((char *)np) + sizeof(*np);
                if (new_format) {
                        /* rebuild full path for new format */
                u32 sz, noff;
                char *pname;
  
-               tag = be32_to_cpup((__be32 *)(*p));
+               tag = be32_to_cpup(*p);
                if (tag == OF_DT_NOP) {
                        *p += 4;
                        continue;
                if (tag != OF_DT_PROP)
                        break;
                *p += 4;
-               sz = be32_to_cpup((__be32 *)(*p));
-               noff = be32_to_cpup((__be32 *)((*p) + 4));
+               sz = be32_to_cpup(*p);
+               noff = be32_to_cpup(*p + 4);
                *p += 8;
                if (be32_to_cpu(blob->version) < 0x10)
-                       *p = ALIGN(*p, sz >= 8 ? 8 : 4);
+                       *p = PTR_ALIGN(*p, sz >= 8 ? 8 : 4);
  
                pname = of_fdt_get_string(blob, noff);
                if (pname == NULL) {
                                np->phandle = be32_to_cpup((__be32 *)*p);
                        pp->name = pname;
                        pp->length = sz;
-                       pp->value = (void *)*p;
+                       pp->value = *p;
                        *prev_pp = pp;
                        prev_pp = &pp->next;
                }
-               *p = ALIGN((*p) + sz, 4);
+               *p = PTR_ALIGN((*p) + sz, 4);
        }
        /* with version 0x10 we may not have the name property, recreate
         * it here from the unit name if absent
                else
                        mem = unflatten_dt_node(blob, mem, p, np, allnextpp,
                                                fpsize);
-               tag = be32_to_cpup((__be32 *)(*p));
+               tag = be32_to_cpup(*p);
        }
        if (tag != OF_DT_END_NODE) {
                pr_err("Weird tag at end of node: %x\n", tag);
@@@ -360,7 -361,8 +361,8 @@@ static void __unflatten_device_tree(str
                             struct device_node **mynodes,
                             void * (*dt_alloc)(u64 size, u64 align))
  {
-       unsigned long start, mem, size;
+       unsigned long size;
+       void *start, *mem;
        struct device_node **allnextp = mynodes;
  
        pr_debug(" -> unflatten_device_tree()\n");
        }
  
        /* First pass, scan for size */
-       start = ((unsigned long)blob) +
-               be32_to_cpu(blob->off_dt_struct);
-       size = unflatten_dt_node(blob, 0, &start, NULL, NULL, 0);
-       size = (size | 3) + 1;
+       start = ((void *)blob) + be32_to_cpu(blob->off_dt_struct);
+       size = (unsigned long)unflatten_dt_node(blob, 0, &start, NULL, NULL, 0);
+       size = ALIGN(size, 4);
  
        pr_debug("  size is %lx, allocating...\n", size);
  
        /* Allocate memory for the expanded device tree */
-       mem = (unsigned long)
-               dt_alloc(size + 4, __alignof__(struct device_node));
+       mem = dt_alloc(size + 4, __alignof__(struct device_node));
+       memset(mem, 0, size);
  
-       memset((void *)mem, 0, size);
+       *(__be32 *)(mem + size) = cpu_to_be32(0xdeadbeef);
  
-       ((__be32 *)mem)[size / 4] = cpu_to_be32(0xdeadbeef);
-       pr_debug("  unflattening %lx...\n", mem);
+       pr_debug("  unflattening %p...\n", mem);
  
        /* Second pass, do actual unflattening */
-       start = ((unsigned long)blob) +
-               be32_to_cpu(blob->off_dt_struct);
+       start = ((void *)blob) + be32_to_cpu(blob->off_dt_struct);
        unflatten_dt_node(blob, mem, &start, NULL, &allnextp, 0);
-       if (be32_to_cpup((__be32 *)start) != OF_DT_END)
-               pr_warning("Weird tag at end of tree: %08x\n", *((u32 *)start));
-       if (be32_to_cpu(((__be32 *)mem)[size / 4]) != 0xdeadbeef)
+       if (be32_to_cpup(start) != OF_DT_END)
+               pr_warning("Weird tag at end of tree: %08x\n", be32_to_cpup(start));
+       if (be32_to_cpup(mem + size) != 0xdeadbeef)
                pr_warning("End of tree marker overwritten: %08x\n",
-                          be32_to_cpu(((__be32 *)mem)[size / 4]));
+                          be32_to_cpup(mem + size));
        *allnextp = NULL;
  
        pr_debug(" <- unflatten_device_tree()\n");
@@@ -545,82 -543,6 +543,82 @@@ int __init of_flat_dt_match(unsigned lo
        return of_fdt_match(initial_boot_params, node, compat);
  }
  
 +struct fdt_scan_status {
 +      const char *name;
 +      int namelen;
 +      int depth;
 +      int found;
 +      int (*iterator)(unsigned long node, const char *uname, int depth, void *data);
 +      void *data;
 +};
 +
 +/**
 + * fdt_scan_node_by_path - iterator for of_scan_flat_dt_by_path function
 + */
 +static int __init fdt_scan_node_by_path(unsigned long node, const char *uname,
 +                                      int depth, void *data)
 +{
 +      struct fdt_scan_status *st = data;
 +
 +      /*
 +       * if scan at the requested fdt node has been completed,
 +       * return -ENXIO to abort further scanning
 +       */
 +      if (depth <= st->depth)
 +              return -ENXIO;
 +
 +      /* requested fdt node has been found, so call iterator function */
 +      if (st->found)
 +              return st->iterator(node, uname, depth, st->data);
 +
 +      /* check if scanning automata is entering next level of fdt nodes */
 +      if (depth == st->depth + 1 &&
 +          strncmp(st->name, uname, st->namelen) == 0 &&
 +          uname[st->namelen] == 0) {
 +              st->depth += 1;
 +              if (st->name[st->namelen] == 0) {
 +                      st->found = 1;
 +              } else {
 +                      const char *next = st->name + st->namelen + 1;
 +                      st->name = next;
 +                      st->namelen = strcspn(next, "/");
 +              }
 +              return 0;
 +      }
 +
 +      /* scan next fdt node */
 +      return 0;
 +}
 +
 +/**
 + * of_scan_flat_dt_by_path - scan flattened tree blob and call callback on each
 + *                         child of the given path.
 + * @path: path to start searching for children
 + * @it: callback function
 + * @data: context data pointer
 + *
 + * This function is used to scan the flattened device-tree starting from the
 + * node given by path. It is used to extract information (like reserved
 + * memory), which is required on ealy boot before we can unflatten the tree.
 + */
 +int __init of_scan_flat_dt_by_path(const char *path,
 +      int (*it)(unsigned long node, const char *name, int depth, void *data),
 +      void *data)
 +{
 +      struct fdt_scan_status st = {path, 0, -1, 0, it, data};
 +      int ret = 0;
 +
 +      if (initial_boot_params)
 +                ret = of_scan_flat_dt(fdt_scan_node_by_path, &st);
 +
 +      if (!st.found)
 +              return -ENOENT;
 +      else if (ret == -ENXIO) /* scan has been completed */
 +              return 0;
 +      else
 +              return ret;
 +}
 +
  #ifdef CONFIG_BLK_DEV_INITRD
  /**
   * early_init_dt_check_for_initrd - Decode initrd location from flat tree
   */
  void __init early_init_dt_check_for_initrd(unsigned long node)
  {
-       unsigned long start, end, len;
+       u64 start, end;
+       unsigned long len;
        __be32 *prop;
  
        pr_debug("Looking for initrd properties... ");
        prop = of_get_flat_dt_prop(node, "linux,initrd-start", &len);
        if (!prop)
                return;
-       start = of_read_ulong(prop, len/4);
+       start = of_read_number(prop, len/4);
  
        prop = of_get_flat_dt_prop(node, "linux,initrd-end", &len);
        if (!prop)
                return;
-       end = of_read_ulong(prop, len/4);
+       end = of_read_number(prop, len/4);
  
        early_init_dt_setup_initrd_arch(start, end);
-       pr_debug("initrd_start=0x%lx  initrd_end=0x%lx\n", start, end);
+       pr_debug("initrd_start=0x%llx  initrd_end=0x%llx\n",
+                (unsigned long long)start, (unsigned long long)end);
  }
  #else
  inline void early_init_dt_check_for_initrd(unsigned long node)
@@@ -774,6 -698,17 +774,17 @@@ int __init early_init_dt_scan_chosen(un
        return 1;
  }
  
+ #ifdef CONFIG_HAVE_MEMBLOCK
+ /*
+  * called from unflatten_device_tree() to bootstrap devicetree itself
+  * Architectures can override this definition if memblock isn't used
+  */
+ void * __init __weak early_init_dt_alloc_memory_arch(u64 size, u64 align)
+ {
+       return __va(memblock_alloc(size, align));
+ }
+ #endif
  /**
   * unflatten_device_tree - create tree of device_nodes from flat blob
   *
@@@ -792,3 -727,14 +803,14 @@@ void __init unflatten_device_tree(void
  }
  
  #endif /* CONFIG_OF_EARLY_FLATTREE */
+ /* Feed entire flattened device tree into the random pool */
+ static int __init add_fdt_randomness(void)
+ {
+       if (initial_boot_params)
+               add_device_randomness(initial_boot_params,
+                               be32_to_cpu(initial_boot_params->totalsize));
+       return 0;
+ }
+ core_initcall(add_fdt_randomness);
diff --combined drivers/of/platform.c
index eeca8a5969731bc397d9aa0f4fdc804470addd2d,f6dcde22082155577b3cdf0b0f55f103e059cae6..9b439ac63d8e73eef85aa490d5cab6ec825120b7
@@@ -21,7 -21,6 +21,7 @@@
  #include <linux/of_device.h>
  #include <linux/of_irq.h>
  #include <linux/of_platform.h>
 +#include <linux/of_reserved_mem.h>
  #include <linux/platform_device.h>
  
  const struct of_device_id of_default_bus_match_table[] = {
@@@ -197,7 -196,7 +197,7 @@@ EXPORT_SYMBOL(of_device_alloc)
   * Returns pointer to created platform device, or NULL if a device was not
   * registered.  Unavailable devices will not get registered.
   */
- struct platform_device *of_platform_device_create_pdata(
+ static struct platform_device *of_platform_device_create_pdata(
                                        struct device_node *np,
                                        const char *bus_id,
                                        void *platform_data,
        dev->dev.bus = &platform_bus_type;
        dev->dev.platform_data = platform_data;
  
 +      of_reserved_mem_device_init(&dev->dev);
 +
        /* We do not fill the DMA ops for platform devices by default.
         * This is currently the responsibility of the platform code
         * to do such, possibly using a device notifier
  
        if (of_device_add(dev) != 0) {
                platform_device_put(dev);
 +              of_reserved_mem_device_release(&dev->dev);
                return NULL;
        }
  
@@@ -268,8 -264,11 +268,11 @@@ static struct amba_device *of_amba_devi
                return NULL;
  
        dev = amba_device_alloc(NULL, 0, 0);
-       if (!dev)
+       if (!dev) {
+               pr_err("%s(): amba_device_alloc() failed for %s\n",
+                      __func__, node->full_name);
                return NULL;
+       }
  
        /* setup generic device info */
        dev->dev.coherent_dma_mask = ~0;
                dev->irq[i] = irq_of_parse_and_map(node, i);
  
        ret = of_address_to_resource(node, 0, &dev->res);
-       if (ret)
+       if (ret) {
+               pr_err("%s(): of_address_to_resource() failed (%d) for %s\n",
+                      __func__, ret, node->full_name);
                goto err_free;
+       }
  
        ret = amba_device_add(dev, &iomem_resource);
-       if (ret)
+       if (ret) {
+               pr_err("%s(): amba_device_add() failed (%d) for %s\n",
+                      __func__, ret, node->full_name);
                goto err_free;
+       }
  
        return dev;
  
@@@ -378,6 -383,10 +387,10 @@@ static int of_platform_bus_create(struc
        }
  
        if (of_device_is_compatible(bus, "arm,primecell")) {
+               /*
+                * Don't return an error here to keep compatibility with older
+                * device tree files.
+                */
                of_amba_device_create(bus, bus_id, platform_data, parent);
                return 0;
        }
diff --combined include/linux/of.h
index 3a45c4f593ad68258129f22a8a6c5e84b4611cda,87d08306fef4b4e3fb0826251d4fda74793008e9..f95aee391e30fcb98eeec0f6569c0b4bc9b8ba31
@@@ -266,7 -266,6 +266,7 @@@ extern int of_device_is_available(cons
  extern const void *of_get_property(const struct device_node *node,
                                const char *name,
                                int *lenp);
 +extern struct device_node *of_get_cpu_node(int cpu, unsigned int *thread);
  #define for_each_property_of_node(dn, pp) \
        for (pp = dn->properties; pp != NULL; pp = pp->next)
  
@@@ -281,6 -280,9 +281,9 @@@ extern struct device_node *of_parse_pha
  extern int of_parse_phandle_with_args(const struct device_node *np,
        const char *list_name, const char *cells_name, int index,
        struct of_phandle_args *out_args);
+ extern int of_parse_phandle_with_fixed_args(const struct device_node *np,
+       const char *list_name, int cells_count, int index,
+       struct of_phandle_args *out_args);
  extern int of_count_phandle_with_args(const struct device_node *np,
        const char *list_name, const char *cells_name);
  
@@@ -324,12 -326,6 +327,6 @@@ extern int of_detach_node(struct device
   */
  const __be32 *of_prop_next_u32(struct property *prop, const __be32 *cur,
                               u32 *pu);
- #define of_property_for_each_u32(np, propname, prop, p, u)    \
-       for (prop = of_find_property(np, propname, NULL),       \
-               p = of_prop_next_u32(prop, NULL, &u);           \
-               p;                                              \
-               p = of_prop_next_u32(prop, p, &u))
  /*
   * struct property *prop;
   * const char *s;
   *         printk("String value: %s\n", s);
   */
  const char *of_prop_next_string(struct property *prop, const char *cur);
- #define of_property_for_each_string(np, propname, prop, s)    \
-       for (prop = of_find_property(np, propname, NULL),       \
-               s = of_prop_next_string(prop, NULL);            \
-               s;                                              \
-               s = of_prop_next_string(prop, s))
  
 +int of_device_is_stdout_path(struct device_node *dn);
 +
  #else /* CONFIG_OF */
  
  static inline const char* of_node_full_name(struct device_node *np)
@@@ -462,12 -451,6 +454,12 @@@ static inline const void *of_get_proper
        return NULL;
  }
  
 +static inline struct device_node *of_get_cpu_node(int cpu,
 +                                      unsigned int *thread)
 +{
 +      return NULL;
 +}
 +
  static inline int of_property_read_u64(const struct device_node *np,
                                       const char *propname, u64 *out_value)
  {
@@@ -497,6 -480,13 +489,13 @@@ static inline int of_parse_phandle_with
        return -ENOSYS;
  }
  
+ static inline int of_parse_phandle_with_fixed_args(const struct device_node *np,
+       const char *list_name, int cells_count, int index,
+       struct of_phandle_args *out_args)
+ {
+       return -ENOSYS;
+ }
  static inline int of_count_phandle_with_args(struct device_node *np,
                                             const char *list_name,
                                             const char *cells_name)
@@@ -514,17 -504,20 +513,25 @@@ static inline int of_machine_is_compati
        return 0;
  }
  
 +static inline int of_device_is_stdout_path(struct device_node *dn)
 +{
 +      return 0;
 +}
 +
+ static inline const __be32 *of_prop_next_u32(struct property *prop,
+               const __be32 *cur, u32 *pu)
+ {
+       return NULL;
+ }
+ static inline const char *of_prop_next_string(struct property *prop,
+               const char *cur)
+ {
+       return NULL;
+ }
  #define of_match_ptr(_ptr)    NULL
  #define of_match_node(_matches, _node)        NULL
- #define of_property_for_each_u32(np, propname, prop, p, u) \
-       while (0)
- #define of_property_for_each_string(np, propname, prop, s) \
-       while (0)
  #endif /* CONFIG_OF */
  
  #ifndef of_node_to_nid
@@@ -573,6 -566,18 +580,18 @@@ static inline int of_property_read_u32(
        return of_property_read_u32_array(np, propname, out_value, 1);
  }
  
+ #define of_property_for_each_u32(np, propname, prop, p, u)    \
+       for (prop = of_find_property(np, propname, NULL),       \
+               p = of_prop_next_u32(prop, NULL, &u);           \
+               p;                                              \
+               p = of_prop_next_u32(prop, p, &u))
+ #define of_property_for_each_string(np, propname, prop, s)    \
+       for (prop = of_find_property(np, propname, NULL),       \
+               s = of_prop_next_string(prop, NULL);            \
+               s;                                              \
+               s = of_prop_next_string(prop, s))
  #if defined(CONFIG_PROC_FS) && defined(CONFIG_PROC_DEVICETREE)
  extern void proc_device_tree_add_node(struct device_node *, struct proc_dir_entry *);
  extern void proc_device_tree_add_prop(struct proc_dir_entry *pde, struct property *prop);
diff --combined include/linux/of_fdt.h
index 19f26f8d2202bd5dc42100458945150c9bd46d31,4a17939b95cc100ff09e63135aa4543ad3f3e72a..a478c62a2aabc4dc38f243e25b572bae62688fec
@@@ -90,9 -90,6 +90,9 @@@ extern void *of_get_flat_dt_prop(unsign
  extern int of_flat_dt_is_compatible(unsigned long node, const char *name);
  extern int of_flat_dt_match(unsigned long node, const char *const *matches);
  extern unsigned long of_get_flat_dt_root(void);
 +extern int of_scan_flat_dt_by_path(const char *path,
 +      int (*it)(unsigned long node, const char *name, int depth, void *data),
 +      void *data);
  
  extern int early_init_dt_scan_chosen(unsigned long node, const char *uname,
                                     int depth, void *data);
@@@ -109,8 -106,7 +109,7 @@@ extern u64 dt_mem_next_cell(int s, __be
   * physical addresses.
   */
  #ifdef CONFIG_BLK_DEV_INITRD
- extern void early_init_dt_setup_initrd_arch(unsigned long start,
-                                           unsigned long end);
+ extern void early_init_dt_setup_initrd_arch(u64 start, u64 end);
  #endif
  
  /* Early flat tree scan hooks */