The FIT spec is not very specific when it comes to device-tree overlay handling. Overlays can be added directely to an config node: config-a { compatible = "machine-compatible"; kernel = "kernel-img-name"; fdt = "fdt-base-name", "fdt-overlay1-name", "..."; } or they are supplied via dedicated config nodes: overlay-2 { fdt = "fdt-overlay2-name"; } Of course these config nodes can have compatibles as well: overlay-3 { compatible = "machine-compatible"; fdt = "fdt-overlay3-name"; } The current fit_find_compatible_unit() code would skip the overlay node if the config-a compatible has the same score as the overlay-3 compatible and if the overlay-3 config-node is listed after the config-a config-node. But if the compatible of config-a config-node has a lower score or the overlay-3 config-note is listed first (the spec does not specify any order) we end up in taking the overlay-3 config-node instead of config-a config-node. Make to code more robust by skip all config nodes matching the pattern from global.of.overlay.fitconfigpattern. Signed-off-by: Marco Felsch <m.felsch@xxxxxxxxxxxxxx> --- common/image-fit.c | 26 +++++++++++++++++++++++++- 1 file changed, 25 insertions(+), 1 deletion(-) diff --git a/common/image-fit.c b/common/image-fit.c index b16752de05bc..bf1562315b40 100644 --- a/common/image-fit.c +++ b/common/image-fit.c @@ -7,6 +7,7 @@ #define pr_fmt(fmt) "FIT: " fmt #include <common.h> +#include <environment.h> #include <init.h> #include <bootm.h> #include <libfile.h> @@ -14,6 +15,7 @@ #include <digest.h> #include <of.h> #include <fs.h> +#include <fnmatch.h> #include <malloc.h> #include <linux/ctype.h> #include <asm/byteorder.h> @@ -715,6 +717,23 @@ static int fit_config_verify_signature(struct fit_handle *handle, struct device_ return ret; } +static bool fit_config_is_overlay(struct device_node *conf_node) +{ + const char *overlay_pattern; + int no_match; + + if (!IS_ENABLED(CONFIG_OF_OVERLAY)) + return false; + + overlay_pattern = getenv_nonempty("global.of.overlay.fitconfigpattern"); + if (!overlay_pattern) + return false; + + no_match = fnmatch(overlay_pattern, conf_node->name, 0); + + return no_match ? false : true; +} + static int fit_find_compatible_unit(struct device_node *conf_node, const char **unit) { @@ -733,7 +752,12 @@ static int fit_find_compatible_unit(struct device_node *conf_node, return -ENOENT; for_each_child_of_node(conf_node, child) { - int score = of_device_is_compatible(child, machine); + int score; + + if (fit_config_is_overlay(child)) + continue; + + score = of_device_is_compatible(child, machine); if (score > best_score) { best_score = score; *unit = child->name; -- 2.39.2