All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 1/3] fdt.c: Add non-boottime device tree functions
       [not found] ` <1290021345-4303-1-git-send-email-stephen.neuendorffer-gjFFaj9aHVfQT0dZR+AlfA@public.gmane.org>
@ 2010-11-17 19:15   ` Stephen Neuendorffer
       [not found]     ` <17453aae-47e7-4b69-b7f4-b4577456c637-+Ck8Kgl/v09ZbvUCbuG1mrjjLBE8jN/0@public.gmane.org>
  2010-11-18 23:54     ` Stephen Neuendorffer
  1 sibling, 1 reply; 41+ messages in thread
From: Stephen Neuendorffer @ 2010-11-17 19:15 UTC (permalink / raw)
  To: grant.likely-s3s/WqlpOiPyB63q8FvJNQ,
	dirk.brandewie-Re5JQEeQqe8AvxtiuMwx3w,
	devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ

In preparation for providing run-time handling of device trees, factor
out some of the basic functions so that they take an arbitrary blob,
rather than relying on the single boot-time tree.

Signed-off-by: Stephen Neuendorffer <stephen.neuendorffer-gjFFaj9aHVfQT0dZR+AlfA@public.gmane.org>
---
 drivers/of/fdt.c       |  129 ++++++++++++++++++++++++++++++-----------------
 include/linux/of_fdt.h |    9 +++
 2 files changed, 91 insertions(+), 47 deletions(-)

diff --git a/drivers/of/fdt.c b/drivers/of/fdt.c
index c1360e0..6ae207a 100644
--- a/drivers/of/fdt.c
+++ b/drivers/of/fdt.c
@@ -22,6 +22,86 @@
 
 #include <asm/page.h>
 
+char *fdt_get_string(u32 offset,
+			  struct boot_param_header *blob)
+{
+	return ((char *)blob) +
+		be32_to_cpu(blob->off_dt_strings) + offset;
+}
+
+/**
+ * of_get_flat_dt_prop_blob - Given a node in the given flat blob, return
+ * the property ptr
+ *
+ * This function can be used within scan_flattened_dt callback to get
+ * access to properties
+ */
+void *fdt_get_property(unsigned long node, const char *name,
+				 unsigned long *size,
+				 struct boot_param_header *blob)
+{
+	unsigned long p = node;
+
+	do {
+		u32 tag = be32_to_cpup((__be32 *)p);
+		u32 sz, noff;
+		const char *nstr;
+
+		p += 4;
+		if (tag == OF_DT_NOP)
+			continue;
+		if (tag != OF_DT_PROP)
+			return NULL;
+
+		sz = be32_to_cpup((__be32 *)p);
+		noff = be32_to_cpup((__be32 *)(p + 4));
+		p += 8;
+		if (be32_to_cpu(blob->version) < 0x10)
+			p = ALIGN(p, sz >= 8 ? 8 : 4);
+
+		nstr = fdt_get_string(noff, blob);
+		if (nstr == NULL) {
+			pr_warning("Can't find property index name !\n");
+			return NULL;
+		}
+		if (strcmp(name, nstr) == 0) {
+			if (size)
+				*size = sz;
+			return (void *)p;
+		}
+		p += sz;
+		p = ALIGN(p, 4);
+	} while (1);
+}
+
+/**
+ * fdt_is_compatible - Return true if given node from the given blob has
+ * compat in its compatible list
+ * @node: node to test
+ * @compat: compatible string to compare with compatible list.
+ * @blob: A device tree blob
+ */
+int fdt_is_compatible(unsigned long node, const char *compat,
+				 struct boot_param_header *blob)
+{
+	const char *cp;
+	unsigned long cplen, l;
+
+	cp = fdt_get_property(node, "compatible", &cplen, blob);
+	if (cp == NULL)
+		return 0;
+	while (cplen > 0) {
+		if (of_compat_cmp(cp, compat, strlen(compat)) == 0)
+			return 1;
+		l = strlen(cp) + 1;
+		cp += l;
+		cplen -= l;
+	}
+
+	return 0;
+}
+
+/* Everything below here references initial_boot_params directly. */
 int __initdata dt_root_addr_cells;
 int __initdata dt_root_size_cells;
 
@@ -121,38 +201,7 @@ unsigned long __init of_get_flat_dt_root(void)
 void *__init of_get_flat_dt_prop(unsigned long node, const char *name,
 				 unsigned long *size)
 {
-	unsigned long p = node;
-
-	do {
-		u32 tag = be32_to_cpup((__be32 *)p);
-		u32 sz, noff;
-		const char *nstr;
-
-		p += 4;
-		if (tag == OF_DT_NOP)
-			continue;
-		if (tag != OF_DT_PROP)
-			return NULL;
-
-		sz = be32_to_cpup((__be32 *)p);
-		noff = be32_to_cpup((__be32 *)(p + 4));
-		p += 8;
-		if (be32_to_cpu(initial_boot_params->version) < 0x10)
-			p = ALIGN(p, sz >= 8 ? 8 : 4);
-
-		nstr = find_flat_dt_string(noff);
-		if (nstr == NULL) {
-			pr_warning("Can't find property index name !\n");
-			return NULL;
-		}
-		if (strcmp(name, nstr) == 0) {
-			if (size)
-				*size = sz;
-			return (void *)p;
-		}
-		p += sz;
-		p = ALIGN(p, 4);
-	} while (1);
+	return fdt_get_property(node, name, size, initial_boot_params);
 }
 
 /**
@@ -162,21 +211,7 @@ void *__init of_get_flat_dt_prop(unsigned long node, const char *name,
  */
 int __init of_flat_dt_is_compatible(unsigned long node, const char *compat)
 {
-	const char *cp;
-	unsigned long cplen, l;
-
-	cp = of_get_flat_dt_prop(node, "compatible", &cplen);
-	if (cp == NULL)
-		return 0;
-	while (cplen > 0) {
-		if (of_compat_cmp(cp, compat, strlen(compat)) == 0)
-			return 1;
-		l = strlen(cp) + 1;
-		cp += l;
-		cplen -= l;
-	}
-
-	return 0;
+	return fdt_is_compatible(node, compat, initial_boot_params);
 }
 
 static void *__init unflatten_dt_alloc(unsigned long *mem, unsigned long size,
diff --git a/include/linux/of_fdt.h b/include/linux/of_fdt.h
index 7bbf5b3..864ec47 100644
--- a/include/linux/of_fdt.h
+++ b/include/linux/of_fdt.h
@@ -58,6 +58,15 @@ struct boot_param_header {
 };
 
 #if defined(CONFIG_OF_FLATTREE)
+/* For scanning an arbitrary device-tree at any time */
+extern char *fdt_get_string(u32 offset,
+			    struct boot_param_header *blob);
+extern void *fdt_get_property(unsigned long node, const char *name,
+			      unsigned long *size,
+			      struct boot_param_header *blob);
+extern int fdt_is_compatible(unsigned long node, const char *name,
+			     struct boot_param_header *blob);
+
 /* TBD: Temporary export of fdt globals - remove when code fully merged */
 extern int __initdata dt_root_addr_cells;
 extern int __initdata dt_root_size_cells;
-- 
1.5.6.6



This email and any attachments are intended for the sole use of the named recipient(s) and contain(s) confidential information that may be proprietary, privileged or copyrighted under applicable law. If you are not the intended recipient, do not read, copy, or forward this email message or any attachments. Delete this email message and any attachments immediately.

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

* [PATCH 2/3] fdt.c: Refactor unflatten_dt_node
       [not found]   ` <1290021345-4303-2-git-send-email-stephen.neuendorffer-gjFFaj9aHVfQT0dZR+AlfA@public.gmane.org>
@ 2010-11-17 19:15     ` Stephen Neuendorffer
       [not found]       ` <897f0b2f-23ac-4652-a61b-fc1ff4e867b6-+Ck8Kgl/v0/T7m58JnLnSLjjLBE8jN/0@public.gmane.org>
  0 siblings, 1 reply; 41+ messages in thread
From: Stephen Neuendorffer @ 2010-11-17 19:15 UTC (permalink / raw)
  To: grant.likely-s3s/WqlpOiPyB63q8FvJNQ,
	dirk.brandewie-Re5JQEeQqe8AvxtiuMwx3w,
	devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ

unflatten_dt_node is a helper function that does most of the work to
convert a device tree blob into tree of device nodes.  This code
now uses a passed-in blob instead of using the single boot-time blob,
allowing it to be called in more contexts.

Signed-off-by: Stephen Neuendorffer <stephen.neuendorffer-gjFFaj9aHVfQT0dZR+AlfA@public.gmane.org>
---
 drivers/of/fdt.c |  251 +++++++++++++++++++++++++++---------------------------
 1 files changed, 127 insertions(+), 124 deletions(-)

diff --git a/drivers/of/fdt.c b/drivers/of/fdt.c
index 6ae207a..c448b2f 100644
--- a/drivers/of/fdt.c
+++ b/drivers/of/fdt.c
@@ -101,120 +101,7 @@ int fdt_is_compatible(unsigned long node, const char *compat,
 	return 0;
 }
 
-/* Everything below here references initial_boot_params directly. */
-int __initdata dt_root_addr_cells;
-int __initdata dt_root_size_cells;
-
-struct boot_param_header *initial_boot_params;
-
-char *find_flat_dt_string(u32 offset)
-{
-	return ((char *)initial_boot_params) +
-		be32_to_cpu(initial_boot_params->off_dt_strings) + offset;
-}
-
-/**
- * of_scan_flat_dt - scan flattened tree blob and call callback on each.
- * @it: callback function
- * @data: context data pointer
- *
- * This function is used to scan the flattened device-tree, it is
- * used to extract the memory information at boot before we can
- * unflatten the tree
- */
-int __init of_scan_flat_dt(int (*it)(unsigned long node,
-				     const char *uname, int depth,
-				     void *data),
-			   void *data)
-{
-	unsigned long p = ((unsigned long)initial_boot_params) +
-		be32_to_cpu(initial_boot_params->off_dt_struct);
-	int rc = 0;
-	int depth = -1;
-
-	do {
-		u32 tag = be32_to_cpup((__be32 *)p);
-		char *pathp;
-
-		p += 4;
-		if (tag == OF_DT_END_NODE) {
-			depth--;
-			continue;
-		}
-		if (tag == OF_DT_NOP)
-			continue;
-		if (tag == OF_DT_END)
-			break;
-		if (tag == OF_DT_PROP) {
-			u32 sz = be32_to_cpup((__be32 *)p);
-			p += 8;
-			if (be32_to_cpu(initial_boot_params->version) < 0x10)
-				p = ALIGN(p, sz >= 8 ? 8 : 4);
-			p += sz;
-			p = ALIGN(p, 4);
-			continue;
-		}
-		if (tag != OF_DT_BEGIN_NODE) {
-			pr_err("Invalid tag %x in flat device tree!\n", tag);
-			return -EINVAL;
-		}
-		depth++;
-		pathp = (char *)p;
-		p = ALIGN(p + strlen(pathp) + 1, 4);
-		if ((*pathp) == '/') {
-			char *lp, *np;
-			for (lp = NULL, np = pathp; *np; np++)
-				if ((*np) == '/')
-					lp = np+1;
-			if (lp != NULL)
-				pathp = lp;
-		}
-		rc = it(p, pathp, depth, data);
-		if (rc != 0)
-			break;
-	} while (1);
-
-	return rc;
-}
-
-/**
- * of_get_flat_dt_root - find the root node in the flat blob
- */
-unsigned long __init of_get_flat_dt_root(void)
-{
-	unsigned long p = ((unsigned long)initial_boot_params) +
-		be32_to_cpu(initial_boot_params->off_dt_struct);
-
-	while (be32_to_cpup((__be32 *)p) == OF_DT_NOP)
-		p += 4;
-	BUG_ON(be32_to_cpup((__be32 *)p) != OF_DT_BEGIN_NODE);
-	p += 4;
-	return ALIGN(p + strlen((char *)p) + 1, 4);
-}
-
-/**
- * of_get_flat_dt_prop - Given a node in the flat blob, return the property ptr
- *
- * This function can be used within scan_flattened_dt callback to get
- * access to properties
- */
-void *__init of_get_flat_dt_prop(unsigned long node, const char *name,
-				 unsigned long *size)
-{
-	return fdt_get_property(node, name, size, initial_boot_params);
-}
-
-/**
- * of_flat_dt_is_compatible - Return true if given node has compat in compatible list
- * @node: node to test
- * @compat: compatible string to compare with compatible list.
- */
-int __init of_flat_dt_is_compatible(unsigned long node, const char *compat)
-{
-	return fdt_is_compatible(node, compat, initial_boot_params);
-}
-
-static void *__init unflatten_dt_alloc(unsigned long *mem, unsigned long size,
+static void *unflatten_dt_alloc(unsigned long *mem, unsigned long size,
 				       unsigned long align)
 {
 	void *res;
@@ -232,12 +119,14 @@ static void *__init unflatten_dt_alloc(unsigned long *mem, unsigned long size,
  * @dad: Parent struct device_node
  * @allnextpp: pointer to ->allnext from last allocated device_node
  * @fpsize: Size of the node path up at the current depth.
+ * @blob: The parent device tree blob
  */
-unsigned long __init unflatten_dt_node(unsigned long mem,
-					unsigned long *p,
-					struct device_node *dad,
-					struct device_node ***allnextpp,
-					unsigned long fpsize)
+unsigned long unflatten_dt_node(unsigned long mem,
+				unsigned long *p,
+				struct device_node *dad,
+				struct device_node ***allnextpp,
+				unsigned long fpsize,
+				struct boot_param_header *blob)
 {
 	struct device_node *np;
 	struct property *pp, **prev_pp = NULL;
@@ -333,10 +222,10 @@ unsigned long __init unflatten_dt_node(unsigned long mem,
 		sz = be32_to_cpup((__be32 *)(*p));
 		noff = be32_to_cpup((__be32 *)((*p) + 4));
 		*p += 8;
-		if (be32_to_cpu(initial_boot_params->version) < 0x10)
+		if (be32_to_cpu(blob->version) < 0x10)
 			*p = ALIGN(*p, sz >= 8 ? 8 : 4);
 
-		pname = find_flat_dt_string(noff);
+		pname = fdt_get_string(noff, blob);
 		if (pname == NULL) {
 			pr_info("Can't find property name in list !\n");
 			break;
@@ -415,7 +304,8 @@ unsigned long __init unflatten_dt_node(unsigned long mem,
 		if (tag == OF_DT_NOP)
 			*p += 4;
 		else
-			mem = unflatten_dt_node(mem, p, np, allnextpp, fpsize);
+			mem = unflatten_dt_node(mem, p, np, allnextpp,
+						fpsize, blob);
 		tag = be32_to_cpup((__be32 *)(*p));
 	}
 	if (tag != OF_DT_END_NODE) {
@@ -426,6 +316,119 @@ unsigned long __init unflatten_dt_node(unsigned long mem,
 	return mem;
 }
 
+/* Everything below here references initial_boot_params directly. */
+int __initdata dt_root_addr_cells;
+int __initdata dt_root_size_cells;
+
+struct boot_param_header *initial_boot_params;
+
+char *find_flat_dt_string(u32 offset)
+{
+	return ((char *)initial_boot_params) +
+		be32_to_cpu(initial_boot_params->off_dt_strings) + offset;
+}
+
+/**
+ * of_scan_flat_dt - scan flattened tree blob and call callback on each.
+ * @it: callback function
+ * @data: context data pointer
+ *
+ * This function is used to scan the flattened device-tree, it is
+ * used to extract the memory information at boot before we can
+ * unflatten the tree
+ */
+int __init of_scan_flat_dt(int (*it)(unsigned long node,
+				     const char *uname, int depth,
+				     void *data),
+			   void *data)
+{
+	unsigned long p = ((unsigned long)initial_boot_params) +
+		be32_to_cpu(initial_boot_params->off_dt_struct);
+	int rc = 0;
+	int depth = -1;
+
+	do {
+		u32 tag = be32_to_cpup((__be32 *)p);
+		char *pathp;
+
+		p += 4;
+		if (tag == OF_DT_END_NODE) {
+			depth--;
+			continue;
+		}
+		if (tag == OF_DT_NOP)
+			continue;
+		if (tag == OF_DT_END)
+			break;
+		if (tag == OF_DT_PROP) {
+			u32 sz = be32_to_cpup((__be32 *)p);
+			p += 8;
+			if (be32_to_cpu(initial_boot_params->version) < 0x10)
+				p = ALIGN(p, sz >= 8 ? 8 : 4);
+			p += sz;
+			p = ALIGN(p, 4);
+			continue;
+		}
+		if (tag != OF_DT_BEGIN_NODE) {
+			pr_err("Invalid tag %x in flat device tree!\n", tag);
+			return -EINVAL;
+		}
+		depth++;
+		pathp = (char *)p;
+		p = ALIGN(p + strlen(pathp) + 1, 4);
+		if ((*pathp) == '/') {
+			char *lp, *np;
+			for (lp = NULL, np = pathp; *np; np++)
+				if ((*np) == '/')
+					lp = np+1;
+			if (lp != NULL)
+				pathp = lp;
+		}
+		rc = it(p, pathp, depth, data);
+		if (rc != 0)
+			break;
+	} while (1);
+
+	return rc;
+}
+
+/**
+ * of_get_flat_dt_root - find the root node in the flat blob
+ */
+unsigned long __init of_get_flat_dt_root(void)
+{
+	unsigned long p = ((unsigned long)initial_boot_params) +
+		be32_to_cpu(initial_boot_params->off_dt_struct);
+
+	while (be32_to_cpup((__be32 *)p) == OF_DT_NOP)
+		p += 4;
+	BUG_ON(be32_to_cpup((__be32 *)p) != OF_DT_BEGIN_NODE);
+	p += 4;
+	return ALIGN(p + strlen((char *)p) + 1, 4);
+}
+
+/**
+ * of_get_flat_dt_prop - Given a node in the flat blob, return the property ptr
+ *
+ * This function can be used within scan_flattened_dt callback to get
+ * access to properties
+ */
+void *__init of_get_flat_dt_prop(unsigned long node, const char *name,
+				 unsigned long *size)
+{
+	return fdt_get_property(node, name, size, initial_boot_params);
+}
+
+/**
+ * of_flat_dt_is_compatible - Return true if given node has compat in compatible list
+ * @node: node to test
+ * @compat: compatible string to compare with compatible list.
+ */
+int __init of_flat_dt_is_compatible(unsigned long node, const char *compat)
+{
+	return fdt_is_compatible(node, compat, initial_boot_params);
+}
+
 #ifdef CONFIG_BLK_DEV_INITRD
 /**
  * early_init_dt_check_for_initrd - Decode initrd location from flat tree
@@ -607,7 +610,7 @@ void __init unflatten_device_tree(void)
 	/* First pass, scan for size */
 	start = ((unsigned long)initial_boot_params) +
 		be32_to_cpu(initial_boot_params->off_dt_struct);
-	size = unflatten_dt_node(0, &start, NULL, NULL, 0);
+	size = unflatten_dt_node(0, &start, NULL, NULL, 0, initial_boot_params);
 	size = (size | 3) + 1;
 
 	pr_debug("  size is %lx, allocating...\n", size);
@@ -624,7 +627,7 @@ void __init unflatten_device_tree(void)
 	/* Second pass, do actual unflattening */
 	start = ((unsigned long)initial_boot_params) +
 		be32_to_cpu(initial_boot_params->off_dt_struct);
-	unflatten_dt_node(mem, &start, NULL, &allnextp, 0);
+	unflatten_dt_node(mem, &start, NULL, &allnextp, 0, initial_boot_params);
 	if (be32_to_cpup((__be32 *)start) != OF_DT_END)
 		pr_warning("Weird tag at end of tree: %08x\n", *((u32 *)start));
 	if (be32_to_cpu(((__be32 *)mem)[size / 4]) != 0xdeadbeef)
-- 
1.5.6.6



This email and any attachments are intended for the sole use of the named recipient(s) and contain(s) confidential information that may be proprietary, privileged or copyrighted under applicable law. If you are not the intended recipient, do not read, copy, or forward this email message or any attachments. Delete this email message and any attachments immediately.

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

* [PATCH 3/3] fdt.c: Refactor unflatten_device_tree and add fdt_unflatten_tree
       [not found]     ` <1290021345-4303-3-git-send-email-stephen.neuendorffer-gjFFaj9aHVfQT0dZR+AlfA@public.gmane.org>
@ 2010-11-17 19:15       ` Stephen Neuendorffer
       [not found]         ` <43c2cd79-efaf-4acf-9c85-ca2ef0738e92-RaUQJvECHis6W+Ha+8ZLibjjLBE8jN/0@public.gmane.org>
  0 siblings, 1 reply; 41+ messages in thread
From: Stephen Neuendorffer @ 2010-11-17 19:15 UTC (permalink / raw)
  To: grant.likely-s3s/WqlpOiPyB63q8FvJNQ,
	dirk.brandewie-Re5JQEeQqe8AvxtiuMwx3w,
	devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ

unflatten_device_tree has two dependencies on things that happen
during boot time.  Firstly, it references the initial device tree
directly. Secondly, it allocates memory using the early boot
allocator.  This patch factors out these dependencies and uses
the new __unflatten_device_tree function to implement a driver-visible
fdt_unflatten_tree function, which can be used to unflatten a
blob after boot time.

Signed-off-by: Stephen Neuendorffer <stephen.neuendorffer-gjFFaj9aHVfQT0dZR+AlfA@public.gmane.org>
---
 drivers/of/fdt.c       |  147 ++++++++++++++++++++++++++++++++----------------
 include/linux/of_fdt.h |    2 +
 2 files changed, 100 insertions(+), 49 deletions(-)

diff --git a/drivers/of/fdt.c b/drivers/of/fdt.c
index c448b2f..e98ee59 100644
--- a/drivers/of/fdt.c
+++ b/drivers/of/fdt.c
@@ -11,10 +11,12 @@
 
 #include <linux/kernel.h>
 #include <linux/initrd.h>
+#include <linux/module.h>
 #include <linux/of.h>
 #include <linux/of_fdt.h>
 #include <linux/string.h>
 #include <linux/errno.h>
+#include <linux/slab.h>
 
 #ifdef CONFIG_PPC
 #include <asm/machdep.h>
@@ -316,6 +318,94 @@ unsigned long unflatten_dt_node(unsigned long mem,
 	return mem;
 }
 
+/**
+ * __unflatten_device_tree - create tree of device_nodes from flat blob
+ *
+ * unflattens a device-tree, creating the
+ * tree of struct device_node. It also fills the "name" and "type"
+ * pointers of the nodes so the normal device-tree walking functions
+ * can be used.
+ * @blob: The blob to expand
+ * @mynodes: The device_node tree created by the call
+ * @dt_alloc: An allocator that provides memory for the resulting tree
+ */
+void __unflatten_device_tree(struct boot_param_header *blob,
+			     struct device_node **mynodes,
+			     unsigned long (*dt_alloc)(u64 size, u64 align))
+{
+	unsigned long start, mem, size;
+	struct device_node **allnextp = mynodes;
+
+	pr_debug(" -> unflatten_device_tree()\n");
+
+	if (!blob) {
+		pr_debug("No device tree pointer\n");
+		return;
+	}
+
+	pr_debug("Unflattening device tree:\n");
+	pr_debug("magic: %08x\n", be32_to_cpu(blob->magic));
+	pr_debug("size: %08x\n", be32_to_cpu(blob->totalsize));
+	pr_debug("version: %08x\n", be32_to_cpu(blob->version));
+
+	if (be32_to_cpu(blob->magic) != OF_DT_HEADER) {
+		pr_err("Invalid device tree blob header\n");
+		return;
+	}
+
+	/* First pass, scan for size */
+	start = ((unsigned long)blob) +
+		be32_to_cpu(blob->off_dt_struct);
+	size = unflatten_dt_node(0, &start, NULL, NULL, 0, blob);
+	size = (size | 3) + 1;
+
+	pr_debug("  size is %lx, allocating...\n", size);
+
+	/* Allocate memory for the expanded device tree */
+	mem = (unsigned long) dt_alloc(size + 4,
+			__alignof__(struct device_node));
+	mem = (unsigned long) __va(mem);
+
+	((__be32 *)mem)[size / 4] = cpu_to_be32(0xdeadbeef);
+
+	pr_debug("  unflattening %lx...\n", mem);
+
+	/* Second pass, do actual unflattening */
+	start = ((unsigned long)blob) +
+		be32_to_cpu(blob->off_dt_struct);
+	unflatten_dt_node(mem, &start, NULL, &allnextp, 0, blob);
+	if (be32_to_cpup((__be32 *)start) != OF_DT_END)
+		pr_warning("Weird tag at end of tree: %08x\n", *((u32 *)start));
+	if (be32_to_cpu(((__be32 *)mem)[size / 4]) != 0xdeadbeef)
+		pr_warning("End of tree marker overwritten: %08x\n",
+			   be32_to_cpu(((__be32 *)mem)[size / 4]));
+	*allnextp = NULL;
+
+	pr_debug(" <- unflatten_device_tree()\n");
+}
+
+static unsigned long kernel_tree_alloc(u64 size, u64 align)
+{
+	return (unsigned long) kzalloc(size, GFP_KERNEL);
+}
+
+/**
+ * fdt_unflatten_tree - create tree of device_nodes from flat blob
+ *
+ * unflattens the device-tree passed by the firmware, creating the
+ * tree of struct device_node. It also fills the "name" and "type"
+ * pointers of the nodes so the normal device-tree walking functions
+ * can be used.
+ */
+void fdt_unflatten_tree(unsigned long *blob,
+			struct device_node **mynodes)
+{
+	struct boot_param_header *device_tree =
+		(struct boot_param_header *)blob;
+	__unflatten_device_tree(device_tree, mynodes, &kernel_tree_alloc);
+}
+EXPORT_SYMBOL_GPL(fdt_unflatten_tree);
+
 /* Everything below here references initial_boot_params directly. */
 int __initdata dt_root_addr_cells;
 int __initdata dt_root_size_cells;
@@ -577,6 +667,12 @@ int __init early_init_dt_scan_chosen(unsigned long node, const char *uname,
 	return 1;
 }
 
+static unsigned long __init early_device_tree_alloc(u64 size, u64 align)
+{
+	unsigned long mem = early_init_dt_alloc_memory_arch(size, align);
+	return (unsigned long) __va(mem);
+}
+
 /**
  * unflatten_device_tree - create tree of device_nodes from flat blob
  *
@@ -587,58 +683,11 @@ int __init early_init_dt_scan_chosen(unsigned long node, const char *uname,
  */
 void __init unflatten_device_tree(void)
 {
-	unsigned long start, mem, size;
-	struct device_node **allnextp = &allnodes;
-
-	pr_debug(" -> unflatten_device_tree()\n");
-
-	if (!initial_boot_params) {
-		pr_debug("No device tree pointer\n");
-		return;
-	}
-
-	pr_debug("Unflattening device tree:\n");
-	pr_debug("magic: %08x\n", be32_to_cpu(initial_boot_params->magic));
-	pr_debug("size: %08x\n", be32_to_cpu(initial_boot_params->totalsize));
-	pr_debug("version: %08x\n", be32_to_cpu(initial_boot_params->version));
-
-	if (be32_to_cpu(initial_boot_params->magic) != OF_DT_HEADER) {
-		pr_err("Invalid device tree blob header\n");
-		return;
-	}
-
-	/* First pass, scan for size */
-	start = ((unsigned long)initial_boot_params) +
-		be32_to_cpu(initial_boot_params->off_dt_struct);
-	size = unflatten_dt_node(0, &start, NULL, NULL, 0, initial_boot_params);
-	size = (size | 3) + 1;
-
-	pr_debug("  size is %lx, allocating...\n", size);
-
-	/* Allocate memory for the expanded device tree */
-	mem = early_init_dt_alloc_memory_arch(size + 4,
-			__alignof__(struct device_node));
-	mem = (unsigned long) __va(mem);
-
-	((__be32 *)mem)[size / 4] = cpu_to_be32(0xdeadbeef);
-
-	pr_debug("  unflattening %lx...\n", mem);
-
-	/* Second pass, do actual unflattening */
-	start = ((unsigned long)initial_boot_params) +
-		be32_to_cpu(initial_boot_params->off_dt_struct);
-	unflatten_dt_node(mem, &start, NULL, &allnextp, 0, initial_boot_params);
-	if (be32_to_cpup((__be32 *)start) != OF_DT_END)
-		pr_warning("Weird tag at end of tree: %08x\n", *((u32 *)start));
-	if (be32_to_cpu(((__be32 *)mem)[size / 4]) != 0xdeadbeef)
-		pr_warning("End of tree marker overwritten: %08x\n",
-			   be32_to_cpu(((__be32 *)mem)[size / 4]));
-	*allnextp = NULL;
+	__unflatten_device_tree(initial_boot_params, &allnodes,
+				early_device_tree_alloc);
 
 	/* Get pointer to OF "/chosen" node for use everywhere */
 	of_chosen = of_find_node_by_path("/chosen");
 	if (of_chosen == NULL)
 		of_chosen = of_find_node_by_path("/chosen@0");
-
-	pr_debug(" <- unflatten_device_tree()\n");
 }
diff --git a/include/linux/of_fdt.h b/include/linux/of_fdt.h
index 864ec47..5b0e2f3 100644
--- a/include/linux/of_fdt.h
+++ b/include/linux/of_fdt.h
@@ -66,6 +66,8 @@ extern void *fdt_get_property(unsigned long node, const char *name,
 			      struct boot_param_header *blob);
 extern int fdt_is_compatible(unsigned long node, const char *name,
 			     struct boot_param_header *blob);
+extern void fdt_unflatten_tree(unsigned long *blob,
+			       struct device_node **mynodes);
 
 /* TBD: Temporary export of fdt globals - remove when code fully merged */
 extern int __initdata dt_root_addr_cells;
-- 
1.5.6.6



This email and any attachments are intended for the sole use of the named recipient(s) and contain(s) confidential information that may be proprietary, privileged or copyrighted under applicable law. If you are not the intended recipient, do not read, copy, or forward this email message or any attachments. Delete this email message and any attachments immediately.

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

* Re: [PATCH 1/3] fdt.c: Add non-boottime device tree functions
       [not found]     ` <17453aae-47e7-4b69-b7f4-b4577456c637-+Ck8Kgl/v09ZbvUCbuG1mrjjLBE8jN/0@public.gmane.org>
@ 2010-11-17 19:42       ` Grant Likely
       [not found]         ` <20101117194203.GA2352-MrY2KI0G/OVr83L8+7iqerDks+cytr/Z@public.gmane.org>
  0 siblings, 1 reply; 41+ messages in thread
From: Grant Likely @ 2010-11-17 19:42 UTC (permalink / raw)
  To: Stephen Neuendorffer; +Cc: devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ

On Wed, Nov 17, 2010 at 11:15:43AM -0800, Stephen Neuendorffer wrote:
> In preparation for providing run-time handling of device trees, factor
> out some of the basic functions so that they take an arbitrary blob,
> rather than relying on the single boot-time tree.
> 
> Signed-off-by: Stephen Neuendorffer <stephen.neuendorffer-gjFFaj9aHVfQT0dZR+AlfA@public.gmane.org>
> ---
>  drivers/of/fdt.c       |  129 ++++++++++++++++++++++++++++++-----------------
>  include/linux/of_fdt.h |    9 +++
>  2 files changed, 91 insertions(+), 47 deletions(-)
> 
> diff --git a/drivers/of/fdt.c b/drivers/of/fdt.c
> index c1360e0..6ae207a 100644
> --- a/drivers/of/fdt.c
> +++ b/drivers/of/fdt.c
> @@ -22,6 +22,86 @@
>  
>  #include <asm/page.h>
>  
> +char *fdt_get_string(u32 offset,
> +			  struct boot_param_header *blob)

nitpicking: Encouraged naming convention is of_flat_dt_* for this
file.  Also, I think it makes more sense for blob to be the first
argument in all of these functions.

> +{
> +	return ((char *)blob) +
> +		be32_to_cpu(blob->off_dt_strings) + offset;
> +}
> +
> +/**
> + * of_get_flat_dt_prop_blob - Given a node in the given flat blob, return
> + * the property ptr
> + *
> + * This function can be used within scan_flattened_dt callback to get
> + * access to properties
> + */
> +void *fdt_get_property(unsigned long node, const char *name,
> +				 unsigned long *size,
> +				 struct boot_param_header *blob)

Colocate this function with the defintiion of
of_flat_dt_get_property()

> +{
> +	unsigned long p = node;

I think 'p' can be made type void* to eliminate all the casting in
this function (although I understand that this patch just moves code;
so that change doesn't need to be in this patch.

> +
> +	do {
> +		u32 tag = be32_to_cpup((__be32 *)p);
> +		u32 sz, noff;
> +		const char *nstr;
> +
> +		p += 4;
> +		if (tag == OF_DT_NOP)
> +			continue;
> +		if (tag != OF_DT_PROP)
> +			return NULL;
> +
> +		sz = be32_to_cpup((__be32 *)p);
> +		noff = be32_to_cpup((__be32 *)(p + 4));
> +		p += 8;
> +		if (be32_to_cpu(blob->version) < 0x10)
> +			p = ALIGN(p, sz >= 8 ? 8 : 4);

If you change p to void*, then PTR_ALIGN can be used.

> +
> +		nstr = fdt_get_string(noff, blob);
> +		if (nstr == NULL) {
> +			pr_warning("Can't find property index name !\n");
> +			return NULL;
> +		}
> +		if (strcmp(name, nstr) == 0) {
> +			if (size)
> +				*size = sz;
> +			return (void *)p;
> +		}
> +		p += sz;
> +		p = ALIGN(p, 4);
> +	} while (1);
> +}
> +
> +/**
> + * fdt_is_compatible - Return true if given node from the given blob has
> + * compat in its compatible list
> + * @node: node to test
> + * @compat: compatible string to compare with compatible list.
> + * @blob: A device tree blob
> + */
> +int fdt_is_compatible(unsigned long node, const char *compat,
> +				 struct boot_param_header *blob)

Colocate this definition with of_flat_dt_is_compatible.

> +{
> +	const char *cp;
> +	unsigned long cplen, l;
> +
> +	cp = fdt_get_property(node, "compatible", &cplen, blob);
> +	if (cp == NULL)
> +		return 0;
> +	while (cplen > 0) {
> +		if (of_compat_cmp(cp, compat, strlen(compat)) == 0)
> +			return 1;
> +		l = strlen(cp) + 1;
> +		cp += l;
> +		cplen -= l;
> +	}
> +
> +	return 0;
> +}
> +
> +/* Everything below here references initial_boot_params directly. */
>  int __initdata dt_root_addr_cells;
>  int __initdata dt_root_size_cells;
>  
> @@ -121,38 +201,7 @@ unsigned long __init of_get_flat_dt_root(void)
>  void *__init of_get_flat_dt_prop(unsigned long node, const char *name,
>  				 unsigned long *size)
>  {
> -	unsigned long p = node;
> -
> -	do {
> -		u32 tag = be32_to_cpup((__be32 *)p);
> -		u32 sz, noff;
> -		const char *nstr;
> -
> -		p += 4;
> -		if (tag == OF_DT_NOP)
> -			continue;
> -		if (tag != OF_DT_PROP)
> -			return NULL;
> -
> -		sz = be32_to_cpup((__be32 *)p);
> -		noff = be32_to_cpup((__be32 *)(p + 4));
> -		p += 8;
> -		if (be32_to_cpu(initial_boot_params->version) < 0x10)
> -			p = ALIGN(p, sz >= 8 ? 8 : 4);
> -
> -		nstr = find_flat_dt_string(noff);
> -		if (nstr == NULL) {
> -			pr_warning("Can't find property index name !\n");
> -			return NULL;
> -		}
> -		if (strcmp(name, nstr) == 0) {
> -			if (size)
> -				*size = sz;
> -			return (void *)p;
> -		}
> -		p += sz;
> -		p = ALIGN(p, 4);
> -	} while (1);
> +	return fdt_get_property(node, name, size, initial_boot_params);
>  }
>  
>  /**
> @@ -162,21 +211,7 @@ void *__init of_get_flat_dt_prop(unsigned long node, const char *name,
>   */
>  int __init of_flat_dt_is_compatible(unsigned long node, const char *compat)
>  {
> -	const char *cp;
> -	unsigned long cplen, l;
> -
> -	cp = of_get_flat_dt_prop(node, "compatible", &cplen);
> -	if (cp == NULL)
> -		return 0;
> -	while (cplen > 0) {
> -		if (of_compat_cmp(cp, compat, strlen(compat)) == 0)
> -			return 1;
> -		l = strlen(cp) + 1;
> -		cp += l;
> -		cplen -= l;
> -	}
> -
> -	return 0;
> +	return fdt_is_compatible(node, compat, initial_boot_params);
>  }
>  
>  static void *__init unflatten_dt_alloc(unsigned long *mem, unsigned long size,
> diff --git a/include/linux/of_fdt.h b/include/linux/of_fdt.h
> index 7bbf5b3..864ec47 100644
> --- a/include/linux/of_fdt.h
> +++ b/include/linux/of_fdt.h
> @@ -58,6 +58,15 @@ struct boot_param_header {
>  };
>  
>  #if defined(CONFIG_OF_FLATTREE)
> +/* For scanning an arbitrary device-tree at any time */
> +extern char *fdt_get_string(u32 offset,
> +			    struct boot_param_header *blob);
> +extern void *fdt_get_property(unsigned long node, const char *name,
> +			      unsigned long *size,
> +			      struct boot_param_header *blob);
> +extern int fdt_is_compatible(unsigned long node, const char *name,
> +			     struct boot_param_header *blob);
> +

Other than renaming the functions to match the existing naming
convention, and making 'blob' the first argument, this patch looks
good to me.

g.

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

* RE: [PATCH 1/3] fdt.c: Add non-boottime device tree functions
       [not found]         ` <20101117194203.GA2352-MrY2KI0G/OVr83L8+7iqerDks+cytr/Z@public.gmane.org>
@ 2010-11-17 19:46           ` Stephen Neuendorffer
       [not found]             ` <ed30f7b9-a1dd-4cd3-a6df-f2361e790185-+Ck8Kgl/v08opVzHvkXDF7jjLBE8jN/0@public.gmane.org>
  2010-11-17 22:53           ` Stephen Neuendorffer
  1 sibling, 1 reply; 41+ messages in thread
From: Stephen Neuendorffer @ 2010-11-17 19:46 UTC (permalink / raw)
  To: Grant Likely; +Cc: devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ



> -----Original Message-----
> From: Grant Likely [mailto:glikely-s3s/WqlpOiPyB63q8FvJNQ@public.gmane.org] On Behalf Of Grant
Likely
> Sent: Wednesday, November 17, 2010 11:42 AM
> To: Stephen Neuendorffer
> Cc: dirk.brandewie-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org; devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ@public.gmane.org
> Subject: Re: [PATCH 1/3] fdt.c: Add non-boottime device tree functions
> 
> On Wed, Nov 17, 2010 at 11:15:43AM -0800, Stephen Neuendorffer wrote:
> > In preparation for providing run-time handling of device trees,
factor
> > out some of the basic functions so that they take an arbitrary blob,
> > rather than relying on the single boot-time tree.
> >
> > Signed-off-by: Stephen Neuendorffer
<stephen.neuendorffer-gjFFaj9aHVfQT0dZR+AlfA@public.gmane.org>
> > ---
> >  drivers/of/fdt.c       |  129
++++++++++++++++++++++++++++++-----------------
> >  include/linux/of_fdt.h |    9 +++
> >  2 files changed, 91 insertions(+), 47 deletions(-)
> >
> > diff --git a/drivers/of/fdt.c b/drivers/of/fdt.c
> > index c1360e0..6ae207a 100644
> > --- a/drivers/of/fdt.c
> > +++ b/drivers/of/fdt.c
> > @@ -22,6 +22,86 @@
> >
> >  #include <asm/page.h>
> >
> > +char *fdt_get_string(u32 offset,
> > +			  struct boot_param_header *blob)
> 
> nitpicking: Encouraged naming convention is of_flat_dt_* for this
> file.  Also, I think it makes more sense for blob to be the first
> argument in all of these functions.

OK... Half of the other functions don't follow that convention, tho...
:)
 
> > +{
> > +	return ((char *)blob) +
> > +		be32_to_cpu(blob->off_dt_strings) + offset;
> > +}
> > +
> > +/**
> > + * of_get_flat_dt_prop_blob - Given a node in the given flat blob,
return
> > + * the property ptr
> > + *
> > + * This function can be used within scan_flattened_dt callback to
get
> > + * access to properties
> > + */
> > +void *fdt_get_property(unsigned long node, const char *name,
> > +				 unsigned long *size,
> > +				 struct boot_param_header *blob)
> 
> Colocate this function with the defintiion of
> of_flat_dt_get_property()

I was trying to separate them lexically from the __init functions, to
avoid confusion
and with the perhaps later intention of putting the early stuff in a
separate file.

> > +{
> > +	unsigned long p = node;
> 
> I think 'p' can be made type void* to eliminate all the casting in
> this function (although I understand that this patch just moves code;
> so that change doesn't need to be in this patch.

I don't intend to make such changes.  (I agree that it would be nice
if the tree no longer references the blob, however).

Steve


This email and any attachments are intended for the sole use of the named recipient(s) and contain(s) confidential information that may be proprietary, privileged or copyrighted under applicable law. If you are not the intended recipient, do not read, copy, or forward this email message or any attachments. Delete this email message and any attachments immediately.

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

* Re: [PATCH 2/3] fdt.c: Refactor unflatten_dt_node
       [not found]       ` <897f0b2f-23ac-4652-a61b-fc1ff4e867b6-+Ck8Kgl/v0/T7m58JnLnSLjjLBE8jN/0@public.gmane.org>
@ 2010-11-17 19:50         ` Grant Likely
  0 siblings, 0 replies; 41+ messages in thread
From: Grant Likely @ 2010-11-17 19:50 UTC (permalink / raw)
  To: Stephen Neuendorffer; +Cc: devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ

On Wed, Nov 17, 2010 at 11:15:44AM -0800, Stephen Neuendorffer wrote:
> unflatten_dt_node is a helper function that does most of the work to
> convert a device tree blob into tree of device nodes.  This code
> now uses a passed-in blob instead of using the single boot-time blob,
> allowing it to be called in more contexts.
> 
> Signed-off-by: Stephen Neuendorffer <stephen.neuendorffer-gjFFaj9aHVfQT0dZR+AlfA@public.gmane.org>

Bulk of the patch looks good but a bit hard to review due to the way
it is constructed (see below).

g.

> ---
>  drivers/of/fdt.c |  251 +++++++++++++++++++++++++++---------------------------
>  1 files changed, 127 insertions(+), 124 deletions(-)
> 
> diff --git a/drivers/of/fdt.c b/drivers/of/fdt.c
> index 6ae207a..c448b2f 100644
> --- a/drivers/of/fdt.c
> +++ b/drivers/of/fdt.c
> @@ -101,120 +101,7 @@ int fdt_is_compatible(unsigned long node, const char *compat,
>  	return 0;
>  }
>  
> -/* Everything below here references initial_boot_params directly. */
> -int __initdata dt_root_addr_cells;
> -int __initdata dt_root_size_cells;
> -
> -struct boot_param_header *initial_boot_params;
> -
> -char *find_flat_dt_string(u32 offset)
> -{
> -	return ((char *)initial_boot_params) +
> -		be32_to_cpu(initial_boot_params->off_dt_strings) + offset;
> -}
> -
> -/**
> - * of_scan_flat_dt - scan flattened tree blob and call callback on each.
> - * @it: callback function
> - * @data: context data pointer
> - *
> - * This function is used to scan the flattened device-tree, it is
> - * used to extract the memory information at boot before we can
> - * unflatten the tree
> - */
> -int __init of_scan_flat_dt(int (*it)(unsigned long node,
> -				     const char *uname, int depth,
> -				     void *data),
> -			   void *data)
> -{
> -	unsigned long p = ((unsigned long)initial_boot_params) +
> -		be32_to_cpu(initial_boot_params->off_dt_struct);
> -	int rc = 0;
> -	int depth = -1;
> -
> -	do {
> -		u32 tag = be32_to_cpup((__be32 *)p);
> -		char *pathp;
> -
> -		p += 4;
> -		if (tag == OF_DT_END_NODE) {
> -			depth--;
> -			continue;
> -		}
> -		if (tag == OF_DT_NOP)
> -			continue;
> -		if (tag == OF_DT_END)
> -			break;
> -		if (tag == OF_DT_PROP) {
> -			u32 sz = be32_to_cpup((__be32 *)p);
> -			p += 8;
> -			if (be32_to_cpu(initial_boot_params->version) < 0x10)
> -				p = ALIGN(p, sz >= 8 ? 8 : 4);
> -			p += sz;
> -			p = ALIGN(p, 4);
> -			continue;
> -		}
> -		if (tag != OF_DT_BEGIN_NODE) {
> -			pr_err("Invalid tag %x in flat device tree!\n", tag);
> -			return -EINVAL;
> -		}
> -		depth++;
> -		pathp = (char *)p;
> -		p = ALIGN(p + strlen(pathp) + 1, 4);
> -		if ((*pathp) == '/') {
> -			char *lp, *np;
> -			for (lp = NULL, np = pathp; *np; np++)
> -				if ((*np) == '/')
> -					lp = np+1;
> -			if (lp != NULL)
> -				pathp = lp;
> -		}
> -		rc = it(p, pathp, depth, data);
> -		if (rc != 0)
> -			break;
> -	} while (1);
> -
> -	return rc;
> -}
> -
> -/**
> - * of_get_flat_dt_root - find the root node in the flat blob
> - */
> -unsigned long __init of_get_flat_dt_root(void)
> -{
> -	unsigned long p = ((unsigned long)initial_boot_params) +
> -		be32_to_cpu(initial_boot_params->off_dt_struct);
> -
> -	while (be32_to_cpup((__be32 *)p) == OF_DT_NOP)
> -		p += 4;
> -	BUG_ON(be32_to_cpup((__be32 *)p) != OF_DT_BEGIN_NODE);
> -	p += 4;
> -	return ALIGN(p + strlen((char *)p) + 1, 4);
> -}
> -
> -/**
> - * of_get_flat_dt_prop - Given a node in the flat blob, return the property ptr
> - *
> - * This function can be used within scan_flattened_dt callback to get
> - * access to properties
> - */
> -void *__init of_get_flat_dt_prop(unsigned long node, const char *name,
> -				 unsigned long *size)
> -{
> -	return fdt_get_property(node, name, size, initial_boot_params);
> -}
> -
> -/**
> - * of_flat_dt_is_compatible - Return true if given node has compat in compatible list
> - * @node: node to test
> - * @compat: compatible string to compare with compatible list.
> - */
> -int __init of_flat_dt_is_compatible(unsigned long node, const char *compat)
> -{
> -	return fdt_is_compatible(node, compat, initial_boot_params);
> -}
> -
> -static void *__init unflatten_dt_alloc(unsigned long *mem, unsigned long size,
> +static void *unflatten_dt_alloc(unsigned long *mem, unsigned long size,
>  				       unsigned long align)
>  {
>  	void *res;
> @@ -232,12 +119,14 @@ static void *__init unflatten_dt_alloc(unsigned long *mem, unsigned long size,
>   * @dad: Parent struct device_node
>   * @allnextpp: pointer to ->allnext from last allocated device_node
>   * @fpsize: Size of the node path up at the current depth.
> + * @blob: The parent device tree blob
>   */
> -unsigned long __init unflatten_dt_node(unsigned long mem,
> -					unsigned long *p,
> -					struct device_node *dad,
> -					struct device_node ***allnextpp,
> -					unsigned long fpsize)
> +unsigned long unflatten_dt_node(unsigned long mem,
> +				unsigned long *p,
> +				struct device_node *dad,
> +				struct device_node ***allnextpp,
> +				unsigned long fpsize,
> +				struct boot_param_header *blob)

Ditto here, blob should be the first argument.

>  {
>  	struct device_node *np;
>  	struct property *pp, **prev_pp = NULL;
> @@ -333,10 +222,10 @@ unsigned long __init unflatten_dt_node(unsigned long mem,
>  		sz = be32_to_cpup((__be32 *)(*p));
>  		noff = be32_to_cpup((__be32 *)((*p) + 4));
>  		*p += 8;
> -		if (be32_to_cpu(initial_boot_params->version) < 0x10)
> +		if (be32_to_cpu(blob->version) < 0x10)
>  			*p = ALIGN(*p, sz >= 8 ? 8 : 4);
>  
> -		pname = find_flat_dt_string(noff);
> +		pname = fdt_get_string(noff, blob);
>  		if (pname == NULL) {
>  			pr_info("Can't find property name in list !\n");
>  			break;
> @@ -415,7 +304,8 @@ unsigned long __init unflatten_dt_node(unsigned long mem,
>  		if (tag == OF_DT_NOP)
>  			*p += 4;
>  		else
> -			mem = unflatten_dt_node(mem, p, np, allnextpp, fpsize);
> +			mem = unflatten_dt_node(mem, p, np, allnextpp,
> +						fpsize, blob);
>  		tag = be32_to_cpup((__be32 *)(*p));
>  	}
>  	if (tag != OF_DT_END_NODE) {
> @@ -426,6 +316,119 @@ unsigned long __init unflatten_dt_node(unsigned long mem,
>  	return mem;
>  }
>  
> +/* Everything below here references initial_boot_params directly. */

Unfortunately moving stuff around like this makes the patch harder to
review because mechanical movement is mixed in with functional
changes.  Can you split the rearrangement into a separate patch?


> +int __initdata dt_root_addr_cells;
> +int __initdata dt_root_size_cells;
> +
> +struct boot_param_header *initial_boot_params;
> +
> +char *find_flat_dt_string(u32 offset)
> +{
> +	return ((char *)initial_boot_params) +
> +		be32_to_cpu(initial_boot_params->off_dt_strings) + offset;
> +}

Shouldn't the body of find_flat_dt_string be using the new
fdt_get_string function from patch 1?  Or better yet, convert all
existing users to the new function?  (There are no users of
find_flat_dt_string outside of fdt.c).

> +
> +/**
> + * of_scan_flat_dt - scan flattened tree blob and call callback on each.
> + * @it: callback function
> + * @data: context data pointer
> + *
> + * This function is used to scan the flattened device-tree, it is
> + * used to extract the memory information at boot before we can
> + * unflatten the tree
> + */
> +int __init of_scan_flat_dt(int (*it)(unsigned long node,
> +				     const char *uname, int depth,
> +				     void *data),
> +			   void *data)
> +{
> +	unsigned long p = ((unsigned long)initial_boot_params) +
> +		be32_to_cpu(initial_boot_params->off_dt_struct);
> +	int rc = 0;
> +	int depth = -1;
> +
> +	do {
> +		u32 tag = be32_to_cpup((__be32 *)p);
> +		char *pathp;
> +
> +		p += 4;
> +		if (tag == OF_DT_END_NODE) {
> +			depth--;
> +			continue;
> +		}
> +		if (tag == OF_DT_NOP)
> +			continue;
> +		if (tag == OF_DT_END)
> +			break;
> +		if (tag == OF_DT_PROP) {
> +			u32 sz = be32_to_cpup((__be32 *)p);
> +			p += 8;
> +			if (be32_to_cpu(initial_boot_params->version) < 0x10)
> +				p = ALIGN(p, sz >= 8 ? 8 : 4);
> +			p += sz;
> +			p = ALIGN(p, 4);
> +			continue;
> +		}
> +		if (tag != OF_DT_BEGIN_NODE) {
> +			pr_err("Invalid tag %x in flat device tree!\n", tag);
> +			return -EINVAL;
> +		}
> +		depth++;
> +		pathp = (char *)p;
> +		p = ALIGN(p + strlen(pathp) + 1, 4);
> +		if ((*pathp) == '/') {
> +			char *lp, *np;
> +			for (lp = NULL, np = pathp; *np; np++)
> +				if ((*np) == '/')
> +					lp = np+1;
> +			if (lp != NULL)
> +				pathp = lp;
> +		}
> +		rc = it(p, pathp, depth, data);
> +		if (rc != 0)
> +			break;
> +	} while (1);
> +
> +	return rc;
> +}
> +
> +/**
> + * of_get_flat_dt_root - find the root node in the flat blob
> + */
> +unsigned long __init of_get_flat_dt_root(void)
> +{
> +	unsigned long p = ((unsigned long)initial_boot_params) +
> +		be32_to_cpu(initial_boot_params->off_dt_struct);
> +
> +	while (be32_to_cpup((__be32 *)p) == OF_DT_NOP)
> +		p += 4;
> +	BUG_ON(be32_to_cpup((__be32 *)p) != OF_DT_BEGIN_NODE);
> +	p += 4;
> +	return ALIGN(p + strlen((char *)p) + 1, 4);
> +}

There should also be a generic version of this which accepts a blob
pointer.

> +
> +/**
> + * of_get_flat_dt_prop - Given a node in the flat blob, return the property ptr
> + *
> + * This function can be used within scan_flattened_dt callback to get
> + * access to properties
> + */
> +void *__init of_get_flat_dt_prop(unsigned long node, const char *name,
> +				 unsigned long *size)
> +{
> +	return fdt_get_property(node, name, size, initial_boot_params);
> +}
> +
> +/**
> + * of_flat_dt_is_compatible - Return true if given node has compat in compatible list
> + * @node: node to test
> + * @compat: compatible string to compare with compatible list.
> + */
> +int __init of_flat_dt_is_compatible(unsigned long node, const char *compat)
> +{
> +	return fdt_is_compatible(node, compat, initial_boot_params);
> +}
> +
>  #ifdef CONFIG_BLK_DEV_INITRD
>  /**
>   * early_init_dt_check_for_initrd - Decode initrd location from flat tree
> @@ -607,7 +610,7 @@ void __init unflatten_device_tree(void)
>  	/* First pass, scan for size */
>  	start = ((unsigned long)initial_boot_params) +
>  		be32_to_cpu(initial_boot_params->off_dt_struct);
> -	size = unflatten_dt_node(0, &start, NULL, NULL, 0);
> +	size = unflatten_dt_node(0, &start, NULL, NULL, 0, initial_boot_params);
>  	size = (size | 3) + 1;
>  
>  	pr_debug("  size is %lx, allocating...\n", size);
> @@ -624,7 +627,7 @@ void __init unflatten_device_tree(void)
>  	/* Second pass, do actual unflattening */
>  	start = ((unsigned long)initial_boot_params) +
>  		be32_to_cpu(initial_boot_params->off_dt_struct);
> -	unflatten_dt_node(mem, &start, NULL, &allnextp, 0);
> +	unflatten_dt_node(mem, &start, NULL, &allnextp, 0, initial_boot_params);
>  	if (be32_to_cpup((__be32 *)start) != OF_DT_END)
>  		pr_warning("Weird tag at end of tree: %08x\n", *((u32 *)start));
>  	if (be32_to_cpu(((__be32 *)mem)[size / 4]) != 0xdeadbeef)
> -- 
> 1.5.6.6
> 
> 
> 
> This email and any attachments are intended for the sole use of the named recipient(s) and contain(s) confidential information that may be proprietary, privileged or copyrighted under applicable law. If you are not the intended recipient, do not read, copy, or forward this email message or any attachments. Delete this email message and any attachments immediately.
> 
> 

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

* Re: [PATCH 3/3] fdt.c: Refactor unflatten_device_tree and add fdt_unflatten_tree
       [not found]         ` <43c2cd79-efaf-4acf-9c85-ca2ef0738e92-RaUQJvECHis6W+Ha+8ZLibjjLBE8jN/0@public.gmane.org>
@ 2010-11-17 19:57           ` Grant Likely
  0 siblings, 0 replies; 41+ messages in thread
From: Grant Likely @ 2010-11-17 19:57 UTC (permalink / raw)
  To: Stephen Neuendorffer; +Cc: devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ

On Wed, Nov 17, 2010 at 11:15:45AM -0800, Stephen Neuendorffer wrote:
> unflatten_device_tree has two dependencies on things that happen
> during boot time.  Firstly, it references the initial device tree
> directly. Secondly, it allocates memory using the early boot
> allocator.  This patch factors out these dependencies and uses
> the new __unflatten_device_tree function to implement a driver-visible
> fdt_unflatten_tree function, which can be used to unflatten a
> blob after boot time.
> 
> Signed-off-by: Stephen Neuendorffer <stephen.neuendorffer-gjFFaj9aHVfQT0dZR+AlfA@public.gmane.org>

Thanks for the series Stephen.  Looks pretty good.  A few more issues.
The hairiest of which is the ugly casting required to manipulate the
allocated mem pointer (see below).

> ---
>  drivers/of/fdt.c       |  147 ++++++++++++++++++++++++++++++++----------------
>  include/linux/of_fdt.h |    2 +
>  2 files changed, 100 insertions(+), 49 deletions(-)
> 
> diff --git a/drivers/of/fdt.c b/drivers/of/fdt.c
> index c448b2f..e98ee59 100644
> --- a/drivers/of/fdt.c
> +++ b/drivers/of/fdt.c
> @@ -11,10 +11,12 @@
>  
>  #include <linux/kernel.h>
>  #include <linux/initrd.h>
> +#include <linux/module.h>
>  #include <linux/of.h>
>  #include <linux/of_fdt.h>
>  #include <linux/string.h>
>  #include <linux/errno.h>
> +#include <linux/slab.h>
>  
>  #ifdef CONFIG_PPC
>  #include <asm/machdep.h>
> @@ -316,6 +318,94 @@ unsigned long unflatten_dt_node(unsigned long mem,
>  	return mem;
>  }
>  
> +/**
> + * __unflatten_device_tree - create tree of device_nodes from flat blob
> + *
> + * unflattens a device-tree, creating the
> + * tree of struct device_node. It also fills the "name" and "type"
> + * pointers of the nodes so the normal device-tree walking functions
> + * can be used.
> + * @blob: The blob to expand
> + * @mynodes: The device_node tree created by the call
> + * @dt_alloc: An allocator that provides memory for the resulting tree
> + */
> +void __unflatten_device_tree(struct boot_param_header *blob,
> +			     struct device_node **mynodes,
> +			     unsigned long (*dt_alloc)(u64 size, u64 align))
> +{
> +	unsigned long start, mem, size;

mem really needs to be changed to a void* I think (see below).

> +	struct device_node **allnextp = mynodes;
> +
> +	pr_debug(" -> unflatten_device_tree()\n");
> +
> +	if (!blob) {
> +		pr_debug("No device tree pointer\n");
> +		return;
> +	}
> +
> +	pr_debug("Unflattening device tree:\n");
> +	pr_debug("magic: %08x\n", be32_to_cpu(blob->magic));
> +	pr_debug("size: %08x\n", be32_to_cpu(blob->totalsize));
> +	pr_debug("version: %08x\n", be32_to_cpu(blob->version));
> +
> +	if (be32_to_cpu(blob->magic) != OF_DT_HEADER) {
> +		pr_err("Invalid device tree blob header\n");
> +		return;
> +	}
> +
> +	/* First pass, scan for size */
> +	start = ((unsigned long)blob) +
> +		be32_to_cpu(blob->off_dt_struct);
> +	size = unflatten_dt_node(0, &start, NULL, NULL, 0, blob);
> +	size = (size | 3) + 1;
> +
> +	pr_debug("  size is %lx, allocating...\n", size);
> +
> +	/* Allocate memory for the expanded device tree */
> +	mem = (unsigned long) dt_alloc(size + 4,
> +			__alignof__(struct device_node));
> +	mem = (unsigned long) __va(mem);
> +
> +	((__be32 *)mem)[size / 4] = cpu_to_be32(0xdeadbeef);
> +
> +	pr_debug("  unflattening %lx...\n", mem);
> +
> +	/* Second pass, do actual unflattening */
> +	start = ((unsigned long)blob) +
> +		be32_to_cpu(blob->off_dt_struct);
> +	unflatten_dt_node(mem, &start, NULL, &allnextp, 0, blob);
> +	if (be32_to_cpup((__be32 *)start) != OF_DT_END)
> +		pr_warning("Weird tag at end of tree: %08x\n", *((u32 *)start));
> +	if (be32_to_cpu(((__be32 *)mem)[size / 4]) != 0xdeadbeef)
> +		pr_warning("End of tree marker overwritten: %08x\n",
> +			   be32_to_cpu(((__be32 *)mem)[size / 4]));
> +	*allnextp = NULL;
> +
> +	pr_debug(" <- unflatten_device_tree()\n");
> +}
> +
> +static unsigned long kernel_tree_alloc(u64 size, u64 align)
> +{
> +	return (unsigned long) kzalloc(size, GFP_KERNEL);

The casting indicates a failure in implementation that needs to be
fixed.

> +}
> +
> +/**
> + * fdt_unflatten_tree - create tree of device_nodes from flat blob
> + *
> + * unflattens the device-tree passed by the firmware, creating the
> + * tree of struct device_node. It also fills the "name" and "type"
> + * pointers of the nodes so the normal device-tree walking functions
> + * can be used.
> + */
> +void fdt_unflatten_tree(unsigned long *blob,
> +			struct device_node **mynodes)
> +{
> +	struct boot_param_header *device_tree =
> +		(struct boot_param_header *)blob;
> +	__unflatten_device_tree(device_tree, mynodes, &kernel_tree_alloc);
> +}
> +EXPORT_SYMBOL_GPL(fdt_unflatten_tree);
> +
>  /* Everything below here references initial_boot_params directly. */
>  int __initdata dt_root_addr_cells;
>  int __initdata dt_root_size_cells;
> @@ -577,6 +667,12 @@ int __init early_init_dt_scan_chosen(unsigned long node, const char *uname,
>  	return 1;
>  }
>  
> +static unsigned long __init early_device_tree_alloc(u64 size, u64 align)
> +{
> +	unsigned long mem = early_init_dt_alloc_memory_arch(size, align);
> +	return (unsigned long) __va(mem);

__unflatten_device_tree is still also applying __va() to the return value
from the alloc function.

> +}
> +

Perhaps all arch users should just be forced to provide a real
function for early_init_dt_alloc_memory_arch (no macros or inlines).

>  /**
>   * unflatten_device_tree - create tree of device_nodes from flat blob
>   *
> @@ -587,58 +683,11 @@ int __init early_init_dt_scan_chosen(unsigned long node, const char *uname,
>   */
>  void __init unflatten_device_tree(void)
>  {
> -	unsigned long start, mem, size;
> -	struct device_node **allnextp = &allnodes;
> -
> -	pr_debug(" -> unflatten_device_tree()\n");
> -
> -	if (!initial_boot_params) {
> -		pr_debug("No device tree pointer\n");
> -		return;
> -	}
> -
> -	pr_debug("Unflattening device tree:\n");
> -	pr_debug("magic: %08x\n", be32_to_cpu(initial_boot_params->magic));
> -	pr_debug("size: %08x\n", be32_to_cpu(initial_boot_params->totalsize));
> -	pr_debug("version: %08x\n", be32_to_cpu(initial_boot_params->version));
> -
> -	if (be32_to_cpu(initial_boot_params->magic) != OF_DT_HEADER) {
> -		pr_err("Invalid device tree blob header\n");
> -		return;
> -	}
> -
> -	/* First pass, scan for size */
> -	start = ((unsigned long)initial_boot_params) +
> -		be32_to_cpu(initial_boot_params->off_dt_struct);
> -	size = unflatten_dt_node(0, &start, NULL, NULL, 0, initial_boot_params);
> -	size = (size | 3) + 1;
> -
> -	pr_debug("  size is %lx, allocating...\n", size);
> -
> -	/* Allocate memory for the expanded device tree */
> -	mem = early_init_dt_alloc_memory_arch(size + 4,
> -			__alignof__(struct device_node));
> -	mem = (unsigned long) __va(mem);
> -
> -	((__be32 *)mem)[size / 4] = cpu_to_be32(0xdeadbeef);
> -
> -	pr_debug("  unflattening %lx...\n", mem);
> -
> -	/* Second pass, do actual unflattening */
> -	start = ((unsigned long)initial_boot_params) +
> -		be32_to_cpu(initial_boot_params->off_dt_struct);
> -	unflatten_dt_node(mem, &start, NULL, &allnextp, 0, initial_boot_params);
> -	if (be32_to_cpup((__be32 *)start) != OF_DT_END)
> -		pr_warning("Weird tag at end of tree: %08x\n", *((u32 *)start));
> -	if (be32_to_cpu(((__be32 *)mem)[size / 4]) != 0xdeadbeef)
> -		pr_warning("End of tree marker overwritten: %08x\n",
> -			   be32_to_cpu(((__be32 *)mem)[size / 4]));
> -	*allnextp = NULL;
> +	__unflatten_device_tree(initial_boot_params, &allnodes,
> +				early_device_tree_alloc);
>  
>  	/* Get pointer to OF "/chosen" node for use everywhere */
>  	of_chosen = of_find_node_by_path("/chosen");
>  	if (of_chosen == NULL)
>  		of_chosen = of_find_node_by_path("/chosen@0");
> -
> -	pr_debug(" <- unflatten_device_tree()\n");
>  }
> diff --git a/include/linux/of_fdt.h b/include/linux/of_fdt.h
> index 864ec47..5b0e2f3 100644
> --- a/include/linux/of_fdt.h
> +++ b/include/linux/of_fdt.h
> @@ -66,6 +66,8 @@ extern void *fdt_get_property(unsigned long node, const char *name,
>  			      struct boot_param_header *blob);
>  extern int fdt_is_compatible(unsigned long node, const char *name,
>  			     struct boot_param_header *blob);
> +extern void fdt_unflatten_tree(unsigned long *blob,
> +			       struct device_node **mynodes);
>  
>  /* TBD: Temporary export of fdt globals - remove when code fully merged */
>  extern int __initdata dt_root_addr_cells;
> -- 
> 1.5.6.6
> 
> 
> 
> This email and any attachments are intended for the sole use of the named recipient(s) and contain(s) confidential information that may be proprietary, privileged or copyrighted under applicable law. If you are not the intended recipient, do not read, copy, or forward this email message or any attachments. Delete this email message and any attachments immediately.
> 
> 

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

* Re: [PATCH 1/3] fdt.c: Add non-boottime device tree functions
       [not found]             ` <ed30f7b9-a1dd-4cd3-a6df-f2361e790185-+Ck8Kgl/v08opVzHvkXDF7jjLBE8jN/0@public.gmane.org>
@ 2010-11-17 20:00               ` Grant Likely
       [not found]                 ` <20101117200012.GD2352-MrY2KI0G/OVr83L8+7iqerDks+cytr/Z@public.gmane.org>
  0 siblings, 1 reply; 41+ messages in thread
From: Grant Likely @ 2010-11-17 20:00 UTC (permalink / raw)
  To: Stephen Neuendorffer; +Cc: devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ

On Wed, Nov 17, 2010 at 11:46:07AM -0800, Stephen Neuendorffer wrote:
> 
> 
> > -----Original Message-----
> > From: Grant Likely [mailto:glikely-s3s/WqlpOiPyB63q8FvJNQ@public.gmane.org] On Behalf Of Grant
> Likely
> > Sent: Wednesday, November 17, 2010 11:42 AM
> > To: Stephen Neuendorffer
> > Cc: dirk.brandewie-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org; devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ@public.gmane.org
> > Subject: Re: [PATCH 1/3] fdt.c: Add non-boottime device tree functions
> > 
> > On Wed, Nov 17, 2010 at 11:15:43AM -0800, Stephen Neuendorffer wrote:
> > > In preparation for providing run-time handling of device trees,
> factor
> > > out some of the basic functions so that they take an arbitrary blob,
> > > rather than relying on the single boot-time tree.
> > >
> > > Signed-off-by: Stephen Neuendorffer
> <stephen.neuendorffer-gjFFaj9aHVfQT0dZR+AlfA@public.gmane.org>
> > > ---
> > >  drivers/of/fdt.c       |  129
> ++++++++++++++++++++++++++++++-----------------
> > >  include/linux/of_fdt.h |    9 +++
> > >  2 files changed, 91 insertions(+), 47 deletions(-)
> > >
> > > diff --git a/drivers/of/fdt.c b/drivers/of/fdt.c
> > > index c1360e0..6ae207a 100644
> > > --- a/drivers/of/fdt.c
> > > +++ b/drivers/of/fdt.c
> > > @@ -22,6 +22,86 @@
> > >
> > >  #include <asm/page.h>
> > >
> > > +char *fdt_get_string(u32 offset,
> > > +			  struct boot_param_header *blob)
> > 
> > nitpicking: Encouraged naming convention is of_flat_dt_* for this
> > file.  Also, I think it makes more sense for blob to be the first
> > argument in all of these functions.
> 
> OK... Half of the other functions don't follow that convention, tho...
> :)

I know.  It's a mess.  But I need to start with something to start
regaining sanity.  :)

>  
> > > +{
> > > +	return ((char *)blob) +
> > > +		be32_to_cpu(blob->off_dt_strings) + offset;
> > > +}
> > > +
> > > +/**
> > > + * of_get_flat_dt_prop_blob - Given a node in the given flat blob,
> return
> > > + * the property ptr
> > > + *
> > > + * This function can be used within scan_flattened_dt callback to
> get
> > > + * access to properties
> > > + */
> > > +void *fdt_get_property(unsigned long node, const char *name,
> > > +				 unsigned long *size,
> > > +				 struct boot_param_header *blob)
> > 
> > Colocate this function with the defintiion of
> > of_flat_dt_get_property()
> 
> I was trying to separate them lexically from the __init functions, to
> avoid confusion
> and with the perhaps later intention of putting the early stuff in a
> separate file.

Fair enough, but if so then split the reorg into a separate patch so
that this patch shows only the functional changes.  Moving stuff
around makes the diff much larger than it needs to be.

> 
> > > +{
> > > +	unsigned long p = node;
> > 
> > I think 'p' can be made type void* to eliminate all the casting in
> > this function (although I understand that this patch just moves code;
> > so that change doesn't need to be in this patch.
> 
> I don't intend to make such changes.  (I agree that it would be nice
> if the tree no longer references the blob, however).

I'm okay with that.  Mostly I was thinking out loud that it needs to
be done.  It is *not* a blocker on this patch.

g.

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

* RE: [PATCH 1/3] fdt.c: Add non-boottime device tree functions
       [not found]                 ` <20101117200012.GD2352-MrY2KI0G/OVr83L8+7iqerDks+cytr/Z@public.gmane.org>
@ 2010-11-17 21:41                   ` Stephen Neuendorffer
  0 siblings, 0 replies; 41+ messages in thread
From: Stephen Neuendorffer @ 2010-11-17 21:41 UTC (permalink / raw)
  To: Grant Likely; +Cc: devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ



> -----Original Message-----
> From: Grant Likely [mailto:glikely-s3s/WqlpOiPyB63q8FvJNQ@public.gmane.org] On Behalf Of Grant
Likely
> Sent: Wednesday, November 17, 2010 12:00 PM
> To: Stephen Neuendorffer
> Cc: dirk.brandewie-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org; devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ@public.gmane.org
> Subject: Re: [PATCH 1/3] fdt.c: Add non-boottime device tree functions
> 
> On Wed, Nov 17, 2010 at 11:46:07AM -0800, Stephen Neuendorffer wrote:
> >
> >
> > > -----Original Message-----
> > > From: Grant Likely [mailto:glikely-s3s/WqlpOiPyB63q8FvJNQ@public.gmane.org] On Behalf Of
Grant
> > Likely
> > > Sent: Wednesday, November 17, 2010 11:42 AM
> > > To: Stephen Neuendorffer
> > > Cc: dirk.brandewie-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org; devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ@public.gmane.org
> > > Subject: Re: [PATCH 1/3] fdt.c: Add non-boottime device tree
functions
> > >
> > > On Wed, Nov 17, 2010 at 11:15:43AM -0800, Stephen Neuendorffer
wrote:
> > > > In preparation for providing run-time handling of device trees,
> > factor
> > > > out some of the basic functions so that they take an arbitrary
blob,
> > > > rather than relying on the single boot-time tree.
> > > >
> > > > Signed-off-by: Stephen Neuendorffer
> > <stephen.neuendorffer-gjFFaj9aHVfQT0dZR+AlfA@public.gmane.org>
> > > > ---
> > > >  drivers/of/fdt.c       |  129
> > ++++++++++++++++++++++++++++++-----------------
> > > >  include/linux/of_fdt.h |    9 +++
> > > >  2 files changed, 91 insertions(+), 47 deletions(-)
> > > >
> > > > diff --git a/drivers/of/fdt.c b/drivers/of/fdt.c
> > > > index c1360e0..6ae207a 100644
> > > > --- a/drivers/of/fdt.c
> > > > +++ b/drivers/of/fdt.c
> > > > @@ -22,6 +22,86 @@
> > > >
> > > >  #include <asm/page.h>
> > > >
> > > > +char *fdt_get_string(u32 offset,
> > > > +			  struct boot_param_header *blob)
> > >
> > > nitpicking: Encouraged naming convention is of_flat_dt_* for this
> > > file.  Also, I think it makes more sense for blob to be the first
> > > argument in all of these functions.
> >
> > OK... Half of the other functions don't follow that convention,
tho...
> > :)
> 
> I know.  It's a mess.  But I need to start with something to start
> regaining sanity.  :)

I thought about this some more and I do think it makes sense to have the
'generic' functions in a separate namespace, since they really are
distinguished in usage from the others marked __init.  I started off
naming
these all *_blob, but the names were really ugly, especially since the
functions
that are getting refactored are the ones that already fail to follow the
convention.

Proposal: if/when the other functions get factored into a separate file,
they
should be renamed to be of_early_flat_dt_*.

Steve

This email and any attachments are intended for the sole use of the named recipient(s) and contain(s) confidential information that may be proprietary, privileged or copyrighted under applicable law. If you are not the intended recipient, do not read, copy, or forward this email message or any attachments. Delete this email message and any attachments immediately.

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

* RE: [PATCH 1/3] fdt.c: Add non-boottime device tree functions
       [not found]         ` <20101117194203.GA2352-MrY2KI0G/OVr83L8+7iqerDks+cytr/Z@public.gmane.org>
  2010-11-17 19:46           ` Stephen Neuendorffer
@ 2010-11-17 22:53           ` Stephen Neuendorffer
       [not found]             ` <eed86eda-ba28-4f12-b615-d293eb1a356e-+Ck8Kgl/v091zOOwW4IIhbjjLBE8jN/0@public.gmane.org>
  1 sibling, 1 reply; 41+ messages in thread
From: Stephen Neuendorffer @ 2010-11-17 22:53 UTC (permalink / raw)
  To: Grant Likely; +Cc: devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ



> -----Original Message-----
> From: Grant Likely [mailto:glikely-s3s/WqlpOiPyB63q8FvJNQ@public.gmane.org] On Behalf Of Grant
Likely
> Sent: Wednesday, November 17, 2010 11:42 AM
> To: Stephen Neuendorffer
> Cc: dirk.brandewie-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org; devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ@public.gmane.org
> Subject: Re: [PATCH 1/3] fdt.c: Add non-boottime device tree functions
> 
> On Wed, Nov 17, 2010 at 11:15:43AM -0800, Stephen Neuendorffer wrote:
> > In preparation for providing run-time handling of device trees,
factor
> > out some of the basic functions so that they take an arbitrary blob,
> > rather than relying on the single boot-time tree.
> >
> > Signed-off-by: Stephen Neuendorffer
<stephen.neuendorffer-gjFFaj9aHVfQT0dZR+AlfA@public.gmane.org>
> > ---
> >  drivers/of/fdt.c       |  129
++++++++++++++++++++++++++++++-----------------
> >  include/linux/of_fdt.h |    9 +++
> >  2 files changed, 91 insertions(+), 47 deletions(-)
> >
> > diff --git a/drivers/of/fdt.c b/drivers/of/fdt.c
> > index c1360e0..6ae207a 100644
> > --- a/drivers/of/fdt.c
> > +++ b/drivers/of/fdt.c
> > @@ -22,6 +22,86 @@
> >
> >  #include <asm/page.h>
> >
> > +char *fdt_get_string(u32 offset,
> > +			  struct boot_param_header *blob)
> 
> nitpicking: Encouraged naming convention is of_flat_dt_* for this
> file.  Also, I think it makes more sense for blob to be the first
> argument in all of these functions.

If I do the rename, then of_flat_dt_is_compatible has a conflict with
the non-blob function, which is
used all over the place in the powerpc platform code.  It seems like
there's already alot of nonsense
between drivers/of/fdt.c, CONFIG_FLATTREE, and of_flat_dt_* conventions.
Perhaps a non conflicting
convention?  of_fdt_* (to match the file) or flattree_* (to match the
Kconfig option).

Suggestions?

Steve


This email and any attachments are intended for the sole use of the named recipient(s) and contain(s) confidential information that may be proprietary, privileged or copyrighted under applicable law. If you are not the intended recipient, do not read, copy, or forward this email message or any attachments. Delete this email message and any attachments immediately.

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

* Re: [PATCH 1/3] fdt.c: Add non-boottime device tree functions
       [not found]             ` <eed86eda-ba28-4f12-b615-d293eb1a356e-+Ck8Kgl/v091zOOwW4IIhbjjLBE8jN/0@public.gmane.org>
@ 2010-11-18  5:35               ` Grant Likely
  0 siblings, 0 replies; 41+ messages in thread
From: Grant Likely @ 2010-11-18  5:35 UTC (permalink / raw)
  To: Stephen Neuendorffer; +Cc: devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ

On Wed, Nov 17, 2010 at 3:53 PM, Stephen Neuendorffer
<stephen.neuendorffer-gjFFaj9aHVfQT0dZR+AlfA@public.gmane.org> wrote:
>
>
>> -----Original Message-----
>> From: Grant Likely [mailto:glikely-s3s/WqlpOiPyB63q8FvJNQ@public.gmane.org] On Behalf Of Grant
> Likely
>> Sent: Wednesday, November 17, 2010 11:42 AM
>> To: Stephen Neuendorffer
>> Cc: dirk.brandewie-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org; devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ@public.gmane.org
>> Subject: Re: [PATCH 1/3] fdt.c: Add non-boottime device tree functions
>>
>> On Wed, Nov 17, 2010 at 11:15:43AM -0800, Stephen Neuendorffer wrote:
>> > In preparation for providing run-time handling of device trees,
> factor
>> > out some of the basic functions so that they take an arbitrary blob,
>> > rather than relying on the single boot-time tree.
>> >
>> > Signed-off-by: Stephen Neuendorffer
> <stephen.neuendorffer-gjFFaj9aHVfQT0dZR+AlfA@public.gmane.org>
>> > ---
>> >  drivers/of/fdt.c       |  129
> ++++++++++++++++++++++++++++++-----------------
>> >  include/linux/of_fdt.h |    9 +++
>> >  2 files changed, 91 insertions(+), 47 deletions(-)
>> >
>> > diff --git a/drivers/of/fdt.c b/drivers/of/fdt.c
>> > index c1360e0..6ae207a 100644
>> > --- a/drivers/of/fdt.c
>> > +++ b/drivers/of/fdt.c
>> > @@ -22,6 +22,86 @@
>> >
>> >  #include <asm/page.h>
>> >
>> > +char *fdt_get_string(u32 offset,
>> > +                     struct boot_param_header *blob)
>>
>> nitpicking: Encouraged naming convention is of_flat_dt_* for this
>> file.  Also, I think it makes more sense for blob to be the first
>> argument in all of these functions.
>
> If I do the rename, then of_flat_dt_is_compatible has a conflict with
> the non-blob function, which is
> used all over the place in the powerpc platform code.  It seems like
> there's already alot of nonsense
> between drivers/of/fdt.c, CONFIG_FLATTREE, and of_flat_dt_* conventions.
> Perhaps a non conflicting
> convention?  of_fdt_* (to match the file) or flattree_* (to match the
> Kconfig option).

Just discussed this on IRC, and even got into the prospect of
replacing the 'of' abbreviation entirely with something like 'dt'
('cause everyone agrees 'of' sucks, and can't figure out why we agreed
to that prefix in the first place).  The flat tree functions are also
get renamed to fdt_*

However, looking at the scope of the change, I doubt that the of_ -->
dt_ rename will actually happen.  So, in order to remain at least
slightly consistent, go ahead and use the of_fdt_ prefix if this
patch.  Bonus points if you also post a patch to rename the old
function names to of_fdt_initial_* (or something) and fixup all the
users (should be trivial since it will just be a global search and
replace).

g.

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

* [PATCH 0/7] add of_fdt_unflatten_tree
       [not found] <1290021345-4303-1-git-send-email-stephen.neuendorffer@xilinx.com>
@ 2010-11-18 23:54     ` Stephen Neuendorffer
       [not found] ` <1290021345-4303-2-git-send-email-stephen.neuendorffer@xilinx.com>
       [not found] ` <1290124502-13125-1-git-send-email-stephen.neuendorffer@xilinx.com>
  2 siblings, 0 replies; 41+ messages in thread
From: Stephen Neuendorffer @ 2010-11-18 23:54 UTC (permalink / raw)
  To: grant.likely-s3s/WqlpOiPyB63q8FvJNQ,
	dirk.brandewie-Re5JQEeQqe8AvxtiuMwx3w,
	devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ,
	linuxppc-dev-uLR06cmDAlY/bJ5BZ2RsiQ,
	microblaze-uclinux-rVRm/Wmeqae7NGdpmJTKYQ

	Currently, fdt blobs are handled solely at boot time.  However,
it may be useful to parse blobs into device trees after boot time.  For
instance, a PCIe device may have an FPGA which includes a device
tree.  This set of patches locally refactors the existing code to enable
this.

Patch 1 and 4-7 are the interesting bits.
Patch 2 and 3 provide the ability to use this code on x86, and are provided mostly for reference.

The non-early boot code has been compile-tested and executed on X86.

Stephen Neuendorffer (7):
  fdt: Add Kconfig for EARLY_FLATTREE
  arch/x86: Add support for device tree code.
  arch/x86: select OF and OF_FLATTREE
  fdt.c: Add non-boottime device tree functions
  fdt.c: Refactor unflatten_dt_node
  fdt.c: Reorder unflatten_dt_node
  fdt.c: Refactor unflatten_device_tree and add fdt_unflatten_tree

 arch/microblaze/Kconfig    |    1 +
 arch/powerpc/Kconfig       |    1 +
 arch/x86/Kconfig           |    2 +
 arch/x86/include/asm/irq.h |    2 +
 arch/x86/kernel/irq.c      |   11 ++
 drivers/of/Kconfig         |    5 +
 drivers/of/fdt.c           |  393 ++++++++++++++++++++++++++------------------
 include/linux/of_fdt.h     |   13 ++
 8 files changed, 272 insertions(+), 156 deletions(-)



This email and any attachments are intended for the sole use of the named recipient(s) and contain(s) confidential information that may be proprietary, privileged or copyrighted under applicable law. If you are not the intended recipient, do not read, copy, or forward this email message or any attachments. Delete this email message and any attachments immediately.

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

* [PATCH 0/7] add of_fdt_unflatten_tree
@ 2010-11-18 23:54     ` Stephen Neuendorffer
  0 siblings, 0 replies; 41+ messages in thread
From: Stephen Neuendorffer @ 2010-11-18 23:54 UTC (permalink / raw)
  To: grant.likely, dirk.brandewie, devicetree-discuss, linuxppc-dev,
	microblaze-uclinux

	Currently, fdt blobs are handled solely at boot time.  However,
it may be useful to parse blobs into device trees after boot time.  For
instance, a PCIe device may have an FPGA which includes a device
tree.  This set of patches locally refactors the existing code to enable
this.

Patch 1 and 4-7 are the interesting bits.
Patch 2 and 3 provide the ability to use this code on x86, and are provided mostly for reference.

The non-early boot code has been compile-tested and executed on X86.

Stephen Neuendorffer (7):
  fdt: Add Kconfig for EARLY_FLATTREE
  arch/x86: Add support for device tree code.
  arch/x86: select OF and OF_FLATTREE
  fdt.c: Add non-boottime device tree functions
  fdt.c: Refactor unflatten_dt_node
  fdt.c: Reorder unflatten_dt_node
  fdt.c: Refactor unflatten_device_tree and add fdt_unflatten_tree

 arch/microblaze/Kconfig    |    1 +
 arch/powerpc/Kconfig       |    1 +
 arch/x86/Kconfig           |    2 +
 arch/x86/include/asm/irq.h |    2 +
 arch/x86/kernel/irq.c      |   11 ++
 drivers/of/Kconfig         |    5 +
 drivers/of/fdt.c           |  393 ++++++++++++++++++++++++++------------------
 include/linux/of_fdt.h     |   13 ++
 8 files changed, 272 insertions(+), 156 deletions(-)



This email and any attachments are intended for the sole use of the named recipient(s) and contain(s) confidential information that may be proprietary, privileged or copyrighted under applicable law. If you are not the intended recipient, do not read, copy, or forward this email message or any attachments. Delete this email message and any attachments immediately.

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

* [PATCH 1/7] fdt: Add Kconfig for EARLY_FLATTREE
       [not found] ` <1290124502-13125-1-git-send-email-stephen.neuendorffer@xilinx.com>
@ 2010-11-18 23:54       ` Stephen Neuendorffer
       [not found]   ` <1290124502-13125-2-git-send-email-stephen.neuendorffer@xilinx.com>
  1 sibling, 0 replies; 41+ messages in thread
From: Stephen Neuendorffer @ 2010-11-18 23:54 UTC (permalink / raw)
  To: grant.likely-s3s/WqlpOiPyB63q8FvJNQ,
	dirk.brandewie-Re5JQEeQqe8AvxtiuMwx3w,
	devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ,
	linuxppc-dev-uLR06cmDAlY/bJ5BZ2RsiQ,
	microblaze-uclinux-rVRm/Wmeqae7NGdpmJTKYQ

The device tree code is now in two pieces: some which can be used generically
on any platform which selects CONFIG_OF_FLATTREE, and some early which is used
at boot time on only a few architectures.  This patch segregates the early
code so that only those architectures which care about it need compile it.
This also means that some of the requirements in the early code (such as
a cmd_line variable) that most architectures (e.g. X86) don't provide
can be ignored.

Signed-off-by: Stephen Neuendorffer <stephen.neuendorffer-gjFFaj9aHVfQT0dZR+AlfA@public.gmane.org>

----

Grant,
We had discussed doing something like this a loooong time ago.  This (or at
least some other way of dealing with cmd_line) is
actually necessary to compile on X86.  Do you still want to do it this way?
Looking at my old email, you suggested only powerpc and microblaze need this.
Is that still the case?

Conflicts:

	drivers/of/fdt.c
---
 arch/microblaze/Kconfig |    1 +
 arch/powerpc/Kconfig    |    1 +
 drivers/of/Kconfig      |    5 +++++
 drivers/of/fdt.c        |    4 ++++
 4 files changed, 11 insertions(+), 0 deletions(-)

diff --git a/arch/microblaze/Kconfig b/arch/microblaze/Kconfig
index 692fdfc..384375c 100644
--- a/arch/microblaze/Kconfig
+++ b/arch/microblaze/Kconfig
@@ -20,6 +20,7 @@ config MICROBLAZE
 	select TRACING_SUPPORT
 	select OF
 	select OF_FLATTREE
+	select OF_EARLY_FLATTREE
 
 config SWAP
 	def_bool n
diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig
index 631e5a0..2cd7b32 100644
--- a/arch/powerpc/Kconfig
+++ b/arch/powerpc/Kconfig
@@ -119,6 +119,7 @@ config PPC
 	default y
 	select OF
 	select OF_FLATTREE
+	select OF_EARLY_FLATTREE
 	select HAVE_FTRACE_MCOUNT_RECORD
 	select HAVE_DYNAMIC_FTRACE
 	select HAVE_FUNCTION_TRACER
diff --git a/drivers/of/Kconfig b/drivers/of/Kconfig
index aa675eb..0199157 100644
--- a/drivers/of/Kconfig
+++ b/drivers/of/Kconfig
@@ -19,6 +19,10 @@ config OF_FLATTREE
 	bool
 	select DTC
 
+config OF_EARLY_FLATTREE
+	bool
+	depends on OF_FLATTREE
+
 config OF_PROMTREE
 	bool
 
@@ -62,3 +66,4 @@ config OF_MDIO
 	  OpenFirmware MDIO bus (Ethernet PHY) accessors
 
 endmenu # OF
+
diff --git a/drivers/of/fdt.c b/drivers/of/fdt.c
index c1360e0..4d71b29 100644
--- a/drivers/of/fdt.c
+++ b/drivers/of/fdt.c
@@ -27,6 +27,8 @@ int __initdata dt_root_size_cells;
 
 struct boot_param_header *initial_boot_params;
 
+#ifdef CONFIG_EARLY_FLATTREE
+
 char *find_flat_dt_string(u32 offset)
 {
 	return ((char *)initial_boot_params) +
@@ -604,3 +606,5 @@ void __init unflatten_device_tree(void)
 
 	pr_debug(" <- unflatten_device_tree()\n");
 }
+
+#endif /* CONFIG_EARLY_FLATTREE */
-- 
1.5.6.6



This email and any attachments are intended for the sole use of the named recipient(s) and contain(s) confidential information that may be proprietary, privileged or copyrighted under applicable law. If you are not the intended recipient, do not read, copy, or forward this email message or any attachments. Delete this email message and any attachments immediately.

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

* [PATCH 1/7] fdt: Add Kconfig for EARLY_FLATTREE
@ 2010-11-18 23:54       ` Stephen Neuendorffer
  0 siblings, 0 replies; 41+ messages in thread
From: Stephen Neuendorffer @ 2010-11-18 23:54 UTC (permalink / raw)
  To: grant.likely, dirk.brandewie, devicetree-discuss, linuxppc-dev,
	microblaze-uclinux

The device tree code is now in two pieces: some which can be used generically
on any platform which selects CONFIG_OF_FLATTREE, and some early which is used
at boot time on only a few architectures.  This patch segregates the early
code so that only those architectures which care about it need compile it.
This also means that some of the requirements in the early code (such as
a cmd_line variable) that most architectures (e.g. X86) don't provide
can be ignored.

Signed-off-by: Stephen Neuendorffer <stephen.neuendorffer@xilinx.com>

----

Grant,
We had discussed doing something like this a loooong time ago.  This (or at
least some other way of dealing with cmd_line) is
actually necessary to compile on X86.  Do you still want to do it this way?
Looking at my old email, you suggested only powerpc and microblaze need this.
Is that still the case?

Conflicts:

	drivers/of/fdt.c
---
 arch/microblaze/Kconfig |    1 +
 arch/powerpc/Kconfig    |    1 +
 drivers/of/Kconfig      |    5 +++++
 drivers/of/fdt.c        |    4 ++++
 4 files changed, 11 insertions(+), 0 deletions(-)

diff --git a/arch/microblaze/Kconfig b/arch/microblaze/Kconfig
index 692fdfc..384375c 100644
--- a/arch/microblaze/Kconfig
+++ b/arch/microblaze/Kconfig
@@ -20,6 +20,7 @@ config MICROBLAZE
 	select TRACING_SUPPORT
 	select OF
 	select OF_FLATTREE
+	select OF_EARLY_FLATTREE
 
 config SWAP
 	def_bool n
diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig
index 631e5a0..2cd7b32 100644
--- a/arch/powerpc/Kconfig
+++ b/arch/powerpc/Kconfig
@@ -119,6 +119,7 @@ config PPC
 	default y
 	select OF
 	select OF_FLATTREE
+	select OF_EARLY_FLATTREE
 	select HAVE_FTRACE_MCOUNT_RECORD
 	select HAVE_DYNAMIC_FTRACE
 	select HAVE_FUNCTION_TRACER
diff --git a/drivers/of/Kconfig b/drivers/of/Kconfig
index aa675eb..0199157 100644
--- a/drivers/of/Kconfig
+++ b/drivers/of/Kconfig
@@ -19,6 +19,10 @@ config OF_FLATTREE
 	bool
 	select DTC
 
+config OF_EARLY_FLATTREE
+	bool
+	depends on OF_FLATTREE
+
 config OF_PROMTREE
 	bool
 
@@ -62,3 +66,4 @@ config OF_MDIO
 	  OpenFirmware MDIO bus (Ethernet PHY) accessors
 
 endmenu # OF
+
diff --git a/drivers/of/fdt.c b/drivers/of/fdt.c
index c1360e0..4d71b29 100644
--- a/drivers/of/fdt.c
+++ b/drivers/of/fdt.c
@@ -27,6 +27,8 @@ int __initdata dt_root_size_cells;
 
 struct boot_param_header *initial_boot_params;
 
+#ifdef CONFIG_EARLY_FLATTREE
+
 char *find_flat_dt_string(u32 offset)
 {
 	return ((char *)initial_boot_params) +
@@ -604,3 +606,5 @@ void __init unflatten_device_tree(void)
 
 	pr_debug(" <- unflatten_device_tree()\n");
 }
+
+#endif /* CONFIG_EARLY_FLATTREE */
-- 
1.5.6.6



This email and any attachments are intended for the sole use of the named recipient(s) and contain(s) confidential information that may be proprietary, privileged or copyrighted under applicable law. If you are not the intended recipient, do not read, copy, or forward this email message or any attachments. Delete this email message and any attachments immediately.

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

* [PATCH 2/7] arch/x86: Add support for device tree code.
       [not found]   ` <1290124502-13125-2-git-send-email-stephen.neuendorffer@xilinx.com>
@ 2010-11-18 23:54         ` Stephen Neuendorffer
       [not found]     ` <1290124502-13125-3-git-send-email-stephen.neuendorffer@xilinx.com>
  1 sibling, 0 replies; 41+ messages in thread
From: Stephen Neuendorffer @ 2010-11-18 23:54 UTC (permalink / raw)
  To: grant.likely-s3s/WqlpOiPyB63q8FvJNQ,
	dirk.brandewie-Re5JQEeQqe8AvxtiuMwx3w,
	devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ,
	linuxppc-dev-uLR06cmDAlY/bJ5BZ2RsiQ,
	microblaze-uclinux-rVRm/Wmeqae7NGdpmJTKYQ

A few support device-tree related support functions that x86 didn't
have before.

Signed-off-by: Stephen Neuendorffer <stephen.neuendorffer-gjFFaj9aHVfQT0dZR+AlfA@public.gmane.org>

----

Looks like just some irq related junk left!
---
 arch/x86/include/asm/irq.h |    2 ++
 arch/x86/kernel/irq.c      |   11 +++++++++++
 2 files changed, 13 insertions(+), 0 deletions(-)

diff --git a/arch/x86/include/asm/irq.h b/arch/x86/include/asm/irq.h
index 5458380..af4e630 100644
--- a/arch/x86/include/asm/irq.h
+++ b/arch/x86/include/asm/irq.h
@@ -10,6 +10,8 @@
 #include <asm/apicdef.h>
 #include <asm/irq_vectors.h>
 
+#define irq_dispose_mapping(...)
+
 static inline int irq_canonicalize(int irq)
 {
 	return ((irq == 2) ? 9 : irq);
diff --git a/arch/x86/kernel/irq.c b/arch/x86/kernel/irq.c
index 91fd0c7..a3aaed4 100644
--- a/arch/x86/kernel/irq.c
+++ b/arch/x86/kernel/irq.c
@@ -364,3 +364,14 @@ void fixup_irqs(void)
 	}
 }
 #endif
+
+#ifdef CONFIG_OF
+#include <linux/of_irq.h>
+unsigned int irq_create_of_mapping(struct device_node *controller,
+				   const u32 *intspec, unsigned int intsize)
+{
+	return intspec[0] + 1;
+}
+EXPORT_SYMBOL_GPL(irq_create_of_mapping);
+
+#endif
-- 
1.5.6.6



This email and any attachments are intended for the sole use of the named recipient(s) and contain(s) confidential information that may be proprietary, privileged or copyrighted under applicable law. If you are not the intended recipient, do not read, copy, or forward this email message or any attachments. Delete this email message and any attachments immediately.

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

* [PATCH 2/7] arch/x86: Add support for device tree code.
@ 2010-11-18 23:54         ` Stephen Neuendorffer
  0 siblings, 0 replies; 41+ messages in thread
From: Stephen Neuendorffer @ 2010-11-18 23:54 UTC (permalink / raw)
  To: grant.likely, dirk.brandewie, devicetree-discuss, linuxppc-dev,
	microblaze-uclinux

A few support device-tree related support functions that x86 didn't
have before.

Signed-off-by: Stephen Neuendorffer <stephen.neuendorffer@xilinx.com>

----

Looks like just some irq related junk left!
---
 arch/x86/include/asm/irq.h |    2 ++
 arch/x86/kernel/irq.c      |   11 +++++++++++
 2 files changed, 13 insertions(+), 0 deletions(-)

diff --git a/arch/x86/include/asm/irq.h b/arch/x86/include/asm/irq.h
index 5458380..af4e630 100644
--- a/arch/x86/include/asm/irq.h
+++ b/arch/x86/include/asm/irq.h
@@ -10,6 +10,8 @@
 #include <asm/apicdef.h>
 #include <asm/irq_vectors.h>
 
+#define irq_dispose_mapping(...)
+
 static inline int irq_canonicalize(int irq)
 {
 	return ((irq == 2) ? 9 : irq);
diff --git a/arch/x86/kernel/irq.c b/arch/x86/kernel/irq.c
index 91fd0c7..a3aaed4 100644
--- a/arch/x86/kernel/irq.c
+++ b/arch/x86/kernel/irq.c
@@ -364,3 +364,14 @@ void fixup_irqs(void)
 	}
 }
 #endif
+
+#ifdef CONFIG_OF
+#include <linux/of_irq.h>
+unsigned int irq_create_of_mapping(struct device_node *controller,
+				   const u32 *intspec, unsigned int intsize)
+{
+	return intspec[0] + 1;
+}
+EXPORT_SYMBOL_GPL(irq_create_of_mapping);
+
+#endif
-- 
1.5.6.6



This email and any attachments are intended for the sole use of the named recipient(s) and contain(s) confidential information that may be proprietary, privileged or copyrighted under applicable law. If you are not the intended recipient, do not read, copy, or forward this email message or any attachments. Delete this email message and any attachments immediately.

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

* [PATCH 3/7] arch/x86: select OF and OF_FLATTREE
       [not found]     ` <1290124502-13125-3-git-send-email-stephen.neuendorffer@xilinx.com>
@ 2010-11-18 23:54           ` Stephen Neuendorffer
       [not found]       ` <1290124502-13125-4-git-send-email-stephen.neuendorffer@xilinx.com>
  1 sibling, 0 replies; 41+ messages in thread
From: Stephen Neuendorffer @ 2010-11-18 23:54 UTC (permalink / raw)
  To: grant.likely-s3s/WqlpOiPyB63q8FvJNQ,
	dirk.brandewie-Re5JQEeQqe8AvxtiuMwx3w,
	devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ,
	linuxppc-dev-uLR06cmDAlY/bJ5BZ2RsiQ,
	microblaze-uclinux-rVRm/Wmeqae7NGdpmJTKYQ

Testing patch to verify that the device tree code can be compiled on X86.
---
 arch/x86/Kconfig |    2 ++
 1 files changed, 2 insertions(+), 0 deletions(-)

diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig
index cea0cd9..0f2ed5b 100644
--- a/arch/x86/Kconfig
+++ b/arch/x86/Kconfig
@@ -59,6 +59,8 @@ config X86
 	select ANON_INODES
 	select HAVE_ARCH_KMEMCHECK
 	select HAVE_USER_RETURN_NOTIFIER
+	select OF
+	select OF_FLATTREE
 
 config INSTRUCTION_DECODER
 	def_bool (KPROBES || PERF_EVENTS)
-- 
1.5.6.6



This email and any attachments are intended for the sole use of the named recipient(s) and contain(s) confidential information that may be proprietary, privileged or copyrighted under applicable law. If you are not the intended recipient, do not read, copy, or forward this email message or any attachments. Delete this email message and any attachments immediately.

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

* [PATCH 3/7] arch/x86: select OF and OF_FLATTREE
@ 2010-11-18 23:54           ` Stephen Neuendorffer
  0 siblings, 0 replies; 41+ messages in thread
From: Stephen Neuendorffer @ 2010-11-18 23:54 UTC (permalink / raw)
  To: grant.likely, dirk.brandewie, devicetree-discuss, linuxppc-dev,
	microblaze-uclinux

Testing patch to verify that the device tree code can be compiled on X86.
---
 arch/x86/Kconfig |    2 ++
 1 files changed, 2 insertions(+), 0 deletions(-)

diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig
index cea0cd9..0f2ed5b 100644
--- a/arch/x86/Kconfig
+++ b/arch/x86/Kconfig
@@ -59,6 +59,8 @@ config X86
 	select ANON_INODES
 	select HAVE_ARCH_KMEMCHECK
 	select HAVE_USER_RETURN_NOTIFIER
+	select OF
+	select OF_FLATTREE
 
 config INSTRUCTION_DECODER
 	def_bool (KPROBES || PERF_EVENTS)
-- 
1.5.6.6



This email and any attachments are intended for the sole use of the named recipient(s) and contain(s) confidential information that may be proprietary, privileged or copyrighted under applicable law. If you are not the intended recipient, do not read, copy, or forward this email message or any attachments. Delete this email message and any attachments immediately.

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

* [PATCH 4/7] fdt.c: Add non-boottime device tree functions
       [not found]       ` <1290124502-13125-4-git-send-email-stephen.neuendorffer@xilinx.com>
@ 2010-11-18 23:54             ` Stephen Neuendorffer
       [not found]         ` <1290124502-13125-5-git-send-email-stephen.neuendorffer@xilinx.com>
  1 sibling, 0 replies; 41+ messages in thread
From: Stephen Neuendorffer @ 2010-11-18 23:54 UTC (permalink / raw)
  To: grant.likely-s3s/WqlpOiPyB63q8FvJNQ,
	dirk.brandewie-Re5JQEeQqe8AvxtiuMwx3w,
	devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ,
	linuxppc-dev-uLR06cmDAlY/bJ5BZ2RsiQ,
	microblaze-uclinux-rVRm/Wmeqae7NGdpmJTKYQ

In preparation for providing run-time handling of device trees, factor
out some of the basic functions so that they take an arbitrary blob,
rather than relying on the single boot-time tree.

Signed-off-by: Stephen Neuendorffer <stephen.neuendorffer-gjFFaj9aHVfQT0dZR+AlfA@public.gmane.org>

--

V2: functions have of_fdt_* names
    removed find_flat_dt_string
    blob argument is first
---
 drivers/of/fdt.c       |  133 ++++++++++++++++++++++++++++-------------------
 include/linux/of_fdt.h |   11 ++++
 2 files changed, 90 insertions(+), 54 deletions(-)

diff --git a/drivers/of/fdt.c b/drivers/of/fdt.c
index 4d71b29..190e26c 100644
--- a/drivers/of/fdt.c
+++ b/drivers/of/fdt.c
@@ -22,6 +22,82 @@
 
 #include <asm/page.h>
 
+char *of_fdt_get_string(struct boot_param_header *blob, u32 offset)
+{
+	return ((char *)blob) +
+		be32_to_cpu(blob->off_dt_strings) + offset;
+}
+
+/**
+ * of_fdt_get_property - Given a node in the given flat blob, return
+ * the property ptr
+ */
+void *of_fdt_get_property(struct boot_param_header *blob,
+		       unsigned long node, const char *name,
+		       unsigned long *size)
+{
+	unsigned long p = node;
+
+	do {
+		u32 tag = be32_to_cpup((__be32 *)p);
+		u32 sz, noff;
+		const char *nstr;
+
+		p += 4;
+		if (tag == OF_DT_NOP)
+			continue;
+		if (tag != OF_DT_PROP)
+			return NULL;
+
+		sz = be32_to_cpup((__be32 *)p);
+		noff = be32_to_cpup((__be32 *)(p + 4));
+		p += 8;
+		if (be32_to_cpu(blob->version) < 0x10)
+			p = ALIGN(p, sz >= 8 ? 8 : 4);
+
+		nstr = of_fdt_get_string(blob, noff);
+		if (nstr == NULL) {
+			pr_warning("Can't find property index name !\n");
+			return NULL;
+		}
+		if (strcmp(name, nstr) == 0) {
+			if (size)
+				*size = sz;
+			return (void *)p;
+		}
+		p += sz;
+		p = ALIGN(p, 4);
+	} while (1);
+}
+
+/**
+ * of_fdt_is_compatible - Return true if given node from the given blob has
+ * compat in its compatible list
+ * @blob: A device tree blob
+ * @node: node to test
+ * @compat: compatible string to compare with compatible list.
+ */
+int of_fdt_is_compatible(struct boot_param_header *blob,
+		      unsigned long node, const char *compat)
+{
+	const char *cp;
+	unsigned long cplen, l;
+
+	cp = of_fdt_get_property(blob, node, "compatible", &cplen);
+	if (cp == NULL)
+		return 0;
+	while (cplen > 0) {
+		if (of_compat_cmp(cp, compat, strlen(compat)) == 0)
+			return 1;
+		l = strlen(cp) + 1;
+		cp += l;
+		cplen -= l;
+	}
+
+	return 0;
+}
+
+/* Everything below here references initial_boot_params directly. */
 int __initdata dt_root_addr_cells;
 int __initdata dt_root_size_cells;
 
@@ -29,12 +105,6 @@ struct boot_param_header *initial_boot_params;
 
 #ifdef CONFIG_EARLY_FLATTREE
 
-char *find_flat_dt_string(u32 offset)
-{
-	return ((char *)initial_boot_params) +
-		be32_to_cpu(initial_boot_params->off_dt_strings) + offset;
-}
-
 /**
  * of_scan_flat_dt - scan flattened tree blob and call callback on each.
  * @it: callback function
@@ -123,38 +193,7 @@ unsigned long __init of_get_flat_dt_root(void)
 void *__init of_get_flat_dt_prop(unsigned long node, const char *name,
 				 unsigned long *size)
 {
-	unsigned long p = node;
-
-	do {
-		u32 tag = be32_to_cpup((__be32 *)p);
-		u32 sz, noff;
-		const char *nstr;
-
-		p += 4;
-		if (tag == OF_DT_NOP)
-			continue;
-		if (tag != OF_DT_PROP)
-			return NULL;
-
-		sz = be32_to_cpup((__be32 *)p);
-		noff = be32_to_cpup((__be32 *)(p + 4));
-		p += 8;
-		if (be32_to_cpu(initial_boot_params->version) < 0x10)
-			p = ALIGN(p, sz >= 8 ? 8 : 4);
-
-		nstr = find_flat_dt_string(noff);
-		if (nstr == NULL) {
-			pr_warning("Can't find property index name !\n");
-			return NULL;
-		}
-		if (strcmp(name, nstr) == 0) {
-			if (size)
-				*size = sz;
-			return (void *)p;
-		}
-		p += sz;
-		p = ALIGN(p, 4);
-	} while (1);
+	return of_fdt_get_property(initial_boot_params, node, name, size);
 }
 
 /**
@@ -164,21 +203,7 @@ void *__init of_get_flat_dt_prop(unsigned long node, const char *name,
  */
 int __init of_flat_dt_is_compatible(unsigned long node, const char *compat)
 {
-	const char *cp;
-	unsigned long cplen, l;
-
-	cp = of_get_flat_dt_prop(node, "compatible", &cplen);
-	if (cp == NULL)
-		return 0;
-	while (cplen > 0) {
-		if (of_compat_cmp(cp, compat, strlen(compat)) == 0)
-			return 1;
-		l = strlen(cp) + 1;
-		cp += l;
-		cplen -= l;
-	}
-
-	return 0;
+	return of_fdt_is_compatible(initial_boot_params, node, compat);
 }
 
 static void *__init unflatten_dt_alloc(unsigned long *mem, unsigned long size,
@@ -303,7 +328,7 @@ unsigned long __init unflatten_dt_node(unsigned long mem,
 		if (be32_to_cpu(initial_boot_params->version) < 0x10)
 			*p = ALIGN(*p, sz >= 8 ? 8 : 4);
 
-		pname = find_flat_dt_string(noff);
+		pname = of_fdt_get_string(initial_boot_params, noff);
 		if (pname == NULL) {
 			pr_info("Can't find property name in list !\n");
 			break;
diff --git a/include/linux/of_fdt.h b/include/linux/of_fdt.h
index 7bbf5b3..70c5b73 100644
--- a/include/linux/of_fdt.h
+++ b/include/linux/of_fdt.h
@@ -58,6 +58,17 @@ struct boot_param_header {
 };
 
 #if defined(CONFIG_OF_FLATTREE)
+
+/* For scanning an arbitrary device-tree at any time */
+extern char *of_fdt_get_string(struct boot_param_header *blob, u32 offset);
+extern void *of_fdt_get_property(struct boot_param_header *blob,
+				 unsigned long node,
+				 const char *name,
+				 unsigned long *size);
+extern int of_fdt_is_compatible(struct boot_param_header *blob,
+				unsigned long node,
+				const char *compat);
+
 /* TBD: Temporary export of fdt globals - remove when code fully merged */
 extern int __initdata dt_root_addr_cells;
 extern int __initdata dt_root_size_cells;
-- 
1.5.6.6



This email and any attachments are intended for the sole use of the named recipient(s) and contain(s) confidential information that may be proprietary, privileged or copyrighted under applicable law. If you are not the intended recipient, do not read, copy, or forward this email message or any attachments. Delete this email message and any attachments immediately.

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

* [PATCH 4/7] fdt.c: Add non-boottime device tree functions
@ 2010-11-18 23:54             ` Stephen Neuendorffer
  0 siblings, 0 replies; 41+ messages in thread
From: Stephen Neuendorffer @ 2010-11-18 23:54 UTC (permalink / raw)
  To: grant.likely, dirk.brandewie, devicetree-discuss, linuxppc-dev,
	microblaze-uclinux

In preparation for providing run-time handling of device trees, factor
out some of the basic functions so that they take an arbitrary blob,
rather than relying on the single boot-time tree.

Signed-off-by: Stephen Neuendorffer <stephen.neuendorffer@xilinx.com>

--

V2: functions have of_fdt_* names
    removed find_flat_dt_string
    blob argument is first
---
 drivers/of/fdt.c       |  133 ++++++++++++++++++++++++++++-------------------
 include/linux/of_fdt.h |   11 ++++
 2 files changed, 90 insertions(+), 54 deletions(-)

diff --git a/drivers/of/fdt.c b/drivers/of/fdt.c
index 4d71b29..190e26c 100644
--- a/drivers/of/fdt.c
+++ b/drivers/of/fdt.c
@@ -22,6 +22,82 @@
 
 #include <asm/page.h>
 
+char *of_fdt_get_string(struct boot_param_header *blob, u32 offset)
+{
+	return ((char *)blob) +
+		be32_to_cpu(blob->off_dt_strings) + offset;
+}
+
+/**
+ * of_fdt_get_property - Given a node in the given flat blob, return
+ * the property ptr
+ */
+void *of_fdt_get_property(struct boot_param_header *blob,
+		       unsigned long node, const char *name,
+		       unsigned long *size)
+{
+	unsigned long p = node;
+
+	do {
+		u32 tag = be32_to_cpup((__be32 *)p);
+		u32 sz, noff;
+		const char *nstr;
+
+		p += 4;
+		if (tag == OF_DT_NOP)
+			continue;
+		if (tag != OF_DT_PROP)
+			return NULL;
+
+		sz = be32_to_cpup((__be32 *)p);
+		noff = be32_to_cpup((__be32 *)(p + 4));
+		p += 8;
+		if (be32_to_cpu(blob->version) < 0x10)
+			p = ALIGN(p, sz >= 8 ? 8 : 4);
+
+		nstr = of_fdt_get_string(blob, noff);
+		if (nstr == NULL) {
+			pr_warning("Can't find property index name !\n");
+			return NULL;
+		}
+		if (strcmp(name, nstr) == 0) {
+			if (size)
+				*size = sz;
+			return (void *)p;
+		}
+		p += sz;
+		p = ALIGN(p, 4);
+	} while (1);
+}
+
+/**
+ * of_fdt_is_compatible - Return true if given node from the given blob has
+ * compat in its compatible list
+ * @blob: A device tree blob
+ * @node: node to test
+ * @compat: compatible string to compare with compatible list.
+ */
+int of_fdt_is_compatible(struct boot_param_header *blob,
+		      unsigned long node, const char *compat)
+{
+	const char *cp;
+	unsigned long cplen, l;
+
+	cp = of_fdt_get_property(blob, node, "compatible", &cplen);
+	if (cp == NULL)
+		return 0;
+	while (cplen > 0) {
+		if (of_compat_cmp(cp, compat, strlen(compat)) == 0)
+			return 1;
+		l = strlen(cp) + 1;
+		cp += l;
+		cplen -= l;
+	}
+
+	return 0;
+}
+
+/* Everything below here references initial_boot_params directly. */
 int __initdata dt_root_addr_cells;
 int __initdata dt_root_size_cells;
 
@@ -29,12 +105,6 @@ struct boot_param_header *initial_boot_params;
 
 #ifdef CONFIG_EARLY_FLATTREE
 
-char *find_flat_dt_string(u32 offset)
-{
-	return ((char *)initial_boot_params) +
-		be32_to_cpu(initial_boot_params->off_dt_strings) + offset;
-}
-
 /**
  * of_scan_flat_dt - scan flattened tree blob and call callback on each.
  * @it: callback function
@@ -123,38 +193,7 @@ unsigned long __init of_get_flat_dt_root(void)
 void *__init of_get_flat_dt_prop(unsigned long node, const char *name,
 				 unsigned long *size)
 {
-	unsigned long p = node;
-
-	do {
-		u32 tag = be32_to_cpup((__be32 *)p);
-		u32 sz, noff;
-		const char *nstr;
-
-		p += 4;
-		if (tag == OF_DT_NOP)
-			continue;
-		if (tag != OF_DT_PROP)
-			return NULL;
-
-		sz = be32_to_cpup((__be32 *)p);
-		noff = be32_to_cpup((__be32 *)(p + 4));
-		p += 8;
-		if (be32_to_cpu(initial_boot_params->version) < 0x10)
-			p = ALIGN(p, sz >= 8 ? 8 : 4);
-
-		nstr = find_flat_dt_string(noff);
-		if (nstr == NULL) {
-			pr_warning("Can't find property index name !\n");
-			return NULL;
-		}
-		if (strcmp(name, nstr) == 0) {
-			if (size)
-				*size = sz;
-			return (void *)p;
-		}
-		p += sz;
-		p = ALIGN(p, 4);
-	} while (1);
+	return of_fdt_get_property(initial_boot_params, node, name, size);
 }
 
 /**
@@ -164,21 +203,7 @@ void *__init of_get_flat_dt_prop(unsigned long node, const char *name,
  */
 int __init of_flat_dt_is_compatible(unsigned long node, const char *compat)
 {
-	const char *cp;
-	unsigned long cplen, l;
-
-	cp = of_get_flat_dt_prop(node, "compatible", &cplen);
-	if (cp == NULL)
-		return 0;
-	while (cplen > 0) {
-		if (of_compat_cmp(cp, compat, strlen(compat)) == 0)
-			return 1;
-		l = strlen(cp) + 1;
-		cp += l;
-		cplen -= l;
-	}
-
-	return 0;
+	return of_fdt_is_compatible(initial_boot_params, node, compat);
 }
 
 static void *__init unflatten_dt_alloc(unsigned long *mem, unsigned long size,
@@ -303,7 +328,7 @@ unsigned long __init unflatten_dt_node(unsigned long mem,
 		if (be32_to_cpu(initial_boot_params->version) < 0x10)
 			*p = ALIGN(*p, sz >= 8 ? 8 : 4);
 
-		pname = find_flat_dt_string(noff);
+		pname = of_fdt_get_string(initial_boot_params, noff);
 		if (pname == NULL) {
 			pr_info("Can't find property name in list !\n");
 			break;
diff --git a/include/linux/of_fdt.h b/include/linux/of_fdt.h
index 7bbf5b3..70c5b73 100644
--- a/include/linux/of_fdt.h
+++ b/include/linux/of_fdt.h
@@ -58,6 +58,17 @@ struct boot_param_header {
 };
 
 #if defined(CONFIG_OF_FLATTREE)
+
+/* For scanning an arbitrary device-tree at any time */
+extern char *of_fdt_get_string(struct boot_param_header *blob, u32 offset);
+extern void *of_fdt_get_property(struct boot_param_header *blob,
+				 unsigned long node,
+				 const char *name,
+				 unsigned long *size);
+extern int of_fdt_is_compatible(struct boot_param_header *blob,
+				unsigned long node,
+				const char *compat);
+
 /* TBD: Temporary export of fdt globals - remove when code fully merged */
 extern int __initdata dt_root_addr_cells;
 extern int __initdata dt_root_size_cells;
-- 
1.5.6.6



This email and any attachments are intended for the sole use of the named recipient(s) and contain(s) confidential information that may be proprietary, privileged or copyrighted under applicable law. If you are not the intended recipient, do not read, copy, or forward this email message or any attachments. Delete this email message and any attachments immediately.

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

* [PATCH 5/7] fdt.c: Refactor unflatten_dt_node
       [not found]         ` <1290124502-13125-5-git-send-email-stephen.neuendorffer@xilinx.com>
@ 2010-11-18 23:55               ` Stephen Neuendorffer
       [not found]           ` <1290124502-13125-6-git-send-email-stephen.neuendorffer@xilinx.com>
  1 sibling, 0 replies; 41+ messages in thread
From: Stephen Neuendorffer @ 2010-11-18 23:55 UTC (permalink / raw)
  To: grant.likely-s3s/WqlpOiPyB63q8FvJNQ,
	dirk.brandewie-Re5JQEeQqe8AvxtiuMwx3w,
	devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ,
	linuxppc-dev-uLR06cmDAlY/bJ5BZ2RsiQ,
	microblaze-uclinux-rVRm/Wmeqae7NGdpmJTKYQ

unflatten_dt_node is a helper function that does most of the work to
convert a device tree blob into tree of device nodes.  This code
now uses a passed-in blob instead of using the single boot-time blob,
allowing it to be called in more contexts.

Signed-off-by: Stephen Neuendorffer <stephen.neuendorffer-gjFFaj9aHVfQT0dZR+AlfA@public.gmane.org>

---

V2: don't reorder
    blob argument first.
---
 drivers/of/fdt.c |   27 ++++++++++++++++-----------
 1 files changed, 16 insertions(+), 11 deletions(-)

diff --git a/drivers/of/fdt.c b/drivers/of/fdt.c
index 190e26c..a07fd1a 100644
--- a/drivers/of/fdt.c
+++ b/drivers/of/fdt.c
@@ -206,7 +206,7 @@ int __init of_flat_dt_is_compatible(unsigned long node, const char *compat)
 	return of_fdt_is_compatible(initial_boot_params, node, compat);
 }
 
-static void *__init unflatten_dt_alloc(unsigned long *mem, unsigned long size,
+static void *unflatten_dt_alloc(unsigned long *mem, unsigned long size,
 				       unsigned long align)
 {
 	void *res;
@@ -220,16 +220,18 @@ static void *__init unflatten_dt_alloc(unsigned long *mem, unsigned long size,
 
 /**
  * unflatten_dt_node - Alloc and populate a device_node from the flat tree
+ * @blob: The parent device tree blob
  * @p: pointer to node in flat tree
  * @dad: Parent struct device_node
  * @allnextpp: pointer to ->allnext from last allocated device_node
  * @fpsize: Size of the node path up at the current depth.
  */
-unsigned long __init unflatten_dt_node(unsigned long mem,
-					unsigned long *p,
-					struct device_node *dad,
-					struct device_node ***allnextpp,
-					unsigned long fpsize)
+unsigned long unflatten_dt_node(struct boot_param_header *blob,
+				unsigned long mem,
+				unsigned long *p,
+				struct device_node *dad,
+				struct device_node ***allnextpp,
+				unsigned long fpsize)
 {
 	struct device_node *np;
 	struct property *pp, **prev_pp = NULL;
@@ -325,10 +327,10 @@ unsigned long __init unflatten_dt_node(unsigned long mem,
 		sz = be32_to_cpup((__be32 *)(*p));
 		noff = be32_to_cpup((__be32 *)((*p) + 4));
 		*p += 8;
-		if (be32_to_cpu(initial_boot_params->version) < 0x10)
+		if (be32_to_cpu(blob->version) < 0x10)
 			*p = ALIGN(*p, sz >= 8 ? 8 : 4);
 
-		pname = of_fdt_get_string(initial_boot_params, noff);
+		pname = of_fdt_get_string(blob, noff);
 		if (pname == NULL) {
 			pr_info("Can't find property name in list !\n");
 			break;
@@ -407,7 +409,8 @@ unsigned long __init unflatten_dt_node(unsigned long mem,
 		if (tag == OF_DT_NOP)
 			*p += 4;
 		else
-			mem = unflatten_dt_node(mem, p, np, allnextpp, fpsize);
+			mem = unflatten_dt_node(blob, mem, p, np, allnextpp,
+						fpsize);
 		tag = be32_to_cpup((__be32 *)(*p));
 	}
 	if (tag != OF_DT_END_NODE) {
@@ -599,7 +602,8 @@ void __init unflatten_device_tree(void)
 	/* First pass, scan for size */
 	start = ((unsigned long)initial_boot_params) +
 		be32_to_cpu(initial_boot_params->off_dt_struct);
-	size = unflatten_dt_node(0, &start, NULL, NULL, 0);
+	size = unflatten_dt_node(initial_boot_params, 0, &start,
+				 NULL, NULL, 0);
 	size = (size | 3) + 1;
 
 	pr_debug("  size is %lx, allocating...\n", size);
@@ -616,7 +620,8 @@ void __init unflatten_device_tree(void)
 	/* Second pass, do actual unflattening */
 	start = ((unsigned long)initial_boot_params) +
 		be32_to_cpu(initial_boot_params->off_dt_struct);
-	unflatten_dt_node(mem, &start, NULL, &allnextp, 0);
+	unflatten_dt_node(initial_boot_params, mem, &start,
+			  NULL, &allnextp, 0);
 	if (be32_to_cpup((__be32 *)start) != OF_DT_END)
 		pr_warning("Weird tag at end of tree: %08x\n", *((u32 *)start));
 	if (be32_to_cpu(((__be32 *)mem)[size / 4]) != 0xdeadbeef)
-- 
1.5.6.6



This email and any attachments are intended for the sole use of the named recipient(s) and contain(s) confidential information that may be proprietary, privileged or copyrighted under applicable law. If you are not the intended recipient, do not read, copy, or forward this email message or any attachments. Delete this email message and any attachments immediately.

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

* [PATCH 5/7] fdt.c: Refactor unflatten_dt_node
@ 2010-11-18 23:55               ` Stephen Neuendorffer
  0 siblings, 0 replies; 41+ messages in thread
From: Stephen Neuendorffer @ 2010-11-18 23:55 UTC (permalink / raw)
  To: grant.likely, dirk.brandewie, devicetree-discuss, linuxppc-dev,
	microblaze-uclinux

unflatten_dt_node is a helper function that does most of the work to
convert a device tree blob into tree of device nodes.  This code
now uses a passed-in blob instead of using the single boot-time blob,
allowing it to be called in more contexts.

Signed-off-by: Stephen Neuendorffer <stephen.neuendorffer@xilinx.com>

---

V2: don't reorder
    blob argument first.
---
 drivers/of/fdt.c |   27 ++++++++++++++++-----------
 1 files changed, 16 insertions(+), 11 deletions(-)

diff --git a/drivers/of/fdt.c b/drivers/of/fdt.c
index 190e26c..a07fd1a 100644
--- a/drivers/of/fdt.c
+++ b/drivers/of/fdt.c
@@ -206,7 +206,7 @@ int __init of_flat_dt_is_compatible(unsigned long node, const char *compat)
 	return of_fdt_is_compatible(initial_boot_params, node, compat);
 }
 
-static void *__init unflatten_dt_alloc(unsigned long *mem, unsigned long size,
+static void *unflatten_dt_alloc(unsigned long *mem, unsigned long size,
 				       unsigned long align)
 {
 	void *res;
@@ -220,16 +220,18 @@ static void *__init unflatten_dt_alloc(unsigned long *mem, unsigned long size,
 
 /**
  * unflatten_dt_node - Alloc and populate a device_node from the flat tree
+ * @blob: The parent device tree blob
  * @p: pointer to node in flat tree
  * @dad: Parent struct device_node
  * @allnextpp: pointer to ->allnext from last allocated device_node
  * @fpsize: Size of the node path up at the current depth.
  */
-unsigned long __init unflatten_dt_node(unsigned long mem,
-					unsigned long *p,
-					struct device_node *dad,
-					struct device_node ***allnextpp,
-					unsigned long fpsize)
+unsigned long unflatten_dt_node(struct boot_param_header *blob,
+				unsigned long mem,
+				unsigned long *p,
+				struct device_node *dad,
+				struct device_node ***allnextpp,
+				unsigned long fpsize)
 {
 	struct device_node *np;
 	struct property *pp, **prev_pp = NULL;
@@ -325,10 +327,10 @@ unsigned long __init unflatten_dt_node(unsigned long mem,
 		sz = be32_to_cpup((__be32 *)(*p));
 		noff = be32_to_cpup((__be32 *)((*p) + 4));
 		*p += 8;
-		if (be32_to_cpu(initial_boot_params->version) < 0x10)
+		if (be32_to_cpu(blob->version) < 0x10)
 			*p = ALIGN(*p, sz >= 8 ? 8 : 4);
 
-		pname = of_fdt_get_string(initial_boot_params, noff);
+		pname = of_fdt_get_string(blob, noff);
 		if (pname == NULL) {
 			pr_info("Can't find property name in list !\n");
 			break;
@@ -407,7 +409,8 @@ unsigned long __init unflatten_dt_node(unsigned long mem,
 		if (tag == OF_DT_NOP)
 			*p += 4;
 		else
-			mem = unflatten_dt_node(mem, p, np, allnextpp, fpsize);
+			mem = unflatten_dt_node(blob, mem, p, np, allnextpp,
+						fpsize);
 		tag = be32_to_cpup((__be32 *)(*p));
 	}
 	if (tag != OF_DT_END_NODE) {
@@ -599,7 +602,8 @@ void __init unflatten_device_tree(void)
 	/* First pass, scan for size */
 	start = ((unsigned long)initial_boot_params) +
 		be32_to_cpu(initial_boot_params->off_dt_struct);
-	size = unflatten_dt_node(0, &start, NULL, NULL, 0);
+	size = unflatten_dt_node(initial_boot_params, 0, &start,
+				 NULL, NULL, 0);
 	size = (size | 3) + 1;
 
 	pr_debug("  size is %lx, allocating...\n", size);
@@ -616,7 +620,8 @@ void __init unflatten_device_tree(void)
 	/* Second pass, do actual unflattening */
 	start = ((unsigned long)initial_boot_params) +
 		be32_to_cpu(initial_boot_params->off_dt_struct);
-	unflatten_dt_node(mem, &start, NULL, &allnextp, 0);
+	unflatten_dt_node(initial_boot_params, mem, &start,
+			  NULL, &allnextp, 0);
 	if (be32_to_cpup((__be32 *)start) != OF_DT_END)
 		pr_warning("Weird tag at end of tree: %08x\n", *((u32 *)start));
 	if (be32_to_cpu(((__be32 *)mem)[size / 4]) != 0xdeadbeef)
-- 
1.5.6.6



This email and any attachments are intended for the sole use of the named recipient(s) and contain(s) confidential information that may be proprietary, privileged or copyrighted under applicable law. If you are not the intended recipient, do not read, copy, or forward this email message or any attachments. Delete this email message and any attachments immediately.

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

* [PATCH 6/7] fdt.c: Reorder unflatten_dt_node
       [not found]           ` <1290124502-13125-6-git-send-email-stephen.neuendorffer@xilinx.com>
@ 2010-11-18 23:55                 ` Stephen Neuendorffer
       [not found]             ` <1290124502-13125-7-git-send-email-stephen.neuendorffer@xilinx.com>
  1 sibling, 0 replies; 41+ messages in thread
From: Stephen Neuendorffer @ 2010-11-18 23:55 UTC (permalink / raw)
  To: grant.likely-s3s/WqlpOiPyB63q8FvJNQ,
	dirk.brandewie-Re5JQEeQqe8AvxtiuMwx3w,
	devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ,
	linuxppc-dev-uLR06cmDAlY/bJ5BZ2RsiQ,
	microblaze-uclinux-rVRm/Wmeqae7NGdpmJTKYQ

Move unflatten_dt_node to be grouped with non-__init functions.

Signed-off-by: Stephen Neuendorffer <stephen.neuendorffer-gjFFaj9aHVfQT0dZR+AlfA@public.gmane.org>
---
 drivers/of/fdt.c |  218 +++++++++++++++++++++++++++---------------------------
 1 files changed, 109 insertions(+), 109 deletions(-)

diff --git a/drivers/of/fdt.c b/drivers/of/fdt.c
index a07fd1a..236a8c9 100644
--- a/drivers/of/fdt.c
+++ b/drivers/of/fdt.c
@@ -97,115 +97,6 @@ int of_fdt_is_compatible(struct boot_param_header *blob,
 	return 0;
 }
 
-/* Everything below here references initial_boot_params directly. */
-int __initdata dt_root_addr_cells;
-int __initdata dt_root_size_cells;
-
-struct boot_param_header *initial_boot_params;
-
-#ifdef CONFIG_EARLY_FLATTREE
-
-/**
- * of_scan_flat_dt - scan flattened tree blob and call callback on each.
- * @it: callback function
- * @data: context data pointer
- *
- * This function is used to scan the flattened device-tree, it is
- * used to extract the memory information at boot before we can
- * unflatten the tree
- */
-int __init of_scan_flat_dt(int (*it)(unsigned long node,
-				     const char *uname, int depth,
-				     void *data),
-			   void *data)
-{
-	unsigned long p = ((unsigned long)initial_boot_params) +
-		be32_to_cpu(initial_boot_params->off_dt_struct);
-	int rc = 0;
-	int depth = -1;
-
-	do {
-		u32 tag = be32_to_cpup((__be32 *)p);
-		char *pathp;
-
-		p += 4;
-		if (tag == OF_DT_END_NODE) {
-			depth--;
-			continue;
-		}
-		if (tag == OF_DT_NOP)
-			continue;
-		if (tag == OF_DT_END)
-			break;
-		if (tag == OF_DT_PROP) {
-			u32 sz = be32_to_cpup((__be32 *)p);
-			p += 8;
-			if (be32_to_cpu(initial_boot_params->version) < 0x10)
-				p = ALIGN(p, sz >= 8 ? 8 : 4);
-			p += sz;
-			p = ALIGN(p, 4);
-			continue;
-		}
-		if (tag != OF_DT_BEGIN_NODE) {
-			pr_err("Invalid tag %x in flat device tree!\n", tag);
-			return -EINVAL;
-		}
-		depth++;
-		pathp = (char *)p;
-		p = ALIGN(p + strlen(pathp) + 1, 4);
-		if ((*pathp) == '/') {
-			char *lp, *np;
-			for (lp = NULL, np = pathp; *np; np++)
-				if ((*np) == '/')
-					lp = np+1;
-			if (lp != NULL)
-				pathp = lp;
-		}
-		rc = it(p, pathp, depth, data);
-		if (rc != 0)
-			break;
-	} while (1);
-
-	return rc;
-}
-
-/**
- * of_get_flat_dt_root - find the root node in the flat blob
- */
-unsigned long __init of_get_flat_dt_root(void)
-{
-	unsigned long p = ((unsigned long)initial_boot_params) +
-		be32_to_cpu(initial_boot_params->off_dt_struct);
-
-	while (be32_to_cpup((__be32 *)p) == OF_DT_NOP)
-		p += 4;
-	BUG_ON(be32_to_cpup((__be32 *)p) != OF_DT_BEGIN_NODE);
-	p += 4;
-	return ALIGN(p + strlen((char *)p) + 1, 4);
-}
-
-/**
- * of_get_flat_dt_prop - Given a node in the flat blob, return the property ptr
- *
- * This function can be used within scan_flattened_dt callback to get
- * access to properties
- */
-void *__init of_get_flat_dt_prop(unsigned long node, const char *name,
-				 unsigned long *size)
-{
-	return of_fdt_get_property(initial_boot_params, node, name, size);
-}
-
-/**
- * of_flat_dt_is_compatible - Return true if given node has compat in compatible list
- * @node: node to test
- * @compat: compatible string to compare with compatible list.
- */
-int __init of_flat_dt_is_compatible(unsigned long node, const char *compat)
-{
-	return of_fdt_is_compatible(initial_boot_params, node, compat);
-}
-
 static void *unflatten_dt_alloc(unsigned long *mem, unsigned long size,
 				       unsigned long align)
 {
@@ -421,6 +312,115 @@ unsigned long unflatten_dt_node(struct boot_param_header *blob,
 	return mem;
 }
 
+/* Everything below here references initial_boot_params directly. */
+int __initdata dt_root_addr_cells;
+int __initdata dt_root_size_cells;
+
+struct boot_param_header *initial_boot_params;
+
+#ifdef CONFIG_EARLY_FLATTREE
+
+/**
+ * of_scan_flat_dt - scan flattened tree blob and call callback on each.
+ * @it: callback function
+ * @data: context data pointer
+ *
+ * This function is used to scan the flattened device-tree, it is
+ * used to extract the memory information at boot before we can
+ * unflatten the tree
+ */
+int __init of_scan_flat_dt(int (*it)(unsigned long node,
+				     const char *uname, int depth,
+				     void *data),
+			   void *data)
+{
+	unsigned long p = ((unsigned long)initial_boot_params) +
+		be32_to_cpu(initial_boot_params->off_dt_struct);
+	int rc = 0;
+	int depth = -1;
+
+	do {
+		u32 tag = be32_to_cpup((__be32 *)p);
+		char *pathp;
+
+		p += 4;
+		if (tag == OF_DT_END_NODE) {
+			depth--;
+			continue;
+		}
+		if (tag == OF_DT_NOP)
+			continue;
+		if (tag == OF_DT_END)
+			break;
+		if (tag == OF_DT_PROP) {
+			u32 sz = be32_to_cpup((__be32 *)p);
+			p += 8;
+			if (be32_to_cpu(initial_boot_params->version) < 0x10)
+				p = ALIGN(p, sz >= 8 ? 8 : 4);
+			p += sz;
+			p = ALIGN(p, 4);
+			continue;
+		}
+		if (tag != OF_DT_BEGIN_NODE) {
+			pr_err("Invalid tag %x in flat device tree!\n", tag);
+			return -EINVAL;
+		}
+		depth++;
+		pathp = (char *)p;
+		p = ALIGN(p + strlen(pathp) + 1, 4);
+		if ((*pathp) == '/') {
+			char *lp, *np;
+			for (lp = NULL, np = pathp; *np; np++)
+				if ((*np) == '/')
+					lp = np+1;
+			if (lp != NULL)
+				pathp = lp;
+		}
+		rc = it(p, pathp, depth, data);
+		if (rc != 0)
+			break;
+	} while (1);
+
+	return rc;
+}
+
+/**
+ * of_get_flat_dt_root - find the root node in the flat blob
+ */
+unsigned long __init of_get_flat_dt_root(void)
+{
+	unsigned long p = ((unsigned long)initial_boot_params) +
+		be32_to_cpu(initial_boot_params->off_dt_struct);
+
+	while (be32_to_cpup((__be32 *)p) == OF_DT_NOP)
+		p += 4;
+	BUG_ON(be32_to_cpup((__be32 *)p) != OF_DT_BEGIN_NODE);
+	p += 4;
+	return ALIGN(p + strlen((char *)p) + 1, 4);
+}
+
+/**
+ * of_get_flat_dt_prop - Given a node in the flat blob, return the property ptr
+ *
+ * This function can be used within scan_flattened_dt callback to get
+ * access to properties
+ */
+void *__init of_get_flat_dt_prop(unsigned long node, const char *name,
+				 unsigned long *size)
+{
+	return of_fdt_get_property(initial_boot_params, node, name, size);
+}
+
+/**
+ * of_flat_dt_is_compatible - Return true if given node has compat in compatible list
+ * @node: node to test
+ * @compat: compatible string to compare with compatible list.
+ */
+int __init of_flat_dt_is_compatible(unsigned long node, const char *compat)
+{
+	return of_fdt_is_compatible(initial_boot_params, node, compat);
+}
+
 #ifdef CONFIG_BLK_DEV_INITRD
 /**
  * early_init_dt_check_for_initrd - Decode initrd location from flat tree
-- 
1.5.6.6



This email and any attachments are intended for the sole use of the named recipient(s) and contain(s) confidential information that may be proprietary, privileged or copyrighted under applicable law. If you are not the intended recipient, do not read, copy, or forward this email message or any attachments. Delete this email message and any attachments immediately.

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

* [PATCH 6/7] fdt.c: Reorder unflatten_dt_node
@ 2010-11-18 23:55                 ` Stephen Neuendorffer
  0 siblings, 0 replies; 41+ messages in thread
From: Stephen Neuendorffer @ 2010-11-18 23:55 UTC (permalink / raw)
  To: grant.likely, dirk.brandewie, devicetree-discuss, linuxppc-dev,
	microblaze-uclinux

Move unflatten_dt_node to be grouped with non-__init functions.

Signed-off-by: Stephen Neuendorffer <stephen.neuendorffer@xilinx.com>
---
 drivers/of/fdt.c |  218 +++++++++++++++++++++++++++---------------------------
 1 files changed, 109 insertions(+), 109 deletions(-)

diff --git a/drivers/of/fdt.c b/drivers/of/fdt.c
index a07fd1a..236a8c9 100644
--- a/drivers/of/fdt.c
+++ b/drivers/of/fdt.c
@@ -97,115 +97,6 @@ int of_fdt_is_compatible(struct boot_param_header *blob,
 	return 0;
 }
 
-/* Everything below here references initial_boot_params directly. */
-int __initdata dt_root_addr_cells;
-int __initdata dt_root_size_cells;
-
-struct boot_param_header *initial_boot_params;
-
-#ifdef CONFIG_EARLY_FLATTREE
-
-/**
- * of_scan_flat_dt - scan flattened tree blob and call callback on each.
- * @it: callback function
- * @data: context data pointer
- *
- * This function is used to scan the flattened device-tree, it is
- * used to extract the memory information at boot before we can
- * unflatten the tree
- */
-int __init of_scan_flat_dt(int (*it)(unsigned long node,
-				     const char *uname, int depth,
-				     void *data),
-			   void *data)
-{
-	unsigned long p = ((unsigned long)initial_boot_params) +
-		be32_to_cpu(initial_boot_params->off_dt_struct);
-	int rc = 0;
-	int depth = -1;
-
-	do {
-		u32 tag = be32_to_cpup((__be32 *)p);
-		char *pathp;
-
-		p += 4;
-		if (tag == OF_DT_END_NODE) {
-			depth--;
-			continue;
-		}
-		if (tag == OF_DT_NOP)
-			continue;
-		if (tag == OF_DT_END)
-			break;
-		if (tag == OF_DT_PROP) {
-			u32 sz = be32_to_cpup((__be32 *)p);
-			p += 8;
-			if (be32_to_cpu(initial_boot_params->version) < 0x10)
-				p = ALIGN(p, sz >= 8 ? 8 : 4);
-			p += sz;
-			p = ALIGN(p, 4);
-			continue;
-		}
-		if (tag != OF_DT_BEGIN_NODE) {
-			pr_err("Invalid tag %x in flat device tree!\n", tag);
-			return -EINVAL;
-		}
-		depth++;
-		pathp = (char *)p;
-		p = ALIGN(p + strlen(pathp) + 1, 4);
-		if ((*pathp) == '/') {
-			char *lp, *np;
-			for (lp = NULL, np = pathp; *np; np++)
-				if ((*np) == '/')
-					lp = np+1;
-			if (lp != NULL)
-				pathp = lp;
-		}
-		rc = it(p, pathp, depth, data);
-		if (rc != 0)
-			break;
-	} while (1);
-
-	return rc;
-}
-
-/**
- * of_get_flat_dt_root - find the root node in the flat blob
- */
-unsigned long __init of_get_flat_dt_root(void)
-{
-	unsigned long p = ((unsigned long)initial_boot_params) +
-		be32_to_cpu(initial_boot_params->off_dt_struct);
-
-	while (be32_to_cpup((__be32 *)p) == OF_DT_NOP)
-		p += 4;
-	BUG_ON(be32_to_cpup((__be32 *)p) != OF_DT_BEGIN_NODE);
-	p += 4;
-	return ALIGN(p + strlen((char *)p) + 1, 4);
-}
-
-/**
- * of_get_flat_dt_prop - Given a node in the flat blob, return the property ptr
- *
- * This function can be used within scan_flattened_dt callback to get
- * access to properties
- */
-void *__init of_get_flat_dt_prop(unsigned long node, const char *name,
-				 unsigned long *size)
-{
-	return of_fdt_get_property(initial_boot_params, node, name, size);
-}
-
-/**
- * of_flat_dt_is_compatible - Return true if given node has compat in compatible list
- * @node: node to test
- * @compat: compatible string to compare with compatible list.
- */
-int __init of_flat_dt_is_compatible(unsigned long node, const char *compat)
-{
-	return of_fdt_is_compatible(initial_boot_params, node, compat);
-}
-
 static void *unflatten_dt_alloc(unsigned long *mem, unsigned long size,
 				       unsigned long align)
 {
@@ -421,6 +312,115 @@ unsigned long unflatten_dt_node(struct boot_param_header *blob,
 	return mem;
 }
 
+/* Everything below here references initial_boot_params directly. */
+int __initdata dt_root_addr_cells;
+int __initdata dt_root_size_cells;
+
+struct boot_param_header *initial_boot_params;
+
+#ifdef CONFIG_EARLY_FLATTREE
+
+/**
+ * of_scan_flat_dt - scan flattened tree blob and call callback on each.
+ * @it: callback function
+ * @data: context data pointer
+ *
+ * This function is used to scan the flattened device-tree, it is
+ * used to extract the memory information at boot before we can
+ * unflatten the tree
+ */
+int __init of_scan_flat_dt(int (*it)(unsigned long node,
+				     const char *uname, int depth,
+				     void *data),
+			   void *data)
+{
+	unsigned long p = ((unsigned long)initial_boot_params) +
+		be32_to_cpu(initial_boot_params->off_dt_struct);
+	int rc = 0;
+	int depth = -1;
+
+	do {
+		u32 tag = be32_to_cpup((__be32 *)p);
+		char *pathp;
+
+		p += 4;
+		if (tag == OF_DT_END_NODE) {
+			depth--;
+			continue;
+		}
+		if (tag == OF_DT_NOP)
+			continue;
+		if (tag == OF_DT_END)
+			break;
+		if (tag == OF_DT_PROP) {
+			u32 sz = be32_to_cpup((__be32 *)p);
+			p += 8;
+			if (be32_to_cpu(initial_boot_params->version) < 0x10)
+				p = ALIGN(p, sz >= 8 ? 8 : 4);
+			p += sz;
+			p = ALIGN(p, 4);
+			continue;
+		}
+		if (tag != OF_DT_BEGIN_NODE) {
+			pr_err("Invalid tag %x in flat device tree!\n", tag);
+			return -EINVAL;
+		}
+		depth++;
+		pathp = (char *)p;
+		p = ALIGN(p + strlen(pathp) + 1, 4);
+		if ((*pathp) == '/') {
+			char *lp, *np;
+			for (lp = NULL, np = pathp; *np; np++)
+				if ((*np) == '/')
+					lp = np+1;
+			if (lp != NULL)
+				pathp = lp;
+		}
+		rc = it(p, pathp, depth, data);
+		if (rc != 0)
+			break;
+	} while (1);
+
+	return rc;
+}
+
+/**
+ * of_get_flat_dt_root - find the root node in the flat blob
+ */
+unsigned long __init of_get_flat_dt_root(void)
+{
+	unsigned long p = ((unsigned long)initial_boot_params) +
+		be32_to_cpu(initial_boot_params->off_dt_struct);
+
+	while (be32_to_cpup((__be32 *)p) == OF_DT_NOP)
+		p += 4;
+	BUG_ON(be32_to_cpup((__be32 *)p) != OF_DT_BEGIN_NODE);
+	p += 4;
+	return ALIGN(p + strlen((char *)p) + 1, 4);
+}
+
+/**
+ * of_get_flat_dt_prop - Given a node in the flat blob, return the property ptr
+ *
+ * This function can be used within scan_flattened_dt callback to get
+ * access to properties
+ */
+void *__init of_get_flat_dt_prop(unsigned long node, const char *name,
+				 unsigned long *size)
+{
+	return of_fdt_get_property(initial_boot_params, node, name, size);
+}
+
+/**
+ * of_flat_dt_is_compatible - Return true if given node has compat in compatible list
+ * @node: node to test
+ * @compat: compatible string to compare with compatible list.
+ */
+int __init of_flat_dt_is_compatible(unsigned long node, const char *compat)
+{
+	return of_fdt_is_compatible(initial_boot_params, node, compat);
+}
+
 #ifdef CONFIG_BLK_DEV_INITRD
 /**
  * early_init_dt_check_for_initrd - Decode initrd location from flat tree
-- 
1.5.6.6



This email and any attachments are intended for the sole use of the named recipient(s) and contain(s) confidential information that may be proprietary, privileged or copyrighted under applicable law. If you are not the intended recipient, do not read, copy, or forward this email message or any attachments. Delete this email message and any attachments immediately.

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

* [PATCH 7/7] fdt.c: Refactor unflatten_device_tree and add fdt_unflatten_tree
       [not found]             ` <1290124502-13125-7-git-send-email-stephen.neuendorffer@xilinx.com>
@ 2010-11-18 23:55                   ` Stephen Neuendorffer
  0 siblings, 0 replies; 41+ messages in thread
From: Stephen Neuendorffer @ 2010-11-18 23:55 UTC (permalink / raw)
  To: grant.likely-s3s/WqlpOiPyB63q8FvJNQ,
	dirk.brandewie-Re5JQEeQqe8AvxtiuMwx3w,
	devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ,
	linuxppc-dev-uLR06cmDAlY/bJ5BZ2RsiQ,
	microblaze-uclinux-rVRm/Wmeqae7NGdpmJTKYQ

unflatten_device_tree has two dependencies on things that happen
during boot time.  Firstly, it references the initial device tree
directly. Secondly, it allocates memory using the early boot
allocator.  This patch factors out these dependencies and uses
the new __unflatten_device_tree function to implement a driver-visible
fdt_unflatten_tree function, which can be used to unflatten a
blob after boot time.

Signed-off-by: Stephen Neuendorffer <stephen.neuendorffer-gjFFaj9aHVfQT0dZR+AlfA@public.gmane.org>

--

V2: remove extra __va() call
	 make dt_alloc functions return void *.  This doesn't fix the general
    strangeness in this code that constantly casts back and forth between
    unsigned long and __be32 *
---
 drivers/of/fdt.c       |  149 +++++++++++++++++++++++++++++++----------------
 include/linux/of_fdt.h |    2 +
 2 files changed, 100 insertions(+), 51 deletions(-)

diff --git a/drivers/of/fdt.c b/drivers/of/fdt.c
index 236a8c9..e29dbe2 100644
--- a/drivers/of/fdt.c
+++ b/drivers/of/fdt.c
@@ -11,10 +11,12 @@
 
 #include <linux/kernel.h>
 #include <linux/initrd.h>
+#include <linux/module.h>
 #include <linux/of.h>
 #include <linux/of_fdt.h>
 #include <linux/string.h>
 #include <linux/errno.h>
+#include <linux/slab.h>
 
 #ifdef CONFIG_PPC
 #include <asm/machdep.h>
@@ -312,6 +314,94 @@ unsigned long unflatten_dt_node(struct boot_param_header *blob,
 	return mem;
 }
 
+/**
+ * __unflatten_device_tree - create tree of device_nodes from flat blob
+ *
+ * unflattens a device-tree, creating the
+ * tree of struct device_node. It also fills the "name" and "type"
+ * pointers of the nodes so the normal device-tree walking functions
+ * can be used.
+ * @blob: The blob to expand
+ * @mynodes: The device_node tree created by the call
+ * @dt_alloc: An allocator that provides a virtual address to memory
+ * for the resulting tree
+ */
+void __unflatten_device_tree(struct boot_param_header *blob,
+			     struct device_node **mynodes,
+			     void * (*dt_alloc)(u64 size, u64 align))
+{
+	unsigned long start, mem, size;
+	struct device_node **allnextp = mynodes;
+
+	pr_debug(" -> unflatten_device_tree()\n");
+
+	if (!blob) {
+		pr_debug("No device tree pointer\n");
+		return;
+	}
+
+	pr_debug("Unflattening device tree:\n");
+	pr_debug("magic: %08x\n", be32_to_cpu(blob->magic));
+	pr_debug("size: %08x\n", be32_to_cpu(blob->totalsize));
+	pr_debug("version: %08x\n", be32_to_cpu(blob->version));
+
+	if (be32_to_cpu(blob->magic) != OF_DT_HEADER) {
+		pr_err("Invalid device tree blob header\n");
+		return;
+	}
+
+	/* First pass, scan for size */
+	start = ((unsigned long)blob) +
+		be32_to_cpu(blob->off_dt_struct);
+	size = unflatten_dt_node(blob, 0, &start, NULL, NULL, 0);
+	size = (size | 3) + 1;
+
+	pr_debug("  size is %lx, allocating...\n", size);
+
+	/* Allocate memory for the expanded device tree */
+	mem = (unsigned long)
+		dt_alloc(size + 4, __alignof__(struct device_node));
+
+	((__be32 *)mem)[size / 4] = cpu_to_be32(0xdeadbeef);
+
+	pr_debug("  unflattening %lx...\n", mem);
+
+	/* Second pass, do actual unflattening */
+	start = ((unsigned long)blob) +
+		be32_to_cpu(blob->off_dt_struct);
+	unflatten_dt_node(blob, mem, &start, NULL, &allnextp, 0);
+	if (be32_to_cpup((__be32 *)start) != OF_DT_END)
+		pr_warning("Weird tag at end of tree: %08x\n", *((u32 *)start));
+	if (be32_to_cpu(((__be32 *)mem)[size / 4]) != 0xdeadbeef)
+		pr_warning("End of tree marker overwritten: %08x\n",
+			   be32_to_cpu(((__be32 *)mem)[size / 4]));
+	*allnextp = NULL;
+
+	pr_debug(" <- unflatten_device_tree()\n");
+}
+
+static void *kernel_tree_alloc(u64 size, u64 align)
+{
+	return kzalloc(size, GFP_KERNEL);
+}
+
+/**
+ * of_fdt_unflatten_tree - create tree of device_nodes from flat blob
+ *
+ * unflattens the device-tree passed by the firmware, creating the
+ * tree of struct device_node. It also fills the "name" and "type"
+ * pointers of the nodes so the normal device-tree walking functions
+ * can be used.
+ */
+void of_fdt_unflatten_tree(unsigned long *blob,
+			struct device_node **mynodes)
+{
+	struct boot_param_header *device_tree =
+		(struct boot_param_header *)blob;
+	__unflatten_device_tree(device_tree, mynodes, &kernel_tree_alloc);
+}
+EXPORT_SYMBOL_GPL(of_fdt_unflatten_tree);
+
 /* Everything below here references initial_boot_params directly. */
 int __initdata dt_root_addr_cells;
 int __initdata dt_root_size_cells;
@@ -569,6 +659,12 @@ int __init early_init_dt_scan_chosen(unsigned long node, const char *uname,
 	return 1;
 }
 
+static void *__init early_device_tree_alloc(u64 size, u64 align)
+{
+	unsigned long mem = early_init_dt_alloc_memory_arch(size, align);
+	return __va(mem);
+}
+
 /**
  * unflatten_device_tree - create tree of device_nodes from flat blob
  *
@@ -579,62 +675,13 @@ int __init early_init_dt_scan_chosen(unsigned long node, const char *uname,
  */
 void __init unflatten_device_tree(void)
 {
-	unsigned long start, mem, size;
-	struct device_node **allnextp = &allnodes;
-
-	pr_debug(" -> unflatten_device_tree()\n");
-
-	if (!initial_boot_params) {
-		pr_debug("No device tree pointer\n");
-		return;
-	}
-
-	pr_debug("Unflattening device tree:\n");
-	pr_debug("magic: %08x\n", be32_to_cpu(initial_boot_params->magic));
-	pr_debug("size: %08x\n", be32_to_cpu(initial_boot_params->totalsize));
-	pr_debug("version: %08x\n", be32_to_cpu(initial_boot_params->version));
-
-	if (be32_to_cpu(initial_boot_params->magic) != OF_DT_HEADER) {
-		pr_err("Invalid device tree blob header\n");
-		return;
-	}
-
-	/* First pass, scan for size */
-	start = ((unsigned long)initial_boot_params) +
-		be32_to_cpu(initial_boot_params->off_dt_struct);
-	size = unflatten_dt_node(initial_boot_params, 0, &start,
-				 NULL, NULL, 0);
-	size = (size | 3) + 1;
-
-	pr_debug("  size is %lx, allocating...\n", size);
-
-	/* Allocate memory for the expanded device tree */
-	mem = early_init_dt_alloc_memory_arch(size + 4,
-			__alignof__(struct device_node));
-	mem = (unsigned long) __va(mem);
-
-	((__be32 *)mem)[size / 4] = cpu_to_be32(0xdeadbeef);
-
-	pr_debug("  unflattening %lx...\n", mem);
-
-	/* Second pass, do actual unflattening */
-	start = ((unsigned long)initial_boot_params) +
-		be32_to_cpu(initial_boot_params->off_dt_struct);
-	unflatten_dt_node(initial_boot_params, mem, &start,
-			  NULL, &allnextp, 0);
-	if (be32_to_cpup((__be32 *)start) != OF_DT_END)
-		pr_warning("Weird tag at end of tree: %08x\n", *((u32 *)start));
-	if (be32_to_cpu(((__be32 *)mem)[size / 4]) != 0xdeadbeef)
-		pr_warning("End of tree marker overwritten: %08x\n",
-			   be32_to_cpu(((__be32 *)mem)[size / 4]));
-	*allnextp = NULL;
+	__unflatten_device_tree(initial_boot_params, &allnodes,
+				early_device_tree_alloc);
 
 	/* Get pointer to OF "/chosen" node for use everywhere */
 	of_chosen = of_find_node_by_path("/chosen");
 	if (of_chosen == NULL)
 		of_chosen = of_find_node_by_path("/chosen@0");
-
-	pr_debug(" <- unflatten_device_tree()\n");
 }
 
 #endif /* CONFIG_EARLY_FLATTREE */
diff --git a/include/linux/of_fdt.h b/include/linux/of_fdt.h
index 70c5b73..9ce5dfd 100644
--- a/include/linux/of_fdt.h
+++ b/include/linux/of_fdt.h
@@ -68,6 +68,8 @@ extern void *of_fdt_get_property(struct boot_param_header *blob,
 extern int of_fdt_is_compatible(struct boot_param_header *blob,
 				unsigned long node,
 				const char *compat);
+extern void of_fdt_unflatten_tree(unsigned long *blob,
+			       struct device_node **mynodes);
 
 /* TBD: Temporary export of fdt globals - remove when code fully merged */
 extern int __initdata dt_root_addr_cells;
-- 
1.5.6.6



This email and any attachments are intended for the sole use of the named recipient(s) and contain(s) confidential information that may be proprietary, privileged or copyrighted under applicable law. If you are not the intended recipient, do not read, copy, or forward this email message or any attachments. Delete this email message and any attachments immediately.

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

* [PATCH 7/7] fdt.c: Refactor unflatten_device_tree and add fdt_unflatten_tree
@ 2010-11-18 23:55                   ` Stephen Neuendorffer
  0 siblings, 0 replies; 41+ messages in thread
From: Stephen Neuendorffer @ 2010-11-18 23:55 UTC (permalink / raw)
  To: grant.likely, dirk.brandewie, devicetree-discuss, linuxppc-dev,
	microblaze-uclinux

unflatten_device_tree has two dependencies on things that happen
during boot time.  Firstly, it references the initial device tree
directly. Secondly, it allocates memory using the early boot
allocator.  This patch factors out these dependencies and uses
the new __unflatten_device_tree function to implement a driver-visible
fdt_unflatten_tree function, which can be used to unflatten a
blob after boot time.

Signed-off-by: Stephen Neuendorffer <stephen.neuendorffer@xilinx.com>

--

V2: remove extra __va() call
	 make dt_alloc functions return void *.  This doesn't fix the general
    strangeness in this code that constantly casts back and forth between
    unsigned long and __be32 *
---
 drivers/of/fdt.c       |  149 +++++++++++++++++++++++++++++++----------------
 include/linux/of_fdt.h |    2 +
 2 files changed, 100 insertions(+), 51 deletions(-)

diff --git a/drivers/of/fdt.c b/drivers/of/fdt.c
index 236a8c9..e29dbe2 100644
--- a/drivers/of/fdt.c
+++ b/drivers/of/fdt.c
@@ -11,10 +11,12 @@
 
 #include <linux/kernel.h>
 #include <linux/initrd.h>
+#include <linux/module.h>
 #include <linux/of.h>
 #include <linux/of_fdt.h>
 #include <linux/string.h>
 #include <linux/errno.h>
+#include <linux/slab.h>
 
 #ifdef CONFIG_PPC
 #include <asm/machdep.h>
@@ -312,6 +314,94 @@ unsigned long unflatten_dt_node(struct boot_param_header *blob,
 	return mem;
 }
 
+/**
+ * __unflatten_device_tree - create tree of device_nodes from flat blob
+ *
+ * unflattens a device-tree, creating the
+ * tree of struct device_node. It also fills the "name" and "type"
+ * pointers of the nodes so the normal device-tree walking functions
+ * can be used.
+ * @blob: The blob to expand
+ * @mynodes: The device_node tree created by the call
+ * @dt_alloc: An allocator that provides a virtual address to memory
+ * for the resulting tree
+ */
+void __unflatten_device_tree(struct boot_param_header *blob,
+			     struct device_node **mynodes,
+			     void * (*dt_alloc)(u64 size, u64 align))
+{
+	unsigned long start, mem, size;
+	struct device_node **allnextp = mynodes;
+
+	pr_debug(" -> unflatten_device_tree()\n");
+
+	if (!blob) {
+		pr_debug("No device tree pointer\n");
+		return;
+	}
+
+	pr_debug("Unflattening device tree:\n");
+	pr_debug("magic: %08x\n", be32_to_cpu(blob->magic));
+	pr_debug("size: %08x\n", be32_to_cpu(blob->totalsize));
+	pr_debug("version: %08x\n", be32_to_cpu(blob->version));
+
+	if (be32_to_cpu(blob->magic) != OF_DT_HEADER) {
+		pr_err("Invalid device tree blob header\n");
+		return;
+	}
+
+	/* First pass, scan for size */
+	start = ((unsigned long)blob) +
+		be32_to_cpu(blob->off_dt_struct);
+	size = unflatten_dt_node(blob, 0, &start, NULL, NULL, 0);
+	size = (size | 3) + 1;
+
+	pr_debug("  size is %lx, allocating...\n", size);
+
+	/* Allocate memory for the expanded device tree */
+	mem = (unsigned long)
+		dt_alloc(size + 4, __alignof__(struct device_node));
+
+	((__be32 *)mem)[size / 4] = cpu_to_be32(0xdeadbeef);
+
+	pr_debug("  unflattening %lx...\n", mem);
+
+	/* Second pass, do actual unflattening */
+	start = ((unsigned long)blob) +
+		be32_to_cpu(blob->off_dt_struct);
+	unflatten_dt_node(blob, mem, &start, NULL, &allnextp, 0);
+	if (be32_to_cpup((__be32 *)start) != OF_DT_END)
+		pr_warning("Weird tag at end of tree: %08x\n", *((u32 *)start));
+	if (be32_to_cpu(((__be32 *)mem)[size / 4]) != 0xdeadbeef)
+		pr_warning("End of tree marker overwritten: %08x\n",
+			   be32_to_cpu(((__be32 *)mem)[size / 4]));
+	*allnextp = NULL;
+
+	pr_debug(" <- unflatten_device_tree()\n");
+}
+
+static void *kernel_tree_alloc(u64 size, u64 align)
+{
+	return kzalloc(size, GFP_KERNEL);
+}
+
+/**
+ * of_fdt_unflatten_tree - create tree of device_nodes from flat blob
+ *
+ * unflattens the device-tree passed by the firmware, creating the
+ * tree of struct device_node. It also fills the "name" and "type"
+ * pointers of the nodes so the normal device-tree walking functions
+ * can be used.
+ */
+void of_fdt_unflatten_tree(unsigned long *blob,
+			struct device_node **mynodes)
+{
+	struct boot_param_header *device_tree =
+		(struct boot_param_header *)blob;
+	__unflatten_device_tree(device_tree, mynodes, &kernel_tree_alloc);
+}
+EXPORT_SYMBOL_GPL(of_fdt_unflatten_tree);
+
 /* Everything below here references initial_boot_params directly. */
 int __initdata dt_root_addr_cells;
 int __initdata dt_root_size_cells;
@@ -569,6 +659,12 @@ int __init early_init_dt_scan_chosen(unsigned long node, const char *uname,
 	return 1;
 }
 
+static void *__init early_device_tree_alloc(u64 size, u64 align)
+{
+	unsigned long mem = early_init_dt_alloc_memory_arch(size, align);
+	return __va(mem);
+}
+
 /**
  * unflatten_device_tree - create tree of device_nodes from flat blob
  *
@@ -579,62 +675,13 @@ int __init early_init_dt_scan_chosen(unsigned long node, const char *uname,
  */
 void __init unflatten_device_tree(void)
 {
-	unsigned long start, mem, size;
-	struct device_node **allnextp = &allnodes;
-
-	pr_debug(" -> unflatten_device_tree()\n");
-
-	if (!initial_boot_params) {
-		pr_debug("No device tree pointer\n");
-		return;
-	}
-
-	pr_debug("Unflattening device tree:\n");
-	pr_debug("magic: %08x\n", be32_to_cpu(initial_boot_params->magic));
-	pr_debug("size: %08x\n", be32_to_cpu(initial_boot_params->totalsize));
-	pr_debug("version: %08x\n", be32_to_cpu(initial_boot_params->version));
-
-	if (be32_to_cpu(initial_boot_params->magic) != OF_DT_HEADER) {
-		pr_err("Invalid device tree blob header\n");
-		return;
-	}
-
-	/* First pass, scan for size */
-	start = ((unsigned long)initial_boot_params) +
-		be32_to_cpu(initial_boot_params->off_dt_struct);
-	size = unflatten_dt_node(initial_boot_params, 0, &start,
-				 NULL, NULL, 0);
-	size = (size | 3) + 1;
-
-	pr_debug("  size is %lx, allocating...\n", size);
-
-	/* Allocate memory for the expanded device tree */
-	mem = early_init_dt_alloc_memory_arch(size + 4,
-			__alignof__(struct device_node));
-	mem = (unsigned long) __va(mem);
-
-	((__be32 *)mem)[size / 4] = cpu_to_be32(0xdeadbeef);
-
-	pr_debug("  unflattening %lx...\n", mem);
-
-	/* Second pass, do actual unflattening */
-	start = ((unsigned long)initial_boot_params) +
-		be32_to_cpu(initial_boot_params->off_dt_struct);
-	unflatten_dt_node(initial_boot_params, mem, &start,
-			  NULL, &allnextp, 0);
-	if (be32_to_cpup((__be32 *)start) != OF_DT_END)
-		pr_warning("Weird tag at end of tree: %08x\n", *((u32 *)start));
-	if (be32_to_cpu(((__be32 *)mem)[size / 4]) != 0xdeadbeef)
-		pr_warning("End of tree marker overwritten: %08x\n",
-			   be32_to_cpu(((__be32 *)mem)[size / 4]));
-	*allnextp = NULL;
+	__unflatten_device_tree(initial_boot_params, &allnodes,
+				early_device_tree_alloc);
 
 	/* Get pointer to OF "/chosen" node for use everywhere */
 	of_chosen = of_find_node_by_path("/chosen");
 	if (of_chosen == NULL)
 		of_chosen = of_find_node_by_path("/chosen@0");
-
-	pr_debug(" <- unflatten_device_tree()\n");
 }
 
 #endif /* CONFIG_EARLY_FLATTREE */
diff --git a/include/linux/of_fdt.h b/include/linux/of_fdt.h
index 70c5b73..9ce5dfd 100644
--- a/include/linux/of_fdt.h
+++ b/include/linux/of_fdt.h
@@ -68,6 +68,8 @@ extern void *of_fdt_get_property(struct boot_param_header *blob,
 extern int of_fdt_is_compatible(struct boot_param_header *blob,
 				unsigned long node,
 				const char *compat);
+extern void of_fdt_unflatten_tree(unsigned long *blob,
+			       struct device_node **mynodes);
 
 /* TBD: Temporary export of fdt globals - remove when code fully merged */
 extern int __initdata dt_root_addr_cells;
-- 
1.5.6.6



This email and any attachments are intended for the sole use of the named recipient(s) and contain(s) confidential information that may be proprietary, privileged or copyrighted under applicable law. If you are not the intended recipient, do not read, copy, or forward this email message or any attachments. Delete this email message and any attachments immediately.

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

* Re: [PATCH 1/7] fdt: Add Kconfig for EARLY_FLATTREE
  2010-11-18 23:54       ` Stephen Neuendorffer
@ 2010-12-30  0:15           ` Grant Likely
  -1 siblings, 0 replies; 41+ messages in thread
From: Grant Likely @ 2010-12-30  0:15 UTC (permalink / raw)
  To: Stephen Neuendorffer
  Cc: microblaze-uclinux-rVRm/Wmeqae7NGdpmJTKYQ,
	devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ,
	linuxppc-dev-uLR06cmDAlY/bJ5BZ2RsiQ

On Thu, Nov 18, 2010 at 03:54:56PM -0800, Stephen Neuendorffer wrote:
> The device tree code is now in two pieces: some which can be used generically
> on any platform which selects CONFIG_OF_FLATTREE, and some early which is used
> at boot time on only a few architectures.  This patch segregates the early
> code so that only those architectures which care about it need compile it.
> This also means that some of the requirements in the early code (such as
> a cmd_line variable) that most architectures (e.g. X86) don't provide
> can be ignored.
> 
> Signed-off-by: Stephen Neuendorffer <stephen.neuendorffer-gjFFaj9aHVfQT0dZR+AlfA@public.gmane.org>

Applied, thanks.  I had to fix up the #ifdef which was testing for
CONFIG_EARLY_FLATTREE instead of CONFIG_OF_EARLY_FLATTREE, and I
reworked OF_EARLY_FLATTREE to select instead of depend on OF_FLATTREE.

Cheers,
g.

> 
> ----
> 
> Grant,
> We had discussed doing something like this a loooong time ago.  This (or at
> least some other way of dealing with cmd_line) is
> actually necessary to compile on X86.  Do you still want to do it this way?
> Looking at my old email, you suggested only powerpc and microblaze need this.
> Is that still the case?
> 
> Conflicts:
> 
> 	drivers/of/fdt.c
> ---
>  arch/microblaze/Kconfig |    1 +
>  arch/powerpc/Kconfig    |    1 +
>  drivers/of/Kconfig      |    5 +++++
>  drivers/of/fdt.c        |    4 ++++
>  4 files changed, 11 insertions(+), 0 deletions(-)
> 
> diff --git a/arch/microblaze/Kconfig b/arch/microblaze/Kconfig
> index 692fdfc..384375c 100644
> --- a/arch/microblaze/Kconfig
> +++ b/arch/microblaze/Kconfig
> @@ -20,6 +20,7 @@ config MICROBLAZE
>  	select TRACING_SUPPORT
>  	select OF
>  	select OF_FLATTREE
> +	select OF_EARLY_FLATTREE
>  
>  config SWAP
>  	def_bool n
> diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig
> index 631e5a0..2cd7b32 100644
> --- a/arch/powerpc/Kconfig
> +++ b/arch/powerpc/Kconfig
> @@ -119,6 +119,7 @@ config PPC
>  	default y
>  	select OF
>  	select OF_FLATTREE
> +	select OF_EARLY_FLATTREE
>  	select HAVE_FTRACE_MCOUNT_RECORD
>  	select HAVE_DYNAMIC_FTRACE
>  	select HAVE_FUNCTION_TRACER
> diff --git a/drivers/of/Kconfig b/drivers/of/Kconfig
> index aa675eb..0199157 100644
> --- a/drivers/of/Kconfig
> +++ b/drivers/of/Kconfig
> @@ -19,6 +19,10 @@ config OF_FLATTREE
>  	bool
>  	select DTC
>  
> +config OF_EARLY_FLATTREE
> +	bool
> +	depends on OF_FLATTREE
> +
>  config OF_PROMTREE
>  	bool
>  
> @@ -62,3 +66,4 @@ config OF_MDIO
>  	  OpenFirmware MDIO bus (Ethernet PHY) accessors
>  
>  endmenu # OF
> +
> diff --git a/drivers/of/fdt.c b/drivers/of/fdt.c
> index c1360e0..4d71b29 100644
> --- a/drivers/of/fdt.c
> +++ b/drivers/of/fdt.c
> @@ -27,6 +27,8 @@ int __initdata dt_root_size_cells;
>  
>  struct boot_param_header *initial_boot_params;
>  
> +#ifdef CONFIG_EARLY_FLATTREE
> +
>  char *find_flat_dt_string(u32 offset)
>  {
>  	return ((char *)initial_boot_params) +
> @@ -604,3 +606,5 @@ void __init unflatten_device_tree(void)
>  
>  	pr_debug(" <- unflatten_device_tree()\n");
>  }
> +
> +#endif /* CONFIG_EARLY_FLATTREE */
> -- 
> 1.5.6.6
> 
> 
> 
> This email and any attachments are intended for the sole use of the named recipient(s) and contain(s) confidential information that may be proprietary, privileged or copyrighted under applicable law. If you are not the intended recipient, do not read, copy, or forward this email message or any attachments. Delete this email message and any attachments immediately.
> 
> 

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

* Re: [PATCH 1/7] fdt: Add Kconfig for EARLY_FLATTREE
@ 2010-12-30  0:15           ` Grant Likely
  0 siblings, 0 replies; 41+ messages in thread
From: Grant Likely @ 2010-12-30  0:15 UTC (permalink / raw)
  To: Stephen Neuendorffer
  Cc: dirk.brandewie, microblaze-uclinux, devicetree-discuss, linuxppc-dev

On Thu, Nov 18, 2010 at 03:54:56PM -0800, Stephen Neuendorffer wrote:
> The device tree code is now in two pieces: some which can be used generically
> on any platform which selects CONFIG_OF_FLATTREE, and some early which is used
> at boot time on only a few architectures.  This patch segregates the early
> code so that only those architectures which care about it need compile it.
> This also means that some of the requirements in the early code (such as
> a cmd_line variable) that most architectures (e.g. X86) don't provide
> can be ignored.
> 
> Signed-off-by: Stephen Neuendorffer <stephen.neuendorffer@xilinx.com>

Applied, thanks.  I had to fix up the #ifdef which was testing for
CONFIG_EARLY_FLATTREE instead of CONFIG_OF_EARLY_FLATTREE, and I
reworked OF_EARLY_FLATTREE to select instead of depend on OF_FLATTREE.

Cheers,
g.

> 
> ----
> 
> Grant,
> We had discussed doing something like this a loooong time ago.  This (or at
> least some other way of dealing with cmd_line) is
> actually necessary to compile on X86.  Do you still want to do it this way?
> Looking at my old email, you suggested only powerpc and microblaze need this.
> Is that still the case?
> 
> Conflicts:
> 
> 	drivers/of/fdt.c
> ---
>  arch/microblaze/Kconfig |    1 +
>  arch/powerpc/Kconfig    |    1 +
>  drivers/of/Kconfig      |    5 +++++
>  drivers/of/fdt.c        |    4 ++++
>  4 files changed, 11 insertions(+), 0 deletions(-)
> 
> diff --git a/arch/microblaze/Kconfig b/arch/microblaze/Kconfig
> index 692fdfc..384375c 100644
> --- a/arch/microblaze/Kconfig
> +++ b/arch/microblaze/Kconfig
> @@ -20,6 +20,7 @@ config MICROBLAZE
>  	select TRACING_SUPPORT
>  	select OF
>  	select OF_FLATTREE
> +	select OF_EARLY_FLATTREE
>  
>  config SWAP
>  	def_bool n
> diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig
> index 631e5a0..2cd7b32 100644
> --- a/arch/powerpc/Kconfig
> +++ b/arch/powerpc/Kconfig
> @@ -119,6 +119,7 @@ config PPC
>  	default y
>  	select OF
>  	select OF_FLATTREE
> +	select OF_EARLY_FLATTREE
>  	select HAVE_FTRACE_MCOUNT_RECORD
>  	select HAVE_DYNAMIC_FTRACE
>  	select HAVE_FUNCTION_TRACER
> diff --git a/drivers/of/Kconfig b/drivers/of/Kconfig
> index aa675eb..0199157 100644
> --- a/drivers/of/Kconfig
> +++ b/drivers/of/Kconfig
> @@ -19,6 +19,10 @@ config OF_FLATTREE
>  	bool
>  	select DTC
>  
> +config OF_EARLY_FLATTREE
> +	bool
> +	depends on OF_FLATTREE
> +
>  config OF_PROMTREE
>  	bool
>  
> @@ -62,3 +66,4 @@ config OF_MDIO
>  	  OpenFirmware MDIO bus (Ethernet PHY) accessors
>  
>  endmenu # OF
> +
> diff --git a/drivers/of/fdt.c b/drivers/of/fdt.c
> index c1360e0..4d71b29 100644
> --- a/drivers/of/fdt.c
> +++ b/drivers/of/fdt.c
> @@ -27,6 +27,8 @@ int __initdata dt_root_size_cells;
>  
>  struct boot_param_header *initial_boot_params;
>  
> +#ifdef CONFIG_EARLY_FLATTREE
> +
>  char *find_flat_dt_string(u32 offset)
>  {
>  	return ((char *)initial_boot_params) +
> @@ -604,3 +606,5 @@ void __init unflatten_device_tree(void)
>  
>  	pr_debug(" <- unflatten_device_tree()\n");
>  }
> +
> +#endif /* CONFIG_EARLY_FLATTREE */
> -- 
> 1.5.6.6
> 
> 
> 
> This email and any attachments are intended for the sole use of the named recipient(s) and contain(s) confidential information that may be proprietary, privileged or copyrighted under applicable law. If you are not the intended recipient, do not read, copy, or forward this email message or any attachments. Delete this email message and any attachments immediately.
> 
> 

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

* Re: [PATCH 2/7] arch/x86: Add support for device tree code.
  2010-11-18 23:54         ` Stephen Neuendorffer
@ 2010-12-30  0:17             ` Grant Likely
  -1 siblings, 0 replies; 41+ messages in thread
From: Grant Likely @ 2010-12-30  0:17 UTC (permalink / raw)
  To: Stephen Neuendorffer
  Cc: microblaze-uclinux-rVRm/Wmeqae7NGdpmJTKYQ,
	devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ,
	linuxppc-dev-uLR06cmDAlY/bJ5BZ2RsiQ

On Thu, Nov 18, 2010 at 03:54:57PM -0800, Stephen Neuendorffer wrote:
> A few support device-tree related support functions that x86 didn't
> have before.
> 
> Signed-off-by: Stephen Neuendorffer <stephen.neuendorffer-gjFFaj9aHVfQT0dZR+AlfA@public.gmane.org>

Skipping this patch.  I expect to pick up Dirk's version instead.

g.

> 
> ----
> 
> Looks like just some irq related junk left!
> ---
>  arch/x86/include/asm/irq.h |    2 ++
>  arch/x86/kernel/irq.c      |   11 +++++++++++
>  2 files changed, 13 insertions(+), 0 deletions(-)
> 
> diff --git a/arch/x86/include/asm/irq.h b/arch/x86/include/asm/irq.h
> index 5458380..af4e630 100644
> --- a/arch/x86/include/asm/irq.h
> +++ b/arch/x86/include/asm/irq.h
> @@ -10,6 +10,8 @@
>  #include <asm/apicdef.h>
>  #include <asm/irq_vectors.h>
>  
> +#define irq_dispose_mapping(...)
> +
>  static inline int irq_canonicalize(int irq)
>  {
>  	return ((irq == 2) ? 9 : irq);
> diff --git a/arch/x86/kernel/irq.c b/arch/x86/kernel/irq.c
> index 91fd0c7..a3aaed4 100644
> --- a/arch/x86/kernel/irq.c
> +++ b/arch/x86/kernel/irq.c
> @@ -364,3 +364,14 @@ void fixup_irqs(void)
>  	}
>  }
>  #endif
> +
> +#ifdef CONFIG_OF
> +#include <linux/of_irq.h>
> +unsigned int irq_create_of_mapping(struct device_node *controller,
> +				   const u32 *intspec, unsigned int intsize)
> +{
> +	return intspec[0] + 1;
> +}
> +EXPORT_SYMBOL_GPL(irq_create_of_mapping);
> +
> +#endif
> -- 
> 1.5.6.6
> 
> 
> 
> This email and any attachments are intended for the sole use of the named recipient(s) and contain(s) confidential information that may be proprietary, privileged or copyrighted under applicable law. If you are not the intended recipient, do not read, copy, or forward this email message or any attachments. Delete this email message and any attachments immediately.
> 
> 

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

* Re: [PATCH 2/7] arch/x86: Add support for device tree code.
@ 2010-12-30  0:17             ` Grant Likely
  0 siblings, 0 replies; 41+ messages in thread
From: Grant Likely @ 2010-12-30  0:17 UTC (permalink / raw)
  To: Stephen Neuendorffer
  Cc: dirk.brandewie, microblaze-uclinux, devicetree-discuss, linuxppc-dev

On Thu, Nov 18, 2010 at 03:54:57PM -0800, Stephen Neuendorffer wrote:
> A few support device-tree related support functions that x86 didn't
> have before.
> 
> Signed-off-by: Stephen Neuendorffer <stephen.neuendorffer@xilinx.com>

Skipping this patch.  I expect to pick up Dirk's version instead.

g.

> 
> ----
> 
> Looks like just some irq related junk left!
> ---
>  arch/x86/include/asm/irq.h |    2 ++
>  arch/x86/kernel/irq.c      |   11 +++++++++++
>  2 files changed, 13 insertions(+), 0 deletions(-)
> 
> diff --git a/arch/x86/include/asm/irq.h b/arch/x86/include/asm/irq.h
> index 5458380..af4e630 100644
> --- a/arch/x86/include/asm/irq.h
> +++ b/arch/x86/include/asm/irq.h
> @@ -10,6 +10,8 @@
>  #include <asm/apicdef.h>
>  #include <asm/irq_vectors.h>
>  
> +#define irq_dispose_mapping(...)
> +
>  static inline int irq_canonicalize(int irq)
>  {
>  	return ((irq == 2) ? 9 : irq);
> diff --git a/arch/x86/kernel/irq.c b/arch/x86/kernel/irq.c
> index 91fd0c7..a3aaed4 100644
> --- a/arch/x86/kernel/irq.c
> +++ b/arch/x86/kernel/irq.c
> @@ -364,3 +364,14 @@ void fixup_irqs(void)
>  	}
>  }
>  #endif
> +
> +#ifdef CONFIG_OF
> +#include <linux/of_irq.h>
> +unsigned int irq_create_of_mapping(struct device_node *controller,
> +				   const u32 *intspec, unsigned int intsize)
> +{
> +	return intspec[0] + 1;
> +}
> +EXPORT_SYMBOL_GPL(irq_create_of_mapping);
> +
> +#endif
> -- 
> 1.5.6.6
> 
> 
> 
> This email and any attachments are intended for the sole use of the named recipient(s) and contain(s) confidential information that may be proprietary, privileged or copyrighted under applicable law. If you are not the intended recipient, do not read, copy, or forward this email message or any attachments. Delete this email message and any attachments immediately.
> 
> 

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

* Re: [PATCH 3/7] arch/x86: select OF and OF_FLATTREE
  2010-11-18 23:54           ` Stephen Neuendorffer
@ 2010-12-30  0:17               ` Grant Likely
  -1 siblings, 0 replies; 41+ messages in thread
From: Grant Likely @ 2010-12-30  0:17 UTC (permalink / raw)
  To: Stephen Neuendorffer
  Cc: microblaze-uclinux-rVRm/Wmeqae7NGdpmJTKYQ,
	devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ,
	linuxppc-dev-uLR06cmDAlY/bJ5BZ2RsiQ

On Thu, Nov 18, 2010 at 03:54:58PM -0800, Stephen Neuendorffer wrote:
> Testing patch to verify that the device tree code can be compiled on X86.
> ---

Skipping this one also.

>  arch/x86/Kconfig |    2 ++
>  1 files changed, 2 insertions(+), 0 deletions(-)
> 
> diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig
> index cea0cd9..0f2ed5b 100644
> --- a/arch/x86/Kconfig
> +++ b/arch/x86/Kconfig
> @@ -59,6 +59,8 @@ config X86
>  	select ANON_INODES
>  	select HAVE_ARCH_KMEMCHECK
>  	select HAVE_USER_RETURN_NOTIFIER
> +	select OF
> +	select OF_FLATTREE
>  
>  config INSTRUCTION_DECODER
>  	def_bool (KPROBES || PERF_EVENTS)
> -- 
> 1.5.6.6
> 
> 
> 
> This email and any attachments are intended for the sole use of the named recipient(s) and contain(s) confidential information that may be proprietary, privileged or copyrighted under applicable law. If you are not the intended recipient, do not read, copy, or forward this email message or any attachments. Delete this email message and any attachments immediately.
> 
> 

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

* Re: [PATCH 3/7] arch/x86: select OF and OF_FLATTREE
@ 2010-12-30  0:17               ` Grant Likely
  0 siblings, 0 replies; 41+ messages in thread
From: Grant Likely @ 2010-12-30  0:17 UTC (permalink / raw)
  To: Stephen Neuendorffer
  Cc: dirk.brandewie, microblaze-uclinux, devicetree-discuss, linuxppc-dev

On Thu, Nov 18, 2010 at 03:54:58PM -0800, Stephen Neuendorffer wrote:
> Testing patch to verify that the device tree code can be compiled on X86.
> ---

Skipping this one also.

>  arch/x86/Kconfig |    2 ++
>  1 files changed, 2 insertions(+), 0 deletions(-)
> 
> diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig
> index cea0cd9..0f2ed5b 100644
> --- a/arch/x86/Kconfig
> +++ b/arch/x86/Kconfig
> @@ -59,6 +59,8 @@ config X86
>  	select ANON_INODES
>  	select HAVE_ARCH_KMEMCHECK
>  	select HAVE_USER_RETURN_NOTIFIER
> +	select OF
> +	select OF_FLATTREE
>  
>  config INSTRUCTION_DECODER
>  	def_bool (KPROBES || PERF_EVENTS)
> -- 
> 1.5.6.6
> 
> 
> 
> This email and any attachments are intended for the sole use of the named recipient(s) and contain(s) confidential information that may be proprietary, privileged or copyrighted under applicable law. If you are not the intended recipient, do not read, copy, or forward this email message or any attachments. Delete this email message and any attachments immediately.
> 
> 

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

* Re: [PATCH 4/7] fdt.c: Add non-boottime device tree functions
  2010-11-18 23:54             ` Stephen Neuendorffer
@ 2010-12-30  0:34                 ` Grant Likely
  -1 siblings, 0 replies; 41+ messages in thread
From: Grant Likely @ 2010-12-30  0:34 UTC (permalink / raw)
  To: Stephen Neuendorffer
  Cc: microblaze-uclinux-rVRm/Wmeqae7NGdpmJTKYQ,
	devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ,
	linuxppc-dev-uLR06cmDAlY/bJ5BZ2RsiQ

On Thu, Nov 18, 2010 at 03:54:59PM -0800, Stephen Neuendorffer wrote:
> In preparation for providing run-time handling of device trees, factor
> out some of the basic functions so that they take an arbitrary blob,
> rather than relying on the single boot-time tree.
> 
> Signed-off-by: Stephen Neuendorffer <stephen.neuendorffer-gjFFaj9aHVfQT0dZR+AlfA@public.gmane.org>

Thanks.  Merged, but one comment below.  Please fix with a followup patch.

g.

> 
> --
> 
> V2: functions have of_fdt_* names
>     removed find_flat_dt_string
>     blob argument is first
> ---
>  drivers/of/fdt.c       |  133 ++++++++++++++++++++++++++++-------------------
>  include/linux/of_fdt.h |   11 ++++
>  2 files changed, 90 insertions(+), 54 deletions(-)
> 
> diff --git a/drivers/of/fdt.c b/drivers/of/fdt.c
> index 4d71b29..190e26c 100644
> --- a/drivers/of/fdt.c
> +++ b/drivers/of/fdt.c
> @@ -22,6 +22,82 @@
>  
>  #include <asm/page.h>
>  
> +char *of_fdt_get_string(struct boot_param_header *blob, u32 offset)
> +{
> +	return ((char *)blob) +
> +		be32_to_cpu(blob->off_dt_strings) + offset;
> +}
> +
> +/**
> + * of_fdt_get_property - Given a node in the given flat blob, return
> + * the property ptr
> + */
> +void *of_fdt_get_property(struct boot_param_header *blob,
> +		       unsigned long node, const char *name,
> +		       unsigned long *size)
> +{
> +	unsigned long p = node;
> +
> +	do {
> +		u32 tag = be32_to_cpup((__be32 *)p);
> +		u32 sz, noff;
> +		const char *nstr;
> +
> +		p += 4;
> +		if (tag == OF_DT_NOP)
> +			continue;
> +		if (tag != OF_DT_PROP)
> +			return NULL;
> +
> +		sz = be32_to_cpup((__be32 *)p);
> +		noff = be32_to_cpup((__be32 *)(p + 4));
> +		p += 8;
> +		if (be32_to_cpu(blob->version) < 0x10)
> +			p = ALIGN(p, sz >= 8 ? 8 : 4);
> +
> +		nstr = of_fdt_get_string(blob, noff);
> +		if (nstr == NULL) {
> +			pr_warning("Can't find property index name !\n");
> +			return NULL;
> +		}
> +		if (strcmp(name, nstr) == 0) {
> +			if (size)
> +				*size = sz;
> +			return (void *)p;
> +		}
> +		p += sz;
> +		p = ALIGN(p, 4);
> +	} while (1);
> +}
> +
> +/**
> + * of_fdt_is_compatible - Return true if given node from the given blob has
> + * compat in its compatible list
> + * @blob: A device tree blob
> + * @node: node to test
> + * @compat: compatible string to compare with compatible list.
> + */
> +int of_fdt_is_compatible(struct boot_param_header *blob,
> +		      unsigned long node, const char *compat)
> +{
> +	const char *cp;
> +	unsigned long cplen, l;
> +
> +	cp = of_fdt_get_property(blob, node, "compatible", &cplen);
> +	if (cp == NULL)
> +		return 0;
> +	while (cplen > 0) {
> +		if (of_compat_cmp(cp, compat, strlen(compat)) == 0)
> +			return 1;

Need to verify that strlen(cp) + 1 is not larger than cplen.
Otherwise cplen could wrap around and the loop won't terminate because
cplen is an unsigned long.

> +		l = strlen(cp) + 1;
> +		cp += l;
> +		cplen -= l;
> +	}
> +
> +	return 0;
> +}
> +
> +/* Everything below here references initial_boot_params directly. */
>  int __initdata dt_root_addr_cells;
>  int __initdata dt_root_size_cells;
>  
> @@ -29,12 +105,6 @@ struct boot_param_header *initial_boot_params;
>  
>  #ifdef CONFIG_EARLY_FLATTREE
>  
> -char *find_flat_dt_string(u32 offset)
> -{
> -	return ((char *)initial_boot_params) +
> -		be32_to_cpu(initial_boot_params->off_dt_strings) + offset;
> -}
> -
>  /**
>   * of_scan_flat_dt - scan flattened tree blob and call callback on each.
>   * @it: callback function
> @@ -123,38 +193,7 @@ unsigned long __init of_get_flat_dt_root(void)
>  void *__init of_get_flat_dt_prop(unsigned long node, const char *name,
>  				 unsigned long *size)
>  {
> -	unsigned long p = node;
> -
> -	do {
> -		u32 tag = be32_to_cpup((__be32 *)p);
> -		u32 sz, noff;
> -		const char *nstr;
> -
> -		p += 4;
> -		if (tag == OF_DT_NOP)
> -			continue;
> -		if (tag != OF_DT_PROP)
> -			return NULL;
> -
> -		sz = be32_to_cpup((__be32 *)p);
> -		noff = be32_to_cpup((__be32 *)(p + 4));
> -		p += 8;
> -		if (be32_to_cpu(initial_boot_params->version) < 0x10)
> -			p = ALIGN(p, sz >= 8 ? 8 : 4);
> -
> -		nstr = find_flat_dt_string(noff);
> -		if (nstr == NULL) {
> -			pr_warning("Can't find property index name !\n");
> -			return NULL;
> -		}
> -		if (strcmp(name, nstr) == 0) {
> -			if (size)
> -				*size = sz;
> -			return (void *)p;
> -		}
> -		p += sz;
> -		p = ALIGN(p, 4);
> -	} while (1);
> +	return of_fdt_get_property(initial_boot_params, node, name, size);
>  }
>  
>  /**
> @@ -164,21 +203,7 @@ void *__init of_get_flat_dt_prop(unsigned long node, const char *name,
>   */
>  int __init of_flat_dt_is_compatible(unsigned long node, const char *compat)
>  {
> -	const char *cp;
> -	unsigned long cplen, l;
> -
> -	cp = of_get_flat_dt_prop(node, "compatible", &cplen);
> -	if (cp == NULL)
> -		return 0;
> -	while (cplen > 0) {
> -		if (of_compat_cmp(cp, compat, strlen(compat)) == 0)
> -			return 1;
> -		l = strlen(cp) + 1;
> -		cp += l;
> -		cplen -= l;
> -	}
> -
> -	return 0;
> +	return of_fdt_is_compatible(initial_boot_params, node, compat);
>  }
>  
>  static void *__init unflatten_dt_alloc(unsigned long *mem, unsigned long size,
> @@ -303,7 +328,7 @@ unsigned long __init unflatten_dt_node(unsigned long mem,
>  		if (be32_to_cpu(initial_boot_params->version) < 0x10)
>  			*p = ALIGN(*p, sz >= 8 ? 8 : 4);
>  
> -		pname = find_flat_dt_string(noff);
> +		pname = of_fdt_get_string(initial_boot_params, noff);
>  		if (pname == NULL) {
>  			pr_info("Can't find property name in list !\n");
>  			break;
> diff --git a/include/linux/of_fdt.h b/include/linux/of_fdt.h
> index 7bbf5b3..70c5b73 100644
> --- a/include/linux/of_fdt.h
> +++ b/include/linux/of_fdt.h
> @@ -58,6 +58,17 @@ struct boot_param_header {
>  };
>  
>  #if defined(CONFIG_OF_FLATTREE)
> +
> +/* For scanning an arbitrary device-tree at any time */
> +extern char *of_fdt_get_string(struct boot_param_header *blob, u32 offset);
> +extern void *of_fdt_get_property(struct boot_param_header *blob,
> +				 unsigned long node,
> +				 const char *name,
> +				 unsigned long *size);
> +extern int of_fdt_is_compatible(struct boot_param_header *blob,
> +				unsigned long node,
> +				const char *compat);
> +
>  /* TBD: Temporary export of fdt globals - remove when code fully merged */
>  extern int __initdata dt_root_addr_cells;
>  extern int __initdata dt_root_size_cells;
> -- 
> 1.5.6.6
> 
> 
> 
> This email and any attachments are intended for the sole use of the named recipient(s) and contain(s) confidential information that may be proprietary, privileged or copyrighted under applicable law. If you are not the intended recipient, do not read, copy, or forward this email message or any attachments. Delete this email message and any attachments immediately.
> 
> 

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

* Re: [PATCH 4/7] fdt.c: Add non-boottime device tree functions
@ 2010-12-30  0:34                 ` Grant Likely
  0 siblings, 0 replies; 41+ messages in thread
From: Grant Likely @ 2010-12-30  0:34 UTC (permalink / raw)
  To: Stephen Neuendorffer
  Cc: dirk.brandewie, microblaze-uclinux, devicetree-discuss, linuxppc-dev

On Thu, Nov 18, 2010 at 03:54:59PM -0800, Stephen Neuendorffer wrote:
> In preparation for providing run-time handling of device trees, factor
> out some of the basic functions so that they take an arbitrary blob,
> rather than relying on the single boot-time tree.
> 
> Signed-off-by: Stephen Neuendorffer <stephen.neuendorffer@xilinx.com>

Thanks.  Merged, but one comment below.  Please fix with a followup patch.

g.

> 
> --
> 
> V2: functions have of_fdt_* names
>     removed find_flat_dt_string
>     blob argument is first
> ---
>  drivers/of/fdt.c       |  133 ++++++++++++++++++++++++++++-------------------
>  include/linux/of_fdt.h |   11 ++++
>  2 files changed, 90 insertions(+), 54 deletions(-)
> 
> diff --git a/drivers/of/fdt.c b/drivers/of/fdt.c
> index 4d71b29..190e26c 100644
> --- a/drivers/of/fdt.c
> +++ b/drivers/of/fdt.c
> @@ -22,6 +22,82 @@
>  
>  #include <asm/page.h>
>  
> +char *of_fdt_get_string(struct boot_param_header *blob, u32 offset)
> +{
> +	return ((char *)blob) +
> +		be32_to_cpu(blob->off_dt_strings) + offset;
> +}
> +
> +/**
> + * of_fdt_get_property - Given a node in the given flat blob, return
> + * the property ptr
> + */
> +void *of_fdt_get_property(struct boot_param_header *blob,
> +		       unsigned long node, const char *name,
> +		       unsigned long *size)
> +{
> +	unsigned long p = node;
> +
> +	do {
> +		u32 tag = be32_to_cpup((__be32 *)p);
> +		u32 sz, noff;
> +		const char *nstr;
> +
> +		p += 4;
> +		if (tag == OF_DT_NOP)
> +			continue;
> +		if (tag != OF_DT_PROP)
> +			return NULL;
> +
> +		sz = be32_to_cpup((__be32 *)p);
> +		noff = be32_to_cpup((__be32 *)(p + 4));
> +		p += 8;
> +		if (be32_to_cpu(blob->version) < 0x10)
> +			p = ALIGN(p, sz >= 8 ? 8 : 4);
> +
> +		nstr = of_fdt_get_string(blob, noff);
> +		if (nstr == NULL) {
> +			pr_warning("Can't find property index name !\n");
> +			return NULL;
> +		}
> +		if (strcmp(name, nstr) == 0) {
> +			if (size)
> +				*size = sz;
> +			return (void *)p;
> +		}
> +		p += sz;
> +		p = ALIGN(p, 4);
> +	} while (1);
> +}
> +
> +/**
> + * of_fdt_is_compatible - Return true if given node from the given blob has
> + * compat in its compatible list
> + * @blob: A device tree blob
> + * @node: node to test
> + * @compat: compatible string to compare with compatible list.
> + */
> +int of_fdt_is_compatible(struct boot_param_header *blob,
> +		      unsigned long node, const char *compat)
> +{
> +	const char *cp;
> +	unsigned long cplen, l;
> +
> +	cp = of_fdt_get_property(blob, node, "compatible", &cplen);
> +	if (cp == NULL)
> +		return 0;
> +	while (cplen > 0) {
> +		if (of_compat_cmp(cp, compat, strlen(compat)) == 0)
> +			return 1;

Need to verify that strlen(cp) + 1 is not larger than cplen.
Otherwise cplen could wrap around and the loop won't terminate because
cplen is an unsigned long.

> +		l = strlen(cp) + 1;
> +		cp += l;
> +		cplen -= l;
> +	}
> +
> +	return 0;
> +}
> +
> +/* Everything below here references initial_boot_params directly. */
>  int __initdata dt_root_addr_cells;
>  int __initdata dt_root_size_cells;
>  
> @@ -29,12 +105,6 @@ struct boot_param_header *initial_boot_params;
>  
>  #ifdef CONFIG_EARLY_FLATTREE
>  
> -char *find_flat_dt_string(u32 offset)
> -{
> -	return ((char *)initial_boot_params) +
> -		be32_to_cpu(initial_boot_params->off_dt_strings) + offset;
> -}
> -
>  /**
>   * of_scan_flat_dt - scan flattened tree blob and call callback on each.
>   * @it: callback function
> @@ -123,38 +193,7 @@ unsigned long __init of_get_flat_dt_root(void)
>  void *__init of_get_flat_dt_prop(unsigned long node, const char *name,
>  				 unsigned long *size)
>  {
> -	unsigned long p = node;
> -
> -	do {
> -		u32 tag = be32_to_cpup((__be32 *)p);
> -		u32 sz, noff;
> -		const char *nstr;
> -
> -		p += 4;
> -		if (tag == OF_DT_NOP)
> -			continue;
> -		if (tag != OF_DT_PROP)
> -			return NULL;
> -
> -		sz = be32_to_cpup((__be32 *)p);
> -		noff = be32_to_cpup((__be32 *)(p + 4));
> -		p += 8;
> -		if (be32_to_cpu(initial_boot_params->version) < 0x10)
> -			p = ALIGN(p, sz >= 8 ? 8 : 4);
> -
> -		nstr = find_flat_dt_string(noff);
> -		if (nstr == NULL) {
> -			pr_warning("Can't find property index name !\n");
> -			return NULL;
> -		}
> -		if (strcmp(name, nstr) == 0) {
> -			if (size)
> -				*size = sz;
> -			return (void *)p;
> -		}
> -		p += sz;
> -		p = ALIGN(p, 4);
> -	} while (1);
> +	return of_fdt_get_property(initial_boot_params, node, name, size);
>  }
>  
>  /**
> @@ -164,21 +203,7 @@ void *__init of_get_flat_dt_prop(unsigned long node, const char *name,
>   */
>  int __init of_flat_dt_is_compatible(unsigned long node, const char *compat)
>  {
> -	const char *cp;
> -	unsigned long cplen, l;
> -
> -	cp = of_get_flat_dt_prop(node, "compatible", &cplen);
> -	if (cp == NULL)
> -		return 0;
> -	while (cplen > 0) {
> -		if (of_compat_cmp(cp, compat, strlen(compat)) == 0)
> -			return 1;
> -		l = strlen(cp) + 1;
> -		cp += l;
> -		cplen -= l;
> -	}
> -
> -	return 0;
> +	return of_fdt_is_compatible(initial_boot_params, node, compat);
>  }
>  
>  static void *__init unflatten_dt_alloc(unsigned long *mem, unsigned long size,
> @@ -303,7 +328,7 @@ unsigned long __init unflatten_dt_node(unsigned long mem,
>  		if (be32_to_cpu(initial_boot_params->version) < 0x10)
>  			*p = ALIGN(*p, sz >= 8 ? 8 : 4);
>  
> -		pname = find_flat_dt_string(noff);
> +		pname = of_fdt_get_string(initial_boot_params, noff);
>  		if (pname == NULL) {
>  			pr_info("Can't find property name in list !\n");
>  			break;
> diff --git a/include/linux/of_fdt.h b/include/linux/of_fdt.h
> index 7bbf5b3..70c5b73 100644
> --- a/include/linux/of_fdt.h
> +++ b/include/linux/of_fdt.h
> @@ -58,6 +58,17 @@ struct boot_param_header {
>  };
>  
>  #if defined(CONFIG_OF_FLATTREE)
> +
> +/* For scanning an arbitrary device-tree at any time */
> +extern char *of_fdt_get_string(struct boot_param_header *blob, u32 offset);
> +extern void *of_fdt_get_property(struct boot_param_header *blob,
> +				 unsigned long node,
> +				 const char *name,
> +				 unsigned long *size);
> +extern int of_fdt_is_compatible(struct boot_param_header *blob,
> +				unsigned long node,
> +				const char *compat);
> +
>  /* TBD: Temporary export of fdt globals - remove when code fully merged */
>  extern int __initdata dt_root_addr_cells;
>  extern int __initdata dt_root_size_cells;
> -- 
> 1.5.6.6
> 
> 
> 
> This email and any attachments are intended for the sole use of the named recipient(s) and contain(s) confidential information that may be proprietary, privileged or copyrighted under applicable law. If you are not the intended recipient, do not read, copy, or forward this email message or any attachments. Delete this email message and any attachments immediately.
> 
> 

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

* Re: [PATCH 5/7] fdt.c: Refactor unflatten_dt_node
  2010-11-18 23:55               ` Stephen Neuendorffer
@ 2010-12-30  0:35                   ` Grant Likely
  -1 siblings, 0 replies; 41+ messages in thread
From: Grant Likely @ 2010-12-30  0:35 UTC (permalink / raw)
  To: Stephen Neuendorffer
  Cc: microblaze-uclinux-rVRm/Wmeqae7NGdpmJTKYQ,
	devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ,
	linuxppc-dev-uLR06cmDAlY/bJ5BZ2RsiQ

On Thu, Nov 18, 2010 at 03:55:00PM -0800, Stephen Neuendorffer wrote:
> unflatten_dt_node is a helper function that does most of the work to
> convert a device tree blob into tree of device nodes.  This code
> now uses a passed-in blob instead of using the single boot-time blob,
> allowing it to be called in more contexts.
> 
> Signed-off-by: Stephen Neuendorffer <stephen.neuendorffer-gjFFaj9aHVfQT0dZR+AlfA@public.gmane.org>

Merged, thanks.

g.

> 
> ---
> 
> V2: don't reorder
>     blob argument first.
> ---
>  drivers/of/fdt.c |   27 ++++++++++++++++-----------
>  1 files changed, 16 insertions(+), 11 deletions(-)
> 
> diff --git a/drivers/of/fdt.c b/drivers/of/fdt.c
> index 190e26c..a07fd1a 100644
> --- a/drivers/of/fdt.c
> +++ b/drivers/of/fdt.c
> @@ -206,7 +206,7 @@ int __init of_flat_dt_is_compatible(unsigned long node, const char *compat)
>  	return of_fdt_is_compatible(initial_boot_params, node, compat);
>  }
>  
> -static void *__init unflatten_dt_alloc(unsigned long *mem, unsigned long size,
> +static void *unflatten_dt_alloc(unsigned long *mem, unsigned long size,
>  				       unsigned long align)
>  {
>  	void *res;
> @@ -220,16 +220,18 @@ static void *__init unflatten_dt_alloc(unsigned long *mem, unsigned long size,
>  
>  /**
>   * unflatten_dt_node - Alloc and populate a device_node from the flat tree
> + * @blob: The parent device tree blob
>   * @p: pointer to node in flat tree
>   * @dad: Parent struct device_node
>   * @allnextpp: pointer to ->allnext from last allocated device_node
>   * @fpsize: Size of the node path up at the current depth.
>   */
> -unsigned long __init unflatten_dt_node(unsigned long mem,
> -					unsigned long *p,
> -					struct device_node *dad,
> -					struct device_node ***allnextpp,
> -					unsigned long fpsize)
> +unsigned long unflatten_dt_node(struct boot_param_header *blob,
> +				unsigned long mem,
> +				unsigned long *p,
> +				struct device_node *dad,
> +				struct device_node ***allnextpp,
> +				unsigned long fpsize)
>  {
>  	struct device_node *np;
>  	struct property *pp, **prev_pp = NULL;
> @@ -325,10 +327,10 @@ unsigned long __init unflatten_dt_node(unsigned long mem,
>  		sz = be32_to_cpup((__be32 *)(*p));
>  		noff = be32_to_cpup((__be32 *)((*p) + 4));
>  		*p += 8;
> -		if (be32_to_cpu(initial_boot_params->version) < 0x10)
> +		if (be32_to_cpu(blob->version) < 0x10)
>  			*p = ALIGN(*p, sz >= 8 ? 8 : 4);
>  
> -		pname = of_fdt_get_string(initial_boot_params, noff);
> +		pname = of_fdt_get_string(blob, noff);
>  		if (pname == NULL) {
>  			pr_info("Can't find property name in list !\n");
>  			break;
> @@ -407,7 +409,8 @@ unsigned long __init unflatten_dt_node(unsigned long mem,
>  		if (tag == OF_DT_NOP)
>  			*p += 4;
>  		else
> -			mem = unflatten_dt_node(mem, p, np, allnextpp, fpsize);
> +			mem = unflatten_dt_node(blob, mem, p, np, allnextpp,
> +						fpsize);
>  		tag = be32_to_cpup((__be32 *)(*p));
>  	}
>  	if (tag != OF_DT_END_NODE) {
> @@ -599,7 +602,8 @@ void __init unflatten_device_tree(void)
>  	/* First pass, scan for size */
>  	start = ((unsigned long)initial_boot_params) +
>  		be32_to_cpu(initial_boot_params->off_dt_struct);
> -	size = unflatten_dt_node(0, &start, NULL, NULL, 0);
> +	size = unflatten_dt_node(initial_boot_params, 0, &start,
> +				 NULL, NULL, 0);
>  	size = (size | 3) + 1;
>  
>  	pr_debug("  size is %lx, allocating...\n", size);
> @@ -616,7 +620,8 @@ void __init unflatten_device_tree(void)
>  	/* Second pass, do actual unflattening */
>  	start = ((unsigned long)initial_boot_params) +
>  		be32_to_cpu(initial_boot_params->off_dt_struct);
> -	unflatten_dt_node(mem, &start, NULL, &allnextp, 0);
> +	unflatten_dt_node(initial_boot_params, mem, &start,
> +			  NULL, &allnextp, 0);
>  	if (be32_to_cpup((__be32 *)start) != OF_DT_END)
>  		pr_warning("Weird tag at end of tree: %08x\n", *((u32 *)start));
>  	if (be32_to_cpu(((__be32 *)mem)[size / 4]) != 0xdeadbeef)
> -- 
> 1.5.6.6
> 
> 
> 
> This email and any attachments are intended for the sole use of the named recipient(s) and contain(s) confidential information that may be proprietary, privileged or copyrighted under applicable law. If you are not the intended recipient, do not read, copy, or forward this email message or any attachments. Delete this email message and any attachments immediately.
> 
> 

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

* Re: [PATCH 5/7] fdt.c: Refactor unflatten_dt_node
@ 2010-12-30  0:35                   ` Grant Likely
  0 siblings, 0 replies; 41+ messages in thread
From: Grant Likely @ 2010-12-30  0:35 UTC (permalink / raw)
  To: Stephen Neuendorffer
  Cc: dirk.brandewie, microblaze-uclinux, devicetree-discuss, linuxppc-dev

On Thu, Nov 18, 2010 at 03:55:00PM -0800, Stephen Neuendorffer wrote:
> unflatten_dt_node is a helper function that does most of the work to
> convert a device tree blob into tree of device nodes.  This code
> now uses a passed-in blob instead of using the single boot-time blob,
> allowing it to be called in more contexts.
> 
> Signed-off-by: Stephen Neuendorffer <stephen.neuendorffer@xilinx.com>

Merged, thanks.

g.

> 
> ---
> 
> V2: don't reorder
>     blob argument first.
> ---
>  drivers/of/fdt.c |   27 ++++++++++++++++-----------
>  1 files changed, 16 insertions(+), 11 deletions(-)
> 
> diff --git a/drivers/of/fdt.c b/drivers/of/fdt.c
> index 190e26c..a07fd1a 100644
> --- a/drivers/of/fdt.c
> +++ b/drivers/of/fdt.c
> @@ -206,7 +206,7 @@ int __init of_flat_dt_is_compatible(unsigned long node, const char *compat)
>  	return of_fdt_is_compatible(initial_boot_params, node, compat);
>  }
>  
> -static void *__init unflatten_dt_alloc(unsigned long *mem, unsigned long size,
> +static void *unflatten_dt_alloc(unsigned long *mem, unsigned long size,
>  				       unsigned long align)
>  {
>  	void *res;
> @@ -220,16 +220,18 @@ static void *__init unflatten_dt_alloc(unsigned long *mem, unsigned long size,
>  
>  /**
>   * unflatten_dt_node - Alloc and populate a device_node from the flat tree
> + * @blob: The parent device tree blob
>   * @p: pointer to node in flat tree
>   * @dad: Parent struct device_node
>   * @allnextpp: pointer to ->allnext from last allocated device_node
>   * @fpsize: Size of the node path up at the current depth.
>   */
> -unsigned long __init unflatten_dt_node(unsigned long mem,
> -					unsigned long *p,
> -					struct device_node *dad,
> -					struct device_node ***allnextpp,
> -					unsigned long fpsize)
> +unsigned long unflatten_dt_node(struct boot_param_header *blob,
> +				unsigned long mem,
> +				unsigned long *p,
> +				struct device_node *dad,
> +				struct device_node ***allnextpp,
> +				unsigned long fpsize)
>  {
>  	struct device_node *np;
>  	struct property *pp, **prev_pp = NULL;
> @@ -325,10 +327,10 @@ unsigned long __init unflatten_dt_node(unsigned long mem,
>  		sz = be32_to_cpup((__be32 *)(*p));
>  		noff = be32_to_cpup((__be32 *)((*p) + 4));
>  		*p += 8;
> -		if (be32_to_cpu(initial_boot_params->version) < 0x10)
> +		if (be32_to_cpu(blob->version) < 0x10)
>  			*p = ALIGN(*p, sz >= 8 ? 8 : 4);
>  
> -		pname = of_fdt_get_string(initial_boot_params, noff);
> +		pname = of_fdt_get_string(blob, noff);
>  		if (pname == NULL) {
>  			pr_info("Can't find property name in list !\n");
>  			break;
> @@ -407,7 +409,8 @@ unsigned long __init unflatten_dt_node(unsigned long mem,
>  		if (tag == OF_DT_NOP)
>  			*p += 4;
>  		else
> -			mem = unflatten_dt_node(mem, p, np, allnextpp, fpsize);
> +			mem = unflatten_dt_node(blob, mem, p, np, allnextpp,
> +						fpsize);
>  		tag = be32_to_cpup((__be32 *)(*p));
>  	}
>  	if (tag != OF_DT_END_NODE) {
> @@ -599,7 +602,8 @@ void __init unflatten_device_tree(void)
>  	/* First pass, scan for size */
>  	start = ((unsigned long)initial_boot_params) +
>  		be32_to_cpu(initial_boot_params->off_dt_struct);
> -	size = unflatten_dt_node(0, &start, NULL, NULL, 0);
> +	size = unflatten_dt_node(initial_boot_params, 0, &start,
> +				 NULL, NULL, 0);
>  	size = (size | 3) + 1;
>  
>  	pr_debug("  size is %lx, allocating...\n", size);
> @@ -616,7 +620,8 @@ void __init unflatten_device_tree(void)
>  	/* Second pass, do actual unflattening */
>  	start = ((unsigned long)initial_boot_params) +
>  		be32_to_cpu(initial_boot_params->off_dt_struct);
> -	unflatten_dt_node(mem, &start, NULL, &allnextp, 0);
> +	unflatten_dt_node(initial_boot_params, mem, &start,
> +			  NULL, &allnextp, 0);
>  	if (be32_to_cpup((__be32 *)start) != OF_DT_END)
>  		pr_warning("Weird tag at end of tree: %08x\n", *((u32 *)start));
>  	if (be32_to_cpu(((__be32 *)mem)[size / 4]) != 0xdeadbeef)
> -- 
> 1.5.6.6
> 
> 
> 
> This email and any attachments are intended for the sole use of the named recipient(s) and contain(s) confidential information that may be proprietary, privileged or copyrighted under applicable law. If you are not the intended recipient, do not read, copy, or forward this email message or any attachments. Delete this email message and any attachments immediately.
> 
> 

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

* Re: [PATCH 6/7] fdt.c: Reorder unflatten_dt_node
  2010-11-18 23:55                 ` Stephen Neuendorffer
@ 2010-12-30  0:36                     ` Grant Likely
  -1 siblings, 0 replies; 41+ messages in thread
From: Grant Likely @ 2010-12-30  0:36 UTC (permalink / raw)
  To: Stephen Neuendorffer
  Cc: microblaze-uclinux-rVRm/Wmeqae7NGdpmJTKYQ,
	devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ,
	linuxppc-dev-uLR06cmDAlY/bJ5BZ2RsiQ

On Thu, Nov 18, 2010 at 03:55:01PM -0800, Stephen Neuendorffer wrote:
> Move unflatten_dt_node to be grouped with non-__init functions.
> 
> Signed-off-by: Stephen Neuendorffer <stephen.neuendorffer-gjFFaj9aHVfQT0dZR+AlfA@public.gmane.org>

Merged, thanks.

g.

> ---
>  drivers/of/fdt.c |  218 +++++++++++++++++++++++++++---------------------------
>  1 files changed, 109 insertions(+), 109 deletions(-)
> 
> diff --git a/drivers/of/fdt.c b/drivers/of/fdt.c
> index a07fd1a..236a8c9 100644
> --- a/drivers/of/fdt.c
> +++ b/drivers/of/fdt.c
> @@ -97,115 +97,6 @@ int of_fdt_is_compatible(struct boot_param_header *blob,
>  	return 0;
>  }
>  
> -/* Everything below here references initial_boot_params directly. */
> -int __initdata dt_root_addr_cells;
> -int __initdata dt_root_size_cells;
> -
> -struct boot_param_header *initial_boot_params;
> -
> -#ifdef CONFIG_EARLY_FLATTREE
> -
> -/**
> - * of_scan_flat_dt - scan flattened tree blob and call callback on each.
> - * @it: callback function
> - * @data: context data pointer
> - *
> - * This function is used to scan the flattened device-tree, it is
> - * used to extract the memory information at boot before we can
> - * unflatten the tree
> - */
> -int __init of_scan_flat_dt(int (*it)(unsigned long node,
> -				     const char *uname, int depth,
> -				     void *data),
> -			   void *data)
> -{
> -	unsigned long p = ((unsigned long)initial_boot_params) +
> -		be32_to_cpu(initial_boot_params->off_dt_struct);
> -	int rc = 0;
> -	int depth = -1;
> -
> -	do {
> -		u32 tag = be32_to_cpup((__be32 *)p);
> -		char *pathp;
> -
> -		p += 4;
> -		if (tag == OF_DT_END_NODE) {
> -			depth--;
> -			continue;
> -		}
> -		if (tag == OF_DT_NOP)
> -			continue;
> -		if (tag == OF_DT_END)
> -			break;
> -		if (tag == OF_DT_PROP) {
> -			u32 sz = be32_to_cpup((__be32 *)p);
> -			p += 8;
> -			if (be32_to_cpu(initial_boot_params->version) < 0x10)
> -				p = ALIGN(p, sz >= 8 ? 8 : 4);
> -			p += sz;
> -			p = ALIGN(p, 4);
> -			continue;
> -		}
> -		if (tag != OF_DT_BEGIN_NODE) {
> -			pr_err("Invalid tag %x in flat device tree!\n", tag);
> -			return -EINVAL;
> -		}
> -		depth++;
> -		pathp = (char *)p;
> -		p = ALIGN(p + strlen(pathp) + 1, 4);
> -		if ((*pathp) == '/') {
> -			char *lp, *np;
> -			for (lp = NULL, np = pathp; *np; np++)
> -				if ((*np) == '/')
> -					lp = np+1;
> -			if (lp != NULL)
> -				pathp = lp;
> -		}
> -		rc = it(p, pathp, depth, data);
> -		if (rc != 0)
> -			break;
> -	} while (1);
> -
> -	return rc;
> -}
> -
> -/**
> - * of_get_flat_dt_root - find the root node in the flat blob
> - */
> -unsigned long __init of_get_flat_dt_root(void)
> -{
> -	unsigned long p = ((unsigned long)initial_boot_params) +
> -		be32_to_cpu(initial_boot_params->off_dt_struct);
> -
> -	while (be32_to_cpup((__be32 *)p) == OF_DT_NOP)
> -		p += 4;
> -	BUG_ON(be32_to_cpup((__be32 *)p) != OF_DT_BEGIN_NODE);
> -	p += 4;
> -	return ALIGN(p + strlen((char *)p) + 1, 4);
> -}
> -
> -/**
> - * of_get_flat_dt_prop - Given a node in the flat blob, return the property ptr
> - *
> - * This function can be used within scan_flattened_dt callback to get
> - * access to properties
> - */
> -void *__init of_get_flat_dt_prop(unsigned long node, const char *name,
> -				 unsigned long *size)
> -{
> -	return of_fdt_get_property(initial_boot_params, node, name, size);
> -}
> -
> -/**
> - * of_flat_dt_is_compatible - Return true if given node has compat in compatible list
> - * @node: node to test
> - * @compat: compatible string to compare with compatible list.
> - */
> -int __init of_flat_dt_is_compatible(unsigned long node, const char *compat)
> -{
> -	return of_fdt_is_compatible(initial_boot_params, node, compat);
> -}
> -
>  static void *unflatten_dt_alloc(unsigned long *mem, unsigned long size,
>  				       unsigned long align)
>  {
> @@ -421,6 +312,115 @@ unsigned long unflatten_dt_node(struct boot_param_header *blob,
>  	return mem;
>  }
>  
> +/* Everything below here references initial_boot_params directly. */
> +int __initdata dt_root_addr_cells;
> +int __initdata dt_root_size_cells;
> +
> +struct boot_param_header *initial_boot_params;
> +
> +#ifdef CONFIG_EARLY_FLATTREE
> +
> +/**
> + * of_scan_flat_dt - scan flattened tree blob and call callback on each.
> + * @it: callback function
> + * @data: context data pointer
> + *
> + * This function is used to scan the flattened device-tree, it is
> + * used to extract the memory information at boot before we can
> + * unflatten the tree
> + */
> +int __init of_scan_flat_dt(int (*it)(unsigned long node,
> +				     const char *uname, int depth,
> +				     void *data),
> +			   void *data)
> +{
> +	unsigned long p = ((unsigned long)initial_boot_params) +
> +		be32_to_cpu(initial_boot_params->off_dt_struct);
> +	int rc = 0;
> +	int depth = -1;
> +
> +	do {
> +		u32 tag = be32_to_cpup((__be32 *)p);
> +		char *pathp;
> +
> +		p += 4;
> +		if (tag == OF_DT_END_NODE) {
> +			depth--;
> +			continue;
> +		}
> +		if (tag == OF_DT_NOP)
> +			continue;
> +		if (tag == OF_DT_END)
> +			break;
> +		if (tag == OF_DT_PROP) {
> +			u32 sz = be32_to_cpup((__be32 *)p);
> +			p += 8;
> +			if (be32_to_cpu(initial_boot_params->version) < 0x10)
> +				p = ALIGN(p, sz >= 8 ? 8 : 4);
> +			p += sz;
> +			p = ALIGN(p, 4);
> +			continue;
> +		}
> +		if (tag != OF_DT_BEGIN_NODE) {
> +			pr_err("Invalid tag %x in flat device tree!\n", tag);
> +			return -EINVAL;
> +		}
> +		depth++;
> +		pathp = (char *)p;
> +		p = ALIGN(p + strlen(pathp) + 1, 4);
> +		if ((*pathp) == '/') {
> +			char *lp, *np;
> +			for (lp = NULL, np = pathp; *np; np++)
> +				if ((*np) == '/')
> +					lp = np+1;
> +			if (lp != NULL)
> +				pathp = lp;
> +		}
> +		rc = it(p, pathp, depth, data);
> +		if (rc != 0)
> +			break;
> +	} while (1);
> +
> +	return rc;
> +}
> +
> +/**
> + * of_get_flat_dt_root - find the root node in the flat blob
> + */
> +unsigned long __init of_get_flat_dt_root(void)
> +{
> +	unsigned long p = ((unsigned long)initial_boot_params) +
> +		be32_to_cpu(initial_boot_params->off_dt_struct);
> +
> +	while (be32_to_cpup((__be32 *)p) == OF_DT_NOP)
> +		p += 4;
> +	BUG_ON(be32_to_cpup((__be32 *)p) != OF_DT_BEGIN_NODE);
> +	p += 4;
> +	return ALIGN(p + strlen((char *)p) + 1, 4);
> +}
> +
> +/**
> + * of_get_flat_dt_prop - Given a node in the flat blob, return the property ptr
> + *
> + * This function can be used within scan_flattened_dt callback to get
> + * access to properties
> + */
> +void *__init of_get_flat_dt_prop(unsigned long node, const char *name,
> +				 unsigned long *size)
> +{
> +	return of_fdt_get_property(initial_boot_params, node, name, size);
> +}
> +
> +/**
> + * of_flat_dt_is_compatible - Return true if given node has compat in compatible list
> + * @node: node to test
> + * @compat: compatible string to compare with compatible list.
> + */
> +int __init of_flat_dt_is_compatible(unsigned long node, const char *compat)
> +{
> +	return of_fdt_is_compatible(initial_boot_params, node, compat);
> +}
> +
>  #ifdef CONFIG_BLK_DEV_INITRD
>  /**
>   * early_init_dt_check_for_initrd - Decode initrd location from flat tree
> -- 
> 1.5.6.6
> 
> 
> 
> This email and any attachments are intended for the sole use of the named recipient(s) and contain(s) confidential information that may be proprietary, privileged or copyrighted under applicable law. If you are not the intended recipient, do not read, copy, or forward this email message or any attachments. Delete this email message and any attachments immediately.
> 
> 

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

* Re: [PATCH 6/7] fdt.c: Reorder unflatten_dt_node
@ 2010-12-30  0:36                     ` Grant Likely
  0 siblings, 0 replies; 41+ messages in thread
From: Grant Likely @ 2010-12-30  0:36 UTC (permalink / raw)
  To: Stephen Neuendorffer
  Cc: dirk.brandewie, microblaze-uclinux, devicetree-discuss, linuxppc-dev

On Thu, Nov 18, 2010 at 03:55:01PM -0800, Stephen Neuendorffer wrote:
> Move unflatten_dt_node to be grouped with non-__init functions.
> 
> Signed-off-by: Stephen Neuendorffer <stephen.neuendorffer@xilinx.com>

Merged, thanks.

g.

> ---
>  drivers/of/fdt.c |  218 +++++++++++++++++++++++++++---------------------------
>  1 files changed, 109 insertions(+), 109 deletions(-)
> 
> diff --git a/drivers/of/fdt.c b/drivers/of/fdt.c
> index a07fd1a..236a8c9 100644
> --- a/drivers/of/fdt.c
> +++ b/drivers/of/fdt.c
> @@ -97,115 +97,6 @@ int of_fdt_is_compatible(struct boot_param_header *blob,
>  	return 0;
>  }
>  
> -/* Everything below here references initial_boot_params directly. */
> -int __initdata dt_root_addr_cells;
> -int __initdata dt_root_size_cells;
> -
> -struct boot_param_header *initial_boot_params;
> -
> -#ifdef CONFIG_EARLY_FLATTREE
> -
> -/**
> - * of_scan_flat_dt - scan flattened tree blob and call callback on each.
> - * @it: callback function
> - * @data: context data pointer
> - *
> - * This function is used to scan the flattened device-tree, it is
> - * used to extract the memory information at boot before we can
> - * unflatten the tree
> - */
> -int __init of_scan_flat_dt(int (*it)(unsigned long node,
> -				     const char *uname, int depth,
> -				     void *data),
> -			   void *data)
> -{
> -	unsigned long p = ((unsigned long)initial_boot_params) +
> -		be32_to_cpu(initial_boot_params->off_dt_struct);
> -	int rc = 0;
> -	int depth = -1;
> -
> -	do {
> -		u32 tag = be32_to_cpup((__be32 *)p);
> -		char *pathp;
> -
> -		p += 4;
> -		if (tag == OF_DT_END_NODE) {
> -			depth--;
> -			continue;
> -		}
> -		if (tag == OF_DT_NOP)
> -			continue;
> -		if (tag == OF_DT_END)
> -			break;
> -		if (tag == OF_DT_PROP) {
> -			u32 sz = be32_to_cpup((__be32 *)p);
> -			p += 8;
> -			if (be32_to_cpu(initial_boot_params->version) < 0x10)
> -				p = ALIGN(p, sz >= 8 ? 8 : 4);
> -			p += sz;
> -			p = ALIGN(p, 4);
> -			continue;
> -		}
> -		if (tag != OF_DT_BEGIN_NODE) {
> -			pr_err("Invalid tag %x in flat device tree!\n", tag);
> -			return -EINVAL;
> -		}
> -		depth++;
> -		pathp = (char *)p;
> -		p = ALIGN(p + strlen(pathp) + 1, 4);
> -		if ((*pathp) == '/') {
> -			char *lp, *np;
> -			for (lp = NULL, np = pathp; *np; np++)
> -				if ((*np) == '/')
> -					lp = np+1;
> -			if (lp != NULL)
> -				pathp = lp;
> -		}
> -		rc = it(p, pathp, depth, data);
> -		if (rc != 0)
> -			break;
> -	} while (1);
> -
> -	return rc;
> -}
> -
> -/**
> - * of_get_flat_dt_root - find the root node in the flat blob
> - */
> -unsigned long __init of_get_flat_dt_root(void)
> -{
> -	unsigned long p = ((unsigned long)initial_boot_params) +
> -		be32_to_cpu(initial_boot_params->off_dt_struct);
> -
> -	while (be32_to_cpup((__be32 *)p) == OF_DT_NOP)
> -		p += 4;
> -	BUG_ON(be32_to_cpup((__be32 *)p) != OF_DT_BEGIN_NODE);
> -	p += 4;
> -	return ALIGN(p + strlen((char *)p) + 1, 4);
> -}
> -
> -/**
> - * of_get_flat_dt_prop - Given a node in the flat blob, return the property ptr
> - *
> - * This function can be used within scan_flattened_dt callback to get
> - * access to properties
> - */
> -void *__init of_get_flat_dt_prop(unsigned long node, const char *name,
> -				 unsigned long *size)
> -{
> -	return of_fdt_get_property(initial_boot_params, node, name, size);
> -}
> -
> -/**
> - * of_flat_dt_is_compatible - Return true if given node has compat in compatible list
> - * @node: node to test
> - * @compat: compatible string to compare with compatible list.
> - */
> -int __init of_flat_dt_is_compatible(unsigned long node, const char *compat)
> -{
> -	return of_fdt_is_compatible(initial_boot_params, node, compat);
> -}
> -
>  static void *unflatten_dt_alloc(unsigned long *mem, unsigned long size,
>  				       unsigned long align)
>  {
> @@ -421,6 +312,115 @@ unsigned long unflatten_dt_node(struct boot_param_header *blob,
>  	return mem;
>  }
>  
> +/* Everything below here references initial_boot_params directly. */
> +int __initdata dt_root_addr_cells;
> +int __initdata dt_root_size_cells;
> +
> +struct boot_param_header *initial_boot_params;
> +
> +#ifdef CONFIG_EARLY_FLATTREE
> +
> +/**
> + * of_scan_flat_dt - scan flattened tree blob and call callback on each.
> + * @it: callback function
> + * @data: context data pointer
> + *
> + * This function is used to scan the flattened device-tree, it is
> + * used to extract the memory information at boot before we can
> + * unflatten the tree
> + */
> +int __init of_scan_flat_dt(int (*it)(unsigned long node,
> +				     const char *uname, int depth,
> +				     void *data),
> +			   void *data)
> +{
> +	unsigned long p = ((unsigned long)initial_boot_params) +
> +		be32_to_cpu(initial_boot_params->off_dt_struct);
> +	int rc = 0;
> +	int depth = -1;
> +
> +	do {
> +		u32 tag = be32_to_cpup((__be32 *)p);
> +		char *pathp;
> +
> +		p += 4;
> +		if (tag == OF_DT_END_NODE) {
> +			depth--;
> +			continue;
> +		}
> +		if (tag == OF_DT_NOP)
> +			continue;
> +		if (tag == OF_DT_END)
> +			break;
> +		if (tag == OF_DT_PROP) {
> +			u32 sz = be32_to_cpup((__be32 *)p);
> +			p += 8;
> +			if (be32_to_cpu(initial_boot_params->version) < 0x10)
> +				p = ALIGN(p, sz >= 8 ? 8 : 4);
> +			p += sz;
> +			p = ALIGN(p, 4);
> +			continue;
> +		}
> +		if (tag != OF_DT_BEGIN_NODE) {
> +			pr_err("Invalid tag %x in flat device tree!\n", tag);
> +			return -EINVAL;
> +		}
> +		depth++;
> +		pathp = (char *)p;
> +		p = ALIGN(p + strlen(pathp) + 1, 4);
> +		if ((*pathp) == '/') {
> +			char *lp, *np;
> +			for (lp = NULL, np = pathp; *np; np++)
> +				if ((*np) == '/')
> +					lp = np+1;
> +			if (lp != NULL)
> +				pathp = lp;
> +		}
> +		rc = it(p, pathp, depth, data);
> +		if (rc != 0)
> +			break;
> +	} while (1);
> +
> +	return rc;
> +}
> +
> +/**
> + * of_get_flat_dt_root - find the root node in the flat blob
> + */
> +unsigned long __init of_get_flat_dt_root(void)
> +{
> +	unsigned long p = ((unsigned long)initial_boot_params) +
> +		be32_to_cpu(initial_boot_params->off_dt_struct);
> +
> +	while (be32_to_cpup((__be32 *)p) == OF_DT_NOP)
> +		p += 4;
> +	BUG_ON(be32_to_cpup((__be32 *)p) != OF_DT_BEGIN_NODE);
> +	p += 4;
> +	return ALIGN(p + strlen((char *)p) + 1, 4);
> +}
> +
> +/**
> + * of_get_flat_dt_prop - Given a node in the flat blob, return the property ptr
> + *
> + * This function can be used within scan_flattened_dt callback to get
> + * access to properties
> + */
> +void *__init of_get_flat_dt_prop(unsigned long node, const char *name,
> +				 unsigned long *size)
> +{
> +	return of_fdt_get_property(initial_boot_params, node, name, size);
> +}
> +
> +/**
> + * of_flat_dt_is_compatible - Return true if given node has compat in compatible list
> + * @node: node to test
> + * @compat: compatible string to compare with compatible list.
> + */
> +int __init of_flat_dt_is_compatible(unsigned long node, const char *compat)
> +{
> +	return of_fdt_is_compatible(initial_boot_params, node, compat);
> +}
> +
>  #ifdef CONFIG_BLK_DEV_INITRD
>  /**
>   * early_init_dt_check_for_initrd - Decode initrd location from flat tree
> -- 
> 1.5.6.6
> 
> 
> 
> This email and any attachments are intended for the sole use of the named recipient(s) and contain(s) confidential information that may be proprietary, privileged or copyrighted under applicable law. If you are not the intended recipient, do not read, copy, or forward this email message or any attachments. Delete this email message and any attachments immediately.
> 
> 

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

* Re: [PATCH 7/7] fdt.c: Refactor unflatten_device_tree and add fdt_unflatten_tree
  2010-11-18 23:55                   ` Stephen Neuendorffer
@ 2010-12-30  0:43                       ` Grant Likely
  -1 siblings, 0 replies; 41+ messages in thread
From: Grant Likely @ 2010-12-30  0:43 UTC (permalink / raw)
  To: Stephen Neuendorffer
  Cc: microblaze-uclinux-rVRm/Wmeqae7NGdpmJTKYQ,
	devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ,
	linuxppc-dev-uLR06cmDAlY/bJ5BZ2RsiQ

On Thu, Nov 18, 2010 at 03:55:02PM -0800, Stephen Neuendorffer wrote:
> unflatten_device_tree has two dependencies on things that happen
> during boot time.  Firstly, it references the initial device tree
> directly. Secondly, it allocates memory using the early boot
> allocator.  This patch factors out these dependencies and uses
> the new __unflatten_device_tree function to implement a driver-visible
> fdt_unflatten_tree function, which can be used to unflatten a
> blob after boot time.
> 
> Signed-off-by: Stephen Neuendorffer <stephen.neuendorffer-gjFFaj9aHVfQT0dZR+AlfA@public.gmane.org>

Merged, thanks.  One comment below, please fix with a followup patch.

g.

> 
> --
> 
> V2: remove extra __va() call
> 	 make dt_alloc functions return void *.  This doesn't fix the general
>     strangeness in this code that constantly casts back and forth between
>     unsigned long and __be32 *
> ---
>  drivers/of/fdt.c       |  149 +++++++++++++++++++++++++++++++----------------
>  include/linux/of_fdt.h |    2 +
>  2 files changed, 100 insertions(+), 51 deletions(-)
> 
> diff --git a/drivers/of/fdt.c b/drivers/of/fdt.c
> index 236a8c9..e29dbe2 100644
> --- a/drivers/of/fdt.c
> +++ b/drivers/of/fdt.c
> @@ -11,10 +11,12 @@
>  
>  #include <linux/kernel.h>
>  #include <linux/initrd.h>
> +#include <linux/module.h>
>  #include <linux/of.h>
>  #include <linux/of_fdt.h>
>  #include <linux/string.h>
>  #include <linux/errno.h>
> +#include <linux/slab.h>
>  
>  #ifdef CONFIG_PPC
>  #include <asm/machdep.h>
> @@ -312,6 +314,94 @@ unsigned long unflatten_dt_node(struct boot_param_header *blob,
>  	return mem;
>  }
>  
> +/**
> + * __unflatten_device_tree - create tree of device_nodes from flat blob
> + *
> + * unflattens a device-tree, creating the
> + * tree of struct device_node. It also fills the "name" and "type"
> + * pointers of the nodes so the normal device-tree walking functions
> + * can be used.
> + * @blob: The blob to expand
> + * @mynodes: The device_node tree created by the call
> + * @dt_alloc: An allocator that provides a virtual address to memory
> + * for the resulting tree
> + */
> +void __unflatten_device_tree(struct boot_param_header *blob,
> +			     struct device_node **mynodes,
> +			     void * (*dt_alloc)(u64 size, u64 align))
> +{
> +	unsigned long start, mem, size;
> +	struct device_node **allnextp = mynodes;
> +
> +	pr_debug(" -> unflatten_device_tree()\n");
> +
> +	if (!blob) {
> +		pr_debug("No device tree pointer\n");
> +		return;
> +	}
> +
> +	pr_debug("Unflattening device tree:\n");
> +	pr_debug("magic: %08x\n", be32_to_cpu(blob->magic));
> +	pr_debug("size: %08x\n", be32_to_cpu(blob->totalsize));
> +	pr_debug("version: %08x\n", be32_to_cpu(blob->version));
> +
> +	if (be32_to_cpu(blob->magic) != OF_DT_HEADER) {
> +		pr_err("Invalid device tree blob header\n");
> +		return;
> +	}
> +
> +	/* First pass, scan for size */
> +	start = ((unsigned long)blob) +
> +		be32_to_cpu(blob->off_dt_struct);
> +	size = unflatten_dt_node(blob, 0, &start, NULL, NULL, 0);
> +	size = (size | 3) + 1;
> +
> +	pr_debug("  size is %lx, allocating...\n", size);
> +
> +	/* Allocate memory for the expanded device tree */
> +	mem = (unsigned long)
> +		dt_alloc(size + 4, __alignof__(struct device_node));
> +
> +	((__be32 *)mem)[size / 4] = cpu_to_be32(0xdeadbeef);
> +
> +	pr_debug("  unflattening %lx...\n", mem);
> +
> +	/* Second pass, do actual unflattening */
> +	start = ((unsigned long)blob) +
> +		be32_to_cpu(blob->off_dt_struct);
> +	unflatten_dt_node(blob, mem, &start, NULL, &allnextp, 0);
> +	if (be32_to_cpup((__be32 *)start) != OF_DT_END)
> +		pr_warning("Weird tag at end of tree: %08x\n", *((u32 *)start));
> +	if (be32_to_cpu(((__be32 *)mem)[size / 4]) != 0xdeadbeef)
> +		pr_warning("End of tree marker overwritten: %08x\n",
> +			   be32_to_cpu(((__be32 *)mem)[size / 4]));
> +	*allnextp = NULL;
> +
> +	pr_debug(" <- unflatten_device_tree()\n");
> +}
> +
> +static void *kernel_tree_alloc(u64 size, u64 align)
> +{
> +	return kzalloc(size, GFP_KERNEL);
> +}
> +
> +/**
> + * of_fdt_unflatten_tree - create tree of device_nodes from flat blob
> + *
> + * unflattens the device-tree passed by the firmware, creating the
> + * tree of struct device_node. It also fills the "name" and "type"
> + * pointers of the nodes so the normal device-tree walking functions
> + * can be used.
> + */
> +void of_fdt_unflatten_tree(unsigned long *blob,
> +			struct device_node **mynodes)
> +{
> +	struct boot_param_header *device_tree =
> +		(struct boot_param_header *)blob;
> +	__unflatten_device_tree(device_tree, mynodes, &kernel_tree_alloc);
> +}
> +EXPORT_SYMBOL_GPL(of_fdt_unflatten_tree);

The blob parameter to of_fdt_unflatten_tree should either be void* or
boot_param_header*.  What's the reason for unsigned long *?  Also,
blob can be passed directly into the __unflatten_device_tree() call.
No reason for the device_tree = blob assignment.  In fact, you could
probably eliminate this function entirely and rename
__unflatten_device_tree to of_fdt_unflatten_tree.

> +
>  /* Everything below here references initial_boot_params directly. */
>  int __initdata dt_root_addr_cells;
>  int __initdata dt_root_size_cells;
> @@ -569,6 +659,12 @@ int __init early_init_dt_scan_chosen(unsigned long node, const char *uname,
>  	return 1;
>  }
>  
> +static void *__init early_device_tree_alloc(u64 size, u64 align)
> +{
> +	unsigned long mem = early_init_dt_alloc_memory_arch(size, align);
> +	return __va(mem);
> +}
> +
>  /**
>   * unflatten_device_tree - create tree of device_nodes from flat blob
>   *
> @@ -579,62 +675,13 @@ int __init early_init_dt_scan_chosen(unsigned long node, const char *uname,
>   */
>  void __init unflatten_device_tree(void)
>  {
> -	unsigned long start, mem, size;
> -	struct device_node **allnextp = &allnodes;
> -
> -	pr_debug(" -> unflatten_device_tree()\n");
> -
> -	if (!initial_boot_params) {
> -		pr_debug("No device tree pointer\n");
> -		return;
> -	}
> -
> -	pr_debug("Unflattening device tree:\n");
> -	pr_debug("magic: %08x\n", be32_to_cpu(initial_boot_params->magic));
> -	pr_debug("size: %08x\n", be32_to_cpu(initial_boot_params->totalsize));
> -	pr_debug("version: %08x\n", be32_to_cpu(initial_boot_params->version));
> -
> -	if (be32_to_cpu(initial_boot_params->magic) != OF_DT_HEADER) {
> -		pr_err("Invalid device tree blob header\n");
> -		return;
> -	}
> -
> -	/* First pass, scan for size */
> -	start = ((unsigned long)initial_boot_params) +
> -		be32_to_cpu(initial_boot_params->off_dt_struct);
> -	size = unflatten_dt_node(initial_boot_params, 0, &start,
> -				 NULL, NULL, 0);
> -	size = (size | 3) + 1;
> -
> -	pr_debug("  size is %lx, allocating...\n", size);
> -
> -	/* Allocate memory for the expanded device tree */
> -	mem = early_init_dt_alloc_memory_arch(size + 4,
> -			__alignof__(struct device_node));
> -	mem = (unsigned long) __va(mem);
> -
> -	((__be32 *)mem)[size / 4] = cpu_to_be32(0xdeadbeef);
> -
> -	pr_debug("  unflattening %lx...\n", mem);
> -
> -	/* Second pass, do actual unflattening */
> -	start = ((unsigned long)initial_boot_params) +
> -		be32_to_cpu(initial_boot_params->off_dt_struct);
> -	unflatten_dt_node(initial_boot_params, mem, &start,
> -			  NULL, &allnextp, 0);
> -	if (be32_to_cpup((__be32 *)start) != OF_DT_END)
> -		pr_warning("Weird tag at end of tree: %08x\n", *((u32 *)start));
> -	if (be32_to_cpu(((__be32 *)mem)[size / 4]) != 0xdeadbeef)
> -		pr_warning("End of tree marker overwritten: %08x\n",
> -			   be32_to_cpu(((__be32 *)mem)[size / 4]));
> -	*allnextp = NULL;
> +	__unflatten_device_tree(initial_boot_params, &allnodes,
> +				early_device_tree_alloc);
>  
>  	/* Get pointer to OF "/chosen" node for use everywhere */
>  	of_chosen = of_find_node_by_path("/chosen");
>  	if (of_chosen == NULL)
>  		of_chosen = of_find_node_by_path("/chosen@0");
> -
> -	pr_debug(" <- unflatten_device_tree()\n");
>  }
>  
>  #endif /* CONFIG_EARLY_FLATTREE */
> diff --git a/include/linux/of_fdt.h b/include/linux/of_fdt.h
> index 70c5b73..9ce5dfd 100644
> --- a/include/linux/of_fdt.h
> +++ b/include/linux/of_fdt.h
> @@ -68,6 +68,8 @@ extern void *of_fdt_get_property(struct boot_param_header *blob,
>  extern int of_fdt_is_compatible(struct boot_param_header *blob,
>  				unsigned long node,
>  				const char *compat);
> +extern void of_fdt_unflatten_tree(unsigned long *blob,
> +			       struct device_node **mynodes);
>  
>  /* TBD: Temporary export of fdt globals - remove when code fully merged */
>  extern int __initdata dt_root_addr_cells;
> -- 
> 1.5.6.6
> 
> 
> 
> This email and any attachments are intended for the sole use of the named recipient(s) and contain(s) confidential information that may be proprietary, privileged or copyrighted under applicable law. If you are not the intended recipient, do not read, copy, or forward this email message or any attachments. Delete this email message and any attachments immediately.
> 
> 

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

* Re: [PATCH 7/7] fdt.c: Refactor unflatten_device_tree and add fdt_unflatten_tree
@ 2010-12-30  0:43                       ` Grant Likely
  0 siblings, 0 replies; 41+ messages in thread
From: Grant Likely @ 2010-12-30  0:43 UTC (permalink / raw)
  To: Stephen Neuendorffer
  Cc: dirk.brandewie, microblaze-uclinux, devicetree-discuss, linuxppc-dev

On Thu, Nov 18, 2010 at 03:55:02PM -0800, Stephen Neuendorffer wrote:
> unflatten_device_tree has two dependencies on things that happen
> during boot time.  Firstly, it references the initial device tree
> directly. Secondly, it allocates memory using the early boot
> allocator.  This patch factors out these dependencies and uses
> the new __unflatten_device_tree function to implement a driver-visible
> fdt_unflatten_tree function, which can be used to unflatten a
> blob after boot time.
> 
> Signed-off-by: Stephen Neuendorffer <stephen.neuendorffer@xilinx.com>

Merged, thanks.  One comment below, please fix with a followup patch.

g.

> 
> --
> 
> V2: remove extra __va() call
> 	 make dt_alloc functions return void *.  This doesn't fix the general
>     strangeness in this code that constantly casts back and forth between
>     unsigned long and __be32 *
> ---
>  drivers/of/fdt.c       |  149 +++++++++++++++++++++++++++++++----------------
>  include/linux/of_fdt.h |    2 +
>  2 files changed, 100 insertions(+), 51 deletions(-)
> 
> diff --git a/drivers/of/fdt.c b/drivers/of/fdt.c
> index 236a8c9..e29dbe2 100644
> --- a/drivers/of/fdt.c
> +++ b/drivers/of/fdt.c
> @@ -11,10 +11,12 @@
>  
>  #include <linux/kernel.h>
>  #include <linux/initrd.h>
> +#include <linux/module.h>
>  #include <linux/of.h>
>  #include <linux/of_fdt.h>
>  #include <linux/string.h>
>  #include <linux/errno.h>
> +#include <linux/slab.h>
>  
>  #ifdef CONFIG_PPC
>  #include <asm/machdep.h>
> @@ -312,6 +314,94 @@ unsigned long unflatten_dt_node(struct boot_param_header *blob,
>  	return mem;
>  }
>  
> +/**
> + * __unflatten_device_tree - create tree of device_nodes from flat blob
> + *
> + * unflattens a device-tree, creating the
> + * tree of struct device_node. It also fills the "name" and "type"
> + * pointers of the nodes so the normal device-tree walking functions
> + * can be used.
> + * @blob: The blob to expand
> + * @mynodes: The device_node tree created by the call
> + * @dt_alloc: An allocator that provides a virtual address to memory
> + * for the resulting tree
> + */
> +void __unflatten_device_tree(struct boot_param_header *blob,
> +			     struct device_node **mynodes,
> +			     void * (*dt_alloc)(u64 size, u64 align))
> +{
> +	unsigned long start, mem, size;
> +	struct device_node **allnextp = mynodes;
> +
> +	pr_debug(" -> unflatten_device_tree()\n");
> +
> +	if (!blob) {
> +		pr_debug("No device tree pointer\n");
> +		return;
> +	}
> +
> +	pr_debug("Unflattening device tree:\n");
> +	pr_debug("magic: %08x\n", be32_to_cpu(blob->magic));
> +	pr_debug("size: %08x\n", be32_to_cpu(blob->totalsize));
> +	pr_debug("version: %08x\n", be32_to_cpu(blob->version));
> +
> +	if (be32_to_cpu(blob->magic) != OF_DT_HEADER) {
> +		pr_err("Invalid device tree blob header\n");
> +		return;
> +	}
> +
> +	/* First pass, scan for size */
> +	start = ((unsigned long)blob) +
> +		be32_to_cpu(blob->off_dt_struct);
> +	size = unflatten_dt_node(blob, 0, &start, NULL, NULL, 0);
> +	size = (size | 3) + 1;
> +
> +	pr_debug("  size is %lx, allocating...\n", size);
> +
> +	/* Allocate memory for the expanded device tree */
> +	mem = (unsigned long)
> +		dt_alloc(size + 4, __alignof__(struct device_node));
> +
> +	((__be32 *)mem)[size / 4] = cpu_to_be32(0xdeadbeef);
> +
> +	pr_debug("  unflattening %lx...\n", mem);
> +
> +	/* Second pass, do actual unflattening */
> +	start = ((unsigned long)blob) +
> +		be32_to_cpu(blob->off_dt_struct);
> +	unflatten_dt_node(blob, mem, &start, NULL, &allnextp, 0);
> +	if (be32_to_cpup((__be32 *)start) != OF_DT_END)
> +		pr_warning("Weird tag at end of tree: %08x\n", *((u32 *)start));
> +	if (be32_to_cpu(((__be32 *)mem)[size / 4]) != 0xdeadbeef)
> +		pr_warning("End of tree marker overwritten: %08x\n",
> +			   be32_to_cpu(((__be32 *)mem)[size / 4]));
> +	*allnextp = NULL;
> +
> +	pr_debug(" <- unflatten_device_tree()\n");
> +}
> +
> +static void *kernel_tree_alloc(u64 size, u64 align)
> +{
> +	return kzalloc(size, GFP_KERNEL);
> +}
> +
> +/**
> + * of_fdt_unflatten_tree - create tree of device_nodes from flat blob
> + *
> + * unflattens the device-tree passed by the firmware, creating the
> + * tree of struct device_node. It also fills the "name" and "type"
> + * pointers of the nodes so the normal device-tree walking functions
> + * can be used.
> + */
> +void of_fdt_unflatten_tree(unsigned long *blob,
> +			struct device_node **mynodes)
> +{
> +	struct boot_param_header *device_tree =
> +		(struct boot_param_header *)blob;
> +	__unflatten_device_tree(device_tree, mynodes, &kernel_tree_alloc);
> +}
> +EXPORT_SYMBOL_GPL(of_fdt_unflatten_tree);

The blob parameter to of_fdt_unflatten_tree should either be void* or
boot_param_header*.  What's the reason for unsigned long *?  Also,
blob can be passed directly into the __unflatten_device_tree() call.
No reason for the device_tree = blob assignment.  In fact, you could
probably eliminate this function entirely and rename
__unflatten_device_tree to of_fdt_unflatten_tree.

> +
>  /* Everything below here references initial_boot_params directly. */
>  int __initdata dt_root_addr_cells;
>  int __initdata dt_root_size_cells;
> @@ -569,6 +659,12 @@ int __init early_init_dt_scan_chosen(unsigned long node, const char *uname,
>  	return 1;
>  }
>  
> +static void *__init early_device_tree_alloc(u64 size, u64 align)
> +{
> +	unsigned long mem = early_init_dt_alloc_memory_arch(size, align);
> +	return __va(mem);
> +}
> +
>  /**
>   * unflatten_device_tree - create tree of device_nodes from flat blob
>   *
> @@ -579,62 +675,13 @@ int __init early_init_dt_scan_chosen(unsigned long node, const char *uname,
>   */
>  void __init unflatten_device_tree(void)
>  {
> -	unsigned long start, mem, size;
> -	struct device_node **allnextp = &allnodes;
> -
> -	pr_debug(" -> unflatten_device_tree()\n");
> -
> -	if (!initial_boot_params) {
> -		pr_debug("No device tree pointer\n");
> -		return;
> -	}
> -
> -	pr_debug("Unflattening device tree:\n");
> -	pr_debug("magic: %08x\n", be32_to_cpu(initial_boot_params->magic));
> -	pr_debug("size: %08x\n", be32_to_cpu(initial_boot_params->totalsize));
> -	pr_debug("version: %08x\n", be32_to_cpu(initial_boot_params->version));
> -
> -	if (be32_to_cpu(initial_boot_params->magic) != OF_DT_HEADER) {
> -		pr_err("Invalid device tree blob header\n");
> -		return;
> -	}
> -
> -	/* First pass, scan for size */
> -	start = ((unsigned long)initial_boot_params) +
> -		be32_to_cpu(initial_boot_params->off_dt_struct);
> -	size = unflatten_dt_node(initial_boot_params, 0, &start,
> -				 NULL, NULL, 0);
> -	size = (size | 3) + 1;
> -
> -	pr_debug("  size is %lx, allocating...\n", size);
> -
> -	/* Allocate memory for the expanded device tree */
> -	mem = early_init_dt_alloc_memory_arch(size + 4,
> -			__alignof__(struct device_node));
> -	mem = (unsigned long) __va(mem);
> -
> -	((__be32 *)mem)[size / 4] = cpu_to_be32(0xdeadbeef);
> -
> -	pr_debug("  unflattening %lx...\n", mem);
> -
> -	/* Second pass, do actual unflattening */
> -	start = ((unsigned long)initial_boot_params) +
> -		be32_to_cpu(initial_boot_params->off_dt_struct);
> -	unflatten_dt_node(initial_boot_params, mem, &start,
> -			  NULL, &allnextp, 0);
> -	if (be32_to_cpup((__be32 *)start) != OF_DT_END)
> -		pr_warning("Weird tag at end of tree: %08x\n", *((u32 *)start));
> -	if (be32_to_cpu(((__be32 *)mem)[size / 4]) != 0xdeadbeef)
> -		pr_warning("End of tree marker overwritten: %08x\n",
> -			   be32_to_cpu(((__be32 *)mem)[size / 4]));
> -	*allnextp = NULL;
> +	__unflatten_device_tree(initial_boot_params, &allnodes,
> +				early_device_tree_alloc);
>  
>  	/* Get pointer to OF "/chosen" node for use everywhere */
>  	of_chosen = of_find_node_by_path("/chosen");
>  	if (of_chosen == NULL)
>  		of_chosen = of_find_node_by_path("/chosen@0");
> -
> -	pr_debug(" <- unflatten_device_tree()\n");
>  }
>  
>  #endif /* CONFIG_EARLY_FLATTREE */
> diff --git a/include/linux/of_fdt.h b/include/linux/of_fdt.h
> index 70c5b73..9ce5dfd 100644
> --- a/include/linux/of_fdt.h
> +++ b/include/linux/of_fdt.h
> @@ -68,6 +68,8 @@ extern void *of_fdt_get_property(struct boot_param_header *blob,
>  extern int of_fdt_is_compatible(struct boot_param_header *blob,
>  				unsigned long node,
>  				const char *compat);
> +extern void of_fdt_unflatten_tree(unsigned long *blob,
> +			       struct device_node **mynodes);
>  
>  /* TBD: Temporary export of fdt globals - remove when code fully merged */
>  extern int __initdata dt_root_addr_cells;
> -- 
> 1.5.6.6
> 
> 
> 
> This email and any attachments are intended for the sole use of the named recipient(s) and contain(s) confidential information that may be proprietary, privileged or copyrighted under applicable law. If you are not the intended recipient, do not read, copy, or forward this email message or any attachments. Delete this email message and any attachments immediately.
> 
> 

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

end of thread, other threads:[~2010-12-30  0:43 UTC | newest]

Thread overview: 41+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
     [not found] <1290021345-4303-1-git-send-email-stephen.neuendorffer@xilinx.com>
     [not found] ` <1290021345-4303-1-git-send-email-stephen.neuendorffer-gjFFaj9aHVfQT0dZR+AlfA@public.gmane.org>
2010-11-17 19:15   ` [PATCH 1/3] fdt.c: Add non-boottime device tree functions Stephen Neuendorffer
     [not found]     ` <17453aae-47e7-4b69-b7f4-b4577456c637-+Ck8Kgl/v09ZbvUCbuG1mrjjLBE8jN/0@public.gmane.org>
2010-11-17 19:42       ` Grant Likely
     [not found]         ` <20101117194203.GA2352-MrY2KI0G/OVr83L8+7iqerDks+cytr/Z@public.gmane.org>
2010-11-17 19:46           ` Stephen Neuendorffer
     [not found]             ` <ed30f7b9-a1dd-4cd3-a6df-f2361e790185-+Ck8Kgl/v08opVzHvkXDF7jjLBE8jN/0@public.gmane.org>
2010-11-17 20:00               ` Grant Likely
     [not found]                 ` <20101117200012.GD2352-MrY2KI0G/OVr83L8+7iqerDks+cytr/Z@public.gmane.org>
2010-11-17 21:41                   ` Stephen Neuendorffer
2010-11-17 22:53           ` Stephen Neuendorffer
     [not found]             ` <eed86eda-ba28-4f12-b615-d293eb1a356e-+Ck8Kgl/v091zOOwW4IIhbjjLBE8jN/0@public.gmane.org>
2010-11-18  5:35               ` Grant Likely
2010-11-18 23:54   ` [PATCH 0/7] add of_fdt_unflatten_tree Stephen Neuendorffer
2010-11-18 23:54     ` Stephen Neuendorffer
     [not found] ` <1290021345-4303-2-git-send-email-stephen.neuendorffer@xilinx.com>
     [not found]   ` <1290021345-4303-2-git-send-email-stephen.neuendorffer-gjFFaj9aHVfQT0dZR+AlfA@public.gmane.org>
2010-11-17 19:15     ` [PATCH 2/3] fdt.c: Refactor unflatten_dt_node Stephen Neuendorffer
     [not found]       ` <897f0b2f-23ac-4652-a61b-fc1ff4e867b6-+Ck8Kgl/v0/T7m58JnLnSLjjLBE8jN/0@public.gmane.org>
2010-11-17 19:50         ` Grant Likely
     [not found]   ` <1290021345-4303-3-git-send-email-stephen.neuendorffer@xilinx.com>
     [not found]     ` <1290021345-4303-3-git-send-email-stephen.neuendorffer-gjFFaj9aHVfQT0dZR+AlfA@public.gmane.org>
2010-11-17 19:15       ` [PATCH 3/3] fdt.c: Refactor unflatten_device_tree and add fdt_unflatten_tree Stephen Neuendorffer
     [not found]         ` <43c2cd79-efaf-4acf-9c85-ca2ef0738e92-RaUQJvECHis6W+Ha+8ZLibjjLBE8jN/0@public.gmane.org>
2010-11-17 19:57           ` Grant Likely
     [not found] ` <1290124502-13125-1-git-send-email-stephen.neuendorffer@xilinx.com>
     [not found]   ` <1290124502-13125-1-git-send-email-stephen.neuendorffer-gjFFaj9aHVfQT0dZR+AlfA@public.gmane.org>
2010-11-18 23:54     ` [PATCH 1/7] fdt: Add Kconfig for EARLY_FLATTREE Stephen Neuendorffer
2010-11-18 23:54       ` Stephen Neuendorffer
     [not found]       ` <d43cf8d1-8821-4400-9c58-692846dd37ac-RaUQJvECHitEus+KprP3J7jjLBE8jN/0@public.gmane.org>
2010-12-30  0:15         ` Grant Likely
2010-12-30  0:15           ` Grant Likely
     [not found]   ` <1290124502-13125-2-git-send-email-stephen.neuendorffer@xilinx.com>
     [not found]     ` <1290124502-13125-2-git-send-email-stephen.neuendorffer-gjFFaj9aHVfQT0dZR+AlfA@public.gmane.org>
2010-11-18 23:54       ` [PATCH 2/7] arch/x86: Add support for device tree code Stephen Neuendorffer
2010-11-18 23:54         ` Stephen Neuendorffer
     [not found]         ` <98608b2e-d138-4dc0-808d-3662ab2c9938-+Ck8Kgl/v0/6UOWq+LNw4LjjLBE8jN/0@public.gmane.org>
2010-12-30  0:17           ` Grant Likely
2010-12-30  0:17             ` Grant Likely
     [not found]     ` <1290124502-13125-3-git-send-email-stephen.neuendorffer@xilinx.com>
     [not found]       ` <1290124502-13125-3-git-send-email-stephen.neuendorffer-gjFFaj9aHVfQT0dZR+AlfA@public.gmane.org>
2010-11-18 23:54         ` [PATCH 3/7] arch/x86: select OF and OF_FLATTREE Stephen Neuendorffer
2010-11-18 23:54           ` Stephen Neuendorffer
     [not found]           ` <111913e5-7481-46b8-b04d-eee3cdc8fc32-RaUQJvECHiuCJ4rNFYUysLjjLBE8jN/0@public.gmane.org>
2010-12-30  0:17             ` Grant Likely
2010-12-30  0:17               ` Grant Likely
     [not found]       ` <1290124502-13125-4-git-send-email-stephen.neuendorffer@xilinx.com>
     [not found]         ` <1290124502-13125-4-git-send-email-stephen.neuendorffer-gjFFaj9aHVfQT0dZR+AlfA@public.gmane.org>
2010-11-18 23:54           ` [PATCH 4/7] fdt.c: Add non-boottime device tree functions Stephen Neuendorffer
2010-11-18 23:54             ` Stephen Neuendorffer
     [not found]             ` <d433b5eb-2d15-4a28-8083-97582bf4617f-+Ck8Kgl/v086yhkse9Y53bjjLBE8jN/0@public.gmane.org>
2010-12-30  0:34               ` Grant Likely
2010-12-30  0:34                 ` Grant Likely
     [not found]         ` <1290124502-13125-5-git-send-email-stephen.neuendorffer@xilinx.com>
     [not found]           ` <1290124502-13125-5-git-send-email-stephen.neuendorffer-gjFFaj9aHVfQT0dZR+AlfA@public.gmane.org>
2010-11-18 23:55             ` [PATCH 5/7] fdt.c: Refactor unflatten_dt_node Stephen Neuendorffer
2010-11-18 23:55               ` Stephen Neuendorffer
     [not found]               ` <e5face75-4978-4686-9d75-d92fa9ec7328-+Ck8Kgl/v0/T7m58JnLnSLjjLBE8jN/0@public.gmane.org>
2010-12-30  0:35                 ` Grant Likely
2010-12-30  0:35                   ` Grant Likely
     [not found]           ` <1290124502-13125-6-git-send-email-stephen.neuendorffer@xilinx.com>
     [not found]             ` <1290124502-13125-6-git-send-email-stephen.neuendorffer-gjFFaj9aHVfQT0dZR+AlfA@public.gmane.org>
2010-11-18 23:55               ` [PATCH 6/7] fdt.c: Reorder unflatten_dt_node Stephen Neuendorffer
2010-11-18 23:55                 ` Stephen Neuendorffer
     [not found]                 ` <972516c0-f170-469f-937f-bfa6be8dd04a-RaUQJvECHiuXHCJdrdq+zrjjLBE8jN/0@public.gmane.org>
2010-12-30  0:36                   ` Grant Likely
2010-12-30  0:36                     ` Grant Likely
     [not found]             ` <1290124502-13125-7-git-send-email-stephen.neuendorffer@xilinx.com>
     [not found]               ` <1290124502-13125-7-git-send-email-stephen.neuendorffer-gjFFaj9aHVfQT0dZR+AlfA@public.gmane.org>
2010-11-18 23:55                 ` [PATCH 7/7] fdt.c: Refactor unflatten_device_tree and add fdt_unflatten_tree Stephen Neuendorffer
2010-11-18 23:55                   ` Stephen Neuendorffer
     [not found]                   ` <8aead437-fb77-4e72-8b66-2b1626f6316d-RaUQJvECHiusiP+nND6G/7jjLBE8jN/0@public.gmane.org>
2010-12-30  0:43                     ` Grant Likely
2010-12-30  0:43                       ` Grant Likely

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.