]> git.kernelconcepts.de Git - karo-tx-uboot.git/blobdiff - common/fdt_support.c
mpc83xx: wait till UPM completes the write to array
[karo-tx-uboot.git] / common / fdt_support.c
index 405b9dbda977f74d08a48bdf4e62919d8545bc7d..8ceeb0faa9d182ff3af838414aa70d1cda0b7afe 100644 (file)
@@ -99,44 +99,85 @@ static int fdt_fixup_stdout(void *fdt, int chosenoff)
 }
 #endif
 
-int fdt_chosen(void *fdt, ulong initrd_start, ulong initrd_end, int force)
+int fdt_initrd(void *fdt, ulong initrd_start, ulong initrd_end, int force)
 {
        int   nodeoffset;
-       int   err;
-       u32   tmp;              /* used to set 32 bit integer properties */
-       char  *str;             /* used to set string properties */
+       int   err, j, total;
+       u32   tmp;
        const char *path;
+       uint64_t addr, size;
 
-       err = fdt_check_header(fdt);
-       if (err < 0) {
-               printf("fdt_chosen: %s\n", fdt_strerror(err));
-               return err;
+       /* Find the "chosen" node.  */
+       nodeoffset = fdt_path_offset (fdt, "/chosen");
+
+       /* If there is no "chosen" node in the blob return */
+       if (nodeoffset < 0) {
+               printf("fdt_initrd: %s\n", fdt_strerror(nodeoffset));
+               return nodeoffset;
        }
 
-       if (initrd_start && initrd_end) {
-               uint64_t addr, size;
-               int  total = fdt_num_mem_rsv(fdt);
-               int  j;
+       /* just return if initrd_start/end aren't valid */
+       if ((initrd_start == 0) || (initrd_end == 0))
+               return 0;
 
-               /*
-                * Look for an existing entry and update it.  If we don't find
-                * the entry, we will j be the next available slot.
-                */
-               for (j = 0; j < total; j++) {
-                       err = fdt_get_mem_rsv(fdt, j, &addr, &size);
-                       if (addr == initrd_start) {
-                               fdt_del_mem_rsv(fdt, j);
-                               break;
-                       }
+       total = fdt_num_mem_rsv(fdt);
+
+       /*
+        * Look for an existing entry and update it.  If we don't find
+        * the entry, we will j be the next available slot.
+        */
+       for (j = 0; j < total; j++) {
+               err = fdt_get_mem_rsv(fdt, j, &addr, &size);
+               if (addr == initrd_start) {
+                       fdt_del_mem_rsv(fdt, j);
+                       break;
                }
+       }
+
+       err = fdt_add_mem_rsv(fdt, initrd_start, initrd_end - initrd_start + 1);
+       if (err < 0) {
+               printf("fdt_initrd: %s\n", fdt_strerror(err));
+               return err;
+       }
 
-               err = fdt_add_mem_rsv(fdt, initrd_start, initrd_end - initrd_start + 1);
+       path = fdt_getprop(fdt, nodeoffset, "linux,initrd-start", NULL);
+       if ((path == NULL) || force) {
+               tmp = __cpu_to_be32(initrd_start);
+               err = fdt_setprop(fdt, nodeoffset,
+                       "linux,initrd-start", &tmp, sizeof(tmp));
                if (err < 0) {
-                       printf("fdt_chosen: %s\n", fdt_strerror(err));
+                       printf("WARNING: "
+                               "could not set linux,initrd-start %s.\n",
+                               fdt_strerror(err));
+                       return err;
+               }
+               tmp = __cpu_to_be32(initrd_end);
+               err = fdt_setprop(fdt, nodeoffset,
+                       "linux,initrd-end", &tmp, sizeof(tmp));
+               if (err < 0) {
+                       printf("WARNING: could not set linux,initrd-end %s.\n",
+                               fdt_strerror(err));
+
                        return err;
                }
        }
 
+       return 0;
+}
+
+int fdt_chosen(void *fdt, int force)
+{
+       int   nodeoffset;
+       int   err;
+       char  *str;             /* used to set string properties */
+       const char *path;
+
+       err = fdt_check_header(fdt);
+       if (err < 0) {
+               printf("fdt_chosen: %s\n", fdt_strerror(err));
+               return err;
+       }
+
        /*
         * Find the "chosen" node.
         */
@@ -173,24 +214,6 @@ int fdt_chosen(void *fdt, ulong initrd_start, ulong initrd_end, int force)
                                        fdt_strerror(err));
                }
        }
-       if (initrd_start && initrd_end) {
-               path = fdt_getprop(fdt, nodeoffset, "linux,initrd-start", NULL);
-               if ((path == NULL) || force) {
-                       tmp = __cpu_to_be32(initrd_start);
-                       err = fdt_setprop(fdt, nodeoffset,
-                               "linux,initrd-start", &tmp, sizeof(tmp));
-                       if (err < 0)
-                               printf("WARNING: "
-                                       "could not set linux,initrd-start %s.\n",
-                                       fdt_strerror(err));
-                       tmp = __cpu_to_be32(initrd_end);
-                       err = fdt_setprop(fdt, nodeoffset,
-                               "linux,initrd-end", &tmp, sizeof(tmp));
-                       if (err < 0)
-                               printf("WARNING: could not set linux,initrd-end %s.\n",
-                                       fdt_strerror(err));
-               }
-       }
 
 #ifdef CONFIG_OF_STDOUT_VIA_ALIAS
        path = fdt_getprop(fdt, nodeoffset, "linux,stdout-path", NULL);
@@ -531,3 +554,42 @@ void fdt_fixup_crypto_node(void *blob, int sec_rev)
                       fdt_strerror(err));
 }
 #endif /* defined(CONFIG_MPC83XX) || defined(CONFIG_MPC85xx) */
+
+/* Resize the fdt to its actual size + a bit of padding */
+int fdt_resize(void *blob)
+{
+       int i;
+       uint64_t addr, size;
+       int total, ret;
+       uint actualsize;
+
+       if (!blob)
+               return 0;
+
+       total = fdt_num_mem_rsv(blob);
+       for (i = 0; i < total; i++) {
+               fdt_get_mem_rsv(blob, i, &addr, &size);
+               if (addr == (uint64_t)(u32)blob) {
+                       fdt_del_mem_rsv(blob, i);
+                       break;
+               }
+       }
+
+       /* Calculate the actual size of the fdt */
+       actualsize = fdt_off_dt_strings(blob) +
+               fdt_size_dt_strings(blob);
+
+       /* Make it so the fdt ends on a page boundary */
+       actualsize = ALIGN(actualsize, 0x1000);
+       actualsize = actualsize - ((uint)blob & 0xfff);
+
+       /* Change the fdt header to reflect the correct size */
+       fdt_set_totalsize(blob, actualsize);
+
+       /* Add the new reservation */
+       ret = fdt_add_mem_rsv(blob, (uint)blob, actualsize);
+       if (ret < 0)
+               return ret;
+
+       return actualsize;
+}