diff options
| author | David Gibson <david@gibson.dropbear.id.au> | 2009-11-26 15:37:13 +1100 | 
|---|---|---|
| committer | Gerald Van Baren <gvb@unssw.com> | 2011-07-14 21:03:53 -0400 | 
| commit | 05a22ba096fb996bb69ab020a8d08aafac2c28ba (patch) | |
| tree | 8f4019af405604abed59b5e05df4be05f166637d /lib | |
| parent | 68d4230c3ccce96a72c5b99e48399bf1796fe3c6 (diff) | |
| download | olio-uboot-2014.01-05a22ba096fb996bb69ab020a8d08aafac2c28ba.tar.xz olio-uboot-2014.01-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')
| -rw-r--r-- | lib/libfdt/fdt_ro.c | 33 | 
1 files changed, 27 insertions, 6 deletions
| diff --git a/lib/libfdt/fdt_ro.c b/lib/libfdt/fdt_ro.c index 1e1e32209..91a354e10 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, |