mail archive of the barebox mailing list
 help / color / mirror / Atom feed
* [PATCH v2 0/7] Device Tree Overlay Support
@ 2019-09-06 13:20 Michael Tretter
  2019-09-06 13:20 ` [PATCH v2 1/7] dtc: add -@ option to enable __symbols__ Michael Tretter
                   ` (7 more replies)
  0 siblings, 8 replies; 15+ messages in thread
From: Michael Tretter @ 2019-09-06 13:20 UTC (permalink / raw)
  To: barebox; +Cc: Michael Tretter

Hello,

This is the v2 for adding device tree overlay support to barebox.

The biggest change is the new function of_overlay_apply_tree() which accepts a
devicetree and the root node of an overlay and applies the overlay to the
devicetree.

Apart from that, I fixed various issues like memory leaks, useless includes,
missing documentation, formatting of output messages, and a missing "static
inline".

Michael

Changelog:

v1 -> v2:
 - export function for applying a device tree overlay
 - define pr_fmt for overlay and resolver
 - remove useless notifier.h
 - fix error handling/memory leak in blspec handling
 - document ownership of overlay memory

rfc -> v1:
 - new of_overlay command
 - no more notifiers for device tree overlays

Michael Tretter (7):
  dtc: add -@ option to enable __symbols__
  of: add support for devicetree overlays
  blspec: add support for devicetree overlays
  of: add iterator for overlays
  firmware: add support to load firmware from dt overlay
  blspec: load firmware if specified in dt overlay
  commands: add of_overlay command for device tree overlays

 Documentation/user/booting-linux.rst |   4 +
 commands/Kconfig                     |  12 ++
 commands/Makefile                    |   1 +
 commands/of_overlay.c                |  89 +++++++++
 common/blspec.c                      |  77 ++++++++
 common/firmware.c                    |  77 ++++++++
 drivers/of/Kconfig                   |   9 +
 drivers/of/Makefile                  |   1 +
 drivers/of/overlay.c                 | 254 ++++++++++++++++++++++++
 drivers/of/resolver.c                | 279 +++++++++++++++++++++++++++
 include/firmware.h                   |   3 +
 include/of.h                         |  40 ++++
 scripts/Makefile.lib                 |   2 +-
 13 files changed, 847 insertions(+), 1 deletion(-)
 create mode 100644 commands/of_overlay.c
 create mode 100644 drivers/of/overlay.c
 create mode 100644 drivers/of/resolver.c

-- 
2.20.1


_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox

^ permalink raw reply	[flat|nested] 15+ messages in thread

* [PATCH v2 1/7] dtc: add -@ option to enable __symbols__
  2019-09-06 13:20 [PATCH v2 0/7] Device Tree Overlay Support Michael Tretter
@ 2019-09-06 13:20 ` Michael Tretter
  2019-09-06 13:20 ` [PATCH v2 2/7] of: add support for devicetree overlays Michael Tretter
                   ` (6 subsequent siblings)
  7 siblings, 0 replies; 15+ messages in thread
From: Michael Tretter @ 2019-09-06 13:20 UTC (permalink / raw)
  To: barebox; +Cc: Michael Tretter

The devicetree overlay driver requires the __symbols__ node to resolve
phandles to the base devicetree. As Barebox applies the overlay to the
live devicetree, the build-in devicetree must be built with the
__symbols__ node.

Signed-off-by: Michael Tretter <m.tretter@pengutronix.de>

---
Changelog:

v1->v2: none
---
 scripts/Makefile.lib | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/scripts/Makefile.lib b/scripts/Makefile.lib
index fc5fe3d7e8..292dc938d9 100644
--- a/scripts/Makefile.lib
+++ b/scripts/Makefile.lib
@@ -292,7 +292,7 @@ $(obj)/%.dtb.S: $(obj)/%.dtb $(srctree)/scripts/gen-dtb-s FORCE
 
 quiet_cmd_dtc = DTC     $@
 cmd_dtc = $(CPP) $(dtc_cpp_flags) -x assembler-with-cpp -o $(dtc-tmp) $< ; \
-	$(objtree)/scripts/dtc/dtc -O dtb -o $@ -b 0 \
+	$(objtree)/scripts/dtc/dtc -@ -O dtb -o $@ -b 0 \
 		-i $(srctree)/arch/$(SRCARCH)/dts $(DTC_FLAGS) \
 		-i $(srctree)/dts/src/$(SRCARCH) \
 		-d $(depfile).dtc $(dtc-tmp) ; \
-- 
2.20.1


_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox

^ permalink raw reply	[flat|nested] 15+ messages in thread

* [PATCH v2 2/7] of: add support for devicetree overlays
  2019-09-06 13:20 [PATCH v2 0/7] Device Tree Overlay Support Michael Tretter
  2019-09-06 13:20 ` [PATCH v2 1/7] dtc: add -@ option to enable __symbols__ Michael Tretter
@ 2019-09-06 13:20 ` Michael Tretter
  2019-09-06 13:20 ` [PATCH v2 3/7] blspec: " Michael Tretter
                   ` (5 subsequent siblings)
  7 siblings, 0 replies; 15+ messages in thread
From: Michael Tretter @ 2019-09-06 13:20 UTC (permalink / raw)
  To: barebox; +Cc: Michael Tretter

The devicetree overlay support is based on the Linux driver for device
tree overlays, but many features that are not required in Barebox are
left out.

Unlike Linux, which applies the overlay to the live devicetree, Barebox
registers a fixup for the overlay which is applied with other fixups to
whatever tree is fixed. This is necessary to apply the overlay to
devicetrees that are passed to Linux, which might differ from the
devicetree that is currently live in Barebox.

Signed-off-by: Michael Tretter <m.tretter@pengutronix.de>

---
Changelog:

v1->v2:
- export function for applying a device tree overlay
- define pr_fmt for overlay and resolver
- remove useless notifier.h
- document ownership of overlay memory
---
 drivers/of/Kconfig    |   9 ++
 drivers/of/Makefile   |   1 +
 drivers/of/overlay.c  | 209 +++++++++++++++++++++++++++++++
 drivers/of/resolver.c | 279 ++++++++++++++++++++++++++++++++++++++++++
 include/of.h          |  27 ++++
 5 files changed, 525 insertions(+)
 create mode 100644 drivers/of/overlay.c
 create mode 100644 drivers/of/resolver.c

diff --git a/drivers/of/Kconfig b/drivers/of/Kconfig
index 24cf4465a8..1bb6639c5a 100644
--- a/drivers/of/Kconfig
+++ b/drivers/of/Kconfig
@@ -50,3 +50,12 @@ config OF_BAREBOX_ENV_IN_FS
 	help
 	  Allow the devie tree configuration of the barebox environment path
 	  to specify a file in filesystem, which will be mounted.
+
+config OF_OVERLAY
+	select OFTREE
+	bool "Devicetree overlays"
+	help
+	  Overlays allow to patch the devicetree. Unlike Linux, Barebox does
+	  not patch the live devicetree, but applies the overlays as fixup to
+	  the devicetree. Furthermore, overlays cannot be removed after they
+	  have been applied.
diff --git a/drivers/of/Makefile b/drivers/of/Makefile
index ec43870061..9c6f8de814 100644
--- a/drivers/of/Makefile
+++ b/drivers/of/Makefile
@@ -6,3 +6,4 @@ obj-y += partition.o
 obj-y += of_net.o
 obj-$(CONFIG_MTD) += of_mtd.o
 obj-$(CONFIG_OF_BAREBOX_DRIVERS) += barebox.o
+obj-$(CONFIG_OF_OVERLAY) += overlay.o resolver.o
diff --git a/drivers/of/overlay.c b/drivers/of/overlay.c
new file mode 100644
index 0000000000..f6a0576183
--- /dev/null
+++ b/drivers/of/overlay.c
@@ -0,0 +1,209 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Functions for working with device tree overlays
+ *
+ * Copyright (C) 2012 Pantelis Antoniou <panto@antoniou-consulting.com>
+ * Copyright (C) 2012 Texas Instruments Inc.
+ * Copyright (C) 2019 Pengutronix, Michael Tretter <m.tretter@pengutronix.de>
+ */
+#define pr_fmt(fmt) "of_overlay: " fmt
+
+#include <common.h>
+#include <of.h>
+#include <errno.h>
+
+static struct device_node *find_target(struct device_node *root,
+				       struct device_node *fragment)
+{
+	struct device_node *node;
+	const char *path;
+	u32 phandle;
+	int ret;
+
+	ret = of_property_read_u32(fragment, "target", &phandle);
+	if (!ret) {
+		node = of_find_node_by_phandle_from(phandle, root);
+		if (!node)
+			pr_err("fragment %pOF: phandle 0x%x not found\n",
+			       fragment, phandle);
+		return node;
+	}
+
+	ret = of_property_read_string(fragment, "target-path", &path);
+	if (!ret) {
+		node = of_find_node_by_path_from(root, path);
+		if (!node)
+			pr_err("fragment %pOF: path '%s' not found\n",
+			       fragment, path);
+		return node;
+	}
+
+	pr_err("fragment %pOF: no target property\n", fragment);
+
+	return NULL;
+}
+
+static int of_overlay_apply(struct device_node *target,
+			    const struct device_node *overlay)
+{
+	struct device_node *child;
+	struct device_node *target_child;
+	struct property *prop;
+	int err;
+
+	if (target == NULL || overlay == NULL)
+		return -EINVAL;
+
+	list_for_each_entry(prop, &overlay->properties, list) {
+		if (of_prop_cmp(prop->name, "name") == 0)
+			continue;
+
+		err = of_set_property(target, prop->name, prop->value,
+				      prop->length, true);
+		if (err)
+			return err;
+	}
+
+	for_each_child_of_node(overlay, child) {
+		target_child = of_get_child_by_name(target, child->name);
+		if (!target_child)
+			target_child = of_new_node(target, child->name);
+		if (!target_child)
+			return -ENOMEM;
+
+		err = of_overlay_apply(target_child, child);
+		if (err)
+			return err;
+	}
+
+	return 0;
+}
+
+static char *of_overlay_fix_path(struct device_node *root,
+				 struct device_node *overlay, const char *path)
+{
+	struct device_node *fragment;
+	struct device_node *target;
+	const char *path_tail;
+	const char *prefix;
+
+	fragment = of_find_node_by_path_from(overlay, path);
+	while ((fragment = of_get_parent(fragment)) != NULL) {
+		if (of_get_child_by_name(fragment, "__overlay__"))
+			break;
+	}
+	if (!fragment)
+		return NULL;
+
+	target = find_target(root, fragment);
+	if (!target)
+		return NULL;
+
+	prefix = of_get_child_by_name(fragment, "__overlay__")->full_name;
+	path_tail = path + strlen(prefix);
+
+	return basprintf("%s%s", target->full_name, path_tail);
+}
+
+static int of_overlay_apply_symbols(struct device_node *root,
+				    struct device_node *overlay)
+{
+	const char *old_path;
+	char *new_path;
+	struct property *prop;
+	struct device_node *root_symbols;
+	struct device_node *overlay_symbols;
+
+	root_symbols = of_get_child_by_name(root, "__symbols__");
+	if (!root_symbols)
+		return -EINVAL;
+
+	overlay_symbols = of_get_child_by_name(overlay, "__symbols__");
+	if (!overlay_symbols)
+		return -EINVAL;
+
+	list_for_each_entry(prop, &overlay_symbols->properties, list) {
+		if (of_prop_cmp(prop->name, "name") == 0)
+			continue;
+
+		old_path = of_property_get_value(prop);
+		new_path = of_overlay_fix_path(root, overlay, old_path);
+
+		pr_debug("add symbol %s with new path %s\n",
+			 prop->name, new_path);
+		of_property_write_string(root_symbols, prop->name, new_path);
+	}
+
+	return 0;
+}
+
+static int of_overlay_apply_fragment(struct device_node *root,
+				     struct device_node *fragment)
+{
+	struct device_node *target;
+	struct device_node *overlay;
+
+	overlay = of_get_child_by_name(fragment, "__overlay__");
+	if (!overlay)
+		return 0;
+
+	target = find_target(root, fragment);
+	if (!target)
+		return -EINVAL;
+
+	return of_overlay_apply(target, overlay);
+}
+
+/**
+ * Apply the overlay on the passed devicetree root
+ * @root: the devicetree onto which the overlay will be applied
+ * @overlay: the devicetree to apply as an overlay
+ */
+int of_overlay_apply_tree(struct device_node *root,
+			  struct device_node *overlay)
+{
+	struct device_node *resolved;
+	struct device_node *fragment;
+	int err;
+
+	resolved = of_resolve_phandles(root, overlay);
+	if (!resolved)
+		return -EINVAL;
+
+	/* Copy symbols from resolved overlay to base device tree */
+	err = of_overlay_apply_symbols(root, resolved);
+	if (err)
+		pr_warn("failed to copy symbols from overlay");
+
+	/* Copy nodes and properties from resolved overlay to root */
+	for_each_child_of_node(resolved, fragment) {
+		err = of_overlay_apply_fragment(root, fragment);
+		if (err)
+			pr_warn("failed to apply %s", fragment->name);
+	}
+
+	of_delete_node(resolved);
+
+	return err;
+}
+
+static int of_overlay_fixup(struct device_node *root, void *data)
+{
+	struct device_node *overlay = data;
+
+	return of_overlay_apply_tree(root, overlay);
+}
+
+/**
+ * Register a devicetree overlay
+ *
+ * The overlay is not applied to the live device tree, but registered as fixup
+ * for the fixed up device tree. Therefore, drivers relying on the overlay
+ * must use the fixed device tree.
+ *
+ * The fixup takes ownership of the overlay.
+ */
+int of_register_overlay(struct device_node *overlay)
+{
+	return of_register_fixup(of_overlay_fixup, overlay);
+}
diff --git a/drivers/of/resolver.c b/drivers/of/resolver.c
new file mode 100644
index 0000000000..9107c1fbb6
--- /dev/null
+++ b/drivers/of/resolver.c
@@ -0,0 +1,279 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Functions for dealing with DT resolution
+ *
+ * Copyright (C) 2012 Pantelis Antoniou <panto@antoniou-consulting.com>
+ * Copyright (C) 2012 Texas Instruments Inc.
+ * Copyright (C) 2019 Pengutronix, Michael Tretter <m.tretter@pengutronix.de>
+ */
+#define pr_fmt(fmt) "of_resolver: " fmt
+
+#include <common.h>
+#include <of.h>
+#include <errno.h>
+
+/**
+ * Recursively update phandles in overlay by adding delta
+ */
+static void adjust_overlay_phandles(struct device_node *overlay, int delta)
+{
+	struct device_node *child;
+	struct property *prop;
+
+	if (overlay->phandle != 0)
+		overlay->phandle += delta;
+
+	list_for_each_entry(prop, &overlay->properties, list) {
+		if (of_prop_cmp(prop->name, "phandle") != 0 &&
+		    of_prop_cmp(prop->name, "linux,phandle") != 0)
+			continue;
+		if (prop->length < 4)
+			continue;
+
+		be32_add_cpu(prop->value, delta);
+	}
+
+	for_each_child_of_node(overlay, child)
+		adjust_overlay_phandles(child, delta);
+}
+
+/**
+ * Update all unresolved phandles in the overlay using prop_fixup
+ *
+ * prop_fixup contains a list of tuples of path:property_name:offset, each of
+ * which refers to a property that is phandle to a node in the base
+ * devicetree.
+ */
+static int update_usages_of_a_phandle_reference(struct device_node *overlay,
+						struct property *prop_fixup,
+						phandle phandle)
+{
+	struct device_node *refnode;
+	struct property *prop;
+	char *value, *cur, *end, *node_path, *prop_name, *s;
+	int offset, len;
+	int err = 0;
+
+	pr_debug("resolve references to %s to phandle 0x%x\n",
+		 prop_fixup->name, phandle);
+
+	value = kmemdup(prop_fixup->value, prop_fixup->length, GFP_KERNEL);
+	if (!value)
+		return -ENOMEM;
+
+	end = value + prop_fixup->length;
+	for (cur = value; cur < end; cur += len + 1) {
+		len = strlen(cur);
+
+		node_path = cur;
+		s = strchr(cur, ':');
+		if (!s) {
+			err = -EINVAL;
+			goto err_fail;
+		}
+		*s++ = '\0';
+
+		prop_name = s;
+		s = strchr(s, ':');
+		if (!s) {
+			err = -EINVAL;
+			goto err_fail;
+		}
+		*s++ = '\0';
+
+		err = kstrtoint(s, 10, &offset);
+		if (err)
+			goto err_fail;
+
+		refnode = of_find_node_by_path_from(overlay, node_path);
+		if (!refnode)
+			continue;
+
+		prop = of_find_property(refnode, prop_name, NULL);
+		if (!prop) {
+			err = -ENOENT;
+			goto err_fail;
+		}
+
+		if (offset < 0 || offset + sizeof(__be32) > prop->length) {
+			err = -EINVAL;
+			goto err_fail;
+		}
+
+		*(__be32 *)(prop->value + offset) = cpu_to_be32(phandle);
+	}
+
+err_fail:
+	kfree(value);
+
+	if (err)
+		pr_debug("failed to resolve references to %s\n",
+			 prop_fixup->name);
+
+	return err;
+}
+
+/*
+ * Adjust the local phandle references by the given phandle delta.
+ *
+ * Subtree @local_fixups, which is overlay node __local_fixups__,
+ * mirrors the fragment node structure at the root of the overlay.
+ *
+ * For each property in the fragments that contains a phandle reference,
+ * @local_fixups has a property of the same name that contains a list
+ * of offsets of the phandle reference(s) within the respective property
+ * value(s).  The values at these offsets will be fixed up.
+ */
+static int adjust_local_phandle_references(struct device_node *local_fixups,
+		struct device_node *overlay, int phandle_delta)
+{
+	struct device_node *child, *overlay_child;
+	struct property *prop_fix, *prop;
+	int err, i, count;
+	unsigned int off;
+
+	if (!local_fixups)
+		return 0;
+
+	list_for_each_entry(prop_fix, &local_fixups->properties, list) {
+		if (!of_prop_cmp(prop_fix->name, "name") ||
+		    !of_prop_cmp(prop_fix->name, "phandle") ||
+		    !of_prop_cmp(prop_fix->name, "linux,phandle"))
+			continue;
+
+		if ((prop_fix->length % sizeof(__be32)) != 0 ||
+		    prop_fix->length == 0)
+			return -EINVAL;
+		count = prop_fix->length / sizeof(__be32);
+
+		prop = of_find_property(overlay, prop_fix->name, NULL);
+		if (!prop)
+			return -EINVAL;
+
+		for (i = 0; i < count; i++) {
+			off = be32_to_cpu(((__be32 *)prop_fix->value)[i]);
+			if ((off + sizeof(__be32)) > prop->length)
+				return -EINVAL;
+
+			be32_add_cpu(prop->value + off, phandle_delta);
+		}
+	}
+
+	for_each_child_of_node(local_fixups, child) {
+		for_each_child_of_node(overlay, overlay_child)
+			if (!of_node_cmp(child->name, overlay_child->name))
+				break;
+		if (!overlay_child)
+			return -EINVAL;
+
+		err = adjust_local_phandle_references(child, overlay_child,
+				phandle_delta);
+		if (err)
+			return err;
+	}
+
+	return 0;
+}
+
+/**
+ * of_resolve_phandles - Resolve phandles in overlay based on root
+ *
+ * Rename phandles in overlay to avoid conflicts with the base devicetree and
+ * replace all phandles in the overlay with their renamed versions. Resolve
+ * phandles referring to nodes in the base devicetree with the phandle from
+ * the base devicetree.
+ *
+ * Returns a new device_node with resolved phandles which must be deleted by
+ * the caller of this function.
+ */
+struct device_node *of_resolve_phandles(struct device_node *root,
+					const struct device_node *overlay)
+{
+	struct device_node *result;
+	struct device_node *local_fixups;
+	struct device_node *refnode;
+	struct device_node *symbols;
+	struct device_node *overlay_fixups;
+	struct property *prop;
+	const char *refpath;
+	phandle delta;
+	int err;
+
+	result = of_copy_node(NULL, overlay);
+	if (!result)
+		return NULL;
+
+	delta = of_get_tree_max_phandle(root) + 1;
+
+	/*
+	 * Rename the phandles in the devicetree overlay to prevent conflicts
+	 * with the phandles in the base devicetree.
+	 */
+	adjust_overlay_phandles(result, delta);
+
+	/*
+	 * __local_fixups__ contains all locations in the overlay that refer
+	 * to a phandle defined in the overlay. We must update the references,
+	 * because we just adjusted the definitions.
+	 */
+	local_fixups = of_find_node_by_name(result, "__local_fixups__");
+	err = adjust_local_phandle_references(local_fixups, result, delta);
+	if (err) {
+		pr_err("failed to fix phandles in overlay\n");
+		goto err;
+	}
+
+	/*
+	 * __fixups__ contains all locations in the overlay that refer to a
+	 * phandle that is not defined in the overlay and should be defined in
+	 * the base device tree. We must update the references, because they
+	 * are otherwise undefined.
+	 */
+	overlay_fixups = of_find_node_by_name(result, "__fixups__");
+	if (!overlay_fixups) {
+		pr_debug("overlay does not contain phandles to base devicetree\n");
+		goto out;
+	}
+
+	symbols = of_find_node_by_path_from(root, "/__symbols__");
+	if (!symbols) {
+		pr_err("__symbols__ missing from base devicetree\n");
+		goto err;
+	}
+
+	list_for_each_entry(prop, &overlay_fixups->properties, list) {
+		if (!of_prop_cmp(prop->name, "name"))
+			continue;
+
+		err = of_property_read_string(symbols, prop->name, &refpath);
+		if (err) {
+			pr_err("cannot find node %s in base devicetree\n",
+			       prop->name);
+			goto err;
+		}
+
+		refnode = of_find_node_by_path_from(root, refpath);
+		if (!refnode) {
+			pr_err("cannot find path %s in base devicetree\n",
+			       refpath);
+			err = -EINVAL;
+			goto err;
+		}
+
+		err = update_usages_of_a_phandle_reference(result, prop,
+							   refnode->phandle);
+		if (err) {
+			pr_err("failed to update phandles for %s in overlay",
+			       prop->name);
+			goto err;
+		}
+	}
+
+out:
+	return result;
+err:
+	of_delete_node(result);
+
+	return NULL;
+
+}
diff --git a/include/of.h b/include/of.h
index b5f54dd4e5..1483c22db1 100644
--- a/include/of.h
+++ b/include/of.h
@@ -870,4 +870,31 @@ static inline struct device_node *of_find_root_node(struct device_node *node)
 
 	return node;
 }
+
+#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_register_overlay(struct device_node *overlay);
+#else
+static inline struct device_node *of_resolve_phandles(struct device_node *root,
+					const struct device_node *overlay)
+{
+	return NULL;
+}
+
+static inline int of_overlay_apply_tree(struct device_node *root,
+					struct device_node *overlay)
+{
+	return -ENOSYS;
+}
+
+static inline int of_register_overlay(struct device_node *overlay)
+{
+	return -ENOSYS;
+}
+
+#endif
+
 #endif /* __OF_H */
-- 
2.20.1


_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox

^ permalink raw reply	[flat|nested] 15+ messages in thread

* [PATCH v2 3/7] blspec: add support for devicetree overlays
  2019-09-06 13:20 [PATCH v2 0/7] Device Tree Overlay Support Michael Tretter
  2019-09-06 13:20 ` [PATCH v2 1/7] dtc: add -@ option to enable __symbols__ Michael Tretter
  2019-09-06 13:20 ` [PATCH v2 2/7] of: add support for devicetree overlays Michael Tretter
@ 2019-09-06 13:20 ` Michael Tretter
  2019-09-06 13:20 ` [PATCH v2 4/7] of: add iterator for overlays Michael Tretter
                   ` (4 subsequent siblings)
  7 siblings, 0 replies; 15+ messages in thread
From: Michael Tretter @ 2019-09-06 13:20 UTC (permalink / raw)
  To: barebox; +Cc: Michael Tretter

Read the devicetree-overlay property from the blspec entry and register
the overlays when booting the blspec entry.

Do not fail the boot if an overlay cannot be loaded, because if Linux
fails to boot without an overlay, the base device tree is broken.

Signed-off-by: Michael Tretter <m.tretter@pengutronix.de>

---
Changelog:

v1->v2:
- fix error handling in blspec handling
---
 Documentation/user/booting-linux.rst |  4 ++
 common/blspec.c                      | 61 ++++++++++++++++++++++++++++
 2 files changed, 65 insertions(+)

diff --git a/Documentation/user/booting-linux.rst b/Documentation/user/booting-linux.rst
index 437f4e80ca..12cd505e71 100644
--- a/Documentation/user/booting-linux.rst
+++ b/Documentation/user/booting-linux.rst
@@ -232,6 +232,10 @@ device where the entry is found on. This makes it possible to use the same rootf
 image on different devices without having to specify a different root= option each
 time.
 
+Additionally to the options defined in the original spec, Barebox has the
+``devicetree-overlay`` option. This is a string value that refer to overlays
+that will be applied to the device tree before passing it to Linux.
+
 Network boot
 ------------
 
diff --git a/common/blspec.c b/common/blspec.c
index 66e5033e35..fbba2fc78c 100644
--- a/common/blspec.c
+++ b/common/blspec.c
@@ -42,6 +42,62 @@ int blspec_entry_var_set(struct blspec_entry *entry, const char *name,
 			val ? strlen(val) + 1 : 0, 1);
 }
 
+static int blspec_apply_oftree_overlay(char *file, const char *abspath,
+				       int dryrun)
+{
+	int ret = 0;
+	struct fdt_header *fdt;
+	struct device_node *overlay;
+	char *path;
+
+	path = basprintf("%s/%s", abspath, file);
+
+	fdt = read_file(path, NULL);
+	if (!fdt) {
+		pr_warn("unable to read \"%s\"\n", path);
+		ret = -EINVAL;
+		goto out;
+	}
+
+	overlay = of_unflatten_dtb(fdt);
+	free(fdt);
+	if (IS_ERR(overlay)) {
+		ret = PTR_ERR(overlay);
+		goto out;
+	}
+
+	if (dryrun) {
+		pr_info("dry run: skip overlay %s\n", path);
+		of_delete_node(overlay);
+		goto out;
+	}
+
+	ret = of_register_overlay(overlay);
+	if (ret) {
+		pr_warn("cannot register devicetree overlay \"%s\"\n", path);
+		of_delete_node(overlay);
+	}
+
+out:
+	free(path);
+
+	return ret;
+}
+
+static void blspec_apply_oftree_overlays(const char *overlays,
+					 const char *abspath, int dryrun)
+{
+	char *overlay;
+	char *sep, *freep;
+
+	sep = freep = xstrdup(overlays);
+
+	while ((overlay = strsep(&sep, " ")))
+		blspec_apply_oftree_overlay(overlay, abspath, dryrun);
+
+	free(freep);
+}
+
 /*
  * blspec_boot - boot an entry
  *
@@ -54,6 +110,7 @@ static int blspec_boot(struct bootentry *be, int verbose, int dryrun)
 	struct blspec_entry *entry = container_of(be, struct blspec_entry, entry);
 	int ret;
 	const char *abspath, *devicetree, *options, *initrd, *linuximage;
+	const char *overlays;
 	const char *appendroot;
 	struct bootm_data data = {
 		.initrd_address = UIMAGE_INVALID_ADDRESS,
@@ -73,6 +130,7 @@ static int blspec_boot(struct bootentry *be, int verbose, int dryrun)
 	initrd = blspec_entry_var_get(entry, "initrd");
 	options = blspec_entry_var_get(entry, "options");
 	linuximage = blspec_entry_var_get(entry, "linux");
+	overlays = blspec_entry_var_get(entry, "devicetree-overlay");
 
 	if (entry->rootpath)
 		abspath = entry->rootpath;
@@ -92,6 +150,9 @@ static int blspec_boot(struct bootentry *be, int verbose, int dryrun)
 		}
 	}
 
+	if (overlays)
+		blspec_apply_oftree_overlays(overlays, abspath, dryrun);
+
 	if (initrd)
 		data.initrd_file = basprintf("%s/%s", abspath, initrd);
 
-- 
2.20.1


_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox

^ permalink raw reply	[flat|nested] 15+ messages in thread

* [PATCH v2 4/7] of: add iterator for overlays
  2019-09-06 13:20 [PATCH v2 0/7] Device Tree Overlay Support Michael Tretter
                   ` (2 preceding siblings ...)
  2019-09-06 13:20 ` [PATCH v2 3/7] blspec: " Michael Tretter
@ 2019-09-06 13:20 ` Michael Tretter
  2019-09-06 13:20 ` [PATCH v2 5/7] firmware: add support to load firmware from dt overlay Michael Tretter
                   ` (3 subsequent siblings)
  7 siblings, 0 replies; 15+ messages in thread
From: Michael Tretter @ 2019-09-06 13:20 UTC (permalink / raw)
  To: barebox; +Cc: Michael Tretter

Device tree overlays (the dto files) may contain multiple fragments for
different target nodes. Each fragment contains a __overlay__ node that
is applied to target node specified in the fragment.

Add a helper to call a function for each fragment in a device tree
overlay to avoid having device tree overlay internal information in
other modules.

Signed-off-by: Michael Tretter <m.tretter@pengutronix.de>

---
Changelog:

v1->v2:
- add static inline for function stub
---
 drivers/of/overlay.c | 45 ++++++++++++++++++++++++++++++++++++++++++++
 include/of.h         | 13 +++++++++++++
 2 files changed, 58 insertions(+)

diff --git a/drivers/of/overlay.c b/drivers/of/overlay.c
index f6a0576183..abfb3df9dc 100644
--- a/drivers/of/overlay.c
+++ b/drivers/of/overlay.c
@@ -194,6 +194,51 @@ static int of_overlay_fixup(struct device_node *root, void *data)
 	return of_overlay_apply_tree(root, overlay);
 }
 
+/**
+ * Iterate the overlay and call process for each fragment
+ *
+ * If process() fails for any fragment, the function will stop to process
+ * other fragments and return the error of the failed process() call.
+ */
+int of_process_overlay(struct device_node *root,
+		       struct device_node *overlay,
+		       int (*process)(struct device_node *target,
+				      struct device_node *overlay, void *data),
+		       void *data)
+{
+	struct device_node *resolved;
+	struct device_node *fragment;
+	int err = 0;
+
+	resolved = of_resolve_phandles(root, overlay);
+	if (!resolved)
+		return -EINVAL;
+
+	for_each_child_of_node(resolved, fragment) {
+		struct device_node *ovl;
+		struct device_node *target;
+
+		ovl = of_get_child_by_name(fragment, "__overlay__");
+		if (!ovl)
+			continue;
+
+		target = find_target(root, fragment);
+		if (!target)
+			continue;
+
+		err = process(target, ovl, data);
+		if (err) {
+			pr_warn("failed to process %s\n", fragment->name);
+			goto out;
+		}
+	}
+
+out:
+	of_delete_node(resolved);
+
+	return err;
+}
+
 /**
  * Register a devicetree overlay
  *
diff --git a/include/of.h b/include/of.h
index 1483c22db1..06dc9f61a5 100644
--- a/include/of.h
+++ b/include/of.h
@@ -877,6 +877,11 @@ struct device_node *of_resolve_phandles(struct device_node *root,
 int of_overlay_apply_tree(struct device_node *root,
 			  struct device_node *overlay);
 int of_register_overlay(struct device_node *overlay);
+int of_process_overlay(struct device_node *root,
+		    struct device_node *overlay,
+		    int (*process)(struct device_node *target,
+				   struct device_node *overlay, void *data),
+		    void *data);
 #else
 static inline struct device_node *of_resolve_phandles(struct device_node *root,
 					const struct device_node *overlay)
@@ -895,6 +900,14 @@ static inline int of_register_overlay(struct device_node *overlay)
 	return -ENOSYS;
 }
 
+static inline int of_process_overlay(struct device_node *root,
+				     struct device_node *overlay,
+				     int (*process)(struct device_node *target,
+						    struct device_node *overlay, void *data),
+				     void *data)
+{
+	return -ENOSYS;
+}
 #endif
 
 #endif /* __OF_H */
-- 
2.20.1


_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox

^ permalink raw reply	[flat|nested] 15+ messages in thread

* [PATCH v2 5/7] firmware: add support to load firmware from dt overlay
  2019-09-06 13:20 [PATCH v2 0/7] Device Tree Overlay Support Michael Tretter
                   ` (3 preceding siblings ...)
  2019-09-06 13:20 ` [PATCH v2 4/7] of: add iterator for overlays Michael Tretter
@ 2019-09-06 13:20 ` Michael Tretter
  2019-09-06 13:20 ` [PATCH v2 6/7] blspec: load firmware if specified in " Michael Tretter
                   ` (2 subsequent siblings)
  7 siblings, 0 replies; 15+ messages in thread
From: Michael Tretter @ 2019-09-06 13:20 UTC (permalink / raw)
  To: barebox; +Cc: Michael Tretter

fpga-region device tree nodes have the firmware-name property that
contains the file name of firmware in the firmware search path (but not
the path) that shall be loaded before the overlay is applied.

Add the firmware_load_overlay() function that accepts an overlay and a
firmware search path, finds the responsible firmware_mgr and loads the
firmware.

Signed-off-by: Michael Tretter <m.tretter@pengutronix.de>

---
Changelog:

v1->v2: none
---
 common/firmware.c  | 77 ++++++++++++++++++++++++++++++++++++++++++++++
 include/firmware.h |  3 ++
 2 files changed, 80 insertions(+)

diff --git a/common/firmware.c b/common/firmware.c
index 9d55d73e7a..d15026cf07 100644
--- a/common/firmware.c
+++ b/common/firmware.c
@@ -62,6 +62,39 @@ struct firmware_mgr *firmwaremgr_find(const char *id)
 	return NULL;
 }
 
+/*
+ * firmwaremgr_find_by_node - find a firmware device handler
+ *
+ * Find a firmware device handler using the device node of the firmware
+ * handler. This allows to retrieve the firmware handler with a phandle from
+ * the device tree.
+ */
+struct firmware_mgr *firmwaremgr_find_by_node(const struct device_node *np)
+{
+	struct firmware_mgr *mgr;
+
+	list_for_each_entry(mgr, &firmwaremgr_list, list)
+		if (mgr->handler->dev->parent->device_node == np)
+			return mgr;
+
+	return NULL;
+}
+
+static struct firmware_mgr *of_node_get_mgr(const struct device_node *np)
+{
+	struct device_node *mgr_node;
+
+	do {
+		if (of_device_is_compatible(np, "fpga-region")) {
+			mgr_node = of_parse_phandle(np, "fpga-mgr", 0);
+			if (mgr_node)
+				return firmwaremgr_find_by_node(mgr_node);
+		}
+	} while ((np = of_get_parent(np)) != NULL);
+
+	return NULL;
+}
+
 /*
  * firmwaremgr_list_handlers - list registered firmware device handlers
  *                             in pretty format
@@ -153,6 +186,40 @@ static int firmware_close(struct cdev *cdev)
 	return 0;
 }
 
+struct overlay_info {
+	const char *firmware_path;
+};
+
+static int load_firmware(struct device_node *target,
+			 struct device_node *fragment, void *data)
+{
+	struct overlay_info *info = data;
+	const char *firmware_name;
+	const char *firmware_path = info->firmware_path;
+	char *firmware;
+	int err;
+	struct firmware_mgr *mgr;
+
+	err = of_property_read_string(fragment,
+				      "firmware-name", &firmware_name);
+	if (err)
+		return 0;
+
+	mgr = of_node_get_mgr(target);
+	if (!mgr)
+		return -EINVAL;
+
+	firmware = basprintf("%s/%s", firmware_path, firmware_name);
+	if (!firmware)
+		return -ENOMEM;
+
+	err = firmwaremgr_load_file(mgr, firmware);
+
+	free(firmware);
+
+	return err;
+}
+
 static struct cdev_operations firmware_ops = {
 	.open = firmware_open,
 	.write = firmware_write,
@@ -210,3 +277,13 @@ int firmwaremgr_load_file(struct firmware_mgr *mgr, const char *firmware)
 
 	return ret;
 }
+
+int firmware_load_overlay(struct device_node *overlay, const char *path)
+{
+	struct overlay_info info = {
+		.firmware_path = path,
+	};
+
+	return of_process_overlay(of_get_root_node(), overlay,
+				  load_firmware, &info);
+}
diff --git a/include/firmware.h b/include/firmware.h
index 284e0f9705..a3c2f9fe4a 100644
--- a/include/firmware.h
+++ b/include/firmware.h
@@ -34,11 +34,14 @@ struct firmware_mgr;
 int firmwaremgr_register(struct firmware_handler *);
 
 struct firmware_mgr *firmwaremgr_find(const char *);
+struct firmware_mgr *firmwaremgr_find_by_node(const struct device_node *np);
 
 void firmwaremgr_list_handlers(void);
 
 int firmwaremgr_load_file(struct firmware_mgr *, const char *path);
 
+int firmware_load_overlay(struct device_node *overlay, const char *path);
+
 #define get_builtin_firmware(name, start, size) \
 	{							\
 		extern char _fw_##name##_start[];		\
-- 
2.20.1


_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox

^ permalink raw reply	[flat|nested] 15+ messages in thread

* [PATCH v2 6/7] blspec: load firmware if specified in dt overlay
  2019-09-06 13:20 [PATCH v2 0/7] Device Tree Overlay Support Michael Tretter
                   ` (4 preceding siblings ...)
  2019-09-06 13:20 ` [PATCH v2 5/7] firmware: add support to load firmware from dt overlay Michael Tretter
@ 2019-09-06 13:20 ` Michael Tretter
  2019-09-11  7:53   ` Ahmad Fatoum
  2019-09-06 13:20 ` [PATCH v2 7/7] commands: add of_overlay command for device tree overlays Michael Tretter
  2019-09-09  8:57 ` [PATCH v2 0/7] Device Tree Overlay Support Sascha Hauer
  7 siblings, 1 reply; 15+ messages in thread
From: Michael Tretter @ 2019-09-06 13:20 UTC (permalink / raw)
  To: barebox; +Cc: Michael Tretter

If a device tree overlay referenced by the blspec depends on firmware,
try to load the firmware from the default Linux firmware search path
/lib/firmware in the about to be started rootfs.

Signed-off-by: Michael Tretter <m.tretter@pengutronix.de>

---
Changelog:

v1->v2: none
---
 common/blspec.c | 16 ++++++++++++++++
 1 file changed, 16 insertions(+)

diff --git a/common/blspec.c b/common/blspec.c
index fbba2fc78c..e733bf1188 100644
--- a/common/blspec.c
+++ b/common/blspec.c
@@ -14,6 +14,7 @@
 
 #include <environment.h>
 #include <globalvar.h>
+#include <firmware.h>
 #include <readkey.h>
 #include <common.h>
 #include <driver.h>
@@ -49,6 +50,7 @@ static int blspec_apply_oftree_overlay(char *file, const char *abspath,
 	struct fdt_header *fdt;
 	struct device_node *overlay;
 	char *path;
+	char *firmware_path;
 
 	path = basprintf("%s/%s", abspath, file);
 
@@ -72,6 +74,20 @@ static int blspec_apply_oftree_overlay(char *file, const char *abspath,
 		goto out;
 	}
 
+	/*
+	 * Unfortunately the device tree overlay contains only the filename of
+	 * the firmware and relies on the firmware search paths to find the
+	 * actual file. Use /lib/firmware in the Linux root directory and hope
+	 * for the best.
+	 */
+	firmware_path = basprintf("%s/%s", abspath, "/lib/firmware");
+	ret = firmware_load_overlay(overlay, firmware_path);
+	free(firmware_path);
+	if (ret) {
+		of_delete_node(overlay);
+		goto out;
+	}
+
 	ret = of_register_overlay(overlay);
 	if (ret) {
 		pr_warn("cannot register devicetree overlay \"%s\"\n", path);
-- 
2.20.1


_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox

^ permalink raw reply	[flat|nested] 15+ messages in thread

* [PATCH v2 7/7] commands: add of_overlay command for device tree overlays
  2019-09-06 13:20 [PATCH v2 0/7] Device Tree Overlay Support Michael Tretter
                   ` (5 preceding siblings ...)
  2019-09-06 13:20 ` [PATCH v2 6/7] blspec: load firmware if specified in " Michael Tretter
@ 2019-09-06 13:20 ` Michael Tretter
  2019-09-11  7:55   ` Ahmad Fatoum
  2019-09-09  8:57 ` [PATCH v2 0/7] Device Tree Overlay Support Sascha Hauer
  7 siblings, 1 reply; 15+ messages in thread
From: Michael Tretter @ 2019-09-06 13:20 UTC (permalink / raw)
  To: barebox; +Cc: Michael Tretter

Add a new command "of_overlay" for applying device tree overlays,
because it does not really fit into any other device tree related
command and would create a mess with the command options.

Signed-off-by: Michael Tretter <m.tretter@pengutronix.de>

---
Changelog:

v1->v2: none
---
 commands/Kconfig      | 12 ++++++
 commands/Makefile     |  1 +
 commands/of_overlay.c | 89 +++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 102 insertions(+)
 create mode 100644 commands/of_overlay.c

diff --git a/commands/Kconfig b/commands/Kconfig
index 039fd7d1ac..01d82031ad 100644
--- a/commands/Kconfig
+++ b/commands/Kconfig
@@ -2088,6 +2088,18 @@ config CMD_OF_FIXUP_STATUS
 	  Register a fixup to enable or disable a device tree node.
 	  Nodes are enabled on default. Disabled with -d.
 
+config CMD_OF_OVERLAY
+	tristate
+	select OFTREE
+	prompt "of_overlay"
+	help
+	  of_overlay - register device tree overlay as fixup
+
+	  Usage: of_overlay [-S path] FILE
+
+	  Options:
+		  -S path	load firmware using this search path
+
 config CMD_OFTREE
 	tristate
 	select OFTREE
diff --git a/commands/Makefile b/commands/Makefile
index e69fb5046f..62ad9ce2b2 100644
--- a/commands/Makefile
+++ b/commands/Makefile
@@ -78,6 +78,7 @@ obj-$(CONFIG_CMD_OF_NODE)	+= of_node.o
 obj-$(CONFIG_CMD_OF_DUMP)	+= of_dump.o
 obj-$(CONFIG_CMD_OF_DISPLAY_TIMINGS)	+= of_display_timings.o
 obj-$(CONFIG_CMD_OF_FIXUP_STATUS)	+= of_fixup_status.o
+obj-$(CONFIG_CMD_OF_OVERLAY)	+= of_overlay.o
 obj-$(CONFIG_CMD_MAGICVAR)	+= magicvar.o
 obj-$(CONFIG_CMD_IOMEM)		+= iomemport.o
 obj-$(CONFIG_CMD_LINUX_EXEC)	+= linux_exec.o
diff --git a/commands/of_overlay.c b/commands/of_overlay.c
new file mode 100644
index 0000000000..f929443bfe
--- /dev/null
+++ b/commands/of_overlay.c
@@ -0,0 +1,89 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (c) 2019 Michael Tretter <m.tretter@pengutronix.de>, Pengutronix
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#include <command.h>
+#include <common.h>
+#include <environment.h>
+#include <fdt.h>
+#include <firmware.h>
+#include <fs.h>
+#include <getopt.h>
+#include <libfile.h>
+#include <of.h>
+
+static int do_of_overlay(int argc, char *argv[])
+{
+	int opt, ret;
+	struct fdt_header *fdt;
+	struct device_node *overlay;
+	const char *search_path = NULL;
+
+	while ((opt = getopt(argc, argv, "S:")) > 0) {
+		switch (opt) {
+		case 'S':
+			search_path = optarg;
+			break;
+		default:
+			return COMMAND_ERROR_USAGE;
+		}
+	}
+
+	if (argc != optind + 1)
+		return COMMAND_ERROR_USAGE;
+
+	fdt = read_file(argv[optind], NULL);
+	if (!fdt) {
+		printf("cannot read %s\n", argv[optind]);
+		return 1;
+	}
+
+	overlay = of_unflatten_dtb(fdt);
+	free(fdt);
+	if (IS_ERR(overlay))
+		return PTR_ERR(overlay);
+
+	if (search_path) {
+		ret = firmware_load_overlay(overlay, search_path);
+		if (ret)
+			goto err;
+	}
+
+	ret = of_register_overlay(overlay);
+	if (ret) {
+		printf("cannot apply oftree overlay: %s\n", strerror(-ret));
+		goto err;
+	}
+
+	return 0;
+
+err:
+	of_delete_node(overlay);
+	return ret;
+}
+
+BAREBOX_CMD_HELP_START(of_overlay)
+BAREBOX_CMD_HELP_TEXT("Options:")
+BAREBOX_CMD_HELP_OPT("-S path", "load firmware using this search path")
+BAREBOX_CMD_HELP_END
+
+BAREBOX_CMD_START(of_overlay)
+	.cmd = do_of_overlay,
+	BAREBOX_CMD_DESC("register device tree overlay as fixup")
+	BAREBOX_CMD_OPTS("[-S path] FILE")
+	BAREBOX_CMD_GROUP(CMD_GRP_MISC)
+	BAREBOX_CMD_HELP(cmd_of_overlay_help)
+BAREBOX_CMD_END
-- 
2.20.1


_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [PATCH v2 0/7] Device Tree Overlay Support
  2019-09-06 13:20 [PATCH v2 0/7] Device Tree Overlay Support Michael Tretter
                   ` (6 preceding siblings ...)
  2019-09-06 13:20 ` [PATCH v2 7/7] commands: add of_overlay command for device tree overlays Michael Tretter
@ 2019-09-09  8:57 ` Sascha Hauer
  2019-09-12  6:57   ` Sascha Hauer
  7 siblings, 1 reply; 15+ messages in thread
From: Sascha Hauer @ 2019-09-09  8:57 UTC (permalink / raw)
  To: Michael Tretter; +Cc: barebox

On Fri, Sep 06, 2019 at 03:20:01PM +0200, Michael Tretter wrote:
> Hello,
> 
> This is the v2 for adding device tree overlay support to barebox.
> 
> The biggest change is the new function of_overlay_apply_tree() which accepts a
> devicetree and the root node of an overlay and applies the overlay to the
> devicetree.
> 
> Apart from that, I fixed various issues like memory leaks, useless includes,
> missing documentation, formatting of output messages, and a missing "static
> inline".
> 
> Michael

Applied, thanks

Sascha

-- 
Pengutronix e.K.                           |                             |
Industrial Linux Solutions                 | http://www.pengutronix.de/  |
Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0    |
Amtsgericht Hildesheim, HRA 2686           | Fax:   +49-5121-206917-5555 |

_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [PATCH v2 6/7] blspec: load firmware if specified in dt overlay
  2019-09-06 13:20 ` [PATCH v2 6/7] blspec: load firmware if specified in " Michael Tretter
@ 2019-09-11  7:53   ` Ahmad Fatoum
  0 siblings, 0 replies; 15+ messages in thread
From: Ahmad Fatoum @ 2019-09-11  7:53 UTC (permalink / raw)
  To: Michael Tretter, barebox

Hello Michael,

On 9/6/19 3:20 PM, Michael Tretter wrote:
> If a device tree overlay referenced by the blspec depends on firmware,
> try to load the firmware from the default Linux firmware search path
> /lib/firmware in the about to be started rootfs.

Linking barebox with CONFIG_BLSPEC, but without CONFIG_OF_OVERLAY
now fails:

./common/blspec.c:84: undefined reference to `firmware_load_overlay'

Cheers
Ahmad

> 
> Signed-off-by: Michael Tretter <m.tretter@pengutronix.de>
> 
> ---
> Changelog:
> 
> v1->v2: none
> ---
>  common/blspec.c | 16 ++++++++++++++++
>  1 file changed, 16 insertions(+)
> 
> diff --git a/common/blspec.c b/common/blspec.c
> index fbba2fc78c..e733bf1188 100644
> --- a/common/blspec.c
> +++ b/common/blspec.c
> @@ -14,6 +14,7 @@
>  
>  #include <environment.h>
>  #include <globalvar.h>
> +#include <firmware.h>
>  #include <readkey.h>
>  #include <common.h>
>  #include <driver.h>
> @@ -49,6 +50,7 @@ static int blspec_apply_oftree_overlay(char *file, const char *abspath,
>  	struct fdt_header *fdt;
>  	struct device_node *overlay;
>  	char *path;
> +	char *firmware_path;
>  
>  	path = basprintf("%s/%s", abspath, file);
>  
> @@ -72,6 +74,20 @@ static int blspec_apply_oftree_overlay(char *file, const char *abspath,
>  		goto out;
>  	}
>  
> +	/*
> +	 * Unfortunately the device tree overlay contains only the filename of
> +	 * the firmware and relies on the firmware search paths to find the
> +	 * actual file. Use /lib/firmware in the Linux root directory and hope
> +	 * for the best.
> +	 */
> +	firmware_path = basprintf("%s/%s", abspath, "/lib/firmware");
> +	ret = firmware_load_overlay(overlay, firmware_path);
> +	free(firmware_path);
> +	if (ret) {
> +		of_delete_node(overlay);
> +		goto out;
> +	}
> +
>  	ret = of_register_overlay(overlay);
>  	if (ret) {
>  		pr_warn("cannot register devicetree overlay \"%s\"\n", path);
> 

-- 
Pengutronix e.K.                           |                             |
Industrial Linux Solutions                 | http://www.pengutronix.de/  |
Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0    |
Amtsgericht Hildesheim, HRA 2686           | Fax:   +49-5121-206917-5555 |

_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [PATCH v2 7/7] commands: add of_overlay command for device tree overlays
  2019-09-06 13:20 ` [PATCH v2 7/7] commands: add of_overlay command for device tree overlays Michael Tretter
@ 2019-09-11  7:55   ` Ahmad Fatoum
  2019-09-11  8:00     ` Ahmad Fatoum
  2019-09-11  9:28     ` Michael Tretter
  0 siblings, 2 replies; 15+ messages in thread
From: Ahmad Fatoum @ 2019-09-11  7:55 UTC (permalink / raw)
  To: barebox, Michael Tretter

Hello Michael,

On 9/6/19 3:20 PM, Michael Tretter wrote:
> Add a new command "of_overlay" for applying device tree overlays,
> because it does not really fit into any other device tree related
> command and would create a mess with the command options.
> 
> Signed-off-by: Michael Tretter <m.tretter@pengutronix.de>
> 
> ---
> Changelog:
> 
> v1->v2: none
> ---
>  commands/Kconfig      | 12 ++++++
>  commands/Makefile     |  1 +
>  commands/of_overlay.c | 89 +++++++++++++++++++++++++++++++++++++++++++
>  3 files changed, 102 insertions(+)
>  create mode 100644 commands/of_overlay.c
> 
> diff --git a/commands/Kconfig b/commands/Kconfig
> index 039fd7d1ac..01d82031ad 100644
> --- a/commands/Kconfig
> +++ b/commands/Kconfig
> @@ -2088,6 +2088,18 @@ config CMD_OF_FIXUP_STATUS
>  	  Register a fixup to enable or disable a device tree node.
>  	  Nodes are enabled on default. Disabled with -d.
>  
> +config CMD_OF_OVERLAY
> +	tristate
> +	select OFTREE

This should depend or select OF_OVERLAY, otherwise:
./commands/of_overlay.c:60: undefined reference to `firmware_load_overlay'

Cheers
Ahmad

> +	prompt "of_overlay"
> +	help
> +	  of_overlay - register device tree overlay as fixup
> +
> +	  Usage: of_overlay [-S path] FILE
> +
> +	  Options:
> +		  -S path	load firmware using this search path
> +
>  config CMD_OFTREE
>  	tristate
>  	select OFTREE
> diff --git a/commands/Makefile b/commands/Makefile
> index e69fb5046f..62ad9ce2b2 100644
> --- a/commands/Makefile
> +++ b/commands/Makefile
> @@ -78,6 +78,7 @@ obj-$(CONFIG_CMD_OF_NODE)	+= of_node.o
>  obj-$(CONFIG_CMD_OF_DUMP)	+= of_dump.o
>  obj-$(CONFIG_CMD_OF_DISPLAY_TIMINGS)	+= of_display_timings.o
>  obj-$(CONFIG_CMD_OF_FIXUP_STATUS)	+= of_fixup_status.o
> +obj-$(CONFIG_CMD_OF_OVERLAY)	+= of_overlay.o
>  obj-$(CONFIG_CMD_MAGICVAR)	+= magicvar.o
>  obj-$(CONFIG_CMD_IOMEM)		+= iomemport.o
>  obj-$(CONFIG_CMD_LINUX_EXEC)	+= linux_exec.o
> diff --git a/commands/of_overlay.c b/commands/of_overlay.c
> new file mode 100644
> index 0000000000..f929443bfe
> --- /dev/null
> +++ b/commands/of_overlay.c
> @@ -0,0 +1,89 @@
> +// SPDX-License-Identifier: GPL-2.0
> +/*
> + * Copyright (c) 2019 Michael Tretter <m.tretter@pengutronix.de>, Pengutronix
> + *
> + * See file CREDITS for list of people who contributed to this
> + * project.
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License version 2
> + * as published by the Free Software Foundation.
> + *
> + * This program is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
> + * GNU General Public License for more details.
> + */
> +
> +#include <command.h>
> +#include <common.h>
> +#include <environment.h>
> +#include <fdt.h>
> +#include <firmware.h>
> +#include <fs.h>
> +#include <getopt.h>
> +#include <libfile.h>
> +#include <of.h>
> +
> +static int do_of_overlay(int argc, char *argv[])
> +{
> +	int opt, ret;
> +	struct fdt_header *fdt;
> +	struct device_node *overlay;
> +	const char *search_path = NULL;
> +
> +	while ((opt = getopt(argc, argv, "S:")) > 0) {
> +		switch (opt) {
> +		case 'S':
> +			search_path = optarg;
> +			break;
> +		default:
> +			return COMMAND_ERROR_USAGE;
> +		}
> +	}
> +
> +	if (argc != optind + 1)
> +		return COMMAND_ERROR_USAGE;
> +
> +	fdt = read_file(argv[optind], NULL);
> +	if (!fdt) {
> +		printf("cannot read %s\n", argv[optind]);
> +		return 1;
> +	}
> +
> +	overlay = of_unflatten_dtb(fdt);
> +	free(fdt);
> +	if (IS_ERR(overlay))
> +		return PTR_ERR(overlay);
> +
> +	if (search_path) {
> +		ret = firmware_load_overlay(overlay, search_path);
> +		if (ret)
> +			goto err;
> +	}
> +
> +	ret = of_register_overlay(overlay);
> +	if (ret) {
> +		printf("cannot apply oftree overlay: %s\n", strerror(-ret));
> +		goto err;
> +	}
> +
> +	return 0;
> +
> +err:
> +	of_delete_node(overlay);
> +	return ret;
> +}
> +
> +BAREBOX_CMD_HELP_START(of_overlay)
> +BAREBOX_CMD_HELP_TEXT("Options:")
> +BAREBOX_CMD_HELP_OPT("-S path", "load firmware using this search path")
> +BAREBOX_CMD_HELP_END
> +
> +BAREBOX_CMD_START(of_overlay)
> +	.cmd = do_of_overlay,
> +	BAREBOX_CMD_DESC("register device tree overlay as fixup")
> +	BAREBOX_CMD_OPTS("[-S path] FILE")
> +	BAREBOX_CMD_GROUP(CMD_GRP_MISC)
> +	BAREBOX_CMD_HELP(cmd_of_overlay_help)
> +BAREBOX_CMD_END
> 

-- 
Pengutronix e.K.                           |                             |
Industrial Linux Solutions                 | http://www.pengutronix.de/  |
Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0    |
Amtsgericht Hildesheim, HRA 2686           | Fax:   +49-5121-206917-5555 |

_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [PATCH v2 7/7] commands: add of_overlay command for device tree overlays
  2019-09-11  7:55   ` Ahmad Fatoum
@ 2019-09-11  8:00     ` Ahmad Fatoum
  2019-09-11  9:28     ` Michael Tretter
  1 sibling, 0 replies; 15+ messages in thread
From: Ahmad Fatoum @ 2019-09-11  8:00 UTC (permalink / raw)
  To: barebox, Michael Tretter


On 9/11/19 9:55 AM, Ahmad Fatoum wrote:
> Hello Michael,
> 
> On 9/6/19 3:20 PM, Michael Tretter wrote:
>> Add a new command "of_overlay" for applying device tree overlays,
>> because it does not really fit into any other device tree related
>> command and would create a mess with the command options.
>>
>> Signed-off-by: Michael Tretter <m.tretter@pengutronix.de>
>>
>> ---
>> Changelog:
>>
>> v1->v2: none
>> ---
>>  commands/Kconfig      | 12 ++++++
>>  commands/Makefile     |  1 +
>>  commands/of_overlay.c | 89 +++++++++++++++++++++++++++++++++++++++++++
>>  3 files changed, 102 insertions(+)
>>  create mode 100644 commands/of_overlay.c
>>
>> diff --git a/commands/Kconfig b/commands/Kconfig
>> index 039fd7d1ac..01d82031ad 100644
>> --- a/commands/Kconfig
>> +++ b/commands/Kconfig
>> @@ -2088,6 +2088,18 @@ config CMD_OF_FIXUP_STATUS
>>  	  Register a fixup to enable or disable a device tree node.
>>  	  Nodes are enabled on default. Disabled with -d.
>>  
>> +config CMD_OF_OVERLAY
>> +	tristate
>> +	select OFTREE
> 
> This should depend or select OF_OVERLAY

and FIRMWARE

, otherwise:
> ./commands/of_overlay.c:60: undefined reference to `firmware_load_overlay'
> 
> Cheers
> Ahmad
> 
>> +	prompt "of_overlay"
>> +	help
>> +	  of_overlay - register device tree overlay as fixup
>> +
>> +	  Usage: of_overlay [-S path] FILE
>> +
>> +	  Options:
>> +		  -S path	load firmware using this search path
>> +
>>  config CMD_OFTREE
>>  	tristate
>>  	select OFTREE
>> diff --git a/commands/Makefile b/commands/Makefile
>> index e69fb5046f..62ad9ce2b2 100644
>> --- a/commands/Makefile
>> +++ b/commands/Makefile
>> @@ -78,6 +78,7 @@ obj-$(CONFIG_CMD_OF_NODE)	+= of_node.o
>>  obj-$(CONFIG_CMD_OF_DUMP)	+= of_dump.o
>>  obj-$(CONFIG_CMD_OF_DISPLAY_TIMINGS)	+= of_display_timings.o
>>  obj-$(CONFIG_CMD_OF_FIXUP_STATUS)	+= of_fixup_status.o
>> +obj-$(CONFIG_CMD_OF_OVERLAY)	+= of_overlay.o
>>  obj-$(CONFIG_CMD_MAGICVAR)	+= magicvar.o
>>  obj-$(CONFIG_CMD_IOMEM)		+= iomemport.o
>>  obj-$(CONFIG_CMD_LINUX_EXEC)	+= linux_exec.o
>> diff --git a/commands/of_overlay.c b/commands/of_overlay.c
>> new file mode 100644
>> index 0000000000..f929443bfe
>> --- /dev/null
>> +++ b/commands/of_overlay.c
>> @@ -0,0 +1,89 @@
>> +// SPDX-License-Identifier: GPL-2.0
>> +/*
>> + * Copyright (c) 2019 Michael Tretter <m.tretter@pengutronix.de>, Pengutronix
>> + *
>> + * See file CREDITS for list of people who contributed to this
>> + * project.
>> + *
>> + * This program is free software; you can redistribute it and/or modify
>> + * it under the terms of the GNU General Public License version 2
>> + * as published by the Free Software Foundation.
>> + *
>> + * This program is distributed in the hope that it will be useful,
>> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
>> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
>> + * GNU General Public License for more details.
>> + */
>> +
>> +#include <command.h>
>> +#include <common.h>
>> +#include <environment.h>
>> +#include <fdt.h>
>> +#include <firmware.h>
>> +#include <fs.h>
>> +#include <getopt.h>
>> +#include <libfile.h>
>> +#include <of.h>
>> +
>> +static int do_of_overlay(int argc, char *argv[])
>> +{
>> +	int opt, ret;
>> +	struct fdt_header *fdt;
>> +	struct device_node *overlay;
>> +	const char *search_path = NULL;
>> +
>> +	while ((opt = getopt(argc, argv, "S:")) > 0) {
>> +		switch (opt) {
>> +		case 'S':
>> +			search_path = optarg;
>> +			break;
>> +		default:
>> +			return COMMAND_ERROR_USAGE;
>> +		}
>> +	}
>> +
>> +	if (argc != optind + 1)
>> +		return COMMAND_ERROR_USAGE;
>> +
>> +	fdt = read_file(argv[optind], NULL);
>> +	if (!fdt) {
>> +		printf("cannot read %s\n", argv[optind]);
>> +		return 1;
>> +	}
>> +
>> +	overlay = of_unflatten_dtb(fdt);
>> +	free(fdt);
>> +	if (IS_ERR(overlay))
>> +		return PTR_ERR(overlay);
>> +
>> +	if (search_path) {
>> +		ret = firmware_load_overlay(overlay, search_path);
>> +		if (ret)
>> +			goto err;
>> +	}
>> +
>> +	ret = of_register_overlay(overlay);
>> +	if (ret) {
>> +		printf("cannot apply oftree overlay: %s\n", strerror(-ret));
>> +		goto err;
>> +	}
>> +
>> +	return 0;
>> +
>> +err:
>> +	of_delete_node(overlay);
>> +	return ret;
>> +}
>> +
>> +BAREBOX_CMD_HELP_START(of_overlay)
>> +BAREBOX_CMD_HELP_TEXT("Options:")
>> +BAREBOX_CMD_HELP_OPT("-S path", "load firmware using this search path")
>> +BAREBOX_CMD_HELP_END
>> +
>> +BAREBOX_CMD_START(of_overlay)
>> +	.cmd = do_of_overlay,
>> +	BAREBOX_CMD_DESC("register device tree overlay as fixup")
>> +	BAREBOX_CMD_OPTS("[-S path] FILE")
>> +	BAREBOX_CMD_GROUP(CMD_GRP_MISC)
>> +	BAREBOX_CMD_HELP(cmd_of_overlay_help)
>> +BAREBOX_CMD_END
>>
> 

-- 
Pengutronix e.K.                           |                             |
Industrial Linux Solutions                 | http://www.pengutronix.de/  |
Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0    |
Amtsgericht Hildesheim, HRA 2686           | Fax:   +49-5121-206917-5555 |

_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [PATCH v2 7/7] commands: add of_overlay command for device tree overlays
  2019-09-11  7:55   ` Ahmad Fatoum
  2019-09-11  8:00     ` Ahmad Fatoum
@ 2019-09-11  9:28     ` Michael Tretter
  2019-09-11  9:33       ` Ahmad Fatoum
  1 sibling, 1 reply; 15+ messages in thread
From: Michael Tretter @ 2019-09-11  9:28 UTC (permalink / raw)
  To: Ahmad Fatoum, barebox

On Wed, 11 Sep 2019 09:55:34 +0200, Ahmad Fatoum wrote:
> On 9/6/19 3:20 PM, Michael Tretter wrote:
> > Add a new command "of_overlay" for applying device tree overlays,
> > because it does not really fit into any other device tree related
> > command and would create a mess with the command options.
> > 
> > Signed-off-by: Michael Tretter <m.tretter@pengutronix.de>
> > 
> > ---
> > Changelog:
> > 
> > v1->v2: none
> > ---
> >  commands/Kconfig      | 12 ++++++
> >  commands/Makefile     |  1 +
> >  commands/of_overlay.c | 89 +++++++++++++++++++++++++++++++++++++++++++
> >  3 files changed, 102 insertions(+)
> >  create mode 100644 commands/of_overlay.c
> > 
> > diff --git a/commands/Kconfig b/commands/Kconfig
> > index 039fd7d1ac..01d82031ad 100644
> > --- a/commands/Kconfig
> > +++ b/commands/Kconfig
> > @@ -2088,6 +2088,18 @@ config CMD_OF_FIXUP_STATUS
> >  	  Register a fixup to enable or disable a device tree node.
> >  	  Nodes are enabled on default. Disabled with -d.
> >  
> > +config CMD_OF_OVERLAY
> > +	tristate
> > +	select OFTREE  
> 
> This should depend or select OF_OVERLAY, otherwise:
> ./commands/of_overlay.c:60: undefined reference to `firmware_load_overlay'

Thanks. Actually, the firmware_load_overlay() function should be stubbed
and return an error, if FIRMWARE is disabled.

Michael

> 
> Cheers
> Ahmad
> 
> > +	prompt "of_overlay"
> > +	help
> > +	  of_overlay - register device tree overlay as fixup
> > +
> > +	  Usage: of_overlay [-S path] FILE
> > +
> > +	  Options:
> > +		  -S path	load firmware using this search path
> > +
> >  config CMD_OFTREE
> >  	tristate
> >  	select OFTREE
> > diff --git a/commands/Makefile b/commands/Makefile
> > index e69fb5046f..62ad9ce2b2 100644
> > --- a/commands/Makefile
> > +++ b/commands/Makefile
> > @@ -78,6 +78,7 @@ obj-$(CONFIG_CMD_OF_NODE)	+= of_node.o
> >  obj-$(CONFIG_CMD_OF_DUMP)	+= of_dump.o
> >  obj-$(CONFIG_CMD_OF_DISPLAY_TIMINGS)	+= of_display_timings.o
> >  obj-$(CONFIG_CMD_OF_FIXUP_STATUS)	+= of_fixup_status.o
> > +obj-$(CONFIG_CMD_OF_OVERLAY)	+= of_overlay.o
> >  obj-$(CONFIG_CMD_MAGICVAR)	+= magicvar.o
> >  obj-$(CONFIG_CMD_IOMEM)		+= iomemport.o
> >  obj-$(CONFIG_CMD_LINUX_EXEC)	+= linux_exec.o
> > diff --git a/commands/of_overlay.c b/commands/of_overlay.c
> > new file mode 100644
> > index 0000000000..f929443bfe
> > --- /dev/null
> > +++ b/commands/of_overlay.c
> > @@ -0,0 +1,89 @@
> > +// SPDX-License-Identifier: GPL-2.0
> > +/*
> > + * Copyright (c) 2019 Michael Tretter <m.tretter@pengutronix.de>, Pengutronix
> > + *
> > + * See file CREDITS for list of people who contributed to this
> > + * project.
> > + *
> > + * This program is free software; you can redistribute it and/or modify
> > + * it under the terms of the GNU General Public License version 2
> > + * as published by the Free Software Foundation.
> > + *
> > + * This program is distributed in the hope that it will be useful,
> > + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> > + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
> > + * GNU General Public License for more details.
> > + */
> > +
> > +#include <command.h>
> > +#include <common.h>
> > +#include <environment.h>
> > +#include <fdt.h>
> > +#include <firmware.h>
> > +#include <fs.h>
> > +#include <getopt.h>
> > +#include <libfile.h>
> > +#include <of.h>
> > +
> > +static int do_of_overlay(int argc, char *argv[])
> > +{
> > +	int opt, ret;
> > +	struct fdt_header *fdt;
> > +	struct device_node *overlay;
> > +	const char *search_path = NULL;
> > +
> > +	while ((opt = getopt(argc, argv, "S:")) > 0) {
> > +		switch (opt) {
> > +		case 'S':
> > +			search_path = optarg;
> > +			break;
> > +		default:
> > +			return COMMAND_ERROR_USAGE;
> > +		}
> > +	}
> > +
> > +	if (argc != optind + 1)
> > +		return COMMAND_ERROR_USAGE;
> > +
> > +	fdt = read_file(argv[optind], NULL);
> > +	if (!fdt) {
> > +		printf("cannot read %s\n", argv[optind]);
> > +		return 1;
> > +	}
> > +
> > +	overlay = of_unflatten_dtb(fdt);
> > +	free(fdt);
> > +	if (IS_ERR(overlay))
> > +		return PTR_ERR(overlay);
> > +
> > +	if (search_path) {
> > +		ret = firmware_load_overlay(overlay, search_path);
> > +		if (ret)
> > +			goto err;
> > +	}
> > +
> > +	ret = of_register_overlay(overlay);
> > +	if (ret) {
> > +		printf("cannot apply oftree overlay: %s\n", strerror(-ret));
> > +		goto err;
> > +	}
> > +
> > +	return 0;
> > +
> > +err:
> > +	of_delete_node(overlay);
> > +	return ret;
> > +}
> > +
> > +BAREBOX_CMD_HELP_START(of_overlay)
> > +BAREBOX_CMD_HELP_TEXT("Options:")
> > +BAREBOX_CMD_HELP_OPT("-S path", "load firmware using this search path")
> > +BAREBOX_CMD_HELP_END
> > +
> > +BAREBOX_CMD_START(of_overlay)
> > +	.cmd = do_of_overlay,
> > +	BAREBOX_CMD_DESC("register device tree overlay as fixup")
> > +	BAREBOX_CMD_OPTS("[-S path] FILE")
> > +	BAREBOX_CMD_GROUP(CMD_GRP_MISC)
> > +	BAREBOX_CMD_HELP(cmd_of_overlay_help)
> > +BAREBOX_CMD_END
> >   
> 

_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [PATCH v2 7/7] commands: add of_overlay command for device tree overlays
  2019-09-11  9:28     ` Michael Tretter
@ 2019-09-11  9:33       ` Ahmad Fatoum
  0 siblings, 0 replies; 15+ messages in thread
From: Ahmad Fatoum @ 2019-09-11  9:33 UTC (permalink / raw)
  To: Michael Tretter, barebox

On 9/11/19 11:28 AM, Michael Tretter wrote:
> On Wed, 11 Sep 2019 09:55:34 +0200, Ahmad Fatoum wrote:
>> On 9/6/19 3:20 PM, Michael Tretter wrote:
>>> Add a new command "of_overlay" for applying device tree overlays,
>>> because it does not really fit into any other device tree related
>>> command and would create a mess with the command options.
>>>
>>> Signed-off-by: Michael Tretter <m.tretter@pengutronix.de>
>>>
>>> ---
>>> Changelog:
>>>
>>> v1->v2: none
>>> ---
>>>  commands/Kconfig      | 12 ++++++
>>>  commands/Makefile     |  1 +
>>>  commands/of_overlay.c | 89 +++++++++++++++++++++++++++++++++++++++++++
>>>  3 files changed, 102 insertions(+)
>>>  create mode 100644 commands/of_overlay.c
>>>
>>> diff --git a/commands/Kconfig b/commands/Kconfig
>>> index 039fd7d1ac..01d82031ad 100644
>>> --- a/commands/Kconfig
>>> +++ b/commands/Kconfig
>>> @@ -2088,6 +2088,18 @@ config CMD_OF_FIXUP_STATUS
>>>  	  Register a fixup to enable or disable a device tree node.
>>>  	  Nodes are enabled on default. Disabled with -d.
>>>  
>>> +config CMD_OF_OVERLAY
>>> +	tristate
>>> +	select OFTREE  
>>
>> This should depend or select OF_OVERLAY, otherwise:
>> ./commands/of_overlay.c:60: undefined reference to `firmware_load_overlay'
> 
> Thanks. Actually, the firmware_load_overlay() function should be stubbed
> and return an error, if FIRMWARE is disabled.

Ye, that would work for the blspec case, because not everyone needs overlays.
For the command though, I'd think that you should ensure at configuration time
that these symbols are enabled.

> 
> Michael
> 
>>
>> Cheers
>> Ahmad
>>
>>> +	prompt "of_overlay"
>>> +	help
>>> +	  of_overlay - register device tree overlay as fixup
>>> +
>>> +	  Usage: of_overlay [-S path] FILE
>>> +
>>> +	  Options:
>>> +		  -S path	load firmware using this search path
>>> +
>>>  config CMD_OFTREE
>>>  	tristate
>>>  	select OFTREE
>>> diff --git a/commands/Makefile b/commands/Makefile
>>> index e69fb5046f..62ad9ce2b2 100644
>>> --- a/commands/Makefile
>>> +++ b/commands/Makefile
>>> @@ -78,6 +78,7 @@ obj-$(CONFIG_CMD_OF_NODE)	+= of_node.o
>>>  obj-$(CONFIG_CMD_OF_DUMP)	+= of_dump.o
>>>  obj-$(CONFIG_CMD_OF_DISPLAY_TIMINGS)	+= of_display_timings.o
>>>  obj-$(CONFIG_CMD_OF_FIXUP_STATUS)	+= of_fixup_status.o
>>> +obj-$(CONFIG_CMD_OF_OVERLAY)	+= of_overlay.o
>>>  obj-$(CONFIG_CMD_MAGICVAR)	+= magicvar.o
>>>  obj-$(CONFIG_CMD_IOMEM)		+= iomemport.o
>>>  obj-$(CONFIG_CMD_LINUX_EXEC)	+= linux_exec.o
>>> diff --git a/commands/of_overlay.c b/commands/of_overlay.c
>>> new file mode 100644
>>> index 0000000000..f929443bfe
>>> --- /dev/null
>>> +++ b/commands/of_overlay.c
>>> @@ -0,0 +1,89 @@
>>> +// SPDX-License-Identifier: GPL-2.0
>>> +/*
>>> + * Copyright (c) 2019 Michael Tretter <m.tretter@pengutronix.de>, Pengutronix
>>> + *
>>> + * See file CREDITS for list of people who contributed to this
>>> + * project.
>>> + *
>>> + * This program is free software; you can redistribute it and/or modify
>>> + * it under the terms of the GNU General Public License version 2
>>> + * as published by the Free Software Foundation.
>>> + *
>>> + * This program is distributed in the hope that it will be useful,
>>> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
>>> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
>>> + * GNU General Public License for more details.
>>> + */
>>> +
>>> +#include <command.h>
>>> +#include <common.h>
>>> +#include <environment.h>
>>> +#include <fdt.h>
>>> +#include <firmware.h>
>>> +#include <fs.h>
>>> +#include <getopt.h>
>>> +#include <libfile.h>
>>> +#include <of.h>
>>> +
>>> +static int do_of_overlay(int argc, char *argv[])
>>> +{
>>> +	int opt, ret;
>>> +	struct fdt_header *fdt;
>>> +	struct device_node *overlay;
>>> +	const char *search_path = NULL;
>>> +
>>> +	while ((opt = getopt(argc, argv, "S:")) > 0) {
>>> +		switch (opt) {
>>> +		case 'S':
>>> +			search_path = optarg;
>>> +			break;
>>> +		default:
>>> +			return COMMAND_ERROR_USAGE;
>>> +		}
>>> +	}
>>> +
>>> +	if (argc != optind + 1)
>>> +		return COMMAND_ERROR_USAGE;
>>> +
>>> +	fdt = read_file(argv[optind], NULL);
>>> +	if (!fdt) {
>>> +		printf("cannot read %s\n", argv[optind]);
>>> +		return 1;
>>> +	}
>>> +
>>> +	overlay = of_unflatten_dtb(fdt);
>>> +	free(fdt);
>>> +	if (IS_ERR(overlay))
>>> +		return PTR_ERR(overlay);
>>> +
>>> +	if (search_path) {
>>> +		ret = firmware_load_overlay(overlay, search_path);
>>> +		if (ret)
>>> +			goto err;
>>> +	}
>>> +
>>> +	ret = of_register_overlay(overlay);
>>> +	if (ret) {
>>> +		printf("cannot apply oftree overlay: %s\n", strerror(-ret));
>>> +		goto err;
>>> +	}
>>> +
>>> +	return 0;
>>> +
>>> +err:
>>> +	of_delete_node(overlay);
>>> +	return ret;
>>> +}
>>> +
>>> +BAREBOX_CMD_HELP_START(of_overlay)
>>> +BAREBOX_CMD_HELP_TEXT("Options:")
>>> +BAREBOX_CMD_HELP_OPT("-S path", "load firmware using this search path")
>>> +BAREBOX_CMD_HELP_END
>>> +
>>> +BAREBOX_CMD_START(of_overlay)
>>> +	.cmd = do_of_overlay,
>>> +	BAREBOX_CMD_DESC("register device tree overlay as fixup")
>>> +	BAREBOX_CMD_OPTS("[-S path] FILE")
>>> +	BAREBOX_CMD_GROUP(CMD_GRP_MISC)
>>> +	BAREBOX_CMD_HELP(cmd_of_overlay_help)
>>> +BAREBOX_CMD_END
>>>   
>>
> 

-- 
Pengutronix e.K.                           |                             |
Industrial Linux Solutions                 | http://www.pengutronix.de/  |
Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0    |
Amtsgericht Hildesheim, HRA 2686           | Fax:   +49-5121-206917-5555 |

_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [PATCH v2 0/7] Device Tree Overlay Support
  2019-09-09  8:57 ` [PATCH v2 0/7] Device Tree Overlay Support Sascha Hauer
@ 2019-09-12  6:57   ` Sascha Hauer
  0 siblings, 0 replies; 15+ messages in thread
From: Sascha Hauer @ 2019-09-12  6:57 UTC (permalink / raw)
  To: Michael Tretter; +Cc: barebox

On Mon, Sep 09, 2019 at 10:57:53AM +0200, Sascha Hauer wrote:
> On Fri, Sep 06, 2019 at 03:20:01PM +0200, Michael Tretter wrote:
> > Hello,
> > 
> > This is the v2 for adding device tree overlay support to barebox.
> > 
> > The biggest change is the new function of_overlay_apply_tree() which accepts a
> > devicetree and the root node of an overlay and applies the overlay to the
> > devicetree.
> > 
> > Apart from that, I fixed various issues like memory leaks, useless includes,
> > missing documentation, formatting of output messages, and a missing "static
> > inline".
> > 
> > Michael
> 
> Applied, thanks

There's more discussion. I dropped the series for now, please resend as
a whole.

Sascha


-- 
Pengutronix e.K.                           |                             |
Industrial Linux Solutions                 | http://www.pengutronix.de/  |
Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0    |
Amtsgericht Hildesheim, HRA 2686           | Fax:   +49-5121-206917-5555 |

_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox

^ permalink raw reply	[flat|nested] 15+ messages in thread

end of thread, other threads:[~2019-09-12  6:57 UTC | newest]

Thread overview: 15+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2019-09-06 13:20 [PATCH v2 0/7] Device Tree Overlay Support Michael Tretter
2019-09-06 13:20 ` [PATCH v2 1/7] dtc: add -@ option to enable __symbols__ Michael Tretter
2019-09-06 13:20 ` [PATCH v2 2/7] of: add support for devicetree overlays Michael Tretter
2019-09-06 13:20 ` [PATCH v2 3/7] blspec: " Michael Tretter
2019-09-06 13:20 ` [PATCH v2 4/7] of: add iterator for overlays Michael Tretter
2019-09-06 13:20 ` [PATCH v2 5/7] firmware: add support to load firmware from dt overlay Michael Tretter
2019-09-06 13:20 ` [PATCH v2 6/7] blspec: load firmware if specified in " Michael Tretter
2019-09-11  7:53   ` Ahmad Fatoum
2019-09-06 13:20 ` [PATCH v2 7/7] commands: add of_overlay command for device tree overlays Michael Tretter
2019-09-11  7:55   ` Ahmad Fatoum
2019-09-11  8:00     ` Ahmad Fatoum
2019-09-11  9:28     ` Michael Tretter
2019-09-11  9:33       ` Ahmad Fatoum
2019-09-09  8:57 ` [PATCH v2 0/7] Device Tree Overlay Support Sascha Hauer
2019-09-12  6:57   ` Sascha Hauer

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox