]> git.kernelconcepts.de Git - karo-tx-uboot.git/blobdiff - common/fdt_support.c
include/bitfield.h: Assure new bitfield value doesn't touch unwanted bits
[karo-tx-uboot.git] / common / fdt_support.c
index 891fcac08e03252e8d6e1d718b6dd4a395198d40..6a5f761cadd13a974c936b8f6890615c6c7dbf82 100644 (file)
@@ -194,6 +194,31 @@ static inline int fdt_setprop_uxx(void *fdt, int nodeoffset, const char *name,
                return fdt_setprop_u32(fdt, nodeoffset, name, (uint32_t)val);
 }
 
+int fdt_root(void *fdt)
+{
+       char *serial;
+       int err;
+
+       err = fdt_check_header(fdt);
+       if (err < 0) {
+               printf("fdt_root: %s\n", fdt_strerror(err));
+               return err;
+       }
+
+       serial = getenv("serial#");
+       if (serial) {
+               err = fdt_setprop(fdt, 0, "serial-number", serial,
+                                 strlen(serial) + 1);
+
+               if (err < 0) {
+                       printf("WARNING: could not set serial-number %s.\n",
+                              fdt_strerror(err));
+                       return err;
+               }
+       }
+
+       return 0;
+}
 
 int fdt_initrd(void *fdt, ulong initrd_start, ulong initrd_end)
 {
@@ -429,6 +454,9 @@ int fdt_fixup_memory_banks(void *blob, u64 start[], u64 size[], int banks)
                return err;
        }
 
+       if (!banks)
+               return 0;
+
        len = fdt_pack_reg(blob, tmp, start, size, banks);
 
        err = fdt_setprop(blob, nodeoffset, "reg", tmp, len);
@@ -711,9 +739,11 @@ static int fdt_del_subnodes(const void *blob, int parent_offset)
        for (ndepth = 0, off = fdt_next_node(blob, parent_offset, &ndepth);
             (off >= 0) && (ndepth > 0);
             off = fdt_next_node(blob, off, &ndepth)) {
-               if (ndepth != 1)
+               if (ndepth < 0)
+                       break;
+               else if (ndepth != 1)
                        continue;
-               if (fdt_getprop(blob, off, "compatible", NULL))
+               else if (fdt_getprop(blob, off, "compatible", NULL))
                        continue;
                debug("delete %s: offset: %x\n",
                        fdt_get_name(blob, off, 0), off);
@@ -738,9 +768,11 @@ int fdt_del_partitions(void *blob, int parent_offset)
        int ret;
 
        while ((off = fdt_next_node(blob, off, &ndepth)) > 0) {
-               if (ndepth != 1)
+               if (ndepth < 0)
+                       break;
+               else if (ndepth != 1)
                        continue;
-               if (fdt_getprop(blob, off, "compatible", NULL))
+               else if (fdt_getprop(blob, off, "compatible", NULL))
                        continue;
                prop = fdt_getprop(blob, off, "label", NULL);
                if (prop == NULL) {
@@ -780,9 +812,11 @@ int fdt_node_set_part_info(void *blob, int parent_offset,
         * the offset in this case
         */
        while ((off = fdt_next_node(blob, off, &ndepth)) > 0) {
-               if (ndepth != 1)
+               if (ndepth < 0)
+                       break;
+               else if (ndepth != 1)
                        continue;
-               if (fdt_getprop(blob, off, "compatible", NULL))
+               else if (fdt_getprop(blob, off, "compatible", NULL))
                        continue;
                parent_offset = off;
                break;
@@ -1543,7 +1577,7 @@ int fdt_setup_simplefb_node(void *fdt, int node, u64 base_address, u32 width,
        if (ret < 0)
                return ret;
 
-       snprintf(name, sizeof(name), "framebuffer@%llx", base_address);
+       snprintf(name, sizeof(name), "framebuffer@%" PRIx64, base_address);
        ret = fdt_set_name(fdt, node, name);
        if (ret < 0)
                return ret;
@@ -1570,3 +1604,32 @@ int fdt_setup_simplefb_node(void *fdt, int node, u64 base_address, u32 width,
 
        return 0;
 }
+
+/*
+ * Update native-mode in display-timings from display environment variable.
+ * The node to update are specified by path.
+ */
+int fdt_fixup_display(void *blob, const char *path, const char *display)
+{
+       int off, toff;
+
+       if (!display || !path)
+               return -FDT_ERR_NOTFOUND;
+
+       toff = fdt_path_offset(blob, path);
+       if (toff >= 0)
+               toff = fdt_subnode_offset(blob, toff, "display-timings");
+       if (toff < 0)
+               return toff;
+
+       for (off = fdt_first_subnode(blob, toff);
+            off >= 0;
+            off = fdt_next_subnode(blob, off)) {
+               uint32_t h = fdt_get_phandle(blob, off);
+               debug("%s:0x%x\n", fdt_get_name(blob, off, NULL),
+                     fdt32_to_cpu(h));
+               if (strcasecmp(fdt_get_name(blob, off, NULL), display) == 0)
+                       return fdt_setprop_u32(blob, toff, "native-mode", h);
+       }
+       return toff;
+}