linuxppc-dev.lists.ozlabs.org archive mirror
 help / color / mirror / Atom feed
* [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] ` <1290124502-13125-1-git-send-email-stephen.neuendorffer@xilinx.com>
  1 sibling, 0 replies; 15+ 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] 15+ 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
  2010-12-30  0:15     ` Grant Likely
       [not found]   ` <1290124502-13125-2-git-send-email-stephen.neuendorffer@xilinx.com>
  1 sibling, 1 reply; 15+ 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] 15+ 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
  2010-12-30  0:17       ` Grant Likely
       [not found]     ` <1290124502-13125-3-git-send-email-stephen.neuendorffer@xilinx.com>
  1 sibling, 1 reply; 15+ 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] 15+ 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
  2010-12-30  0:17         ` Grant Likely
       [not found]       ` <1290124502-13125-4-git-send-email-stephen.neuendorffer@xilinx.com>
  1 sibling, 1 reply; 15+ 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] 15+ 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
  2010-12-30  0:34           ` Grant Likely
       [not found]         ` <1290124502-13125-5-git-send-email-stephen.neuendorffer@xilinx.com>
  1 sibling, 1 reply; 15+ 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] 15+ 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
  2010-12-30  0:35             ` Grant Likely
       [not found]           ` <1290124502-13125-6-git-send-email-stephen.neuendorffer@xilinx.com>
  1 sibling, 1 reply; 15+ 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] 15+ 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
  2010-12-30  0:36               ` Grant Likely
       [not found]             ` <1290124502-13125-7-git-send-email-stephen.neuendorffer@xilinx.com>
  1 sibling, 1 reply; 15+ 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] 15+ 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
  2010-12-30  0:43                 ` Grant Likely
  0 siblings, 1 reply; 15+ 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] 15+ messages in thread

* Re: [PATCH 1/7] fdt: Add Kconfig for EARLY_FLATTREE
  2010-11-18 23:54   ` [PATCH 1/7] fdt: Add Kconfig for EARLY_FLATTREE Stephen Neuendorffer
@ 2010-12-30  0:15     ` Grant Likely
  0 siblings, 0 replies; 15+ 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] 15+ messages in thread

* Re: [PATCH 2/7] arch/x86: Add support for device tree code.
  2010-11-18 23:54     ` [PATCH 2/7] arch/x86: Add support for device tree code Stephen Neuendorffer
@ 2010-12-30  0:17       ` Grant Likely
  0 siblings, 0 replies; 15+ 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] 15+ messages in thread

* Re: [PATCH 3/7] arch/x86: select OF and OF_FLATTREE
  2010-11-18 23:54       ` [PATCH 3/7] arch/x86: select OF and OF_FLATTREE Stephen Neuendorffer
@ 2010-12-30  0:17         ` Grant Likely
  0 siblings, 0 replies; 15+ 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] 15+ messages in thread

* Re: [PATCH 4/7] fdt.c: Add non-boottime device tree functions
  2010-11-18 23:54         ` [PATCH 4/7] fdt.c: Add non-boottime device tree functions Stephen Neuendorffer
@ 2010-12-30  0:34           ` Grant Likely
  0 siblings, 0 replies; 15+ 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] 15+ messages in thread

* Re: [PATCH 5/7] fdt.c: Refactor unflatten_dt_node
  2010-11-18 23:55           ` [PATCH 5/7] fdt.c: Refactor unflatten_dt_node Stephen Neuendorffer
@ 2010-12-30  0:35             ` Grant Likely
  0 siblings, 0 replies; 15+ 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] 15+ messages in thread

* Re: [PATCH 6/7] fdt.c: Reorder unflatten_dt_node
  2010-11-18 23:55             ` [PATCH 6/7] fdt.c: Reorder unflatten_dt_node Stephen Neuendorffer
@ 2010-12-30  0:36               ` Grant Likely
  0 siblings, 0 replies; 15+ 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] 15+ messages in thread

* Re: [PATCH 7/7] fdt.c: Refactor unflatten_device_tree and add fdt_unflatten_tree
  2010-11-18 23:55               ` [PATCH 7/7] fdt.c: Refactor unflatten_device_tree and add fdt_unflatten_tree Stephen Neuendorffer
@ 2010-12-30  0:43                 ` Grant Likely
  0 siblings, 0 replies; 15+ 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] 15+ messages in thread

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

Thread overview: 15+ 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>
2010-11-18 23:54 ` [PATCH 0/7] add of_fdt_unflatten_tree Stephen Neuendorffer
     [not found] ` <1290124502-13125-1-git-send-email-stephen.neuendorffer@xilinx.com>
2010-11-18 23:54   ` [PATCH 1/7] fdt: Add Kconfig for EARLY_FLATTREE Stephen Neuendorffer
2010-12-30  0:15     ` Grant Likely
     [not found]   ` <1290124502-13125-2-git-send-email-stephen.neuendorffer@xilinx.com>
2010-11-18 23:54     ` [PATCH 2/7] arch/x86: Add support for device tree code Stephen Neuendorffer
2010-12-30  0:17       ` Grant Likely
     [not found]     ` <1290124502-13125-3-git-send-email-stephen.neuendorffer@xilinx.com>
2010-11-18 23:54       ` [PATCH 3/7] arch/x86: select OF and OF_FLATTREE Stephen Neuendorffer
2010-12-30  0:17         ` Grant Likely
     [not found]       ` <1290124502-13125-4-git-send-email-stephen.neuendorffer@xilinx.com>
2010-11-18 23:54         ` [PATCH 4/7] fdt.c: Add non-boottime device tree functions Stephen Neuendorffer
2010-12-30  0:34           ` Grant Likely
     [not found]         ` <1290124502-13125-5-git-send-email-stephen.neuendorffer@xilinx.com>
2010-11-18 23:55           ` [PATCH 5/7] fdt.c: Refactor unflatten_dt_node Stephen Neuendorffer
2010-12-30  0:35             ` Grant Likely
     [not found]           ` <1290124502-13125-6-git-send-email-stephen.neuendorffer@xilinx.com>
2010-11-18 23:55             ` [PATCH 6/7] fdt.c: Reorder unflatten_dt_node Stephen Neuendorffer
2010-12-30  0:36               ` Grant Likely
     [not found]             ` <1290124502-13125-7-git-send-email-stephen.neuendorffer@xilinx.com>
2010-11-18 23:55               ` [PATCH 7/7] fdt.c: Refactor unflatten_device_tree and add fdt_unflatten_tree Stephen Neuendorffer
2010-12-30  0:43                 ` Grant Likely

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).