Patchwork [U-Boot,1/2] fdt: add support the ePAPR "phandle" property

login
register
mail settings
Submitter Timur Tabi
Date May 6, 2011, 5:56 p.m.
Message ID <1304704593-9067-1-git-send-email-timur@freescale.com>
Download mbox | patch
Permalink /patch/94423/
State Superseded
Headers show

Comments

Timur Tabi - May 6, 2011, 5:56 p.m.
The ePAPR specification says that phandle properties should be called
"phandle", and not "linux,phandle".  To facilitate the migration from
"linux,phandle" to "phandle", we update some functions to support both
properties.

Signed-off-by: Timur Tabi <timur@freescale.com>
---
 common/fdt_support.c |    6 ++++++
 include/libfdt.h     |   10 ++++++++++
 lib/libfdt/fdt_ro.c  |   18 ++++++++++++++++++
 3 files changed, 34 insertions(+), 0 deletions(-)
Grant Likely - May 6, 2011, 6:46 p.m.
On Fri, May 6, 2011 at 11:56 AM, Timur Tabi <timur@freescale.com> wrote:
> The ePAPR specification says that phandle properties should be called
> "phandle", and not "linux,phandle".  To facilitate the migration from
> "linux,phandle" to "phandle", we update some functions to support both
> properties.
>
> Signed-off-by: Timur Tabi <timur@freescale.com>

As discussed on IRC, upstream libfdt already supports the "phandle"
property, so u-boot needs to be updated to the latest version from the
dtc.git repo on git.jdl.com.  You'll still need the change to
common/fdt_support.c though.

g.

> ---
>  common/fdt_support.c |    6 ++++++
>  include/libfdt.h     |   10 ++++++++++
>  lib/libfdt/fdt_ro.c  |   18 ++++++++++++++++++
>  3 files changed, 34 insertions(+), 0 deletions(-)
>
> diff --git a/common/fdt_support.c b/common/fdt_support.c
> index 496040b..85715ff 100644
> --- a/common/fdt_support.c
> +++ b/common/fdt_support.c
> @@ -1187,6 +1187,12 @@ int fdt_alloc_phandle(void *blob)
>
>        for (offset = fdt_next_node(blob, -1, NULL); offset >= 0;
>             offset = fdt_next_node(blob, offset, NULL)) {
> +               /* Check the ePAPR-compliant "phandle" property name */
> +               val = fdt_getprop(blob, offset, "phandle", &len);
> +               if (val)
> +                       phandle = max(*val, phandle);
> +
> +               /* Also check the deprecated "linux,phandle" property name */
>                val = fdt_getprop(blob, offset, "linux,phandle", &len);
>                if (val)
>                        phandle = max(*val, phandle);
> diff --git a/include/libfdt.h b/include/libfdt.h
> index d23d40e..092dd34 100644
> --- a/include/libfdt.h
> +++ b/include/libfdt.h
> @@ -452,6 +452,11 @@ static inline void *fdt_getprop_w(void *fdt, int nodeoffset,
>  * fdt_get_phandle() retrieves the phandle of the device tree node at
>  * structure block offset nodeoffset.
>  *
> + * Both the ePAPR "phandle" property as well as the legacy "linux,phandle"
> + * property are supported.  If the device tree node contains both properties,
> + * then "phandle" is used.  However, it is considered an error if the two
> + * properties contain different values.
> + *
>  * returns:
>  *     the phandle of the node at nodeoffset, on success (!= 0, != -1)
>  *     0, if the node has no phandle, or another error occurs
> @@ -662,6 +667,11 @@ int fdt_node_offset_by_phandle(const void *fdt, uint32_t phandle);
>  * 'compatible' property with the given string as one of its elements,
>  * it returns non-zero otherwise, or on error.
>  *
> + * Both the ePAPR "phandle" property as well as the legacy "linux,phandle"
> + * property are supported.  If the device tree node contains both properties,
> + * then "phandle" is used.  However, it is considered an error if the two
> + * properties contain different values.
> + *
>  * returns:
>  *     0, if the node has a 'compatible' property listing the given string
>  *     1, if the node has a 'compatible' property, but it does not list
> diff --git a/lib/libfdt/fdt_ro.c b/lib/libfdt/fdt_ro.c
> index 1e1e322..57a901f 100644
> --- a/lib/libfdt/fdt_ro.c
> +++ b/lib/libfdt/fdt_ro.c
> @@ -278,6 +278,14 @@ uint32_t fdt_get_phandle(const void *fdt, int nodeoffset)
>        const uint32_t *php;
>        int len;
>
> +       /* First, check the "phandle" property */
> +       php = fdt_getprop(fdt, nodeoffset, "phandle", &len);
> +       if (php) {
> +               /* If the property exists, then use it if it's valid */
> +               return len == sizeof(*php) ? fdt32_to_cpu(*php) : 0;
> +       }
> +
> +       /* No "phandle", so check "linux,phandle" */
>        php = fdt_getprop(fdt, nodeoffset, "linux,phandle", &len);
>        if (!php || (len != sizeof(*php)))
>                return 0;
> @@ -440,9 +448,19 @@ 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 ret;
> +
>        if ((phandle == 0) || (phandle == -1))
>                return -FDT_ERR_BADPHANDLE;
>        phandle = cpu_to_fdt32(phandle);
> +
> +       /* First check for a matching "phandle" property */
> +       ret = fdt_node_offset_by_prop_value(fdt, -1, "phandle",
> +                                           &phandle, sizeof(phandle));
> +       if (ret > 0)
> +               return ret;
> +
> +       /* No "phandle", so check "linux,phandle" */
>        return fdt_node_offset_by_prop_value(fdt, -1, "linux,phandle",
>                                             &phandle, sizeof(phandle));
>  }
> --
> 1.7.3.4
>
>
>
Timur Tabi - May 6, 2011, 6:53 p.m.
Grant Likely wrote:
> As discussed on IRC, upstream libfdt already supports the "phandle"
> property, so u-boot needs to be updated to the latest version from the
> dtc.git repo on git.jdl.com.  You'll still need the change to
> common/fdt_support.c though.

Upstream libfdt was fixed back in 2009.  Why is U-Boot and Linux so outdated?
Shouldn't there be a regular plan to update U-boot and Linux as libfdt is
updated?  I don't see how an 18-month backlog is acceptable.

No offense, but this sounds like something the U-boot fdt maintainer is supposed
to be doing regularly.

Patch

diff --git a/common/fdt_support.c b/common/fdt_support.c
index 496040b..85715ff 100644
--- a/common/fdt_support.c
+++ b/common/fdt_support.c
@@ -1187,6 +1187,12 @@  int fdt_alloc_phandle(void *blob)
 
 	for (offset = fdt_next_node(blob, -1, NULL); offset >= 0;
 	     offset = fdt_next_node(blob, offset, NULL)) {
+		/* Check the ePAPR-compliant "phandle" property name */
+		val = fdt_getprop(blob, offset, "phandle", &len);
+		if (val)
+			phandle = max(*val, phandle);
+
+		/* Also check the deprecated "linux,phandle" property name */
 		val = fdt_getprop(blob, offset, "linux,phandle", &len);
 		if (val)
 			phandle = max(*val, phandle);
diff --git a/include/libfdt.h b/include/libfdt.h
index d23d40e..092dd34 100644
--- a/include/libfdt.h
+++ b/include/libfdt.h
@@ -452,6 +452,11 @@  static inline void *fdt_getprop_w(void *fdt, int nodeoffset,
  * fdt_get_phandle() retrieves the phandle of the device tree node at
  * structure block offset nodeoffset.
  *
+ * Both the ePAPR "phandle" property as well as the legacy "linux,phandle"
+ * property are supported.  If the device tree node contains both properties,
+ * then "phandle" is used.  However, it is considered an error if the two
+ * properties contain different values.
+ *
  * returns:
  *	the phandle of the node at nodeoffset, on success (!= 0, != -1)
  *	0, if the node has no phandle, or another error occurs
@@ -662,6 +667,11 @@  int fdt_node_offset_by_phandle(const void *fdt, uint32_t phandle);
  * 'compatible' property with the given string as one of its elements,
  * it returns non-zero otherwise, or on error.
  *
+ * Both the ePAPR "phandle" property as well as the legacy "linux,phandle"
+ * property are supported.  If the device tree node contains both properties,
+ * then "phandle" is used.  However, it is considered an error if the two
+ * properties contain different values.
+ *
  * returns:
  *	0, if the node has a 'compatible' property listing the given string
  *	1, if the node has a 'compatible' property, but it does not list
diff --git a/lib/libfdt/fdt_ro.c b/lib/libfdt/fdt_ro.c
index 1e1e322..57a901f 100644
--- a/lib/libfdt/fdt_ro.c
+++ b/lib/libfdt/fdt_ro.c
@@ -278,6 +278,14 @@  uint32_t fdt_get_phandle(const void *fdt, int nodeoffset)
 	const uint32_t *php;
 	int len;
 
+	/* First, check the "phandle" property */
+	php = fdt_getprop(fdt, nodeoffset, "phandle", &len);
+	if (php) {
+		/* If the property exists, then use it if it's valid */
+		return len == sizeof(*php) ? fdt32_to_cpu(*php) : 0;
+	}
+
+	/* No "phandle", so check "linux,phandle" */
 	php = fdt_getprop(fdt, nodeoffset, "linux,phandle", &len);
 	if (!php || (len != sizeof(*php)))
 		return 0;
@@ -440,9 +448,19 @@  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 ret;
+
 	if ((phandle == 0) || (phandle == -1))
 		return -FDT_ERR_BADPHANDLE;
 	phandle = cpu_to_fdt32(phandle);
+
+	/* First check for a matching "phandle" property */
+	ret = fdt_node_offset_by_prop_value(fdt, -1, "phandle",
+					    &phandle, sizeof(phandle));
+	if (ret > 0)
+		return ret;
+
+	/* No "phandle", so check "linux,phandle" */
 	return fdt_node_offset_by_prop_value(fdt, -1, "linux,phandle",
 					     &phandle, sizeof(phandle));
 }