* Should never be returned, if it is, it indicates a bug in
         * libfdt itself. */
 
-#define FDT_ERR_MAX            13
+/* Errors in device tree content */
+#define FDT_ERR_BADNCELLS      14
+       /* FDT_ERR_BADNCELLS: Device tree has a #address-cells, #size-cells
+        * or similar property with a bad format or value */
+
+#define FDT_ERR_MAX            14
 
 /**********************************************************************/
 /* Low-level functions (you probably don't need these)                */
                                  const char *name, int namelen);
 
 /**
- * fdt_get_alias - retrieve the path referenced by a given alias
+ * fdt_get_alias - retreive the path referenced by a given alias
  * @fdt: pointer to the device tree blob
- * @name: name of the alias to look up
+ * @name: name of the alias th look up
  *
  * fdt_get_alias() retrieves the value of a given alias.  That is, the
  * value of the property named 'name' in the node /aliases.
  *     offset = fdt_node_offset_by_prop_value(fdt, -1, propname,
  *                                            propval, proplen);
  *     while (offset != -FDT_ERR_NOTFOUND) {
- *             ... other code here ...
+ *             // other code here
  *             offset = fdt_node_offset_by_prop_value(fdt, offset, propname,
  *                                                    propval, proplen);
  *     }
  * idiom can be used:
  *     offset = fdt_node_offset_by_compatible(fdt, -1, compatible);
  *     while (offset != -FDT_ERR_NOTFOUND) {
- *             ... other code here ...
+ *             // other code here
  *             offset = fdt_node_offset_by_compatible(fdt, offset, compatible);
  *     }
  *
  */
 int fdt_stringlist_contains(const char *strlist, int listlen, const char *str);
 
+/**********************************************************************/
+/* Read-only functions (addressing related)                           */
+/**********************************************************************/
+
+/**
+ * FDT_MAX_NCELLS - maximum value for #address-cells and #size-cells
+ *
+ * This is the maximum value for #address-cells, #size-cells and
+ * similar properties that will be processed by libfdt.  IEE1275
+ * requires that OF implementations handle values up to 4.
+ * Implementations may support larger values, but in practice higher
+ * values aren't used.
+ */
+#define FDT_MAX_NCELLS         4
+
+/**
+ * fdt_address_cells - retrieve address size for a bus represented in the tree
+ * @fdt: pointer to the device tree blob
+ * @nodeoffset: offset of the node to find the address size for
+ *
+ * When the node has a valid #address-cells property, returns its value.
+ *
+ * returns:
+ *     0 <= n < FDT_MAX_NCELLS, on success
+ *      2, if the node has no #address-cells property
+ *      -FDT_ERR_BADNCELLS, if the node has a badly formatted or invalid
+ *             #address-cells property
+ *     -FDT_ERR_BADMAGIC,
+ *     -FDT_ERR_BADVERSION,
+ *     -FDT_ERR_BADSTATE,
+ *     -FDT_ERR_BADSTRUCTURE,
+ *     -FDT_ERR_TRUNCATED, standard meanings
+ */
+int fdt_address_cells(const void *fdt, int nodeoffset);
+
+/**
+ * fdt_size_cells - retrieve address range size for a bus represented in the
+ *                  tree
+ * @fdt: pointer to the device tree blob
+ * @nodeoffset: offset of the node to find the address range size for
+ *
+ * When the node has a valid #size-cells property, returns its value.
+ *
+ * returns:
+ *     0 <= n < FDT_MAX_NCELLS, on success
+ *      2, if the node has no #address-cells property
+ *      -FDT_ERR_BADNCELLS, if the node has a badly formatted or invalid
+ *             #size-cells property
+ *     -FDT_ERR_BADMAGIC,
+ *     -FDT_ERR_BADVERSION,
+ *     -FDT_ERR_BADSTATE,
+ *     -FDT_ERR_BADSTRUCTURE,
+ *     -FDT_ERR_TRUNCATED, standard meanings
+ */
+int fdt_size_cells(const void *fdt, int nodeoffset);
+
+
 /**********************************************************************/
 /* Write-in-place functions                                           */
 /**********************************************************************/
 /**********************************************************************/
 
 int fdt_create(void *buf, int bufsize);
+int fdt_resize(void *fdt, void *buf, int bufsize);
 int fdt_add_reservemap_entry(void *fdt, uint64_t addr, uint64_t size);
 int fdt_finish_reservemap(void *fdt);
 int fdt_begin_node(void *fdt, const char *name);
 
--- /dev/null
+/*
+ * libfdt - Flat Device Tree manipulation
+ * Copyright (C) 2014 David Gibson <david@gibson.dropbear.id.au>
+ * SPDX-License-Identifier:    GPL-2.0+ BSD-2-Clause
+ */
+#include "libfdt_env.h"
+
+#ifndef USE_HOSTCC
+#include <fdt.h>
+#include <libfdt.h>
+#else
+#include "fdt_host.h"
+#endif
+
+#include "libfdt_internal.h"
+
+int fdt_address_cells(const void *fdt, int nodeoffset)
+{
+       const fdt32_t *ac;
+       int val;
+       int len;
+
+       ac = fdt_getprop(fdt, nodeoffset, "#address-cells", &len);
+       if (!ac)
+               return 2;
+
+       if (len != sizeof(*ac))
+               return -FDT_ERR_BADNCELLS;
+
+       val = fdt32_to_cpu(*ac);
+       if ((val <= 0) || (val > FDT_MAX_NCELLS))
+               return -FDT_ERR_BADNCELLS;
+
+       return val;
+}
+
+int fdt_size_cells(const void *fdt, int nodeoffset)
+{
+       const fdt32_t *sc;
+       int val;
+       int len;
+
+       sc = fdt_getprop(fdt, nodeoffset, "#size-cells", &len);
+       if (!sc)
+               return 2;
+
+       if (len != sizeof(*sc))
+               return -FDT_ERR_BADNCELLS;
+
+       val = fdt32_to_cpu(*sc);
+       if ((val < 0) || (val > FDT_MAX_NCELLS))
+               return -FDT_ERR_BADNCELLS;
+
+       return val;
+}
 
        return 0;
 }
 
+int fdt_resize(void *fdt, void *buf, int bufsize)
+{
+       size_t headsize, tailsize;
+       char *oldtail, *newtail;
+
+       FDT_SW_CHECK_HEADER(fdt);
+
+       headsize = fdt_off_dt_struct(fdt);
+       tailsize = fdt_size_dt_strings(fdt);
+
+       if ((headsize + tailsize) > bufsize)
+               return -FDT_ERR_NOSPACE;
+
+       oldtail = (char *)fdt + fdt_totalsize(fdt) - tailsize;
+       newtail = (char *)buf + bufsize - tailsize;
+
+       /* Two cases to avoid clobbering data if the old and new
+        * buffers partially overlap */
+       if (buf <= fdt) {
+               memmove(buf, fdt, headsize);
+               memmove(newtail, oldtail, tailsize);
+       } else {
+               memmove(newtail, oldtail, tailsize);
+               memmove(buf, fdt, headsize);
+       }
+
+       fdt_set_off_dt_strings(buf, bufsize);
+       fdt_set_totalsize(buf, bufsize);
+
+       return 0;
+}
+
 int fdt_add_reservemap_entry(void *fdt, uint64_t addr, uint64_t size)
 {
        struct fdt_reserve_entry *re;