[RFC Patch 3/3] blspec: allow setting compatible depth

Rouven Czerwinski r.czerwinski at pengutronix.de
Thu Mar 3 22:24:13 PST 2022


In some cases its desirable to not only evaluate the first compatible of
the barebox device tree against the bootspec device tree, but following
compatibles as well. This is the case if fallback needs to be
implemented for older device trees which use a different compatible.
Allow setting the compatible depth by board code.

Signed-off-by: Rouven Czerwinski <r.czerwinski at pengutronix.de>
---
 common/blspec.c  | 99 +++++++++++++++++++++++++++++++-----------------
 include/blspec.h |  2 +-
 2 files changed, 65 insertions(+), 36 deletions(-)

diff --git a/common/blspec.c b/common/blspec.c
index c1b1991338..4713a2157f 100644
--- a/common/blspec.c
+++ b/common/blspec.c
@@ -22,6 +22,8 @@
 #include <linux/err.h>
 #include <mtd/ubi-user.h>
 
+static unsigned int compatible_depth = 1;
+
 /*
  * blspec_entry_var_set - set a variable to a value
  */
@@ -32,6 +34,11 @@ int blspec_entry_var_set(struct blspec_entry *entry, const char *name,
 			val ? strlen(val) + 1 : 0, 1);
 }
 
+void blspec_set_compatible_depth(unsigned int depth)
+{
+	compatible_depth = depth;
+}
+
 static int blspec_overlay_fixup(struct device_node *root, void *ctx)
 {
 	struct blspec_entry *entry = ctx;
@@ -542,6 +549,10 @@ int blspec_scan_directory(struct bootentries *bootentries, const char *root)
 	struct list_head entry_list;
 	struct blspec_list_entry *lentry;
 	struct blspec_list_entry *temp;
+	struct device_node *barebox_root;
+	struct property *prop;
+	const char *compat;
+	int depth;
 
 	INIT_LIST_HEAD(&entry_list);
 
@@ -611,51 +622,69 @@ int blspec_scan_directory(struct bootentries *bootentries, const char *root)
 		lentry->entry = entry;
 		lentry->name = d->d_name;
 
-		list_add_sort(&entry_list, &lentry->list, compare);
+		list_add_sort(&lentry->list, &entry_list, compare);
 	}
 
-	list_for_each_entry_safe(lentry, temp, &entry_list, list) {
-		char *devname = NULL, *hwdevname = NULL;
+	barebox_root = of_get_root_node();
 
-		entry = lentry->entry;
+	prop = of_find_property(barebox_root, "compatible", NULL);
 
-		if (!entry_is_of_compatible(entry, of_get_machine_compatible())) {
-			blspec_entry_free(&entry->entry);
-			list_del(&lentry->list);
-			free(lentry);
-			continue;
-		}
+	compat = of_prop_next_string(prop, NULL);
+	depth = compatible_depth;
+	do {
+		list_for_each_entry_safe(lentry, temp, &entry_list, list) {
+			char *devname = NULL, *hwdevname = NULL;
 
-		if (!entry_is_match_machine_id(entry)) {
-			blspec_entry_free(&entry->entry);
-			list_del(&lentry->list);
-			free(lentry);
-			continue;
-		}
+			entry = lentry->entry;
 
-		found++;
+			if (!entry_is_of_compatible(entry, compat)) {
+				if (depth == 1) {
+					blspec_entry_free(&entry->entry);
+					list_del(&lentry->list);
+					free(lentry);
+				}
+				continue;
+			}
 
-		if (entry->cdev && entry->cdev->dev) {
-			devname = xstrdup(dev_name(entry->cdev->dev));
-			if (entry->cdev->dev->parent)
-				hwdevname = xstrdup(dev_name(entry->cdev->dev->parent));
-		}
+			if (!entry_is_match_machine_id(entry)) {
+				if (depth == 1) {
+					blspec_entry_free(&entry->entry);
+					list_del(&lentry->list);
+					free(lentry);
+				}
+				continue;
+			}
 
-		entry->entry.title = xasprintf("%s (%s)", blspec_entry_var_get(entry, "title"),
-					       entry->configpath);
-		entry->entry.description = basprintf("blspec entry, device: %s hwdevice: %s",
-						    devname ? devname : "none",
-						    hwdevname ? hwdevname : "none");
-		free(devname);
-		free(hwdevname);
+			found++;
 
-		entry->entry.me.type = MENU_ENTRY_NORMAL;
-		entry->entry.release = blspec_entry_free;
+			if (entry->cdev && entry->cdev->dev) {
+				devname = xstrdup(dev_name(entry->cdev->dev));
+				if (entry->cdev->dev->parent)
+					hwdevname = xstrdup(dev_name(entry->cdev->dev->parent));
+			}
 
-		bootentries_add_entry(bootentries, &entry->entry);
-		list_del(&lentry->list);
-		free(lentry);
-	}
+			entry->entry.title = xasprintf("%s (%s)", blspec_entry_var_get(entry, "title"),
+						       entry->configpath);
+			entry->entry.description = basprintf("blspec entry, device: %s hwdevice: %s",
+							     devname ? devname : "none",
+							     hwdevname ? hwdevname : "none");
+			free(devname);
+			free(hwdevname);
+
+			entry->entry.me.type = MENU_ENTRY_NORMAL;
+			entry->entry.release = blspec_entry_free;
+
+			bootentries_add_entry(bootentries, &entry->entry);
+			list_del(&lentry->list);
+			free(lentry);
+		}
+
+		compat = of_prop_next_string(prop, compat);
+		if (!compat)
+			break;
+
+		depth--;
+	} while (depth > 0);
 
 	ret = found;
 
diff --git a/include/blspec.h b/include/blspec.h
index 37076cd47c..f499ad8b2d 100644
--- a/include/blspec.h
+++ b/include/blspec.h
@@ -23,5 +23,5 @@ int blspec_scan_devices(struct bootentries *bootentries);
 int blspec_scan_device(struct bootentries *bootentries, struct device_d *dev);
 int blspec_scan_devicename(struct bootentries *bootentries, const char *devname);
 int blspec_scan_directory(struct bootentries *bootentries, const char *root);
-
+void blspec_set_compatible_depth(unsigned int depth);
 #endif /* __LOADER_H__ */
-- 
2.35.1




More information about the barebox mailing list