summaryrefslogtreecommitdiffstats
path: root/common/blspec.c
diff options
context:
space:
mode:
authorMichael Tretter <m.tretter@pengutronix.de>2019-09-13 15:14:40 +0200
committerSascha Hauer <s.hauer@pengutronix.de>2019-09-16 09:06:18 +0200
commitda2c36c0a911992d80448f9afa5acc9d70871ed0 (patch)
tree6be756dc6c1a8c4cd5ef56d4281f1d5b0e083315 /common/blspec.c
parentbbd241efa5ae048cd7a96c5b232e729b9180e6f2 (diff)
downloadbarebox-da2c36c0a911992d80448f9afa5acc9d70871ed0.tar.gz
barebox-da2c36c0a911992d80448f9afa5acc9d70871ed0.tar.xz
blspec: add support for devicetree overlays
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> Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
Diffstat (limited to 'common/blspec.c')
-rw-r--r--common/blspec.c61
1 files changed, 61 insertions, 0 deletions
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);