mail archive of the barebox mailing list
 help / color / mirror / Atom feed
* [PATCH] devicetree improvements
@ 2013-01-11 13:24 Sascha Hauer
  2013-01-11 13:24 ` [PATCH 01/16] of: make of_get_fixed_tree more universally usable Sascha Hauer
                   ` (15 more replies)
  0 siblings, 16 replies; 17+ messages in thread
From: Sascha Hauer @ 2013-01-11 13:24 UTC (permalink / raw)
  To: barebox


This series contains several improvements in how barebox handles
devicetrees. In short barebox has an internal storage place for
devicetrees which can be used to a) probe barebox itself from
the devicetree and b) pass it to the kernel. This is not new,
but the following series implements this much more consistently.
Also with this series it's possible to manipulate (create/update/delete
properties and nodes) the devicetree.

I've already written Documentation for this (hurray!), it can be found
here:

http://wiki.barebox.org/doku.php?id=user:devicetree&do=edit&rev=

Below is what I checked into the Wiki (There's also documentation
for of_node and of_property in the Wiki, not in this mail).

====== devicetree handling in barebox ======

NOTE: This page contains information for patches currently under review.

==== General overview ====

barebox handles devicetrees for two different purposes. First barebox itself
can be probed from devicetrees. This feature is currently under development and
is not generally used. Second barebox can pass devicetrees to the Linux Kernel.
This feature is ready to use on ARM and PowerPC.

barebox has a single internal place for storing a devicetree. This is further
referred to as internal devicetree storage or short internal storage. This
storage place is used to probe barebox from the devicetree and to pass a
devicetree to the Kernel. The devicetree manipulation commands generally work
on the internal storage. For just starting a kernel with devicetree the
internal storage can completely be bypassed when a dtb file is given to the
bootm command, but then the devicetree manipulation commands can't be used.

==== barebox internal devicetree storage ====

Unless barebox itself is probed from the devicetree the internal storage will
be empty after startup. A devicetree can be loaded to internal storage using
the oftree command:

  oftree -l /env/oftree

After executing this command the internal devicetree storage can be shown with:

  oftree -d
   {
          #address-cells: <0x1>
          #size-cells: <0x1>
          model: "Freescale i.MX51 Babbage Board"
          compatible: "fsl,imx51-babbage", "fsl,imx51"
          chosen {
          };
          ...
    };

Further arguments exist to show only parts of the devicetree, see
[[commands:oftree]] for more details.

By default the [[commands:bootm]] command uses this devicetree to start the
kernel with.

==== Manipulating the devicetree ====

the [[commands:of_node]] and [[commands:of_property]] commands exist to
manipulate the internal devicetree storage. [[commands:of_node]] is used to
create or delete nodes:

  # create a node /soc/foo:
  of_node -c /soc/foo
  # and delete it again:
  of_node -d /soc/foo

The [[commands:of_property]] command is used to create/modify/delete
properties:

  # add/modify a property:
  of_property -s /soc/aips@70000000/serial@73fc0000 status okay
  # delete a property:
  of_property -d /soc/aips@70000000/serial@73fc0000 status

the [[commands:of_property]] command understands several formats for specifying
the value of the property for specifying cells, bytestreams and cells, see the
command help for more details.

==== devicetree overlays ====

Basic support for devicetree overlays exist, but this is currently not
complete. phandles are not handled currently, so this can only be used for
updates which does not contain phandles. Overlays can be done simply by calling
oftree -l multiple times:

  oftree -l /env/base.dtb
  oftree -l /env/overlay.dtb

==== probing devices from the devicetree ====

Once a devicetree has been loaded into internal storage the devices found there
can be probed using the -p option to the oftree command. barebox will only
probe devices which are not probed already from platform devices. For detecting
whether a device is probed already the physical address is used. This means
that only platform devices with a physical address can be handled this way. If
a node describes a i2c bus the (additional) i2c devices will not be probed.
After probing each existing device which has a correspondent device in the
devicetree will have a devicenode attached to it. This can be examined using
the devinfo command:

  barebox@Freescale i.MX51 PDK:/ devinfo 73fc0000.serial
  resources:
  num   : 0
  start : 0x73fc0000
  size  : 0x00004000
  driver: imx_serial
  bus: platform
  
  no info available for 73fc0000.serial
  no parameters available
  
  device node: /soc/aips@70000000/serial@73fc0000
  serial@73fc0000 {
          compatible: "fsl,imx51-uart", "fsl,imx21-uart"
          reg: <0x73fc0000 0x4000>
          interrupts: <0x20>
          clocks: <0x2 0x1e 0x2 0x1f>
          clock-names: "ipg", "per"
          status: "okay"
          pinctrl-names: "default"
          pinctrl-0: <0xb>
  };


barebox will only use the internal devicetree during probe, so after the
devicetree has been probed it can (but of course does not have to) be freed
again using oftree -f. The newly probed devices will continue to exist, just
the additional devicenode is gone.


The following changes since commit 46dae550cdccfee407f8ced183f9102296cb79b7:

  ARM am33xx: the hsmmc is a omap4 type mmc controller (2013-01-10 20:41:42 +0100)

are available in the git repository at:

  git://git.pengutronix.de/git/barebox.git pu/oftree

for you to fetch changes up to 8d84eb6090e46c6013dfd1890b09a78096b5ca46:

  commands: Add of_node command (2013-01-11 14:10:17 +0100)

----------------------------------------------------------------
Sascha Hauer (16):
      of: make of_get_fixed_tree more universally usable
      of: Fix invalid path for of_find_node_by_path
      ARM android image: remove double of_fix_tree
      of: of_free fixes
      of of_free: remove old node from allnodes list
      of: return root node when looking for a node with path /
      of: rename of_parse_dtb to of_unflatten_dtb
      of: Add support for converting the unflattened tree back to a dtb
      of: remove unused barebox_fdt
      ARM bootm: only use concatenated oftree when no other is available
      of: unflatten: allow overlay dtbs
      oftree command: refactor
      of: add of_delete_property
      of: rename new_device_node to of_new_node and export it
      commands: Add of_property command
      commands: Add of_node command

 arch/arm/lib/bootm.c   |    9 +-
 arch/arm/lib/bootu.c   |    2 +-
 arch/arm/lib/bootz.c   |    2 +-
 commands/Kconfig       |   15 +++
 commands/Makefile      |    2 +
 commands/bootm.c       |   32 ++----
 commands/of_node.c     |  111 +++++++++++++++++++
 commands/of_property.c |  280 ++++++++++++++++++++++++++++++++++++++++++++++++
 commands/oftree.c      |  110 ++++++++++++-------
 common/oftree.c        |   59 ++++++++--
 drivers/of/base.c      |  143 ++++++++++++++++++++++---
 include/of.h           |   11 +-
 12 files changed, 677 insertions(+), 99 deletions(-)
 create mode 100644 commands/of_node.c
 create mode 100644 commands/of_property.c

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

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

* [PATCH 01/16] of: make of_get_fixed_tree more universally usable
  2013-01-11 13:24 [PATCH] devicetree improvements Sascha Hauer
@ 2013-01-11 13:24 ` Sascha Hauer
  2013-01-11 13:24 ` [PATCH 02/16] of: Fix invalid path for of_find_node_by_path Sascha Hauer
                   ` (14 subsequent siblings)
  15 siblings, 0 replies; 17+ messages in thread
From: Sascha Hauer @ 2013-01-11 13:24 UTC (permalink / raw)
  To: barebox

Currently the bootm code uses of_fix_tree to apply the fixups
to the devicetree given on the command line. This function assumes
that there is enough space for the fixups available. Also on ARM
we have to make sure the tree does not cross 1Mib boundaries.

This patch moves the space allocation and alignment ensurance
to of_get_fixed_tree and uses it in bootm. This is the first
step for making of_get_fixed_tree the single point of devicetree
handling in barebox.
of_get_fixed_tree now takes an argument of the input fdt. If it is
given, this one is used, otherwise an internal oftree is used which
will be created in subsequent patches.

Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
 arch/arm/lib/bootu.c |    2 +-
 arch/arm/lib/bootz.c |    2 +-
 commands/bootm.c     |   32 ++++++++------------------------
 common/oftree.c      |   50 +++++++++++++++++++++++++++++++++++++++++++++-----
 include/of.h         |    2 +-
 5 files changed, 56 insertions(+), 32 deletions(-)

diff --git a/arch/arm/lib/bootu.c b/arch/arm/lib/bootu.c
index 75e0de3..fdb0362 100644
--- a/arch/arm/lib/bootu.c
+++ b/arch/arm/lib/bootu.c
@@ -23,7 +23,7 @@ static int do_bootu(int argc, char *argv[])
 		kernel = (void *)simple_strtoul(argv[1], NULL, 0);
 
 #ifdef CONFIG_OFTREE
-	oftree = of_get_fixed_tree();
+	oftree = of_get_fixed_tree(NULL);
 #endif
 
 	start_linux(kernel, 0, 0, 0, oftree);
diff --git a/arch/arm/lib/bootz.c b/arch/arm/lib/bootz.c
index 9f5b3b4..e32a77b 100644
--- a/arch/arm/lib/bootz.c
+++ b/arch/arm/lib/bootz.c
@@ -109,7 +109,7 @@ static int do_bootz(int argc, char *argv[])
 
 	printf("loaded zImage from %s with size %d\n", argv[1], end);
 #ifdef CONFIG_OFTREE
-	oftree = of_get_fixed_tree();
+	oftree = of_get_fixed_tree(NULL);
 #endif
 
 	start_linux(zimage, swap, 0, 0, oftree);
diff --git a/commands/bootm.c b/commands/bootm.c
index 483e6a1..d8b8469 100644
--- a/commands/bootm.c
+++ b/commands/bootm.c
@@ -139,9 +139,7 @@ static int bootm_open_oftree(struct image_data *data, const char *oftree, int nu
 {
 	enum filetype ft;
 	struct fdt_header *fdt, *fixfdt;
-	int ret;
 	size_t size;
-	unsigned int align;
 
 	if (bootm_verbose(data))
 		printf("Loading oftree from '%s'\n", oftree);
@@ -190,36 +188,18 @@ static int bootm_open_oftree(struct image_data *data, const char *oftree, int nu
 				file_type_to_string(ft));
 	}
 
-	/*
-	 * ARM Linux uses a single 1MiB section (with 1MiB alignment)
-	 * for mapping the devicetree, so we are not allowed to cross
-	 * 1MiB boundaries.
-	 */
-	align = 1 << fls(size + OFTREE_SIZE_INCREASE - 1);
-
-	fixfdt = xmemalign(align, size + OFTREE_SIZE_INCREASE);
-	memcpy(fixfdt, fdt, size);
-
-
-	ret = fdt_open_into(fdt, fixfdt, size + OFTREE_SIZE_INCREASE);
+	fixfdt = of_get_fixed_tree(fdt);
+	if (!fixfdt)
+		return -EINVAL;
 
 	free(fdt);
 
-	if (ret) {
-		printf("unable to parse %s\n", oftree);
-		return -ENODEV;
-	}
-
-	ret = of_fix_tree(fixfdt);
-	if (ret)
-		return ret;
-
 	if (bootm_verbose(data) > 1)
 		fdt_print(fixfdt, "/");
 
 	data->oftree = fixfdt;
 
-	return ret;
+	return 0;
 }
 #endif
 
@@ -420,6 +400,10 @@ static int do_bootm(int argc, char *argv[])
 		ret = bootm_open_oftree(&data, oftree, oftree_num);
 		if (ret)
 			goto err_out;
+	} else {
+		data.oftree = of_get_fixed_tree(NULL);
+		if (bootm_verbose(&data) && data.oftree)
+			printf("using internal devicetree\n");
 	}
 #endif
 	if (data.os_address == UIMAGE_SOME_ADDRESS)
diff --git a/common/oftree.c b/common/oftree.c
index 3e8c6f8..0dd6d5c 100644
--- a/common/oftree.c
+++ b/common/oftree.c
@@ -294,6 +294,10 @@ int of_register_fixup(int (*fixup)(struct fdt_header *))
 	return 0;
 }
 
+/*
+ * Apply registered fixups for the given fdt. The fdt must have
+ * enough free space to apply the fixups.
+ */
 int of_fix_tree(struct fdt_header *fdt)
 {
 	struct of_fixup *of_fixup;
@@ -308,14 +312,50 @@ int of_fix_tree(struct fdt_header *fdt)
 	return 0;
 }
 
-struct fdt_header *of_get_fixed_tree(void)
+/*
+ * The size by which we increase the dtb to have space for additional
+ * fixups. Ideally this would be done by libfdt automatically
+ */
+#define OFTREE_SIZE_INCREASE 0x8000
+
+/*
+ * Get the fixed fdt. This function uses the fdt input pointer
+ * if provided or the barebox internal devicetree if not.
+ * It increases the size of the tree and applies the registered
+ * fixups.
+ */
+struct fdt_header *of_get_fixed_tree(struct fdt_header *fdt)
 {
 	int ret;
+	void *fixfdt;
+	int size, align;
 
-	if (!barebox_fdt)
+	if (!fdt)
 		return NULL;
-	ret = of_fix_tree(barebox_fdt);
+
+	size = fdt_totalsize(fdt);
+
+	/*
+	 * ARM Linux uses a single 1MiB section (with 1MiB alignment)
+	 * for mapping the devicetree, so we are not allowed to cross
+	 * 1MiB boundaries.
+	 */
+	align = 1 << fls(size + OFTREE_SIZE_INCREASE - 1);
+
+	fixfdt = xmemalign(align, size + OFTREE_SIZE_INCREASE);
+	ret = fdt_open_into(fdt, fixfdt, size + OFTREE_SIZE_INCREASE);
+
 	if (ret)
-		return NULL;
-	return barebox_fdt;
+		goto out_free;
+
+	ret = of_fix_tree(fixfdt);
+	if (ret)
+		goto out_free;
+
+	return fixfdt;
+
+out_free:
+	free(fixfdt);
+
+	return NULL;
 }
diff --git a/include/of.h b/include/of.h
index 58b4590..3999ded 100644
--- a/include/of.h
+++ b/include/of.h
@@ -9,7 +9,7 @@ extern struct fdt_header *barebox_fdt;
 
 int fdt_print(struct fdt_header *working_fdt, const char *pathp);
 
-struct fdt_header *of_get_fixed_tree(void);
+struct fdt_header *of_get_fixed_tree(struct fdt_header *fdt);
 int of_fix_tree(struct fdt_header *fdt);
 int of_register_fixup(int (*fixup)(struct fdt_header *));
 
-- 
1.7.10.4


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

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

* [PATCH 02/16] of: Fix invalid path for of_find_node_by_path
  2013-01-11 13:24 [PATCH] devicetree improvements Sascha Hauer
  2013-01-11 13:24 ` [PATCH 01/16] of: make of_get_fixed_tree more universally usable Sascha Hauer
@ 2013-01-11 13:24 ` Sascha Hauer
  2013-01-11 13:24 ` [PATCH 03/16] ARM android image: remove double of_fix_tree Sascha Hauer
                   ` (13 subsequent siblings)
  15 siblings, 0 replies; 17+ messages in thread
From: Sascha Hauer @ 2013-01-11 13:24 UTC (permalink / raw)
  To: barebox

When of_find_node_by_path is called with a non existing path we
return just some node. return NULL instead.

Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
 drivers/of/base.c |    5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/drivers/of/base.c b/drivers/of/base.c
index 7a41618..399adc8 100644
--- a/drivers/of/base.c
+++ b/drivers/of/base.c
@@ -487,9 +487,10 @@ struct device_node *of_find_node_by_path(const char *path)
 
 	list_for_each_entry(np, &allnodes, list) {
 		if (np->full_name && (strcmp(np->full_name, path) == 0))
-			break;
+			return np;
 	}
-	return np;
+
+	return NULL;
 }
 EXPORT_SYMBOL(of_find_node_by_path);
 
-- 
1.7.10.4


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

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

* [PATCH 03/16] ARM android image: remove double of_fix_tree
  2013-01-11 13:24 [PATCH] devicetree improvements Sascha Hauer
  2013-01-11 13:24 ` [PATCH 01/16] of: make of_get_fixed_tree more universally usable Sascha Hauer
  2013-01-11 13:24 ` [PATCH 02/16] of: Fix invalid path for of_find_node_by_path Sascha Hauer
@ 2013-01-11 13:24 ` Sascha Hauer
  2013-01-11 13:24 ` [PATCH 04/16] of: of_free fixes Sascha Hauer
                   ` (12 subsequent siblings)
  15 siblings, 0 replies; 17+ messages in thread
From: Sascha Hauer @ 2013-01-11 13:24 UTC (permalink / raw)
  To: barebox

With bootm of_fix_tree() will already be called from the generic bootm
code, so do not do this again in the Android image handler.

Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
Cc: Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com>
---
 arch/arm/lib/bootm.c |    6 ------
 1 file changed, 6 deletions(-)

diff --git a/arch/arm/lib/bootm.c b/arch/arm/lib/bootm.c
index 51ac9af..b7dc96e 100644
--- a/arch/arm/lib/bootm.c
+++ b/arch/arm/lib/bootm.c
@@ -402,12 +402,6 @@ static int do_bootm_aimage(struct image_data *data)
 	if (!getenv("aimage_noverwrite_tags"))
 		armlinux_set_bootparams((void*)header->tags_addr);
 
-	if (IS_ENABLED(CONFIG_OFTREE) && data->oftree) {
-		ret = of_fix_tree(data->oftree);
-		if (ret)
-			goto err_out;
-	}
-
 	cmp = &header->second_stage;
 	if (cmp->size) {
 		void (*second)(void);
-- 
1.7.10.4


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

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

* [PATCH 04/16] of: of_free fixes
  2013-01-11 13:24 [PATCH] devicetree improvements Sascha Hauer
                   ` (2 preceding siblings ...)
  2013-01-11 13:24 ` [PATCH 03/16] ARM android image: remove double of_fix_tree Sascha Hauer
@ 2013-01-11 13:24 ` Sascha Hauer
  2013-01-11 13:24 ` [PATCH 05/16] of of_free: remove old node from allnodes list Sascha Hauer
                   ` (11 subsequent siblings)
  15 siblings, 0 replies; 17+ messages in thread
From: Sascha Hauer @ 2013-01-11 13:24 UTC (permalink / raw)
  To: barebox

- Add missing prototype for of_free()
- When root node is freed set root_node to NULL
- (re)scan aliases after freeing a node. This is necessary because
  the freed node may be an alias or point to an alias

Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
 drivers/of/base.c |   11 +++++++++++
 include/of.h      |    1 +
 2 files changed, 12 insertions(+)

diff --git a/drivers/of/base.c b/drivers/of/base.c
index 399adc8..6c1ccd7 100644
--- a/drivers/of/base.c
+++ b/drivers/of/base.c
@@ -138,6 +138,12 @@ static void of_alias_add(struct alias_prop *ap, struct device_node *np,
 void of_alias_scan(void)
 {
 	struct property *pp;
+	struct alias_prop *app, *tmp;
+
+	list_for_each_entry_safe(app, tmp, &aliases_lookup, link)
+		free(app);
+
+	INIT_LIST_HEAD(&aliases_lookup);
 
 	of_aliases = of_find_node_by_path("/aliases");
 	if (!of_aliases)
@@ -777,6 +783,11 @@ void of_free(struct device_node *node)
 	free(node->name);
 	free(node->full_name);
 	free(node);
+
+	if (node == root_node)
+		root_node = NULL;
+
+	of_alias_scan();
 }
 
 static void __of_probe(struct device_node *node)
diff --git a/include/of.h b/include/of.h
index 3999ded..4054917 100644
--- a/include/of.h
+++ b/include/of.h
@@ -107,6 +107,7 @@ int of_machine_is_compatible(const char *compat);
 void of_print_nodes(struct device_node *node, int indent);
 int of_probe(void);
 int of_parse_dtb(struct fdt_header *fdt);
+void of_free(struct device_node *node);
 
 int of_property_read_string(struct device_node *np, const char *propname,
 				const char **out_string);
-- 
1.7.10.4


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

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

* [PATCH 05/16] of of_free: remove old node from allnodes list
  2013-01-11 13:24 [PATCH] devicetree improvements Sascha Hauer
                   ` (3 preceding siblings ...)
  2013-01-11 13:24 ` [PATCH 04/16] of: of_free fixes Sascha Hauer
@ 2013-01-11 13:24 ` Sascha Hauer
  2013-01-11 13:24 ` [PATCH 06/16] of: return root node when looking for a node with path / Sascha Hauer
                   ` (10 subsequent siblings)
  15 siblings, 0 replies; 17+ messages in thread
From: Sascha Hauer @ 2013-01-11 13:24 UTC (permalink / raw)
  To: barebox

Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
 drivers/of/base.c |    2 ++
 1 file changed, 2 insertions(+)

diff --git a/drivers/of/base.c b/drivers/of/base.c
index 6c1ccd7..3e91e36 100644
--- a/drivers/of/base.c
+++ b/drivers/of/base.c
@@ -761,6 +761,8 @@ void of_free(struct device_node *node)
 	if (!node)
 		return;
 
+	list_del(&node->list);
+
 	list_for_each_entry_safe(p, pt, &node->properties, list) {
 		list_del(&p->list);
 		free(p->name);
-- 
1.7.10.4


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

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

* [PATCH 06/16] of: return root node when looking for a node with path /
  2013-01-11 13:24 [PATCH] devicetree improvements Sascha Hauer
                   ` (4 preceding siblings ...)
  2013-01-11 13:24 ` [PATCH 05/16] of of_free: remove old node from allnodes list Sascha Hauer
@ 2013-01-11 13:24 ` Sascha Hauer
  2013-01-11 13:24 ` [PATCH 07/16] of: rename of_parse_dtb to of_unflatten_dtb Sascha Hauer
                   ` (9 subsequent siblings)
  15 siblings, 0 replies; 17+ messages in thread
From: Sascha Hauer @ 2013-01-11 13:24 UTC (permalink / raw)
  To: barebox

Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
 drivers/of/base.c |    3 +++
 1 file changed, 3 insertions(+)

diff --git a/drivers/of/base.c b/drivers/of/base.c
index 3e91e36..69fbf9a 100644
--- a/drivers/of/base.c
+++ b/drivers/of/base.c
@@ -491,6 +491,9 @@ struct device_node *of_find_node_by_path(const char *path)
 {
 	struct device_node *np;
 
+	if (!strcmp(path, "/"))
+		return root_node;
+
 	list_for_each_entry(np, &allnodes, list) {
 		if (np->full_name && (strcmp(np->full_name, path) == 0))
 			return np;
-- 
1.7.10.4


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

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

* [PATCH 07/16] of: rename of_parse_dtb to of_unflatten_dtb
  2013-01-11 13:24 [PATCH] devicetree improvements Sascha Hauer
                   ` (5 preceding siblings ...)
  2013-01-11 13:24 ` [PATCH 06/16] of: return root node when looking for a node with path / Sascha Hauer
@ 2013-01-11 13:24 ` Sascha Hauer
  2013-01-11 13:24 ` [PATCH 08/16] of: Add support for converting the unflattened tree back to a dtb Sascha Hauer
                   ` (8 subsequent siblings)
  15 siblings, 0 replies; 17+ messages in thread
From: Sascha Hauer @ 2013-01-11 13:24 UTC (permalink / raw)
  To: barebox

The process of unflatten the device tree is known from the kernel,
so rename the function, because that's what it does.

Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
 commands/oftree.c |    2 +-
 drivers/of/base.c |    2 +-
 include/of.h      |    1 +
 3 files changed, 3 insertions(+), 2 deletions(-)

diff --git a/commands/oftree.c b/commands/oftree.c
index 7404db5..b9d3c7b 100644
--- a/commands/oftree.c
+++ b/commands/oftree.c
@@ -108,7 +108,7 @@ static int do_oftree(int argc, char *argv[])
 			return 1;
 		}
 
-		ret = of_parse_dtb(fdt);
+		ret = of_unflatten_dtb(fdt);
 		if (ret) {
 			printf("parse oftree: %s\n", strerror(-ret));
 			return 1;
diff --git a/drivers/of/base.c b/drivers/of/base.c
index 69fbf9a..cb1989d 100644
--- a/drivers/of/base.c
+++ b/drivers/of/base.c
@@ -833,7 +833,7 @@ int of_probe(void)
  * Parse a flat device tree binary blob and store it in the barebox
  * internal tree format,
  */
-int of_parse_dtb(struct fdt_header *fdt)
+int of_unflatten_dtb(struct fdt_header *fdt)
 {
 	const void *nodep;	/* property node pointer */
 	int  nodeoffset;	/* node offset from libfdt */
diff --git a/include/of.h b/include/of.h
index 4054917..7682503 100644
--- a/include/of.h
+++ b/include/of.h
@@ -108,6 +108,7 @@ void of_print_nodes(struct device_node *node, int indent);
 int of_probe(void);
 int of_parse_dtb(struct fdt_header *fdt);
 void of_free(struct device_node *node);
+int of_unflatten_dtb(struct fdt_header *fdt);
 
 int of_property_read_string(struct device_node *np, const char *propname,
 				const char **out_string);
-- 
1.7.10.4


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

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

* [PATCH 08/16] of: Add support for converting the unflattened tree back to a dtb
  2013-01-11 13:24 [PATCH] devicetree improvements Sascha Hauer
                   ` (6 preceding siblings ...)
  2013-01-11 13:24 ` [PATCH 07/16] of: rename of_parse_dtb to of_unflatten_dtb Sascha Hauer
@ 2013-01-11 13:24 ` Sascha Hauer
  2013-01-11 13:24 ` [PATCH 09/16] of: remove unused barebox_fdt Sascha Hauer
                   ` (7 subsequent siblings)
  15 siblings, 0 replies; 17+ messages in thread
From: Sascha Hauer @ 2013-01-11 13:24 UTC (permalink / raw)
  To: barebox

We already have support for unflattening the devicetree. This patch
adds support for converting it back to a dtb.

Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
 drivers/of/base.c |   64 +++++++++++++++++++++++++++++++++++++++++++++++++++++
 include/of.h      |    1 +
 2 files changed, 65 insertions(+)

diff --git a/drivers/of/base.c b/drivers/of/base.c
index cb1989d..3307f41 100644
--- a/drivers/of/base.c
+++ b/drivers/of/base.c
@@ -24,6 +24,7 @@
 #include <malloc.h>
 #include <init.h>
 #include <memory.h>
+#include <sizes.h>
 #include <linux/ctype.h>
 
 /**
@@ -909,6 +910,69 @@ int of_unflatten_dtb(struct fdt_header *fdt)
 	return 0;
 }
 
+static int __of_flatten_dtb(void *fdt, struct device_node *node)
+{
+	struct property *p;
+	struct device_node *n;
+	int ret;
+
+	ret = fdt_begin_node(fdt, node->name);
+	if (ret)
+		return ret;
+
+	list_for_each_entry(p, &node->properties, list) {
+		ret = fdt_property(fdt, p->name, p->value, p->length);
+		if (ret)
+			return ret;
+	}
+
+	list_for_each_entry(n, &node->children, parent_list) {
+		ret = __of_flatten_dtb(fdt, n);
+		if (ret)
+			return ret;
+	}
+
+	ret = fdt_end_node(fdt);
+
+	return ret;
+}
+
+#define DTB_SIZE	SZ_128K
+
+void *of_flatten_dtb(void)
+{
+	void *fdt;
+	int ret;
+
+	if (!root_node)
+		return NULL;
+
+	fdt = malloc(DTB_SIZE);
+	if (!fdt)
+		return NULL;
+
+	ret = fdt_create(fdt, DTB_SIZE);
+	if (ret)
+		goto out_free;
+
+	ret = fdt_finish_reservemap(fdt);
+	if (ret)
+		goto out_free;
+
+	ret = __of_flatten_dtb(fdt, root_node);
+	if (ret)
+		goto out_free;
+
+	fdt_finish(fdt);
+
+	return fdt;
+
+out_free:
+	free(fdt);
+
+	return NULL;
+}
+
 int of_device_is_stdout_path(struct device_d *dev)
 {
 	struct device_node *dn;
diff --git a/include/of.h b/include/of.h
index 7682503..80ec447 100644
--- a/include/of.h
+++ b/include/of.h
@@ -109,6 +109,7 @@ int of_probe(void);
 int of_parse_dtb(struct fdt_header *fdt);
 void of_free(struct device_node *node);
 int of_unflatten_dtb(struct fdt_header *fdt);
+void *of_flatten_dtb(void);
 
 int of_property_read_string(struct device_node *np, const char *propname,
 				const char **out_string);
-- 
1.7.10.4


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

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

* [PATCH 09/16] of: remove unused barebox_fdt
  2013-01-11 13:24 [PATCH] devicetree improvements Sascha Hauer
                   ` (7 preceding siblings ...)
  2013-01-11 13:24 ` [PATCH 08/16] of: Add support for converting the unflattened tree back to a dtb Sascha Hauer
@ 2013-01-11 13:24 ` Sascha Hauer
  2013-01-11 13:24 ` [PATCH 10/16] ARM bootm: only use concatenated oftree when no other is available Sascha Hauer
                   ` (6 subsequent siblings)
  15 siblings, 0 replies; 17+ messages in thread
From: Sascha Hauer @ 2013-01-11 13:24 UTC (permalink / raw)
  To: barebox

barebox_fdt should once become the pointer to the barebox internal
devicetree. Since barebox has its own internal devicetree format
this was never used. remove it.

Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
 commands/oftree.c |    9 +--------
 common/oftree.c   |    2 --
 include/of.h      |    2 --
 3 files changed, 1 insertion(+), 12 deletions(-)

diff --git a/commands/oftree.c b/commands/oftree.c
index b9d3c7b..17af9eb 100644
--- a/commands/oftree.c
+++ b/commands/oftree.c
@@ -62,8 +62,6 @@ static int do_oftree(int argc, char *argv[])
 			}
 			break;
 		case 'f':
-			free(barebox_fdt);
-			barebox_fdt = NULL;
 			return 0;
 		case 'n':
 			node = optarg;
@@ -88,12 +86,7 @@ static int do_oftree(int argc, char *argv[])
 			fdt_print(fdt, node);
 			free(fdt);
 		} else {
-			if (barebox_fdt) {
-				fdt_print(barebox_fdt, node);
-				return 0;
-			} else {
-				return 1;
-			}
+			return 1;
 		}
 		return 0;
 	}
diff --git a/common/oftree.c b/common/oftree.c
index 0dd6d5c..d699cb6 100644
--- a/common/oftree.c
+++ b/common/oftree.c
@@ -246,8 +246,6 @@ int fdt_get_path_or_create(struct fdt_header *fdt, const char *path)
 	return nodeoffset;
 }
 
-struct fdt_header *barebox_fdt;
-
 static int of_fixup_bootargs(struct fdt_header *fdt)
 {
 	int nodeoffset;
diff --git a/include/of.h b/include/of.h
index 80ec447..e1a778d 100644
--- a/include/of.h
+++ b/include/of.h
@@ -5,8 +5,6 @@
 #include <errno.h>
 #include <asm/byteorder.h>
 
-extern struct fdt_header *barebox_fdt;
-
 int fdt_print(struct fdt_header *working_fdt, const char *pathp);
 
 struct fdt_header *of_get_fixed_tree(struct fdt_header *fdt);
-- 
1.7.10.4


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

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

* [PATCH 10/16] ARM bootm: only use concatenated oftree when no other is available
  2013-01-11 13:24 [PATCH] devicetree improvements Sascha Hauer
                   ` (8 preceding siblings ...)
  2013-01-11 13:24 ` [PATCH 09/16] of: remove unused barebox_fdt Sascha Hauer
@ 2013-01-11 13:24 ` Sascha Hauer
  2013-01-11 13:24 ` [PATCH 11/16] of: unflatten: allow overlay dtbs Sascha Hauer
                   ` (5 subsequent siblings)
  15 siblings, 0 replies; 17+ messages in thread
From: Sascha Hauer @ 2013-01-11 13:24 UTC (permalink / raw)
  To: barebox

When an oftree is already specified use it. This lets the user
boot a kernel with an oftree he provided himself rather than
hardcoding the concatenated one.

Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
 arch/arm/lib/bootm.c |    3 +++
 1 file changed, 3 insertions(+)

diff --git a/arch/arm/lib/bootm.c b/arch/arm/lib/bootm.c
index b7dc96e..dc29004 100644
--- a/arch/arm/lib/bootm.c
+++ b/arch/arm/lib/bootm.c
@@ -138,6 +138,9 @@ static int do_bootz_linux_fdt(int fd, struct image_data *data)
 
 	u32 end;
 
+	if (data->oftree)
+		return -ENXIO;
+
 	header = &__header;
 	ret = read(fd, header, sizeof(*header));
 	if (ret < sizeof(*header))
-- 
1.7.10.4


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

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

* [PATCH 11/16] of: unflatten: allow overlay dtbs
  2013-01-11 13:24 [PATCH] devicetree improvements Sascha Hauer
                   ` (9 preceding siblings ...)
  2013-01-11 13:24 ` [PATCH 10/16] ARM bootm: only use concatenated oftree when no other is available Sascha Hauer
@ 2013-01-11 13:24 ` Sascha Hauer
  2013-01-11 13:24 ` [PATCH 12/16] oftree command: refactor Sascha Hauer
                   ` (4 subsequent siblings)
  15 siblings, 0 replies; 17+ messages in thread
From: Sascha Hauer @ 2013-01-11 13:24 UTC (permalink / raw)
  To: barebox

This implements overlaying a currently loaded dtb with another dtb.
We used to return -EBUSY when a oftree is currently loaded. Instead
of doing this, check if a node already exists before creating a new
one. Similarly, if a property already exists, just overwrite the
value instead of creating a new property.

Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
 drivers/of/base.c |   33 ++++++++++++++++++++++-----------
 1 file changed, 22 insertions(+), 11 deletions(-)

diff --git a/drivers/of/base.c b/drivers/of/base.c
index 3307f41..527121d 100644
--- a/drivers/of/base.c
+++ b/drivers/of/base.c
@@ -845,13 +845,11 @@ int of_unflatten_dtb(struct fdt_header *fdt)
 	const struct fdt_property *fdt_prop;
 	const char *pathp;
 	int depth = 10000;
-	struct device_node *node = NULL;
+	struct device_node *node = NULL, *n;
+	struct property *p;
 	char buf[1024];
 	int ret;
 
-	if (root_node)
-		return -EBUSY;
-
 	nodeoffset = fdt_path_offset(fdt, "/");
 	if (nodeoffset < 0) {
 		/*
@@ -875,12 +873,17 @@ int of_unflatten_dtb(struct fdt_header *fdt)
 			if (ret)
 				return -EINVAL;
 
-			node = new_device_node(node);
-			if (!node->parent)
-				root_node = node;
-			node->full_name = xstrdup(buf);
-			node->name = xstrdup(pathp);
-			list_add_tail(&node->list, &allnodes);
+			n = of_find_node_by_path(buf);
+			if (n) {
+				node = n;
+			} else {
+				node = new_device_node(node);
+				if (!node->parent)
+					root_node = node;
+				node->full_name = xstrdup(buf);
+				node->name = xstrdup(pathp);
+				list_add_tail(&node->list, &allnodes);
+			}
 			break;
 		case FDT_END_NODE:
 			node = node->parent;
@@ -892,7 +895,15 @@ int of_unflatten_dtb(struct fdt_header *fdt)
 					fdt32_to_cpu(fdt_prop->nameoff));
 			len      = fdt32_to_cpu(fdt_prop->len);
 			nodep    = fdt_prop->data;
-			new_property(node, pathp, nodep, len);
+
+			p = of_find_property(node, pathp);
+			if (p) {
+				free(p->value);
+				p->value = xzalloc(len);
+				memcpy(p->value, nodep, len);
+			} else {
+				new_property(node, pathp, nodep, len);
+			}
 			break;
 		case FDT_NOP:
 			break;
-- 
1.7.10.4


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

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

* [PATCH 12/16] oftree command: refactor
  2013-01-11 13:24 [PATCH] devicetree improvements Sascha Hauer
                   ` (10 preceding siblings ...)
  2013-01-11 13:24 ` [PATCH 11/16] of: unflatten: allow overlay dtbs Sascha Hauer
@ 2013-01-11 13:24 ` Sascha Hauer
  2013-01-11 13:24 ` [PATCH 13/16] of: add of_delete_property Sascha Hauer
                   ` (3 subsequent siblings)
  15 siblings, 0 replies; 17+ messages in thread
From: Sascha Hauer @ 2013-01-11 13:24 UTC (permalink / raw)
  To: barebox

This has several improvements for the oftree command:

- loading a devicetree (-l) and actually probing (-p) it now is separated
- the command now can dump the internal devicetree or a dtb given on the
  command line.
- The -f option now actually frees the internal devicetree

With this the usage pattern for this command is:

oftree -l /env/oftree

oftree -d -n /sound

oftree -d /env/oftree

oftree -f

oftree -p

oftree -l -p /env/oftree

Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
 commands/oftree.c |   99 ++++++++++++++++++++++++++++++++++++-----------------
 common/oftree.c   |   11 ++++--
 2 files changed, 76 insertions(+), 34 deletions(-)

diff --git a/commands/oftree.c b/commands/oftree.c
index 17af9eb..c5239eb 100644
--- a/commands/oftree.c
+++ b/commands/oftree.c
@@ -39,17 +39,23 @@
 
 static int do_oftree(int argc, char *argv[])
 {
-	struct fdt_header *fdt;
+	struct fdt_header *fdt = NULL;
+	void *fdt_free = NULL;
 	int size;
 	int opt;
 	char *file = NULL;
 	const char *node = "/";
 	int dump = 0;
 	int probe = 0;
+	int load = 0;
+	int free_of = 0;
 	int ret;
 
-	while ((opt = getopt(argc, argv, "dpfn:")) > 0) {
+	while ((opt = getopt(argc, argv, "dpfn:l")) > 0) {
 		switch (opt) {
+		case 'l':
+			load = 1;
+			break;
 		case 'd':
 			dump = 1;
 			break;
@@ -62,66 +68,97 @@ static int do_oftree(int argc, char *argv[])
 			}
 			break;
 		case 'f':
-			return 0;
+			free_of = 1;
+			break;
 		case 'n':
 			node = optarg;
 			break;
 		}
 	}
 
+	if (free_of) {
+		struct device_node *root = of_get_root_node();
+
+		if (root)
+			of_free(root);
+
+		return 0;
+	}
+
 	if (optind < argc)
 		file = argv[optind];
 
-	if (!dump && !probe)
+	if (!dump && !probe && !load)
 		return COMMAND_ERROR_USAGE;
 
-	if (dump) {
-		if (file) {
-			fdt = read_file(file, &size);
-			if (!fdt) {
-				printf("unable to read %s\n", file);
-				return 1;
-			}
-
-			fdt_print(fdt, node);
-			free(fdt);
-		} else {
+	if (file) {
+		fdt = read_file(file, &size);
+		if (!fdt) {
+			printf("unable to read %s\n", file);
 			return 1;
 		}
-		return 0;
-	}
 
-	if (probe) {
-		if (!file)
-			return COMMAND_ERROR_USAGE;
+		fdt_free = fdt;
+	}
 
-		fdt = read_file(file, &size);
+	if (load) {
 		if (!fdt) {
-			perror("open");
-			return 1;
+			printf("no fdt given\n");
+			ret = -ENOENT;
+
+			goto out;
 		}
 
 		ret = of_unflatten_dtb(fdt);
 		if (ret) {
 			printf("parse oftree: %s\n", strerror(-ret));
-			return 1;
+			goto out;
 		}
+	}
 
-		of_probe();
+	if (dump) {
+		if (fdt) {
+			ret = fdt_print(fdt, node);
+		} else {
+			struct device_node *n = of_find_node_by_path(node);
+
+			if (!n) {
+				ret = -ENOENT;
+				goto out;
+			}
+
+			of_print_nodes(n, 0);
+
+			ret = 0;
+		}
+
+		goto out;
 	}
 
-	return 0;
+	if (probe) {
+		ret = of_probe();
+		if (ret)
+			goto out;
+	}
+
+	ret = 0;
+out:
+	free(fdt_free);
+
+	return ret;
 }
 
 BAREBOX_CMD_HELP_START(oftree)
-BAREBOX_CMD_HELP_USAGE("oftree [OPTIONS]\n")
-BAREBOX_CMD_HELP_OPT  ("-p <FILE>",  "probe devices in oftree from <file>\n")
-BAREBOX_CMD_HELP_OPT  ("-d [FILE]",  "dump oftree from [FILE] or the parsed tree if no file is given\n")
-BAREBOX_CMD_HELP_OPT  ("-f",  "free stored oftree\n")
+BAREBOX_CMD_HELP_USAGE("oftree [OPTIONS] [DTB]\n")
+BAREBOX_CMD_HELP_OPT  ("-l",  "Load [DTB] to internal devicetree\n")
+BAREBOX_CMD_HELP_OPT  ("-p",  "probe devices from stored devicetree\n")
+BAREBOX_CMD_HELP_OPT  ("-d",  "dump oftree from [DTB] or the parsed tree if no dtb is given\n")
+BAREBOX_CMD_HELP_OPT  ("-f",  "free stored devicetree\n")
+BAREBOX_CMD_HELP_OPT  ("-n <node>",  "specify root devicenode to dump for -d\n")
 BAREBOX_CMD_HELP_END
 
 BAREBOX_CMD_START(oftree)
 	.cmd		= do_oftree,
-	.usage		= "handle oftrees",
+	.usage		= "handle devicetrees",
 	BAREBOX_CMD_HELP(cmd_oftree_help)
 BAREBOX_CMD_END
diff --git a/common/oftree.c b/common/oftree.c
index d699cb6..0df5209 100644
--- a/common/oftree.c
+++ b/common/oftree.c
@@ -325,11 +325,14 @@ int of_fix_tree(struct fdt_header *fdt)
 struct fdt_header *of_get_fixed_tree(struct fdt_header *fdt)
 {
 	int ret;
-	void *fixfdt;
+	void *fixfdt, *internalfdt = NULL;
 	int size, align;
 
-	if (!fdt)
-		return NULL;
+	if (!fdt) {
+		fdt = internalfdt = of_flatten_dtb();
+		if (!fdt)
+			return NULL;
+	}
 
 	size = fdt_totalsize(fdt);
 
@@ -343,6 +346,8 @@ struct fdt_header *of_get_fixed_tree(struct fdt_header *fdt)
 	fixfdt = xmemalign(align, size + OFTREE_SIZE_INCREASE);
 	ret = fdt_open_into(fdt, fixfdt, size + OFTREE_SIZE_INCREASE);
 
+	free(internalfdt);
+
 	if (ret)
 		goto out_free;
 
-- 
1.7.10.4


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

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

* [PATCH 13/16] of: add of_delete_property
  2013-01-11 13:24 [PATCH] devicetree improvements Sascha Hauer
                   ` (11 preceding siblings ...)
  2013-01-11 13:24 ` [PATCH 12/16] oftree command: refactor Sascha Hauer
@ 2013-01-11 13:24 ` Sascha Hauer
  2013-01-11 13:24 ` [PATCH 14/16] of: rename new_device_node to of_new_node and export it Sascha Hauer
                   ` (2 subsequent siblings)
  15 siblings, 0 replies; 17+ messages in thread
From: Sascha Hauer @ 2013-01-11 13:24 UTC (permalink / raw)
  To: barebox

This adds a function to delete a property from the currently loaded
devicetree. Also export new_property as of_new_property.

Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
 drivers/of/base.c |   13 +++++++++++--
 include/of.h      |    3 +++
 2 files changed, 14 insertions(+), 2 deletions(-)

diff --git a/drivers/of/base.c b/drivers/of/base.c
index 527121d..5910b40 100644
--- a/drivers/of/base.c
+++ b/drivers/of/base.c
@@ -600,7 +600,7 @@ static struct device_node *new_device_node(struct device_node *parent)
 	return node;
 }
 
-static struct property *new_property(struct device_node *node, const char *name,
+struct property *of_new_property(struct device_node *node, const char *name,
 		const void *data, int len)
 {
 	struct property *prop;
@@ -617,6 +617,15 @@ static struct property *new_property(struct device_node *node, const char *name,
 	return prop;
 }
 
+void of_delete_property(struct property *pp)
+{
+	list_del(&pp->list);
+
+	free(pp->name);
+	free(pp->value);
+	free(pp);
+}
+
 static struct device_d *add_of_device(struct device_node *node)
 {
 	struct device_d *dev;
@@ -902,7 +911,7 @@ int of_unflatten_dtb(struct fdt_header *fdt)
 				p->value = xzalloc(len);
 				memcpy(p->value, nodep, len);
 			} else {
-				new_property(node, pathp, nodep, len);
+				of_new_property(node, pathp, nodep, len);
 			}
 			break;
 		case FDT_NOP:
diff --git a/include/of.h b/include/of.h
index e1a778d..e53f94c 100644
--- a/include/of.h
+++ b/include/of.h
@@ -108,6 +108,9 @@ int of_parse_dtb(struct fdt_header *fdt);
 void of_free(struct device_node *node);
 int of_unflatten_dtb(struct fdt_header *fdt);
 void *of_flatten_dtb(void);
+struct property *of_new_property(struct device_node *node, const char *name,
+		const void *data, int len);
+void of_delete_property(struct property *pp);
 
 int of_property_read_string(struct device_node *np, const char *propname,
 				const char **out_string);
-- 
1.7.10.4


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

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

* [PATCH 14/16] of: rename new_device_node to of_new_node and export it
  2013-01-11 13:24 [PATCH] devicetree improvements Sascha Hauer
                   ` (12 preceding siblings ...)
  2013-01-11 13:24 ` [PATCH 13/16] of: add of_delete_property Sascha Hauer
@ 2013-01-11 13:24 ` Sascha Hauer
  2013-01-11 13:24 ` [PATCH 15/16] commands: Add of_property command Sascha Hauer
  2013-01-11 13:24 ` [PATCH 16/16] commands: Add of_node command Sascha Hauer
  15 siblings, 0 replies; 17+ messages in thread
From: Sascha Hauer @ 2013-01-11 13:24 UTC (permalink / raw)
  To: barebox

of_new_node now takes the parent node and the name as argument and
creates a new node. This simplifies the caller and also makes the
function useful for others, so export it.

Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
 drivers/of/base.c |   24 +++++++++++++++++-------
 include/of.h      |    1 +
 2 files changed, 18 insertions(+), 7 deletions(-)

diff --git a/drivers/of/base.c b/drivers/of/base.c
index 5910b40..c9e93f6 100644
--- a/drivers/of/base.c
+++ b/drivers/of/base.c
@@ -585,18 +585,33 @@ void of_print_nodes(struct device_node *node, int indent)
 	printf("};\n");
 }
 
-static struct device_node *new_device_node(struct device_node *parent)
+struct device_node *of_new_node(struct device_node *parent, const char *name)
 {
 	struct device_node *node;
 
+	if (!parent && root_node)
+		return NULL;
+
 	node = xzalloc(sizeof(*node));
 	node->parent = parent;
 	if (parent)
 		list_add_tail(&node->parent_list, &parent->children);
+	else
+		root_node = node;
 
 	INIT_LIST_HEAD(&node->children);
 	INIT_LIST_HEAD(&node->properties);
 
+	if (parent) {
+		node->name = xstrdup(name);
+		node->full_name = asprintf("%s/%s", node->parent->full_name, name);
+	} else {
+		node->name = xstrdup("");
+		node->full_name = xstrdup("");
+	}
+
+	list_add_tail(&node->list, &allnodes);
+
 	return node;
 }
 
@@ -886,12 +901,7 @@ int of_unflatten_dtb(struct fdt_header *fdt)
 			if (n) {
 				node = n;
 			} else {
-				node = new_device_node(node);
-				if (!node->parent)
-					root_node = node;
-				node->full_name = xstrdup(buf);
-				node->name = xstrdup(pathp);
-				list_add_tail(&node->list, &allnodes);
+				node = of_new_node(node, pathp);
 			}
 			break;
 		case FDT_END_NODE:
diff --git a/include/of.h b/include/of.h
index e53f94c..ea23d85 100644
--- a/include/of.h
+++ b/include/of.h
@@ -108,6 +108,7 @@ int of_parse_dtb(struct fdt_header *fdt);
 void of_free(struct device_node *node);
 int of_unflatten_dtb(struct fdt_header *fdt);
 void *of_flatten_dtb(void);
+struct device_node *of_new_node(struct device_node *parent, const char *name);
 struct property *of_new_property(struct device_node *node, const char *name,
 		const void *data, int len);
 void of_delete_property(struct property *pp);
-- 
1.7.10.4


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

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

* [PATCH 15/16] commands: Add of_property command
  2013-01-11 13:24 [PATCH] devicetree improvements Sascha Hauer
                   ` (13 preceding siblings ...)
  2013-01-11 13:24 ` [PATCH 14/16] of: rename new_device_node to of_new_node and export it Sascha Hauer
@ 2013-01-11 13:24 ` Sascha Hauer
  2013-01-11 13:24 ` [PATCH 16/16] commands: Add of_node command Sascha Hauer
  15 siblings, 0 replies; 17+ messages in thread
From: Sascha Hauer @ 2013-01-11 13:24 UTC (permalink / raw)
  To: barebox

The of_property command allows to modify/add/delete properties.
Parsing user input is based on U-Boot code with some fixes added
for catching invalid input.

Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
 commands/Kconfig       |    8 ++
 commands/Makefile      |    1 +
 commands/of_property.c |  280 ++++++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 289 insertions(+)
 create mode 100644 commands/of_property.c

diff --git a/commands/Kconfig b/commands/Kconfig
index 53cee5c..c0879b9 100644
--- a/commands/Kconfig
+++ b/commands/Kconfig
@@ -484,6 +484,14 @@ config CMD_OFTREE_PROBE
 	help
 	  This enables the -p option to probe devices from the devicetree
 
+config CMD_OF_PROPERTY
+	tristate
+	select OFTREE
+	prompt "of_property"
+	help
+	  The of_property command allows setting and deleting of properties in
+	  the currently loaded devicetree.
+
 endmenu
 
 menu "testing"
diff --git a/commands/Makefile b/commands/Makefile
index 359f566..98d61c6 100644
--- a/commands/Makefile
+++ b/commands/Makefile
@@ -67,6 +67,7 @@ obj-$(CONFIG_CMD_LED_TRIGGER)	+= trigger.o
 obj-$(CONFIG_CMD_USB)		+= usb.o
 obj-$(CONFIG_CMD_TIME)		+= time.o
 obj-$(CONFIG_CMD_OFTREE)	+= oftree.o
+obj-$(CONFIG_CMD_OF_PROPERTY)	+= of_property.o
 obj-$(CONFIG_CMD_MAGICVAR)	+= magicvar.o
 obj-$(CONFIG_CMD_IOMEM)		+= iomem.o
 obj-$(CONFIG_CMD_LINUX_EXEC)	+= linux_exec.o
diff --git a/commands/of_property.c b/commands/of_property.c
new file mode 100644
index 0000000..42b6f11
--- /dev/null
+++ b/commands/of_property.c
@@ -0,0 +1,280 @@
+/*
+ * of_property.c - device tree property handling support
+ *
+ * Copyright (c) 2013 Sascha Hauer <s.hauer@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 <common.h>
+#include <environment.h>
+#include <fdt.h>
+#include <of.h>
+#include <command.h>
+#include <fs.h>
+#include <malloc.h>
+#include <libfdt.h>
+#include <linux/ctype.h>
+#include <asm/byteorder.h>
+#include <errno.h>
+#include <getopt.h>
+#include <init.h>
+
+static int of_parse_prop_cells(char * const *newval, int count, char *data, int *len)
+{
+	char *cp;
+	unsigned long tmp;	/* holds converted values */
+	int stridx = 0;
+	char *newp = newval[0];
+
+	newp++;
+
+	while (1) {
+		if (*newp == '>')
+			return 0;
+
+		if (*newp == '\0') {
+			newp = newval[++stridx];
+
+			if (stridx == count) {
+				printf("missing '>'\n");
+				return -EINVAL;
+			}
+
+			continue;
+		}
+
+		cp = newp;
+		tmp = simple_strtoul(cp, &newp, 0);
+		*(__be32 *)data = __cpu_to_be32(tmp);
+		data  += 4;
+		*len += 4;
+
+		/* If the ptr didn't advance, something went wrong */
+		if ((newp - cp) <= 0) {
+			printf("cannot not convert \"%s\"\n", cp);
+			return -EINVAL;
+		}
+
+		while (*newp == ' ')
+			newp++;
+	}
+}
+
+static int of_parse_prop_stream(char * const *newval, int count, char *data, int *len)
+{
+	char *cp;
+	unsigned long tmp;	/* holds converted values */
+	int stridx = 0;
+	char *newp = newval[0];
+
+	newp++;
+
+	while (1) {
+		if (*newp == ']')
+			return 0;
+
+		while (*newp == ' ')
+			newp++;
+
+		if (*newp == '\0') {
+			newp = newval[++stridx];
+
+			if (stridx == count) {
+				printf("missing ']'\n");
+				return -EINVAL;
+			}
+
+			continue;
+		}
+
+		cp = newp;
+		tmp = simple_strtoul(newp, &newp, 16);
+		*data++ = tmp & 0xff;
+		*len    = *len + 1;
+
+		/* If the ptr didn't advance, something went wrong */
+		if ((newp - cp) <= 0) {
+			printf("cannot not convert \"%s\"\n", cp);
+			return -EINVAL;
+		}
+	}
+}
+
+static int of_parse_prop_string(char * const *newval, int count, char *data, int *len)
+{
+	int stridx = 0;
+	char *newp = newval[0];
+
+	/*
+	 * Assume it is one or more strings.  Copy it into our
+	 * data area for convenience (including the
+	 * terminating '\0's).
+	 */
+	while (stridx < count) {
+		size_t length = strlen(newp) + 1;
+
+		strcpy(data, newp);
+		data += length;
+		*len += length;
+		newp = newval[++stridx];
+	}
+
+	return 0;
+}
+
+/*
+ * Parse the user's input, partially heuristic.  Valid formats:
+ * <0x00112233 4 05>	- an array of cells.  Numbers follow standard
+ *			C conventions.
+ * [00 11 22 .. nn] - byte stream
+ * "string"	- If the the value doesn't start with "<" or "[", it is
+ *			treated as a string.  Note that the quotes are
+ *			stripped by the parser before we get the string.
+ * newval: An array of strings containing the new property as specified
+ *	on the command line
+ * count: The number of strings in the array
+ * data: A bytestream to be placed in the property
+ * len: The length of the resulting bytestream
+ */
+static int of_parse_prop(char * const *newval, int count, char *data, int *len)
+{
+	char *newp;		/* temporary newval char pointer */
+
+	*len = 0;
+
+	if (!count)
+		return 0;
+
+	newp = newval[0];
+
+	switch (*newp) {
+	case '<':
+		return of_parse_prop_cells(newval, count, data, len);
+	case '[':
+		return of_parse_prop_stream(newval, count, data, len);
+	default:
+		return of_parse_prop_string(newval, count, data, len);
+	}
+}
+
+static int do_of_property(int argc, char *argv[])
+{
+	int opt;
+	int delete = 0;
+	int set = 0;
+	int ret;
+	char *path = NULL, *propname = NULL;
+	struct device_node *node = NULL;
+	struct property *pp = NULL;
+
+	while ((opt = getopt(argc, argv, "ds")) > 0) {
+		switch (opt) {
+		case 'd':
+			delete = 1;
+			break;
+		case 's':
+			set = 1;
+			break;
+		default:
+			return COMMAND_ERROR_USAGE;
+		}
+	}
+
+	if (optind < argc) {
+		path = argv[optind];
+		node = of_find_node_by_path(path);
+		if (!node) {
+			printf("Cannot find nodepath %s\n", path);
+			return -ENOENT;
+		}
+	}
+
+	if (optind + 1 < argc) {
+		propname = argv[optind + 1];
+
+		pp = of_find_property(node, propname);
+		if (!set && !pp) {
+			printf("Cannot find property %s\n", propname);
+			return -ENOENT;
+		}
+	}
+
+	debug("path: %s propname: %s\n", path, propname);
+
+	if (delete) {
+		if (!node || !pp)
+			return COMMAND_ERROR_USAGE;
+
+		of_delete_property(pp);
+
+		return 0;
+	}
+
+	if (set) {
+		int num_args = argc - optind - 2;
+		int len;
+		void *data;
+
+		if (!node)
+			return COMMAND_ERROR_USAGE;
+
+		/*
+		 * standard console buffer size. The result won't be bigger than the
+		 * string input.
+		 */
+		data = malloc(1024);
+		if (!data)
+			return -ENOMEM;
+
+		ret = of_parse_prop(&argv[optind + 2], num_args, data, &len);
+		if (ret) {
+			free(data);
+			return ret;
+		}
+
+		if (pp) {
+			free(pp->value);
+			/* limit property data to the actual size */
+			data = xrealloc(data, len);
+			pp->value = data;
+			pp->length = len;
+		} else {
+			pp = of_new_property(node, propname, data, len);
+			if (!pp) {
+				printf("Cannot create property %s\n", propname);
+				free(data);
+				return 1;
+			}
+		}
+	}
+
+	return 0;
+}
+
+BAREBOX_CMD_HELP_START(of_property)
+BAREBOX_CMD_HELP_USAGE("of_property [OPTIONS] [NODE] [PROPERTY] [VALUES]\n")
+BAREBOX_CMD_HELP_OPT  ("-s",  "set property to value\n")
+BAREBOX_CMD_HELP_OPT  ("-d",  "delete property\n")
+BAREBOX_CMD_HELP_TEXT ("\nvalid formats for values:\n")
+BAREBOX_CMD_HELP_TEXT ("<0x00112233 4 05> - an array of cells\n")
+BAREBOX_CMD_HELP_TEXT ("[00 11 22 .. nn]  - byte stream\n")
+BAREBOX_CMD_HELP_TEXT ("If the value does not start with '<' or '[' it is interpreted as strings\n")
+BAREBOX_CMD_HELP_END
+
+BAREBOX_CMD_START(of_property)
+	.cmd		= do_of_property,
+	.usage		= "handle of properties",
+	BAREBOX_CMD_HELP(cmd_of_property_help)
+BAREBOX_CMD_END
-- 
1.7.10.4


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

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

* [PATCH 16/16] commands: Add of_node command
  2013-01-11 13:24 [PATCH] devicetree improvements Sascha Hauer
                   ` (14 preceding siblings ...)
  2013-01-11 13:24 ` [PATCH 15/16] commands: Add of_property command Sascha Hauer
@ 2013-01-11 13:24 ` Sascha Hauer
  15 siblings, 0 replies; 17+ messages in thread
From: Sascha Hauer @ 2013-01-11 13:24 UTC (permalink / raw)
  To: barebox

This command allows to create/delete device nodes.

Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
 commands/Kconfig   |    7 ++++
 commands/Makefile  |    1 +
 commands/of_node.c |  111 ++++++++++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 119 insertions(+)
 create mode 100644 commands/of_node.c

diff --git a/commands/Kconfig b/commands/Kconfig
index c0879b9..9c668c6 100644
--- a/commands/Kconfig
+++ b/commands/Kconfig
@@ -492,6 +492,13 @@ config CMD_OF_PROPERTY
 	  The of_property command allows setting and deleting of properties in
 	  the currently loaded devicetree.
 
+config CMD_OF_NODE
+	tristate
+	select OFTREE
+	prompt "of_node"
+	help
+	  The of_property command allows adding and removing devicetree nodes.
+
 endmenu
 
 menu "testing"
diff --git a/commands/Makefile b/commands/Makefile
index 98d61c6..2df807b 100644
--- a/commands/Makefile
+++ b/commands/Makefile
@@ -68,6 +68,7 @@ obj-$(CONFIG_CMD_USB)		+= usb.o
 obj-$(CONFIG_CMD_TIME)		+= time.o
 obj-$(CONFIG_CMD_OFTREE)	+= oftree.o
 obj-$(CONFIG_CMD_OF_PROPERTY)	+= of_property.o
+obj-$(CONFIG_CMD_OF_NODE)	+= of_node.o
 obj-$(CONFIG_CMD_MAGICVAR)	+= magicvar.o
 obj-$(CONFIG_CMD_IOMEM)		+= iomem.o
 obj-$(CONFIG_CMD_LINUX_EXEC)	+= linux_exec.o
diff --git a/commands/of_node.c b/commands/of_node.c
new file mode 100644
index 0000000..a370e26
--- /dev/null
+++ b/commands/of_node.c
@@ -0,0 +1,111 @@
+/*
+ * of_node.c - device tree node handling support
+ *
+ * Copyright (c) 2013 Sascha Hauer <s.hauer@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 <common.h>
+#include <environment.h>
+#include <fdt.h>
+#include <of.h>
+#include <command.h>
+#include <fs.h>
+#include <malloc.h>
+#include <libfdt.h>
+#include <linux/ctype.h>
+#include <asm/byteorder.h>
+#include <errno.h>
+#include <getopt.h>
+#include <init.h>
+#include <libgen.h>
+
+static int do_of_node(int argc, char *argv[])
+{
+	int opt;
+	int delete = 0;
+	int create = 0;
+	char *path = NULL;
+	struct device_node *node = NULL;
+
+	while ((opt = getopt(argc, argv, "cd")) > 0) {
+		switch (opt) {
+		case 'c':
+			create = 1;
+			break;
+		case 'd':
+			delete = 1;
+			break;
+		default:
+			return COMMAND_ERROR_USAGE;
+		}
+	}
+
+	if (optind < argc) {
+		path = argv[optind];
+	}
+
+	if (create) {
+		char *name;
+
+		if (!path)
+			return COMMAND_ERROR_USAGE;
+
+		name = xstrdup(basename(path));
+		path = dirname(path);
+
+		node = of_find_node_by_path(path);
+		if (!node) {
+			printf("Cannot find nodepath %s\n", path);
+			free(name);
+			return -ENOENT;
+		}
+
+		debug("create node \"%s\" \"%s\"\n", path, name);
+
+		of_new_node(node, name);
+
+		free(name);
+
+		return 0;
+	}
+
+	if (delete) {
+		if (!path)
+			return COMMAND_ERROR_USAGE;
+
+		node = of_find_node_by_path(path);
+		if (!node) {
+			printf("Cannot find nodepath %s\n", path);
+			return -ENOENT;
+		}
+
+		of_free(node);
+	}
+
+	return 0;
+}
+
+BAREBOX_CMD_HELP_START(of_node)
+BAREBOX_CMD_HELP_USAGE("of_node [OPTIONS] [NODE] [NAME]\n")
+BAREBOX_CMD_HELP_OPT  ("-c",  "create a new node\n")
+BAREBOX_CMD_HELP_OPT  ("-d",  "delete a node\n")
+BAREBOX_CMD_HELP_END
+
+BAREBOX_CMD_START(of_node)
+	.cmd		= do_of_node,
+	.usage		= "handle of nodes",
+	BAREBOX_CMD_HELP(cmd_of_node_help)
+BAREBOX_CMD_END
-- 
1.7.10.4


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

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

end of thread, other threads:[~2013-01-11 13:25 UTC | newest]

Thread overview: 17+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2013-01-11 13:24 [PATCH] devicetree improvements Sascha Hauer
2013-01-11 13:24 ` [PATCH 01/16] of: make of_get_fixed_tree more universally usable Sascha Hauer
2013-01-11 13:24 ` [PATCH 02/16] of: Fix invalid path for of_find_node_by_path Sascha Hauer
2013-01-11 13:24 ` [PATCH 03/16] ARM android image: remove double of_fix_tree Sascha Hauer
2013-01-11 13:24 ` [PATCH 04/16] of: of_free fixes Sascha Hauer
2013-01-11 13:24 ` [PATCH 05/16] of of_free: remove old node from allnodes list Sascha Hauer
2013-01-11 13:24 ` [PATCH 06/16] of: return root node when looking for a node with path / Sascha Hauer
2013-01-11 13:24 ` [PATCH 07/16] of: rename of_parse_dtb to of_unflatten_dtb Sascha Hauer
2013-01-11 13:24 ` [PATCH 08/16] of: Add support for converting the unflattened tree back to a dtb Sascha Hauer
2013-01-11 13:24 ` [PATCH 09/16] of: remove unused barebox_fdt Sascha Hauer
2013-01-11 13:24 ` [PATCH 10/16] ARM bootm: only use concatenated oftree when no other is available Sascha Hauer
2013-01-11 13:24 ` [PATCH 11/16] of: unflatten: allow overlay dtbs Sascha Hauer
2013-01-11 13:24 ` [PATCH 12/16] oftree command: refactor Sascha Hauer
2013-01-11 13:24 ` [PATCH 13/16] of: add of_delete_property Sascha Hauer
2013-01-11 13:24 ` [PATCH 14/16] of: rename new_device_node to of_new_node and export it Sascha Hauer
2013-01-11 13:24 ` [PATCH 15/16] commands: Add of_property command Sascha Hauer
2013-01-11 13:24 ` [PATCH 16/16] commands: Add of_node command Sascha Hauer

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