mail archive of the barebox mailing list
 help / color / mirror / Atom feed
* [PATCH v3 0/8] Device Tree Overlay Support
@ 2019-09-13 13:14 Michael Tretter
  2019-09-13 13:14 ` [PATCH v3 1/8] of: add support for devicetree overlays Michael Tretter
                   ` (8 more replies)
  0 siblings, 9 replies; 10+ messages in thread
From: Michael Tretter @ 2019-09-13 13:14 UTC (permalink / raw)
  To: barebox; +Cc: Michael Tretter

Hello,

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

I added a new config item for building the build-in device tree with
__symbols__. As __symbols__ increases the size of the dtb and you don't need
symbols in the build-in device tree to use overlays on other device trees.
Therefore, this should be disabled unless actually needed.

Furthermore, I completely reworked the function to load firmware from a
devicetree overlay, because it must be successful whenever the overlay does
not reference firmware. However, it must always fail if the overlay references
firmware which cannot be loaded, because Barebox must not apply the overlay
without the according firmware.

There are a few other minor changes which I describe in the respective
patches.

Michael

Changelog:

v2 -> v3:
 - new file of_firmware for loading firmware from overlay
 - fix error handling when CONFIG_FIRMWARE is off
 - separate patch for firmwaremgr_find_by_node
 - make __symbols__ in build-in devicetree configurable

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 (8):
  of: add support for devicetree overlays
  blspec: add support for devicetree overlays
  of: add iterator for overlays
  firmware: add function to find firmware by devicetree node
  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
  dtc: optionally add add __symbols__ to build-in devicetree

 Documentation/user/booting-linux.rst |   4 +
 commands/Kconfig                     |  12 ++
 commands/Makefile                    |   1 +
 commands/of_overlay.c                |  89 +++++++++
 common/blspec.c                      |  78 ++++++++
 common/firmware.c                    |  18 ++
 drivers/of/Kconfig                   |  26 +++
 drivers/of/Makefile                  |   1 +
 drivers/of/of_firmware.c             |  86 +++++++++
 drivers/of/overlay.c                 | 247 ++++++++++++++++++++++++
 drivers/of/resolver.c                | 279 +++++++++++++++++++++++++++
 include/firmware.h                   |  15 ++
 include/of.h                         |  47 +++++
 scripts/Makefile.lib                 |   4 +
 14 files changed, 907 insertions(+)
 create mode 100644 commands/of_overlay.c
 create mode 100644 drivers/of/of_firmware.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] 10+ messages in thread

* [PATCH v3 1/8] of: add support for devicetree overlays
  2019-09-13 13:14 [PATCH v3 0/8] Device Tree Overlay Support Michael Tretter
@ 2019-09-13 13:14 ` Michael Tretter
  2019-09-13 13:14 ` [PATCH v3 2/8] blspec: " Michael Tretter
                   ` (7 subsequent siblings)
  8 siblings, 0 replies; 10+ messages in thread
From: Michael Tretter @ 2019-09-13 13:14 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:

v2->v3: none

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] 10+ messages in thread

* [PATCH v3 2/8] blspec: add support for devicetree overlays
  2019-09-13 13:14 [PATCH v3 0/8] Device Tree Overlay Support Michael Tretter
  2019-09-13 13:14 ` [PATCH v3 1/8] of: add support for devicetree overlays Michael Tretter
@ 2019-09-13 13:14 ` Michael Tretter
  2019-09-13 13:14 ` [PATCH v3 3/8] of: add iterator for overlays Michael Tretter
                   ` (6 subsequent siblings)
  8 siblings, 0 replies; 10+ messages in thread
From: Michael Tretter @ 2019-09-13 13:14 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:

v2->v3: none

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] 10+ messages in thread

* [PATCH v3 3/8] of: add iterator for overlays
  2019-09-13 13:14 [PATCH v3 0/8] Device Tree Overlay Support Michael Tretter
  2019-09-13 13:14 ` [PATCH v3 1/8] of: add support for devicetree overlays Michael Tretter
  2019-09-13 13:14 ` [PATCH v3 2/8] blspec: " Michael Tretter
@ 2019-09-13 13:14 ` Michael Tretter
  2019-09-13 13:14 ` [PATCH v3 4/8] firmware: add function to find firmware by devicetree node Michael Tretter
                   ` (5 subsequent siblings)
  8 siblings, 0 replies; 10+ messages in thread
From: Michael Tretter @ 2019-09-13 13:14 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:

v2->v3:
- clarify warning if process fails
- move phandle resolving step to caller

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

diff --git a/drivers/of/overlay.c b/drivers/of/overlay.c
index f6a0576183..de79e05cbc 100644
--- a/drivers/of/overlay.c
+++ b/drivers/of/overlay.c
@@ -194,6 +194,44 @@ 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 *fragment;
+	int err = 0;
+
+	for_each_child_of_node(overlay, 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 overlay for %s\n",
+				target->name);
+			break;
+		}
+	}
+
+	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] 10+ messages in thread

* [PATCH v3 4/8] firmware: add function to find firmware by devicetree node
  2019-09-13 13:14 [PATCH v3 0/8] Device Tree Overlay Support Michael Tretter
                   ` (2 preceding siblings ...)
  2019-09-13 13:14 ` [PATCH v3 3/8] of: add iterator for overlays Michael Tretter
@ 2019-09-13 13:14 ` Michael Tretter
  2019-09-13 13:14 ` [PATCH v3 5/8] firmware: add support to load firmware from dt overlay Michael Tretter
                   ` (4 subsequent siblings)
  8 siblings, 0 replies; 10+ messages in thread
From: Michael Tretter @ 2019-09-13 13:14 UTC (permalink / raw)
  To: barebox; +Cc: Michael Tretter

Allows to get the firmware manager using a phandle from the devicetree.

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

---
Changelog:

v2->v3:
- new separate patch for adding the function
---
 common/firmware.c  | 18 ++++++++++++++++++
 include/firmware.h | 15 +++++++++++++++
 2 files changed, 33 insertions(+)

diff --git a/common/firmware.c b/common/firmware.c
index 9d55d73e7a..609cf11822 100644
--- a/common/firmware.c
+++ b/common/firmware.c
@@ -62,6 +62,24 @@ 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;
+}
+
 /*
  * firmwaremgr_list_handlers - list registered firmware device handlers
  *                             in pretty format
diff --git a/include/firmware.h b/include/firmware.h
index 284e0f9705..7c01a77118 100644
--- a/include/firmware.h
+++ b/include/firmware.h
@@ -34,10 +34,25 @@ struct firmware_mgr;
 int firmwaremgr_register(struct firmware_handler *);
 
 struct firmware_mgr *firmwaremgr_find(const char *);
+#ifdef CONFIG_FIRMWARE
+struct firmware_mgr *firmwaremgr_find_by_node(const struct device_node *np);
+#else
+static inline struct firmware_mgr *firmwaremgr_find_by_node(const struct device_node *np)
+{
+	return NULL;
+}
+#endif
 
 void firmwaremgr_list_handlers(void);
 
+#ifdef CONFIG_FIRMWARE
 int firmwaremgr_load_file(struct firmware_mgr *, const char *path);
+#else
+static inline int firmwaremgr_load_file(struct firmware_mgr *mgr, const char *path)
+{
+	return -ENOSYS;
+}
+#endif
 
 #define get_builtin_firmware(name, start, size) \
 	{							\
-- 
2.20.1


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

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

* [PATCH v3 5/8] firmware: add support to load firmware from dt overlay
  2019-09-13 13:14 [PATCH v3 0/8] Device Tree Overlay Support Michael Tretter
                   ` (3 preceding siblings ...)
  2019-09-13 13:14 ` [PATCH v3 4/8] firmware: add function to find firmware by devicetree node Michael Tretter
@ 2019-09-13 13:14 ` Michael Tretter
  2019-09-13 13:14 ` [PATCH v3 6/8] blspec: load firmware if specified in " Michael Tretter
                   ` (3 subsequent siblings)
  8 siblings, 0 replies; 10+ messages in thread
From: Michael Tretter @ 2019-09-13 13:14 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 of_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:

v2->v3:
- move functions from firmware to new module of_firmware
- rename function accordingly
- return success whenever there is no firmware in the overlay

v1->v2: none
---
 drivers/of/Makefile      |  2 +-
 drivers/of/of_firmware.c | 86 ++++++++++++++++++++++++++++++++++++++++
 include/of.h             |  7 ++++
 3 files changed, 94 insertions(+), 1 deletion(-)
 create mode 100644 drivers/of/of_firmware.c

diff --git a/drivers/of/Makefile b/drivers/of/Makefile
index 9c6f8de814..b6847752d2 100644
--- a/drivers/of/Makefile
+++ b/drivers/of/Makefile
@@ -6,4 +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
+obj-$(CONFIG_OF_OVERLAY) += overlay.o resolver.o of_firmware.o
diff --git a/drivers/of/of_firmware.c b/drivers/of/of_firmware.c
new file mode 100644
index 0000000000..0135631fb8
--- /dev/null
+++ b/drivers/of/of_firmware.c
@@ -0,0 +1,86 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) 2019 Pengutronix, Michael Tretter <m.tretter@pengutronix.de>
+ */
+#include <common.h>
+#include <firmware.h>
+#include <of.h>
+
+struct overlay_info {
+	const char *firmware_path;
+};
+
+static struct firmware_mgr *of_node_get_mgr(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;
+}
+
+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);
+	/* Nothing to do if property does not exist. */
+	if (err == -EINVAL)
+		return 0;
+	else if (err)
+		return -EINVAL;
+
+	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;
+}
+
+int of_firmware_load_overlay(struct device_node *overlay, const char *path)
+{
+	struct overlay_info info = {
+		.firmware_path = path,
+	};
+	int err;
+	struct device_node *root;
+	struct device_node *resolved;
+	struct device_node *ovl;
+
+	root = of_get_root_node();
+	/*
+	 * If we cannot resolve the symbols in the overlay, ensure that the
+	 * overlay does depend on firmware to be loaded.
+	 */
+	resolved = of_resolve_phandles(root, overlay);
+	ovl = resolved ? resolved : overlay;
+
+	err = of_process_overlay(root, ovl,
+				 load_firmware, &info);
+
+	if (resolved)
+		of_delete_node(resolved);
+
+	return err;
+}
diff --git a/include/of.h b/include/of.h
index 06dc9f61a5..5466517a6d 100644
--- a/include/of.h
+++ b/include/of.h
@@ -882,6 +882,8 @@ int of_process_overlay(struct device_node *root,
 		    int (*process)(struct device_node *target,
 				   struct device_node *overlay, void *data),
 		    void *data);
+
+int of_firmware_load_overlay(struct device_node *overlay, const char *path);
 #else
 static inline struct device_node *of_resolve_phandles(struct device_node *root,
 					const struct device_node *overlay)
@@ -908,6 +910,11 @@ static inline int of_process_overlay(struct device_node *root,
 {
 	return -ENOSYS;
 }
+
+static inline int of_firmware_load_overlay(struct device_node *overlay, const char *path)
+{
+	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] 10+ messages in thread

* [PATCH v3 6/8] blspec: load firmware if specified in dt overlay
  2019-09-13 13:14 [PATCH v3 0/8] Device Tree Overlay Support Michael Tretter
                   ` (4 preceding siblings ...)
  2019-09-13 13:14 ` [PATCH v3 5/8] firmware: add support to load firmware from dt overlay Michael Tretter
@ 2019-09-13 13:14 ` Michael Tretter
  2019-09-13 13:14 ` [PATCH v3 7/8] commands: add of_overlay command for device tree overlays Michael Tretter
                   ` (2 subsequent siblings)
  8 siblings, 0 replies; 10+ messages in thread
From: Michael Tretter @ 2019-09-13 13:14 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:

v2->v3:
- fix name of of_firmware_load_overlay()
- print warning if loading firmware fails

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

diff --git a/common/blspec.c b/common/blspec.c
index fbba2fc78c..7c27e0b869 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,21 @@ 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 = of_firmware_load_overlay(overlay, firmware_path);
+	free(firmware_path);
+	if (ret) {
+		pr_warn("failed to load firmware: 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);
-- 
2.20.1


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

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

* [PATCH v3 7/8] commands: add of_overlay command for device tree overlays
  2019-09-13 13:14 [PATCH v3 0/8] Device Tree Overlay Support Michael Tretter
                   ` (5 preceding siblings ...)
  2019-09-13 13:14 ` [PATCH v3 6/8] blspec: load firmware if specified in " Michael Tretter
@ 2019-09-13 13:14 ` Michael Tretter
  2019-09-13 13:14 ` [PATCH v3 8/8] dtc: optionally add add __symbols__ to build-in devicetree Michael Tretter
  2019-09-16  7:07 ` [PATCH v3 0/8] Device Tree Overlay Support Sascha Hauer
  8 siblings, 0 replies; 10+ messages in thread
From: Michael Tretter @ 2019-09-13 13:14 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:

v2->v3:
- select OF_OVERLAY from CMD_OF_OVERLAY
- fix name of of_firmware_load_overlay()

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 e03110fd46..298e0fb9e9 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 OF_OVERLAY
+	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 5cd35b78a7..ebdc437e55 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..de3c3dcee5
--- /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 = of_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] 10+ messages in thread

* [PATCH v3 8/8] dtc: optionally add add __symbols__ to build-in devicetree
  2019-09-13 13:14 [PATCH v3 0/8] Device Tree Overlay Support Michael Tretter
                   ` (6 preceding siblings ...)
  2019-09-13 13:14 ` [PATCH v3 7/8] commands: add of_overlay command for device tree overlays Michael Tretter
@ 2019-09-13 13:14 ` Michael Tretter
  2019-09-16  7:07 ` [PATCH v3 0/8] Device Tree Overlay Support Sascha Hauer
  8 siblings, 0 replies; 10+ messages in thread
From: Michael Tretter @ 2019-09-13 13:14 UTC (permalink / raw)
  To: barebox; +Cc: Michael Tretter

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

It is configurable, because adding __symbols__ significantly increases
the size of the devicetree binary. When configuring Barebox, a developer
should be able to enable or disable devicetree overlay support and as
this only affects the build-in devicetree, which is linked to the image
anyway, use a Kconfig item for configuring the __symbols__.

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

---
Changelog:

v2->v3:
- make __symbols__ configurable

v1->v2: none
---
 drivers/of/Kconfig   | 17 +++++++++++++++++
 scripts/Makefile.lib |  4 ++++
 2 files changed, 21 insertions(+)

diff --git a/drivers/of/Kconfig b/drivers/of/Kconfig
index 1bb6639c5a..fd820b26f5 100644
--- a/drivers/of/Kconfig
+++ b/drivers/of/Kconfig
@@ -59,3 +59,20 @@ config OF_OVERLAY
 	  not patch the live devicetree, but applies the overlays as fixup to
 	  the devicetree. Furthermore, overlays cannot be removed after they
 	  have been applied.
+
+config OF_OVERLAY_LIVE
+	depends on OF_OVERLAY
+	default n
+	bool "Support devicetree overlays on live devicetree"
+	help
+	  This option allows to use devicetree overlays with the live
+	  devicetree. It is not required to apply overlays to any other
+	  devicetree.
+
+	  This builds the build-in devicetree with __symbols__, which
+	  significantly increases the size of the dtb file.
+
+	  Enable this option only if you actually need the live devicetree
+	  while applying in the devicetree overlay. This is usually the case if
+	  applying the overlay has other side effects than changing the
+	  devicetree.
diff --git a/scripts/Makefile.lib b/scripts/Makefile.lib
index c4d307ae30..ad0484de3a 100644
--- a/scripts/Makefile.lib
+++ b/scripts/Makefile.lib
@@ -292,6 +292,10 @@ DTC_FLAGS += -Wno-unit_address_vs_reg \
 	 -Wno-unique_unit_address \
 	 -Wno-pci_device_reg
 
+ifeq ($(CONFIG_OF_OVERLAY_LIVE), y)
+DTC_FLAGS += -@
+endif
+
 # Generate an assembly file to wrap the output of the device tree compiler
 quiet_cmd_dt_S_dtb = DTB     $@
 cmd_dt_S_dtb = $(srctree)/scripts/gen-dtb-s $(subst -,_,$(*F)) $< $(CONFIG_IMD) > $@
-- 
2.20.1


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

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

* Re: [PATCH v3 0/8] Device Tree Overlay Support
  2019-09-13 13:14 [PATCH v3 0/8] Device Tree Overlay Support Michael Tretter
                   ` (7 preceding siblings ...)
  2019-09-13 13:14 ` [PATCH v3 8/8] dtc: optionally add add __symbols__ to build-in devicetree Michael Tretter
@ 2019-09-16  7:07 ` Sascha Hauer
  8 siblings, 0 replies; 10+ messages in thread
From: Sascha Hauer @ 2019-09-16  7:07 UTC (permalink / raw)
  To: Michael Tretter; +Cc: barebox

On Fri, Sep 13, 2019 at 03:14:38PM +0200, Michael Tretter wrote:
> Hello,
> 
> This is the v3 for adding device tree overlay support to barebox.
> 
> I added a new config item for building the build-in device tree with
> __symbols__. As __symbols__ increases the size of the dtb and you don't need
> symbols in the build-in device tree to use overlays on other device trees.
> Therefore, this should be disabled unless actually needed.
> 
> Furthermore, I completely reworked the function to load firmware from a
> devicetree overlay, because it must be successful whenever the overlay does
> not reference firmware. However, it must always fail if the overlay references
> firmware which cannot be loaded, because Barebox must not apply the overlay
> without the according firmware.
> 
> There are a few other minor changes which I describe in the respective
> patches.

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] 10+ messages in thread

end of thread, other threads:[~2019-09-16  7:07 UTC | newest]

Thread overview: 10+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2019-09-13 13:14 [PATCH v3 0/8] Device Tree Overlay Support Michael Tretter
2019-09-13 13:14 ` [PATCH v3 1/8] of: add support for devicetree overlays Michael Tretter
2019-09-13 13:14 ` [PATCH v3 2/8] blspec: " Michael Tretter
2019-09-13 13:14 ` [PATCH v3 3/8] of: add iterator for overlays Michael Tretter
2019-09-13 13:14 ` [PATCH v3 4/8] firmware: add function to find firmware by devicetree node Michael Tretter
2019-09-13 13:14 ` [PATCH v3 5/8] firmware: add support to load firmware from dt overlay Michael Tretter
2019-09-13 13:14 ` [PATCH v3 6/8] blspec: load firmware if specified in " Michael Tretter
2019-09-13 13:14 ` [PATCH v3 7/8] commands: add of_overlay command for device tree overlays Michael Tretter
2019-09-13 13:14 ` [PATCH v3 8/8] dtc: optionally add add __symbols__ to build-in devicetree Michael Tretter
2019-09-16  7:07 ` [PATCH v3 0/8] Device Tree Overlay Support Sascha Hauer

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