Merge branch 'master' of git://git.denx.de/u-boot-usb
[oweals/u-boot.git] / common / image-fit.c
index c9ffc441aa653bae7fbb756a691d4998a4fc597f..5c63c769de274e721ae767fae96da61f013bb8be 100644 (file)
@@ -1522,6 +1522,10 @@ int fit_check_format(const void *fit)
  * compatible list, "foo,bar", matches a compatible string in the root of fdt1.
  * "bim,bam" in fdt2 matches the second string which isn't as good as fdt1.
  *
+ * As an optimization, the compatible property from the FDT's root node can be
+ * copied into the configuration node in the FIT image. This is required to
+ * match configurations with compressed FDTs.
+ *
  * returns:
  *     offset to the configuration to use if one was found
  *     -1 otherwise
@@ -1554,55 +1558,62 @@ int fit_conf_find_compat(const void *fit, const void *fdt)
        for (noffset = fdt_next_node(fit, confs_noffset, &ndepth);
                        (noffset >= 0) && (ndepth > 0);
                        noffset = fdt_next_node(fit, noffset, &ndepth)) {
-               const void *kfdt;
+               const void *fdt;
                const char *kfdt_name;
-               int kfdt_noffset;
+               int kfdt_noffset, compat_noffset;
                const char *cur_fdt_compat;
                int len;
-               size_t size;
+               size_t sz;
                int i;
 
                if (ndepth > 1)
                        continue;
 
-               kfdt_name = fdt_getprop(fit, noffset, "fdt", &len);
-               if (!kfdt_name) {
-                       debug("No fdt property found.\n");
-                       continue;
-               }
-               kfdt_noffset = fdt_subnode_offset(fit, images_noffset,
-                                                 kfdt_name);
-               if (kfdt_noffset < 0) {
-                       debug("No image node named \"%s\" found.\n",
-                             kfdt_name);
-                       continue;
-               }
+               /* If there's a compat property in the config node, use that. */
+               if (fdt_getprop(fit, noffset, "compatible", NULL)) {
+                       fdt = fit;                /* search in FIT image */
+                       compat_noffset = noffset; /* search under config node */
+               } else {        /* Otherwise extract it from the kernel FDT. */
+                       kfdt_name = fdt_getprop(fit, noffset, "fdt", &len);
+                       if (!kfdt_name) {
+                               debug("No fdt property found.\n");
+                               continue;
+                       }
+                       kfdt_noffset = fdt_subnode_offset(fit, images_noffset,
+                                                         kfdt_name);
+                       if (kfdt_noffset < 0) {
+                               debug("No image node named \"%s\" found.\n",
+                                     kfdt_name);
+                               continue;
+                       }
 
-               if (!fit_image_check_comp(fit, kfdt_noffset, IH_COMP_NONE)) {
-                       debug("Can't extract compat from \"%s\" (compressed)\n",
-                             kfdt_name);
-                       continue;
-               }
+                       if (!fit_image_check_comp(fit, kfdt_noffset,
+                                                 IH_COMP_NONE)) {
+                               debug("Can't extract compat from \"%s\" "
+                                     "(compressed)\n", kfdt_name);
+                               continue;
+                       }
 
-               /*
-                * Get a pointer to this configuration's fdt.
-                */
-               if (fit_image_get_data(fit, kfdt_noffset, &kfdt, &size)) {
-                       debug("Failed to get fdt \"%s\".\n", kfdt_name);
-                       continue;
+                       /* search in this config's kernel FDT */
+                       if (fit_image_get_data(fit, kfdt_noffset, &fdt, &sz)) {
+                               debug("Failed to get fdt \"%s\".\n", kfdt_name);
+                               continue;
+                       }
+
+                       compat_noffset = 0;  /* search kFDT under root node */
                }
 
                len = fdt_compat_len;
                cur_fdt_compat = fdt_compat;
                /*
                 * Look for a match for each U-Boot compatibility string in
-                * turn in this configuration's fdt.
+                * turn in the compat string property.
                 */
                for (i = 0; len > 0 &&
                     (!best_match_offset || best_match_pos > i); i++) {
                        int cur_len = strlen(cur_fdt_compat) + 1;
 
-                       if (!fdt_node_check_compatible(kfdt, 0,
+                       if (!fdt_node_check_compatible(fdt, compat_noffset,
                                                       cur_fdt_compat)) {
                                best_match_offset = noffset;
                                best_match_pos = i;
@@ -1987,10 +1998,11 @@ int fit_image_load(bootm_headers_t *images, ulong addr,
        comp = IH_COMP_NONE;
        loadbuf = buf;
        /* Kernel images get decompressed later in bootm_load_os(). */
-       if (!(image_type == IH_TYPE_KERNEL ||
-             image_type == IH_TYPE_KERNEL_NOLOAD) &&
-           !fit_image_get_comp(fit, noffset, &comp) &&
-           comp != IH_COMP_NONE) {
+       if (!fit_image_get_comp(fit, noffset, &comp) &&
+           comp != IH_COMP_NONE &&
+           !(image_type == IH_TYPE_KERNEL ||
+             image_type == IH_TYPE_KERNEL_NOLOAD ||
+             image_type == IH_TYPE_RAMDISK)) {
                ulong max_decomp_len = len * 20;
                if (load == data) {
                        loadbuf = malloc(max_decomp_len);
@@ -2010,6 +2022,10 @@ int fit_image_load(bootm_headers_t *images, ulong addr,
                memcpy(loadbuf, buf, len);
        }
 
+       if (image_type == IH_TYPE_RAMDISK && comp != IH_COMP_NONE)
+               puts("WARNING: 'compression' nodes for ramdisks are deprecated,"
+                    " please fix your .its file!\n");
+
        /* verify that image data is a proper FDT blob */
        if (image_type == IH_TYPE_FLATDT && fdt_check_header(loadbuf)) {
                puts("Subimage data is not a FDT");