Introduce an overlay based method for constructing a base DT blob
to pass to the kernel.

Both canned and runtime feature selection is supported.

Signed-off-by: Pantelis Antoniou <pantelis.anton...@konsulko.com>
---
 common/image-fdt.c                           |   7 +-
 common/image-fit.c                           | 216 ++++++++++++++++++++++++--
 doc/uImage.FIT/command_syntax_extensions.txt |  12 +-
 doc/uImage.FIT/overlay-fdt-boot.txt          | 221 +++++++++++++++++++++++++++
 doc/uImage.FIT/source_file_format.txt        |   6 +-
 include/image.h                              |  10 ++
 6 files changed, 454 insertions(+), 18 deletions(-)
 create mode 100644 doc/uImage.FIT/overlay-fdt-boot.txt

diff --git a/common/image-fdt.c b/common/image-fdt.c
index c6e8832..a59134c 100644
--- a/common/image-fdt.c
+++ b/common/image-fdt.c
@@ -356,17 +356,16 @@ int boot_get_fdt(int flag, int argc, char * const argv[], 
uint8_t arch,
                        if (fit_check_format(buf)) {
                                ulong load, len;
 
-                               fdt_noffset = fit_image_load(images,
+                               fdt_noffset = boot_get_fdt_fit(images,
                                        fdt_addr, &fit_uname_fdt,
                                        &fit_uname_config,
-                                       arch, IH_TYPE_FLATDT,
-                                       BOOTSTAGE_ID_FIT_FDT_START,
-                                       FIT_LOAD_OPTIONAL, &load, &len);
+                                       arch, &load, &len);
 
                                images->fit_hdr_fdt = map_sysmem(fdt_addr, 0);
                                images->fit_uname_fdt = fit_uname_fdt;
                                images->fit_noffset_fdt = fdt_noffset;
                                fdt_addr = load;
+
                                break;
                        } else
 #endif
diff --git a/common/image-fit.c b/common/image-fit.c
index 109ecfa..cb089ea 100644
--- a/common/image-fit.c
+++ b/common/image-fit.c
@@ -19,6 +19,7 @@
 #include <errno.h>
 #include <mapmem.h>
 #include <asm/io.h>
+#include <malloc.h>
 DECLARE_GLOBAL_DATA_PTR;
 #endif /* !USE_HOSTCC*/
 
@@ -434,6 +435,10 @@ void fit_image_print(const void *fit, int image_noffset, 
const char *p)
                        printf("0x%08lx\n", load);
        }
 
+       /* optional load address for FDT */
+       if (type == IH_TYPE_FLATDT && !fit_image_get_load(fit, image_noffset, 
&load))
+               printf("%s  Load Address: 0x%08lx\n", p, load);
+
        if ((type == IH_TYPE_KERNEL) || (type == IH_TYPE_STANDALONE) ||
            (type == IH_TYPE_RAMDISK)) {
                ret = fit_image_get_entry(fit, image_noffset, &entry);
@@ -1454,6 +1459,8 @@ int fit_conf_get_node(const void *fit, const char 
*conf_uname)
 {
        int noffset, confs_noffset;
        int len;
+       const char *s;
+       char *conf_uname_copy = NULL;
 
        confs_noffset = fdt_path_offset(fit, FIT_CONFS_PATH);
        if (confs_noffset < 0) {
@@ -1475,29 +1482,58 @@ int fit_conf_get_node(const void *fit, const char 
*conf_uname)
                debug("Found default configuration: '%s'\n", conf_uname);
        }
 
+       s = strchr(conf_uname, '#');
+       if (s) {
+               len = s - conf_uname;
+               conf_uname_copy = malloc(len + 1);
+               if (!conf_uname_copy) {
+                       debug("Can't allocate uname copy: '%s'\n",
+                                       conf_uname);
+                       return -ENOMEM;
+               }
+               memcpy(conf_uname_copy, conf_uname, len);
+               conf_uname_copy[len] = '\0';
+               conf_uname = conf_uname_copy;
+       }
+
        noffset = fdt_subnode_offset(fit, confs_noffset, conf_uname);
        if (noffset < 0) {
                debug("Can't get node offset for configuration unit name: '%s' 
(%s)\n",
                      conf_uname, fdt_strerror(noffset));
        }
 
+       if (conf_uname_copy)
+               free(conf_uname_copy);
+
        return noffset;
 }
 
-int fit_conf_get_prop_node(const void *fit, int noffset,
+int fit_conf_get_prop_node_count(const void *fit, int noffset,
                const char *prop_name)
 {
-       char *uname;
+       return fdt_stringlist_count(fit, noffset, prop_name);
+}
+
+int fit_conf_get_prop_node_index(const void *fit, int noffset,
+               const char *prop_name, int index)
+{
+       const char *uname;
        int len;
 
        /* get kernel image unit name from configuration kernel property */
-       uname = (char *)fdt_getprop(fit, noffset, prop_name, &len);
+       uname = fdt_stringlist_get(fit, noffset, prop_name, index, &len);
        if (uname == NULL)
                return len;
 
        return fit_image_get_node(fit, uname);
 }
 
+int fit_conf_get_prop_node(const void *fit, int noffset,
+               const char *prop_name)
+{
+       return fit_conf_get_prop_node_index(fit, noffset, prop_name, 0);
+}
+
 /**
  * fit_conf_print - prints out the FIT configuration details
  * @fit: pointer to the FIT format image header
@@ -1515,7 +1551,7 @@ void fit_conf_print(const void *fit, int noffset, const 
char *p)
        char *desc;
        const char *uname;
        int ret;
-       int loadables_index;
+       int fdt_index, loadables_index;
 
        /* Mandatory properties */
        ret = fit_get_desc(fit, noffset, &desc);
@@ -1537,9 +1573,17 @@ void fit_conf_print(const void *fit, int noffset, const 
char *p)
        if (uname)
                printf("%s  Init Ramdisk: %s\n", p, uname);
 
-       uname = fdt_getprop(fit, noffset, FIT_FDT_PROP, NULL);
-       if (uname)
-               printf("%s  FDT:          %s\n", p, uname);
+       for (fdt_index = 0;
+            uname = fdt_stringlist_get(fit, noffset, FIT_FDT_PROP,
+                                       fdt_index, NULL), uname;
+            fdt_index++) {
+
+               if (fdt_index == 0)
+                       printf("%s  FDT:          ", p);
+               else
+                       printf("%s                ", p);
+               printf("%s\n", uname);
+       }
 
        uname = fdt_getprop(fit, noffset, FIT_FPGA_PROP, NULL);
        if (uname)
@@ -1575,8 +1619,8 @@ static int fit_image_select(const void *fit, int 
rd_noffset, int verify)
        return 0;
 }
 
-int fit_get_node_from_config(bootm_headers_t *images, const char *prop_name,
-                       ulong addr)
+int fit_get_node_from_config_index(bootm_headers_t *images, const char 
*prop_name,
+                       ulong addr, int index)
 {
        int cfg_noffset;
        void *fit_hdr;
@@ -1593,7 +1637,8 @@ int fit_get_node_from_config(bootm_headers_t *images, 
const char *prop_name,
                return -EINVAL;
        }
 
-       noffset = fit_conf_get_prop_node(fit_hdr, cfg_noffset, prop_name);
+       noffset = fit_conf_get_prop_node_index(fit_hdr, cfg_noffset, prop_name,
+                                              index);
        if (noffset < 0) {
                debug("*  %s: no '%s' in config\n", prop_name, prop_name);
                return -ENOENT;
@@ -1602,6 +1647,12 @@ int fit_get_node_from_config(bootm_headers_t *images, 
const char *prop_name,
        return noffset;
 }
 
+int fit_get_node_from_config(bootm_headers_t *images, const char *prop_name,
+                       ulong addr)
+{
+       return fit_get_node_from_config_index(images, prop_name, addr, 0);
+}
+
 /**
  * fit_get_image_type_property() - get property name for IH_TYPE_...
  *
@@ -1689,7 +1740,8 @@ int fit_image_load(bootm_headers_t *images, ulong addr,
                                        BOOTSTAGE_SUB_NO_UNIT_NAME);
                        return -ENOENT;
                }
-               fit_uname_config = fdt_get_name(fit, cfg_noffset, NULL);
+               if (!fit_uname_config)
+                       fit_uname_config = fdt_get_name(fit, cfg_noffset, NULL);
                printf("   Using '%s' configuration\n", fit_uname_config);
                if (image_type == IH_TYPE_KERNEL) {
                        /* Remember (and possibly verify) this config */
@@ -1841,6 +1893,7 @@ int fit_image_load(bootm_headers_t *images, ulong addr,
                dst = map_sysmem(load, len);
                memmove(dst, buf, len);
                data = load;
+
        }
        bootstage_mark(bootstage_id + BOOTSTAGE_SUB_LOAD);
 
@@ -1873,3 +1926,144 @@ int boot_get_setup_fit(bootm_headers_t *images, uint8_t 
arch,
 
        return ret;
 }
+
+#ifndef USE_HOSTCC
+int boot_get_fdt_fit(bootm_headers_t *images, ulong addr,
+                  const char **fit_unamep, const char **fit_uname_configp,
+                  int arch, ulong *datap, ulong *lenp)
+{
+       int fdt_noffset, cfg_noffset, count;
+       const void *fit;
+       const char *fit_uname = NULL;
+       const char *fit_uname_config = NULL;
+       char *fit_uname_config_copy = NULL;
+       char *next_config = NULL;
+       ulong load, len;
+#ifdef CONFIG_OF_LIBFDT_OVERLAY
+       ulong image_start, image_end;
+       ulong ovload, ovlen;
+       const char *uconfig;
+       const char *uname;
+       void *base, *ov;
+       int i, err, noffset, ov_noffset;
+#endif
+
+       fit_uname = fit_unamep ? *fit_unamep : NULL;
+
+       if (fit_uname_configp && *fit_uname_configp) {
+               fit_uname_config_copy = strdup(*fit_uname_configp);
+               if (!fit_uname_config_copy)
+                       return -ENOMEM;
+
+               next_config = strchr(fit_uname_config_copy, '#');
+               if (next_config)
+                       *next_config++ = '\0';
+               if (next_config - 1 > fit_uname_config_copy)
+                       fit_uname_config = fit_uname_config_copy;
+       }
+
+       fdt_noffset = fit_image_load(images,
+               addr, &fit_uname, &fit_uname_config,
+               arch, IH_TYPE_FLATDT,
+               BOOTSTAGE_ID_FIT_FDT_START,
+               FIT_LOAD_OPTIONAL, &load, &len);
+
+       if (fdt_noffset < 0)
+               goto out;
+
+       debug("fit_uname=%s, fit_uname_config=%s\n",
+                       fit_uname ? fit_uname : "<NULL>",
+                       fit_uname_config ? fit_uname_config : "<NULL>");
+
+       fit = map_sysmem(addr, 0);
+
+       cfg_noffset = fit_conf_get_node(fit, fit_uname_config);
+
+       /* single blob, or error just return as well */
+       count = fit_conf_get_prop_node_count(fit, cfg_noffset, FIT_FDT_PROP);
+       if (count <= 1 && !next_config)
+               goto out;
+
+       /* we need to apply overlays */
+
+#ifdef CONFIG_OF_LIBFDT_OVERLAY
+       image_start = addr;
+       image_end = addr + fit_get_size(fit);
+       /* verify that relocation took place by load address not being in fit */
+       if (load >= image_start && load < image_end) {
+               /* check is simplified; fit load checks for overlaps */
+               printf("Overlayed FDT requires relocation\n");
+               fdt_noffset = -EBADF;
+               goto out;
+       }
+
+       base = map_sysmem(load, len);
+
+       /* apply extra configs in FIT first, followed by args */
+       for (i = 1; ; i++) {
+               if (i < count) {
+                       noffset = fit_conf_get_prop_node_index(fit, cfg_noffset,
+                                                              FIT_FDT_PROP, i);
+                       uname = fit_get_name(fit, noffset, NULL);
+                       uconfig = NULL;
+               } else {
+                       if (!next_config)
+                               break;
+                       uconfig = next_config;
+                       next_config = strchr(next_config, '#');
+                       if (next_config)
+                               *next_config++ = '\0';
+                       uname = NULL;
+               }
+
+               debug("%d: using uname=%s uconfig=%s\n", i, uname, uconfig);
+
+               ov_noffset = fit_image_load(images,
+                       addr, &uname, &uconfig,
+                       arch, IH_TYPE_FLATDT,
+                       BOOTSTAGE_ID_FIT_FDT_START,
+                       FIT_LOAD_REQUIRED, &ovload, &ovlen);
+               if (ov_noffset < 0) {
+                       printf("load of %s failed\n", uname);
+                       continue;
+               }
+               debug("%s loaded at 0x%08lx len=0x%08lx\n",
+                               uname, ovload, ovlen);
+               ov = map_sysmem(ovload, ovlen);
+
+               base = map_sysmem(load, len + ovlen);
+               err = fdt_open_into(base, base, len + ovlen);
+               if (err < 0) {
+                       printf("failed on fdt_open_into\n");
+                       fdt_noffset = err;
+                       goto out;
+               }
+               err = fdt_overlay_apply(base, ov);
+               if (err < 0) {
+                       printf("failed on fdt_overlay_apply\n");
+                       fdt_noffset = err;
+                       goto out;
+               }
+               fdt_pack(base);
+               len = fdt_totalsize(base);
+       }
+#else
+       printf("config with overlays but CONFIG_OF_LIBFDT_OVERLAY not set\n");
+       fdt_noffset = -EBADF;
+#endif
+
+out:
+       if (datap)
+               *datap = load;
+       if (lenp)
+               *lenp = len;
+       if (fit_unamep)
+               *fit_unamep = fit_uname;
+       if (fit_uname_configp)
+               *fit_uname_configp = fit_uname_config;
+
+       if (fit_uname_config_copy)
+               free(fit_uname_config_copy);
+       return fdt_noffset;
+}
+#endif
diff --git a/doc/uImage.FIT/command_syntax_extensions.txt 
b/doc/uImage.FIT/command_syntax_extensions.txt
index 6c99b1c..676f992 100644
--- a/doc/uImage.FIT/command_syntax_extensions.txt
+++ b/doc/uImage.FIT/command_syntax_extensions.txt
@@ -36,7 +36,7 @@ Old uImage:
 New uImage:
 8.  bootm <addr1>
 9.  bootm [<addr1>]:<subimg1>
-10. bootm [<addr1>]#<conf>
+10. bootm [<addr1>]#<conf>[#<extra-conf[#...]]
 11. bootm [<addr1>]:<subimg1> [<addr2>]:<subimg2>
 12. bootm [<addr1>]:<subimg1> [<addr2>]:<subimg2> [<addr3>]:<subimg3>
 13. bootm [<addr1>]:<subimg1> [<addr2>]:<subimg2> <addr3>
@@ -129,6 +129,12 @@ following syntax:
 - new uImage configuration specification
 <addr>#<configuration unit_name>
 
+- new uImage configuration specification with extra configuration components
+<addr>#<configuration unit_name>[#<extra configuration unit_name>[#..]]
+
+The extra configuration currently is supported only for additional device tree
+overlays to apply on the base device tree supplied by the first configuration
+unit.
 
 Examples:
 
@@ -138,6 +144,10 @@ bootm 200000:kernel@1
 - boot configuration "cfg@1" from a new uImage located at 200000:
 bootm 200000#cfg@1
 
+- boot configuration "cfg@1" with extra "cfg@2" from a new uImage located
+  at 200000:
+bootm 200000#cfg@1#cfg@2
+
 - boot "kernel@1" from a new uImage at 200000 with initrd "ramdisk@2" found in
   some other new uImage stored at address 800000:
 bootm 200000:kernel@1 800000:ramdisk@2
diff --git a/doc/uImage.FIT/overlay-fdt-boot.txt 
b/doc/uImage.FIT/overlay-fdt-boot.txt
new file mode 100644
index 0000000..dbdf2a1
--- /dev/null
+++ b/doc/uImage.FIT/overlay-fdt-boot.txt
@@ -0,0 +1,221 @@
+U-Boot FDT Overlay usage
+========================
+
+Introduction
+------------
+In many cases it is desirable to have a single FIT image support a multitude
+of similar boards and their expansion options. The same kernel on DT enabled
+platforms can support this easily enough by providing a DT blob upon boot
+that matches the desired configuration.
+
+Configuration without overlays
+------------------------------
+
+Take a hypothetical board named 'foo' where there are different supported
+revisions, reva and revb. Assume that both board revisions can use add a bar
+add-on board, while only the revb board can use a baz add-on board.
+
+Without using overlays the configuration would be as follows for every case.
+
+       /dts-v1/;
+       / {
+               images {
+                       kernel@1 {
+                               data = /incbin/("./zImage");
+                               type = "kernel";
+                               arch = "arm";
+                               os = "linux";
+                               load = <0x82000000>;
+                               entry = <0x82000000>;
+                       };
+                       fdt@1 {
+                               data = /incbin/("./foo-reva.dtb");
+                               type = "flat_dt";
+                               arch = "arm";
+                       };
+                       fdt@2 {
+                               data = /incbin/("./foo-revb.dtb");
+                               type = "flat_dt";
+                               arch = "arm";
+                       };
+                       fdt@3 {
+                               data = /incbin/("./foo-reva-bar.dtb");
+                               type = "flat_dt";
+                               arch = "arm";
+                       };
+                       fdt@4 {
+                               data = /incbin/("./foo-revb-bar.dtb");
+                               type = "flat_dt";
+                               arch = "arm";
+                       };
+                       fdt@5 {
+                               data = /incbin/("./foo-revb-baz.dtb");
+                               type = "flat_dt";
+                               arch = "arm";
+                       };
+                       fdt@6 {
+                               data = /incbin/("./foo-revb-bar-baz.dtb");
+                               type = "flat_dt";
+                               arch = "arm";
+                       };
+               };
+
+               configurations {
+                       default = "foo-reva.dtb;
+                       foo-reva.dtb {
+                               kernel = "kernel@1";
+                               fdt = "fdt@1";
+                       };
+                       foo-revb.dtb {
+                               kernel = "kernel@1";
+                               fdt = "fdt@2";
+                       };
+                       foo-reva-bar.dtb {
+                               kernel = "kernel@1";
+                               fdt = "fdt@3";
+                       };
+                       foo-revb-bar.dtb {
+                               kernel = "kernel@1";
+                               fdt = "fdt@4";
+                       };
+                       foo-revb-baz.dtb {
+                               kernel = "kernel@1";
+                               fdt = "fdt@5";
+                       };
+                       foo-revb-bar-baz.dtb {
+                               kernel = "kernel@1";
+                               fdt = "fdt@6";
+                       };
+               };
+       };
+
+Note the blob needs to be compiled for each case and the combinatorial 
explosion of
+configurations. A typical device tree blob is in the low hunderds of kbytes so 
a
+multitude of configuration grows the image quite a bit.
+
+Booting this image is done by using
+
+       # bootm <addr>#<config>
+
+Where config is one of:
+       foo-reva.dtb, foo-revb.dtb, foo-reva-bar.dtb, foo-revb-bar.dtb,
+       foo-revb-baz.dtb, foo-revb-bar-baz.dtb
+
+This selects the DTB to use when booting.
+
+Configuration using overlays
+----------------------------
+
+Device tree overlays can be applied to a base DT and result in the same blob
+being passed to the booting kernel. This saves on space and avoid the 
combinatorial
+explosion problem.
+
+       /dts-v1/;
+       / {
+               images {
+                       kernel@1 {
+                               data = /incbin/("./zImage");
+                               type = "kernel";
+                               arch = "arm";
+                               os = "linux";
+                               load = <0x82000000>;
+                               entry = <0x82000000>;
+                       };
+                       fdt@1 {
+                               data = /incbin/("./foo.dtb");
+                               type = "flat_dt";
+                               arch = "arm";
+                               load = <0x87f00000>;
+                       };
+                       fdt@2 {
+                               data = /incbin/("./reva.dtbo");
+                               type = "flat_dt";
+                               arch = "arm";
+                               load = <0x87fc0000>;
+                       };
+                       fdt@3 {
+                               data = /incbin/("./revb.dtbo");
+                               type = "flat_dt";
+                               arch = "arm";
+                               load = <0x87fc0000>;
+                       };
+                       fdt@4 {
+                               data = /incbin/("./bar.dtbo");
+                               type = "flat_dt";
+                               arch = "arm";
+                               load = <0x87fc0000>;
+                       };
+                       fdt@5 {
+                               data = /incbin/("./baz.dtbo");
+                               type = "flat_dt";
+                               arch = "arm";
+                               load = <0x87fc0000>;
+                       };
+               };
+
+               configurations {
+                       default = "foo-reva.dtb;
+                       foo-reva.dtb {
+                               kernel = "kernel@1";
+                               fdt = "fdt@1", "fdt@2";
+                       };
+                       foo-revb.dtb {
+                               kernel = "kernel@1";
+                               fdt = "fdt@1", "fdt@3";
+                       };
+                       foo-reva-bar.dtb {
+                               kernel = "kernel@1";
+                               fdt = "fdt@1", "fdt@2", "fdt@4";
+                       };
+                       foo-revb-bar.dtb {
+                               kernel = "kernel@1";
+                               fdt = "fdt@1", "fdt@3", "fdt@4";
+                       };
+                       foo-revb-baz.dtb {
+                               kernel = "kernel@1";
+                               fdt = "fdt@1", "fdt@3", "fdt@5";
+                       };
+                       foo-revb-bar-baz.dtb {
+                               kernel = "kernel@1";
+                               fdt = "fdt@1", "fdt@3", "fdt@4", "fdt@5";
+                       };
+                       bar {
+                               fdt = "fdt@4";
+                       };
+                       baz {
+                               fdt = "fdt@5";
+                       };
+               };
+       };
+
+Booting this image is exactly the same as the non-overlay example.
+u-boot will retrieve the base blob and apply the overlays in sequence as
+they are declared in the configuration.
+
+Note the minimum amount of different DT blobs, as well as the requirement for
+the DT blobs to have a load address; the overlay application requires the blobs
+to be writeable.
+
+Configuration using overlays and feature selection
+--------------------------------------------------
+
+Although the configuration in the previous section works is a bit inflexible
+since it requires all possible configuration options to be laid out before
+hand in the FIT image. For the add-on boards the extra config selection method
+might make sense.
+
+Note the two bar & baz configuration nodes. To boot a reva board with
+the bar add-on board enabled simply use:
+
+       # bootm <addr>#foo-reva.dtb#bar
+
+While booting a revb with bar and baz is as follows:
+
+       # bootm <addr>#foo-revb.dtb#bar#baz
+
+The limitation for a feature selection configuration node is that a single
+fdt option is currently supported.
+
+Pantelis Antoniou
+pantelis.anton...@konsulko.com
+12/6/2017
diff --git a/doc/uImage.FIT/source_file_format.txt 
b/doc/uImage.FIT/source_file_format.txt
index 136d3d7..ba8013a 100644
--- a/doc/uImage.FIT/source_file_format.txt
+++ b/doc/uImage.FIT/source_file_format.txt
@@ -235,7 +235,7 @@ o config@1
   |- description = "configuration description"
   |- kernel = "kernel sub-node unit name"
   |- ramdisk = "ramdisk sub-node unit name"
-  |- fdt = "fdt sub-node unit-name"
+  |- fdt = "fdt sub-node unit-name" [, "fdt overlay sub-node unit-name", ...]
   |- fpga = "fpga sub-node unit-name"
   |- loadables = "loadables sub-node unit-name"
 
@@ -249,7 +249,9 @@ o config@1
   - ramdisk : Unit name of the corresponding ramdisk image (component image
     node of a "ramdisk" type).
   - fdt : Unit name of the corresponding fdt blob (component image node of a
-    "fdt type").
+    "fdt type"). Additional fdt overlay nodes can be supplied which signify
+    that the resulting device tree blob is generated by the first base fdt
+    blob with all subsequent overlays applied.
   - setup : Unit name of the corresponding setup binary (used for booting
     an x86 kernel). This contains the setup.bin file built by the kernel.
   - fpga : Unit name of the corresponding fpga bitstream blob
diff --git a/include/image.h b/include/image.h
index c6f1513..aef71f3 100644
--- a/include/image.h
+++ b/include/image.h
@@ -592,6 +592,10 @@ int boot_get_loadable(int argc, char * const argv[], 
bootm_headers_t *images,
 int boot_get_setup_fit(bootm_headers_t *images, uint8_t arch,
                       ulong *setup_start, ulong *setup_len);
 
+int boot_get_fdt_fit(bootm_headers_t *images, ulong addr,
+                  const char **fit_unamep, const char **fit_uname_configp,
+                  int arch, ulong *datap, ulong *lenp);
+
 /**
  * fit_image_load() - load an image from a FIT
  *
@@ -657,6 +661,8 @@ int fit_image_load(bootm_headers_t *images, ulong addr,
  */
 int fit_get_node_from_config(bootm_headers_t *images, const char *prop_name,
                        ulong addr);
+int fit_get_node_from_config_index(bootm_headers_t *images, const char 
*prop_name,
+                       ulong addr, int index);
 
 int boot_get_fdt(int flag, int argc, char * const argv[], uint8_t arch,
                 bootm_headers_t *images,
@@ -986,6 +992,10 @@ int fit_check_format(const void *fit);
 int fit_conf_find_compat(const void *fit, const void *fdt);
 int fit_conf_get_node(const void *fit, const char *conf_uname);
 
+int fit_conf_get_prop_node_count(const void *fit, int noffset,
+               const char *prop_name);
+int fit_conf_get_prop_node_index(const void *fit, int noffset,
+               const char *prop_name, int index);
 /**
  * fit_conf_get_prop_node() - Get node refered to by a configuration
  * @fit:       FIT to check
-- 
2.1.4

_______________________________________________
U-Boot mailing list
U-Boot@lists.denx.de
https://lists.denx.de/listinfo/u-boot

Reply via email to