Hello Sascha, On 6/24/21 10:52 AM, Sascha Hauer wrote: > [...] > + > +static int of_overlay_global_fixup(struct device_node *root, void *data) > +{ > + char *dir; > + int ret; > + > + if (*of_overlay_dir == '/') > + return of_overlay_apply_dir(root, of_overlay_dir, true); > + > + dir = concat_path_file(of_overlay_basedir, of_overlay_dir); > + > + ret = of_overlay_apply_dir(root, of_overlay_dir, true); shouldn't this be ret = of_overlay_apply_dir(root, dir, true); in order to use the concatenated path? Regards, Michael > + > + free(dir); > + > + return ret; > +} > + > +/** > + * of_overlay_register_filter - register a new overlay filter > + * @filter: The new filter > + * > + * Register a new overlay filter. A filter can either match on > + * the filename or on the content of an overlay, but not on both. > + * If that's desired two filters have to be registered. > + * > + * @return: 0 for success, negative error code otherwise > + */ > +int of_overlay_register_filter(struct of_overlay_filter *filter) > +{ > + if (filter->filter_filename && filter->filter_content) > + return -EINVAL; > + > + list_add_tail(&filter->list, &of_overlay_filters); > + > + return 0; > +} > + > +/** > + * of_overlay_filter_filename - A filter that matches on the filename of > + * an overlay > + * @f: The filter > + * @filename: The filename of the overlay > + * > + * This filter matches when the filename matches one of the patterns given > + * in global.of.overlay.filepattern. global.of.overlay.filepattern shall > + * contain a space separated list of wildcard patterns. > + * > + * @return: True when the overlay shall be applied, false otherwise. > + */ > +static bool of_overlay_filter_filename(struct of_overlay_filter *f, > + const char *filename) > +{ > + char *p, *path, *n; > + int ret; > + bool apply; > + > + p = path = strdup(of_overlay_filepattern); > + > + while ((n = strsep_unescaped(&p, " "))) { > + if (!*n) > + continue; > + > + ret = fnmatch(n, filename, 0); > + > + if (!ret) { > + apply = true; > + goto out; > + } > + } > + > + apply = false; > +out: > + free(path); > + > + return apply; > +} > + > +static struct of_overlay_filter of_overlay_filepattern_filter = { > + .name = "filepattern", > + .filter_filename = of_overlay_filter_filename, > +}; > + > +/** > + * of_overlay_filter_compatible - A filter that matches on the compatible of > + * an overlay > + * @f: The filter > + * @ovl: The overlay > + * > + * This filter matches when the compatible of an overlay matches to one > + * of the compatibles given in global.of.overlay.compatible. When the > + * overlay doesn't contain a compatible entry it is considered matching. > + * Also when no compatibles are given in global.of.overlay.compatible > + * all overlays will match. > + * > + * @return: True when the overlay shall be applied, false otherwise. > + */ > +static bool of_overlay_filter_compatible(struct of_overlay_filter *f, > + struct device_node *ovl) > +{ > + char *p, *n, *compatibles; > + bool res = false; > + > + if (!of_overlay_compatible || !*of_overlay_compatible) > + return true; > + if (!of_find_property(ovl, "compatible", NULL)) > + return true; > + > + p = compatibles = xstrdup(of_overlay_compatible); > + > + while ((n = strsep_unescaped(&p, " "))) { > + if (!*n) > + continue; > + > + if (of_device_is_compatible(ovl, n)) { > + res = true; > + break; > + } > + } > + > + free(compatibles); > + > + return res; > +} > + > +static struct of_overlay_filter of_overlay_compatible_filter = { > + .name = "compatible", > + .filter_content = of_overlay_filter_compatible, > +}; > + > +static int of_overlay_init(void) > +{ > + of_overlay_filepattern = strdup("*"); > + of_overlay_filter = strdup("filepattern compatible"); > + of_overlay_set_basedir("/"); > + > + globalvar_add_simple_string("of.overlay.compatible", &of_overlay_compatible); > + globalvar_add_simple_string("of.overlay.filepattern", &of_overlay_filepattern); > + globalvar_add_simple_string("of.overlay.filter", &of_overlay_filter); > + globalvar_add_simple_string("of.overlay.dir", &of_overlay_dir); > + > + of_overlay_register_filter(&of_overlay_filepattern_filter); > + of_overlay_register_filter(&of_overlay_compatible_filter); > + > + of_register_fixup(of_overlay_global_fixup, NULL); > + > + return 0; > +} > +device_initcall(of_overlay_init); > + > +BAREBOX_MAGICVAR(global.of.overlay.compatible, "space separated list of compatibles an overlay must match"); > +BAREBOX_MAGICVAR(global.of.overlay.filepattern, "space separated list of filepatterns an overlay must match"); > +BAREBOX_MAGICVAR(global.of.overlay.dir, "Directory to look for dt overlays"); > +BAREBOX_MAGICVAR(global.of.overlay.filter, "space separated list of filters"); > diff --git a/include/of.h b/include/of.h > index 59c1250fb2..b698220b1e 100644 > --- a/include/of.h > +++ b/include/of.h > @@ -1022,12 +1022,20 @@ static inline struct device_node *of_find_root_node(struct device_node *node) > return node; > } > > +struct of_overlay_filter { > + bool (*filter_filename)(struct of_overlay_filter *, const char *filename); > + bool (*filter_content)(struct of_overlay_filter *, struct device_node *); > + char *name; > + struct list_head list; > +}; > + > #ifdef CONFIG_OF_OVERLAY > struct device_node *of_resolve_phandles(struct device_node *root, > const struct device_node *overlay); > int of_overlay_apply_tree(struct device_node *root, > struct device_node *overlay); > -int of_overlay_apply_file(struct device_node *root, const char *filename); > +int of_overlay_apply_file(struct device_node *root, const char *filename, > + bool filter); > int of_register_overlay(struct device_node *overlay); > int of_process_overlay(struct device_node *root, > struct device_node *overlay, > @@ -1038,6 +1046,8 @@ int of_process_overlay(struct device_node *root, > int of_overlay_pre_load_firmware(struct device_node *root, struct device_node *overlay); > int of_overlay_load_firmware(void); > void of_overlay_load_firmware_clear(void); > +void of_overlay_set_basedir(const char *path); > +int of_overlay_register_filter(struct of_overlay_filter *); > #else > static inline struct device_node *of_resolve_phandles(struct device_node *root, > const struct device_node *overlay) > @@ -1052,7 +1062,7 @@ static inline int of_overlay_apply_tree(struct device_node *root, > } > > static inline int of_overlay_apply_file(struct device_node *root, > - const char *filename) > + const char *filename, bool filter) > { > return -ENOSYS; > } > @@ -1086,6 +1096,10 @@ static inline void of_overlay_load_firmware_clear(void) > { > } > > +static inline void of_overlay_set_basedir(const char *path) > +{ > +} > + > #endif > > #endif /* __OF_H */ > _______________________________________________ barebox mailing list barebox@xxxxxxxxxxxxxxxxxxx http://lists.infradead.org/mailman/listinfo/barebox