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>
This commit is contained in:
parent
68d4230c3c
commit
05a22ba096
|
|
@ -278,9 +278,14 @@ uint32_t fdt_get_phandle(const void *fdt, int nodeoffset)
|
||||||
const uint32_t *php;
|
const uint32_t *php;
|
||||||
int len;
|
int len;
|
||||||
|
|
||||||
php = fdt_getprop(fdt, nodeoffset, "linux,phandle", &len);
|
/* FIXME: This is a bit sub-optimal, since we potentially scan
|
||||||
if (!php || (len != sizeof(*php)))
|
* over all the properties twice. */
|
||||||
return 0;
|
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);
|
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 fdt_node_offset_by_phandle(const void *fdt, uint32_t phandle)
|
||||||
{
|
{
|
||||||
|
int offset;
|
||||||
|
|
||||||
if ((phandle == 0) || (phandle == -1))
|
if ((phandle == 0) || (phandle == -1))
|
||||||
return -FDT_ERR_BADPHANDLE;
|
return -FDT_ERR_BADPHANDLE;
|
||||||
phandle = cpu_to_fdt32(phandle);
|
|
||||||
return fdt_node_offset_by_prop_value(fdt, -1, "linux,phandle",
|
FDT_CHECK_HEADER(fdt);
|
||||||
&phandle, sizeof(phandle));
|
|
||||||
|
/* 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,
|
static int _fdt_stringlist_contains(const char *strlist, int listlen,
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue