summaryrefslogtreecommitdiffstats
path: root/lib/libfdt
diff options
context:
space:
mode:
authorDavid Gibson <david@gibson.dropbear.id.au>2009-11-26 15:37:13 +1100
committerGerald Van Baren <gvb@unssw.com>2011-07-14 21:03:53 -0400
commit05a22ba096fb996bb69ab020a8d08aafac2c28ba (patch)
tree8f4019af405604abed59b5e05df4be05f166637d /lib/libfdt
parent68d4230c3ccce96a72c5b99e48399bf1796fe3c6 (diff)
downloadu-boot-05a22ba096fb996bb69ab020a8d08aafac2c28ba.tar.gz
u-boot-05a22ba096fb996bb69ab020a8d08aafac2c28ba.tar.xz
u-boot-05a22ba096fb996bb69ab020a8d08aafac2c28ba.zip
Support ePAPR compliant phandle properties
Currently, the Linux kernel, libfdt and dtc, when using flattened device trees encode a node's phandle into a property named "linux,phandle". The ePAPR specification, however - aiming as it is to not be a Linux specific spec - requires that phandles be encoded in a property named simply "phandle". This patch adds support for this newer approach to dtc and libfdt. Specifically: - fdt_get_phandle() will now return the correct phandle if it is supplied in either of these properties - fdt_node_offset_by_phandle() will correctly find a node with the given phandle encoded in either property. - By default, when auto-generating phandles, dtc will encode it into both properties for maximum compatibility. A new -H option allows either only old-style or only new-style properties to be generated. - If phandle properties are explicitly supplied in the dts file, dtc will not auto-generate ones in the alternate format. - If both properties are supplied, dtc will check that they have the same value. - Some existing testcases are updated to use a mix of old and new-style phandles, partially testing the changes. - A new phandle_format test further tests the libfdt support, and the -H option. Signed-off-by: David Gibson <david@gibson.dropbear.id.au> This was extracted from the DTC commit: d75b33af676d0beac8398651a7f09037555a550b Mon Sep 17 00:00:00 2001 Signed-off-by: Gerald Van Baren <vanbaren@cideas.com>
Diffstat (limited to 'lib/libfdt')
-rw-r--r--lib/libfdt/fdt_ro.c33
1 files changed, 27 insertions, 6 deletions
diff --git a/lib/libfdt/fdt_ro.c b/lib/libfdt/fdt_ro.c
index 1e1e32209c..91a354e108 100644
--- a/lib/libfdt/fdt_ro.c
+++ b/lib/libfdt/fdt_ro.c
@@ -278,9 +278,14 @@ uint32_t fdt_get_phandle(const void *fdt, int nodeoffset)
const uint32_t *php;
int len;
- php = fdt_getprop(fdt, nodeoffset, "linux,phandle", &len);
- if (!php || (len != sizeof(*php)))
- return 0;
+ /* FIXME: This is a bit sub-optimal, since we potentially scan
+ * over all the properties twice. */
+ php = fdt_getprop(fdt, nodeoffset, "phandle", &len);
+ if (!php || (len != sizeof(*php))) {
+ php = fdt_getprop(fdt, nodeoffset, "linux,phandle", &len);
+ if (!php || (len != sizeof(*php)))
+ return 0;
+ }
return fdt32_to_cpu(*php);
}
@@ -440,11 +445,27 @@ int fdt_node_offset_by_prop_value(const void *fdt, int startoffset,
int fdt_node_offset_by_phandle(const void *fdt, uint32_t phandle)
{
+ int offset;
+
if ((phandle == 0) || (phandle == -1))
return -FDT_ERR_BADPHANDLE;
- phandle = cpu_to_fdt32(phandle);
- return fdt_node_offset_by_prop_value(fdt, -1, "linux,phandle",
- &phandle, sizeof(phandle));
+
+ FDT_CHECK_HEADER(fdt);
+
+ /* FIXME: The algorithm here is pretty horrible: we
+ * potentially scan each property of a node in
+ * fdt_get_phandle(), then if that didn't find what
+ * we want, we scan over them again making our way to the next
+ * node. Still it's the easiest to implement approach;
+ * performance can come later. */
+ for (offset = fdt_next_node(fdt, -1, NULL);
+ offset >= 0;
+ offset = fdt_next_node(fdt, offset, NULL)) {
+ if (fdt_get_phandle(fdt, offset) == phandle)
+ return offset;
+ }
+
+ return offset; /* error from fdt_next_node() */
}
static int _fdt_stringlist_contains(const char *strlist, int listlen,