]> git.ipfire.org Git - people/ms/u-boot.git/blobdiff - lib/libfdt/fdt_rw.c
Merge branch 'master' of git://www.denx.de/git/u-boot-imx
[people/ms/u-boot.git] / lib / libfdt / fdt_rw.c
index 6fa4f13073d28fd76c886b1154e254ca1c6e1fd0..80a321214153708b85a962a94f38186335c29a20 100644 (file)
@@ -3,7 +3,7 @@
  * Copyright (C) 2006 David Gibson, IBM Corporation.
  * SPDX-License-Identifier:    GPL-2.0+ BSD-2-Clause
  */
-#include "libfdt_env.h"
+#include <libfdt_env.h>
 
 #ifndef USE_HOSTCC
 #include <fdt.h>
@@ -43,9 +43,9 @@ static int _fdt_rw_check_header(void *fdt)
 
 #define FDT_RW_CHECK_HEADER(fdt) \
        { \
-               int err; \
-               if ((err = _fdt_rw_check_header(fdt)) != 0) \
-                       return err; \
+               int __err; \
+               if ((__err = _fdt_rw_check_header(fdt)) != 0) \
+                       return __err; \
        }
 
 static inline int _fdt_data_size(void *fdt)
@@ -60,6 +60,8 @@ static int _fdt_splice(void *fdt, void *splicepoint, int oldlen, int newlen)
 
        if (((p + oldlen) < p) || ((p + oldlen) > end))
                return -FDT_ERR_BADOFFSET;
+       if ((p < (char *)fdt) || ((end - oldlen + newlen) < (char *)fdt))
+               return -FDT_ERR_BADOFFSET;
        if ((end - oldlen + newlen) > ((char *)fdt + fdt_totalsize(fdt)))
                return -FDT_ERR_NOSPACE;
        memmove(p + newlen, p + oldlen, end - p - oldlen);
@@ -148,17 +150,13 @@ int fdt_add_mem_rsv(void *fdt, uint64_t address, uint64_t size)
 int fdt_del_mem_rsv(void *fdt, int n)
 {
        struct fdt_reserve_entry *re = _fdt_mem_rsv_w(fdt, n);
-       int err;
 
        FDT_RW_CHECK_HEADER(fdt);
 
        if (n >= fdt_num_mem_rsv(fdt))
                return -FDT_ERR_NOTFOUND;
 
-       err = _fdt_splice_mem_rsv(fdt, re, 1, 0);
-       if (err)
-               return err;
-       return 0;
+       return _fdt_splice_mem_rsv(fdt, re, 1, 0);
 }
 
 static int _fdt_resize_property(void *fdt, int nodeoffset, const char *name,
@@ -168,7 +166,7 @@ static int _fdt_resize_property(void *fdt, int nodeoffset, const char *name,
        int err;
 
        *prop = fdt_get_property_w(fdt, nodeoffset, name, &oldlen);
-       if (! (*prop))
+       if (!*prop)
                return oldlen;
 
        if ((err = _fdt_splice_struct(fdt, (*prop)->data, FDT_TAGALIGN(oldlen),
@@ -244,7 +242,8 @@ int fdt_setprop(void *fdt, int nodeoffset, const char *name,
        if (err)
                return err;
 
-       memcpy(prop->data, val, len);
+       if (len)
+               memcpy(prop->data, val, len);
        return 0;
 }
 
@@ -283,7 +282,7 @@ int fdt_delprop(void *fdt, int nodeoffset, const char *name)
        FDT_RW_CHECK_HEADER(fdt);
 
        prop = fdt_get_property_w(fdt, nodeoffset, name, &len);
-       if (! prop)
+       if (!prop)
                return len;
 
        proplen = sizeof(*prop) + FDT_TAGALIGN(len);
@@ -449,3 +448,35 @@ int fdt_pack(void *fdt)
 
        return 0;
 }
+
+int fdt_remove_unused_strings(const void *old, void *new)
+{
+       const struct fdt_property *old_prop;
+       struct fdt_property *new_prop;
+       int size = fdt_totalsize(old);
+       int next_offset, offset;
+       const char *str;
+       int ret;
+       int tag = FDT_PROP;
+
+       /* Make a copy and remove the strings */
+       memcpy(new, old, size);
+       fdt_set_size_dt_strings(new, 0);
+
+       /* Add every property name back into the new string table */
+       for (offset = 0; tag != FDT_END; offset = next_offset) {
+               tag = fdt_next_tag(old, offset, &next_offset);
+               if (tag != FDT_PROP)
+                       continue;
+               old_prop = fdt_get_property_by_offset(old, offset, NULL);
+               new_prop = (struct fdt_property *)(unsigned long)
+                       fdt_get_property_by_offset(new, offset, NULL);
+               str = fdt_string(old, fdt32_to_cpu(old_prop->nameoff));
+               ret = _fdt_find_add_string(new, str);
+               if (ret < 0)
+                       return ret;
+               new_prop->nameoff = cpu_to_fdt32(ret);
+       }
+
+       return 0;
+}