All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v4 0/4] of: remove *phandle properties from expanded device tree
@ 2017-05-02  2:46 ` frowand.list-Re5JQEeQqe8AvxtiuMwx3w
  0 siblings, 0 replies; 15+ messages in thread
From: frowand.list @ 2017-05-02  2:46 UTC (permalink / raw)
  To: Rob Herring, stephen.boyd; +Cc: devicetree, linux-kernel

From: Frank Rowand <frank.rowand@sony.com>

Remove "phandle" and "linux,phandle" properties from the internal
device tree.  The phandle will still be in the struct device_node
phandle field.

This is to resolve the issue found by Stephen Boyd [1] when he changed
the type of struct property.value from void * to const void *.  As
a result of the type change, the overlay code had compile errors
where the resolver updates phandle values.

  [1] http://lkml.iu.edu/hypermail/linux/kernel/1702.1/04160.html

Patch 1 is the phandle related changes.

Patches 2 - 4 are minor fixups for issues that became visible
while implementing patch 1.

Changes from v3:
   - patch 1: fix incorrect variable name in __of_add_phandle_sysfs().
     Problem was reported by the kbuild test robot

Changes from v2:
   - patch 1: Remove check in __of_add_phandle_sysfs() that would not
     add a sysfs entry if IS_ENABLED(CONFIG_PPC_PSERIES)

Changes from v1:
   - Remove phandle properties in of_attach_node(), before attaching
     the node to the live tree.
   - Add the phandle sysfs entry for the node in of_attach_node().
   - When creating an overlay changeset, duplicate the node phandle in
     __of_node_dup().


Frank Rowand (4):
  of: remove *phandle properties from expanded device tree
  of: make __of_attach_node() static
  of: be consistent in form of file mode
  of: detect invalid phandle in overlay

 drivers/of/base.c       | 50 +++++++++++++++++++++++++++++++++++++++----
 drivers/of/dynamic.c    | 56 ++++++++++++++++++++++++++++++++++++-------------
 drivers/of/fdt.c        | 40 +++++++++++++++++++++--------------
 drivers/of/of_private.h |  2 +-
 drivers/of/overlay.c    |  8 ++++---
 drivers/of/resolver.c   | 23 +-------------------
 include/linux/of.h      |  1 +
 7 files changed, 120 insertions(+), 60 deletions(-)

-- 
Frank Rowand <frank.rowand@sony.com>

^ permalink raw reply	[flat|nested] 15+ messages in thread

* [PATCH v4 0/4] of: remove *phandle properties from expanded device tree
@ 2017-05-02  2:46 ` frowand.list-Re5JQEeQqe8AvxtiuMwx3w
  0 siblings, 0 replies; 15+ messages in thread
From: frowand.list-Re5JQEeQqe8AvxtiuMwx3w @ 2017-05-02  2:46 UTC (permalink / raw)
  To: Rob Herring, stephen.boyd-QSEj5FYQhm4dnm+yROfE0A
  Cc: devicetree-u79uwXL29TY76Z2rM5mHXA, linux-kernel-u79uwXL29TY76Z2rM5mHXA

From: Frank Rowand <frank.rowand-7U/KSKJipcs@public.gmane.org>

Remove "phandle" and "linux,phandle" properties from the internal
device tree.  The phandle will still be in the struct device_node
phandle field.

This is to resolve the issue found by Stephen Boyd [1] when he changed
the type of struct property.value from void * to const void *.  As
a result of the type change, the overlay code had compile errors
where the resolver updates phandle values.

  [1] http://lkml.iu.edu/hypermail/linux/kernel/1702.1/04160.html

Patch 1 is the phandle related changes.

Patches 2 - 4 are minor fixups for issues that became visible
while implementing patch 1.

Changes from v3:
   - patch 1: fix incorrect variable name in __of_add_phandle_sysfs().
     Problem was reported by the kbuild test robot

Changes from v2:
   - patch 1: Remove check in __of_add_phandle_sysfs() that would not
     add a sysfs entry if IS_ENABLED(CONFIG_PPC_PSERIES)

Changes from v1:
   - Remove phandle properties in of_attach_node(), before attaching
     the node to the live tree.
   - Add the phandle sysfs entry for the node in of_attach_node().
   - When creating an overlay changeset, duplicate the node phandle in
     __of_node_dup().


Frank Rowand (4):
  of: remove *phandle properties from expanded device tree
  of: make __of_attach_node() static
  of: be consistent in form of file mode
  of: detect invalid phandle in overlay

 drivers/of/base.c       | 50 +++++++++++++++++++++++++++++++++++++++----
 drivers/of/dynamic.c    | 56 ++++++++++++++++++++++++++++++++++++-------------
 drivers/of/fdt.c        | 40 +++++++++++++++++++++--------------
 drivers/of/of_private.h |  2 +-
 drivers/of/overlay.c    |  8 ++++---
 drivers/of/resolver.c   | 23 +-------------------
 include/linux/of.h      |  1 +
 7 files changed, 120 insertions(+), 60 deletions(-)

-- 
Frank Rowand <frank.rowand-7U/KSKJipcs@public.gmane.org>

--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply	[flat|nested] 15+ messages in thread

* [PATCH v4 1/4] of: remove *phandle properties from expanded device tree
@ 2017-05-02  2:46   ` frowand.list-Re5JQEeQqe8AvxtiuMwx3w
  0 siblings, 0 replies; 15+ messages in thread
From: frowand.list @ 2017-05-02  2:46 UTC (permalink / raw)
  To: Rob Herring, stephen.boyd; +Cc: devicetree, linux-kernel

From: Frank Rowand <frank.rowand@sony.com>

Remove "phandle", "linux,phandle", and "ibm,phandle" properties from
the internal device tree.  The phandle will still be in the struct
device_node phandle field.

This is to resolve the issue found by Stephen Boyd [1] when he changed
the type of struct property.value from void * to const void *.  As
a result of the type change, the overlay code had compile errors
where the resolver updates phandle values.

  [1] http://lkml.iu.edu/hypermail/linux/kernel/1702.1/04160.html

- Add sysfs infrastructure to report np->phandle, as if it was a property.
- Do not create "phandle" "ibm,phandle", and "linux,phandle" properties
  in the expanded device tree.
- Remove phandle properties in of_attach_node(), for nodes dynamically
  attached to the live tree.  Add the phandle sysfs entry for these nodes.
- When creating an overlay changeset, duplicate the node phandle in
  __of_node_dup().
- Remove no longer needed checks to exclude "phandle" and "linux,phandle"
  properties in several locations.
- A side effect of these changes is that the obsolete "linux,phandle" and
  "ibm,phandle" properties will no longer appear in /proc/device-tree (they
  will appear as "phandle").

Signed-off-by: Frank Rowand <frank.rowand@sony.com>
---
 drivers/of/base.c       | 48 ++++++++++++++++++++++++++++++++++++++++---
 drivers/of/dynamic.c    | 54 +++++++++++++++++++++++++++++++++++++------------
 drivers/of/fdt.c        | 40 +++++++++++++++++++++---------------
 drivers/of/of_private.h |  1 +
 drivers/of/overlay.c    |  4 +---
 drivers/of/resolver.c   | 23 +--------------------
 include/linux/of.h      |  1 +
 7 files changed, 114 insertions(+), 57 deletions(-)

diff --git a/drivers/of/base.c b/drivers/of/base.c
index d7c4629a3a2d..8a0cf9003cf8 100644
--- a/drivers/of/base.c
+++ b/drivers/of/base.c
@@ -116,6 +116,19 @@ static ssize_t of_node_property_read(struct file *filp, struct kobject *kobj,
 	return memory_read_from_buffer(buf, count, &offset, pp->value, pp->length);
 }
 
+static ssize_t of_node_phandle_read(struct file *filp, struct kobject *kobj,
+				struct bin_attribute *bin_attr, char *buf,
+				loff_t offset, size_t count)
+{
+	phandle phandle;
+	struct device_node *np;
+
+	np = container_of(bin_attr, struct device_node, attr_phandle);
+	phandle = cpu_to_be32(np->phandle);
+	return memory_read_from_buffer(buf, count, &offset, &phandle,
+				       sizeof(phandle));
+}
+
 /* always return newly allocated name, caller must free after use */
 static const char *safe_name(struct kobject *kobj, const char *orig_name)
 {
@@ -164,6 +177,35 @@ int __of_add_property_sysfs(struct device_node *np, struct property *pp)
 	return rc;
 }
 
+/*
+ * In the imported device tree (fdt), phandle is a property.  In the
+ * internal data structure it is instead stored in the struct device_node.
+ * Make phandle visible in sysfs as if it was a property.
+ */
+int __of_add_phandle_sysfs(struct device_node *np)
+{
+	int rc;
+
+	if (!IS_ENABLED(CONFIG_SYSFS))
+		return 0;
+
+	if (!of_kset || !of_node_is_attached(np))
+		return 0;
+
+	if (!np->phandle || np->phandle == 0xffffffff)
+		return 0;
+
+	sysfs_bin_attr_init(&np->attr_phandle);
+	np->attr_phandle.attr.name = "phandle";
+	np->attr_phandle.attr.mode = 0444;
+	np->attr_phandle.size = sizeof(np->phandle);
+	np->attr_phandle.read = of_node_phandle_read;
+
+	rc = sysfs_create_bin_file(&np->kobj, &np->attr_phandle);
+	WARN(rc, "error adding attribute phandle to node %s\n", np->full_name);
+	return rc;
+}
+
 int __of_attach_node_sysfs(struct device_node *np)
 {
 	const char *name;
@@ -193,6 +235,8 @@ int __of_attach_node_sysfs(struct device_node *np)
 	if (rc)
 		return rc;
 
+	__of_add_phandle_sysfs(np);
+
 	for_each_property_of_node(np, pp)
 		__of_add_property_sysfs(np, pp);
 
@@ -2097,9 +2141,7 @@ void of_alias_scan(void * (*dt_alloc)(u64 size, u64 align))
 		int id, len;
 
 		/* Skip those we do not want to proceed */
-		if (!strcmp(pp->name, "name") ||
-		    !strcmp(pp->name, "phandle") ||
-		    !strcmp(pp->name, "linux,phandle"))
+		if (!strcmp(pp->name, "name"))
 			continue;
 
 		np = of_find_node_by_path(pp->value);
diff --git a/drivers/of/dynamic.c b/drivers/of/dynamic.c
index 888fdbc09992..59545b8fbf46 100644
--- a/drivers/of/dynamic.c
+++ b/drivers/of/dynamic.c
@@ -218,19 +218,6 @@ int of_property_notify(int action, struct device_node *np,
 
 void __of_attach_node(struct device_node *np)
 {
-	const __be32 *phandle;
-	int sz;
-
-	np->name = __of_get_property(np, "name", NULL) ? : "<NULL>";
-	np->type = __of_get_property(np, "device_type", NULL) ? : "<NULL>";
-
-	phandle = __of_get_property(np, "phandle", &sz);
-	if (!phandle)
-		phandle = __of_get_property(np, "linux,phandle", &sz);
-	if (IS_ENABLED(CONFIG_PPC_PSERIES) && !phandle)
-		phandle = __of_get_property(np, "ibm,phandle", &sz);
-	np->phandle = (phandle && (sz >= 4)) ? be32_to_cpup(phandle) : 0;
-
 	np->child = NULL;
 	np->sibling = np->parent->child;
 	np->parent->child = np;
@@ -243,11 +230,47 @@ void __of_attach_node(struct device_node *np)
 int of_attach_node(struct device_node *np)
 {
 	struct of_reconfig_data rd;
+	struct property *prev;
+	struct property *prop;
+	struct property *save_next;
 	unsigned long flags;
+	const __be32 *phandle;
+	int sz;
 
 	memset(&rd, 0, sizeof(rd));
 	rd.dn = np;
 
+	np->name = __of_get_property(np, "name", NULL) ? : "<NULL>";
+	np->type = __of_get_property(np, "device_type", NULL) ? : "<NULL>";
+
+	phandle = __of_get_property(np, "phandle", &sz);
+	if (!phandle)
+		phandle = __of_get_property(np, "linux,phandle", &sz);
+	if (IS_ENABLED(CONFIG_PPC_PSERIES) && !phandle)
+		phandle = __of_get_property(np, "ibm,phandle", &sz);
+	np->phandle = (phandle && (sz >= 4)) ? be32_to_cpup(phandle) : 0;
+
+	/* remove phandle properties from node */
+	prev = NULL;
+	for (prop = np->properties; prop != NULL; ) {
+		save_next = prop->next;
+		if (!strcmp(prop->name, "phandle") ||
+		    !strcmp(prop->name, "ibm,phandle") ||
+		    !strcmp(prop->name, "linux,phandle")) {
+			if (prev)
+				prev->next = prop->next;
+			else
+				np->properties = prop->next;
+			prop->next = np->deadprops;
+			np->deadprops = prop;
+		} else {
+			prev = prop;
+		}
+		prop = save_next;
+	}
+
+	__of_add_phandle_sysfs(np);
+
 	mutex_lock(&of_mutex);
 	raw_spin_lock_irqsave(&devtree_lock, flags);
 	__of_attach_node(np);
@@ -429,6 +452,7 @@ struct device_node *__of_node_dup(const struct device_node *np, const char *fmt,
 	/* Iterate over and duplicate all properties */
 	if (np) {
 		struct property *pp, *new_pp;
+		node->phandle = np->phandle;
 		for_each_property_of_node(np, pp) {
 			new_pp = __of_prop_dup(pp, GFP_KERNEL);
 			if (!new_pp)
@@ -441,6 +465,10 @@ struct device_node *__of_node_dup(const struct device_node *np, const char *fmt,
 			}
 		}
 	}
+
+	node->name = __of_get_property(node, "name", NULL) ? : "<NULL>";
+	node->type = __of_get_property(node, "device_type", NULL) ? : "<NULL>";
+
 	return node;
 
  err_prop:
diff --git a/drivers/of/fdt.c b/drivers/of/fdt.c
index e5ce4b59e162..270f31b0c259 100644
--- a/drivers/of/fdt.c
+++ b/drivers/of/fdt.c
@@ -181,6 +181,8 @@ static void populate_properties(const void *blob,
 		const __be32 *val;
 		const char *pname;
 		u32 sz;
+		int prop_is_phandle = 0;
+		int prop_is_ibm_phandle = 0;
 
 		val = fdt_getprop_by_offset(blob, cur, &pname, &sz);
 		if (!val) {
@@ -196,11 +198,6 @@ static void populate_properties(const void *blob,
 		if (!strcmp(pname, "name"))
 			has_name = true;
 
-		pp = unflatten_dt_alloc(mem, sizeof(struct property),
-					__alignof__(struct property));
-		if (dryrun)
-			continue;
-
 		/* We accept flattened tree phandles either in
 		 * ePAPR-style "phandle" properties, or the
 		 * legacy "linux,phandle" properties.  If both
@@ -208,23 +205,34 @@ static void populate_properties(const void *blob,
 		 * will get weird. Don't do that.
 		 */
 		if (!strcmp(pname, "phandle") ||
-		    !strcmp(pname, "linux,phandle")) {
-			if (!np->phandle)
-				np->phandle = be32_to_cpup(val);
-		}
+		    !strcmp(pname, "linux,phandle"))
+			prop_is_phandle = 1;
 
 		/* And we process the "ibm,phandle" property
 		 * used in pSeries dynamic device tree
 		 * stuff
 		 */
-		if (!strcmp(pname, "ibm,phandle"))
-			np->phandle = be32_to_cpup(val);
+		if (!strcmp(pname, "ibm,phandle")) {
+			prop_is_phandle = 1;
+			prop_is_ibm_phandle = 1;
+		}
+
+		if (!prop_is_phandle)
+			pp = unflatten_dt_alloc(mem, sizeof(struct property),
+						__alignof__(struct property));
 
-		pp->name   = (char *)pname;
-		pp->length = sz;
-		pp->value  = (__be32 *)val;
-		*pprev     = pp;
-		pprev      = &pp->next;
+		if (dryrun)
+			continue;
+
+		if (!prop_is_phandle) {
+			pp->name   = (char *)pname;
+			pp->length = sz;
+			pp->value  = (__be32 *)val;
+			*pprev     = pp;
+			pprev      = &pp->next;
+		} else if (prop_is_ibm_phandle || !np->phandle) {
+			np->phandle = be32_to_cpup(val);
+		}
 	}
 
 	/* With version 0x10 we may not have the name property,
diff --git a/drivers/of/of_private.h b/drivers/of/of_private.h
index 18bbb4517e25..33f11a5384f3 100644
--- a/drivers/of/of_private.h
+++ b/drivers/of/of_private.h
@@ -47,6 +47,7 @@ extern int of_property_notify(int action, struct device_node *np,
 extern void of_node_release(struct kobject *kobj);
 extern int __of_changeset_apply(struct of_changeset *ocs);
 extern int __of_changeset_revert(struct of_changeset *ocs);
+extern int __of_add_phandle_sysfs(struct device_node *np);
 #else /* CONFIG_OF_DYNAMIC */
 static inline int of_property_notify(int action, struct device_node *np,
 				     struct property *prop, struct property *old_prop)
diff --git a/drivers/of/overlay.c b/drivers/of/overlay.c
index 7827786718d8..ca0b85f5deb1 100644
--- a/drivers/of/overlay.c
+++ b/drivers/of/overlay.c
@@ -101,9 +101,7 @@ static int of_overlay_apply_single_property(struct of_overlay *ov,
 	tprop = of_find_property(target, prop->name, NULL);
 
 	/* special properties are not meant to be updated (silent NOP) */
-	if (of_prop_cmp(prop->name, "name") == 0 ||
-	    of_prop_cmp(prop->name, "phandle") == 0 ||
-	    of_prop_cmp(prop->name, "linux,phandle") == 0)
+	if (!of_prop_cmp(prop->name, "name"))
 		return 0;
 
 	propn = __of_prop_dup(prop, GFP_KERNEL);
diff --git a/drivers/of/resolver.c b/drivers/of/resolver.c
index 7ae9863cb0a4..624cbaeae0a4 100644
--- a/drivers/of/resolver.c
+++ b/drivers/of/resolver.c
@@ -71,30 +71,11 @@ static void adjust_overlay_phandles(struct device_node *overlay,
 		int phandle_delta)
 {
 	struct device_node *child;
-	struct property *prop;
-	phandle phandle;
 
 	/* adjust node's phandle in node */
 	if (overlay->phandle != 0 && overlay->phandle != OF_PHANDLE_ILLEGAL)
 		overlay->phandle += phandle_delta;
 
-	/* copy adjusted phandle into *phandle properties */
-	for_each_property_of_node(overlay, prop) {
-
-		if (of_prop_cmp(prop->name, "phandle") &&
-		    of_prop_cmp(prop->name, "linux,phandle"))
-			continue;
-
-		if (prop->length < 4)
-			continue;
-
-		phandle = be32_to_cpup(prop->value);
-		if (phandle == OF_PHANDLE_ILLEGAL)
-			continue;
-
-		*(uint32_t *)prop->value = cpu_to_be32(overlay->phandle);
-	}
-
 	for_each_child_of_node(overlay, child)
 		adjust_overlay_phandles(child, phandle_delta);
 }
@@ -197,9 +178,7 @@ static int adjust_local_phandle_references(struct device_node *local_fixups,
 	for_each_property_of_node(local_fixups, prop_fix) {
 
 		/* skip properties added automatically */
-		if (!of_prop_cmp(prop_fix->name, "name") ||
-		    !of_prop_cmp(prop_fix->name, "phandle") ||
-		    !of_prop_cmp(prop_fix->name, "linux,phandle"))
+		if (!of_prop_cmp(prop_fix->name, "name"))
 			continue;
 
 		if ((prop_fix->length % 4) != 0 || prop_fix->length == 0)
diff --git a/include/linux/of.h b/include/linux/of.h
index 21e6323de0f3..4e86e05853f3 100644
--- a/include/linux/of.h
+++ b/include/linux/of.h
@@ -61,6 +61,7 @@ struct device_node {
 	struct	kobject kobj;
 	unsigned long _flags;
 	void	*data;
+	struct bin_attribute attr_phandle;
 #if defined(CONFIG_SPARC)
 	const char *path_component_name;
 	unsigned int unique_id;
-- 
Frank Rowand <frank.rowand@sony.com>

^ permalink raw reply related	[flat|nested] 15+ messages in thread

* [PATCH v4 1/4] of: remove *phandle properties from expanded device tree
@ 2017-05-02  2:46   ` frowand.list-Re5JQEeQqe8AvxtiuMwx3w
  0 siblings, 0 replies; 15+ messages in thread
From: frowand.list-Re5JQEeQqe8AvxtiuMwx3w @ 2017-05-02  2:46 UTC (permalink / raw)
  To: Rob Herring, stephen.boyd-QSEj5FYQhm4dnm+yROfE0A
  Cc: devicetree-u79uwXL29TY76Z2rM5mHXA, linux-kernel-u79uwXL29TY76Z2rM5mHXA

From: Frank Rowand <frank.rowand-7U/KSKJipcs@public.gmane.org>

Remove "phandle", "linux,phandle", and "ibm,phandle" properties from
the internal device tree.  The phandle will still be in the struct
device_node phandle field.

This is to resolve the issue found by Stephen Boyd [1] when he changed
the type of struct property.value from void * to const void *.  As
a result of the type change, the overlay code had compile errors
where the resolver updates phandle values.

  [1] http://lkml.iu.edu/hypermail/linux/kernel/1702.1/04160.html

- Add sysfs infrastructure to report np->phandle, as if it was a property.
- Do not create "phandle" "ibm,phandle", and "linux,phandle" properties
  in the expanded device tree.
- Remove phandle properties in of_attach_node(), for nodes dynamically
  attached to the live tree.  Add the phandle sysfs entry for these nodes.
- When creating an overlay changeset, duplicate the node phandle in
  __of_node_dup().
- Remove no longer needed checks to exclude "phandle" and "linux,phandle"
  properties in several locations.
- A side effect of these changes is that the obsolete "linux,phandle" and
  "ibm,phandle" properties will no longer appear in /proc/device-tree (they
  will appear as "phandle").

Signed-off-by: Frank Rowand <frank.rowand-7U/KSKJipcs@public.gmane.org>
---
 drivers/of/base.c       | 48 ++++++++++++++++++++++++++++++++++++++++---
 drivers/of/dynamic.c    | 54 +++++++++++++++++++++++++++++++++++++------------
 drivers/of/fdt.c        | 40 +++++++++++++++++++++---------------
 drivers/of/of_private.h |  1 +
 drivers/of/overlay.c    |  4 +---
 drivers/of/resolver.c   | 23 +--------------------
 include/linux/of.h      |  1 +
 7 files changed, 114 insertions(+), 57 deletions(-)

diff --git a/drivers/of/base.c b/drivers/of/base.c
index d7c4629a3a2d..8a0cf9003cf8 100644
--- a/drivers/of/base.c
+++ b/drivers/of/base.c
@@ -116,6 +116,19 @@ static ssize_t of_node_property_read(struct file *filp, struct kobject *kobj,
 	return memory_read_from_buffer(buf, count, &offset, pp->value, pp->length);
 }
 
+static ssize_t of_node_phandle_read(struct file *filp, struct kobject *kobj,
+				struct bin_attribute *bin_attr, char *buf,
+				loff_t offset, size_t count)
+{
+	phandle phandle;
+	struct device_node *np;
+
+	np = container_of(bin_attr, struct device_node, attr_phandle);
+	phandle = cpu_to_be32(np->phandle);
+	return memory_read_from_buffer(buf, count, &offset, &phandle,
+				       sizeof(phandle));
+}
+
 /* always return newly allocated name, caller must free after use */
 static const char *safe_name(struct kobject *kobj, const char *orig_name)
 {
@@ -164,6 +177,35 @@ int __of_add_property_sysfs(struct device_node *np, struct property *pp)
 	return rc;
 }
 
+/*
+ * In the imported device tree (fdt), phandle is a property.  In the
+ * internal data structure it is instead stored in the struct device_node.
+ * Make phandle visible in sysfs as if it was a property.
+ */
+int __of_add_phandle_sysfs(struct device_node *np)
+{
+	int rc;
+
+	if (!IS_ENABLED(CONFIG_SYSFS))
+		return 0;
+
+	if (!of_kset || !of_node_is_attached(np))
+		return 0;
+
+	if (!np->phandle || np->phandle == 0xffffffff)
+		return 0;
+
+	sysfs_bin_attr_init(&np->attr_phandle);
+	np->attr_phandle.attr.name = "phandle";
+	np->attr_phandle.attr.mode = 0444;
+	np->attr_phandle.size = sizeof(np->phandle);
+	np->attr_phandle.read = of_node_phandle_read;
+
+	rc = sysfs_create_bin_file(&np->kobj, &np->attr_phandle);
+	WARN(rc, "error adding attribute phandle to node %s\n", np->full_name);
+	return rc;
+}
+
 int __of_attach_node_sysfs(struct device_node *np)
 {
 	const char *name;
@@ -193,6 +235,8 @@ int __of_attach_node_sysfs(struct device_node *np)
 	if (rc)
 		return rc;
 
+	__of_add_phandle_sysfs(np);
+
 	for_each_property_of_node(np, pp)
 		__of_add_property_sysfs(np, pp);
 
@@ -2097,9 +2141,7 @@ void of_alias_scan(void * (*dt_alloc)(u64 size, u64 align))
 		int id, len;
 
 		/* Skip those we do not want to proceed */
-		if (!strcmp(pp->name, "name") ||
-		    !strcmp(pp->name, "phandle") ||
-		    !strcmp(pp->name, "linux,phandle"))
+		if (!strcmp(pp->name, "name"))
 			continue;
 
 		np = of_find_node_by_path(pp->value);
diff --git a/drivers/of/dynamic.c b/drivers/of/dynamic.c
index 888fdbc09992..59545b8fbf46 100644
--- a/drivers/of/dynamic.c
+++ b/drivers/of/dynamic.c
@@ -218,19 +218,6 @@ int of_property_notify(int action, struct device_node *np,
 
 void __of_attach_node(struct device_node *np)
 {
-	const __be32 *phandle;
-	int sz;
-
-	np->name = __of_get_property(np, "name", NULL) ? : "<NULL>";
-	np->type = __of_get_property(np, "device_type", NULL) ? : "<NULL>";
-
-	phandle = __of_get_property(np, "phandle", &sz);
-	if (!phandle)
-		phandle = __of_get_property(np, "linux,phandle", &sz);
-	if (IS_ENABLED(CONFIG_PPC_PSERIES) && !phandle)
-		phandle = __of_get_property(np, "ibm,phandle", &sz);
-	np->phandle = (phandle && (sz >= 4)) ? be32_to_cpup(phandle) : 0;
-
 	np->child = NULL;
 	np->sibling = np->parent->child;
 	np->parent->child = np;
@@ -243,11 +230,47 @@ void __of_attach_node(struct device_node *np)
 int of_attach_node(struct device_node *np)
 {
 	struct of_reconfig_data rd;
+	struct property *prev;
+	struct property *prop;
+	struct property *save_next;
 	unsigned long flags;
+	const __be32 *phandle;
+	int sz;
 
 	memset(&rd, 0, sizeof(rd));
 	rd.dn = np;
 
+	np->name = __of_get_property(np, "name", NULL) ? : "<NULL>";
+	np->type = __of_get_property(np, "device_type", NULL) ? : "<NULL>";
+
+	phandle = __of_get_property(np, "phandle", &sz);
+	if (!phandle)
+		phandle = __of_get_property(np, "linux,phandle", &sz);
+	if (IS_ENABLED(CONFIG_PPC_PSERIES) && !phandle)
+		phandle = __of_get_property(np, "ibm,phandle", &sz);
+	np->phandle = (phandle && (sz >= 4)) ? be32_to_cpup(phandle) : 0;
+
+	/* remove phandle properties from node */
+	prev = NULL;
+	for (prop = np->properties; prop != NULL; ) {
+		save_next = prop->next;
+		if (!strcmp(prop->name, "phandle") ||
+		    !strcmp(prop->name, "ibm,phandle") ||
+		    !strcmp(prop->name, "linux,phandle")) {
+			if (prev)
+				prev->next = prop->next;
+			else
+				np->properties = prop->next;
+			prop->next = np->deadprops;
+			np->deadprops = prop;
+		} else {
+			prev = prop;
+		}
+		prop = save_next;
+	}
+
+	__of_add_phandle_sysfs(np);
+
 	mutex_lock(&of_mutex);
 	raw_spin_lock_irqsave(&devtree_lock, flags);
 	__of_attach_node(np);
@@ -429,6 +452,7 @@ struct device_node *__of_node_dup(const struct device_node *np, const char *fmt,
 	/* Iterate over and duplicate all properties */
 	if (np) {
 		struct property *pp, *new_pp;
+		node->phandle = np->phandle;
 		for_each_property_of_node(np, pp) {
 			new_pp = __of_prop_dup(pp, GFP_KERNEL);
 			if (!new_pp)
@@ -441,6 +465,10 @@ struct device_node *__of_node_dup(const struct device_node *np, const char *fmt,
 			}
 		}
 	}
+
+	node->name = __of_get_property(node, "name", NULL) ? : "<NULL>";
+	node->type = __of_get_property(node, "device_type", NULL) ? : "<NULL>";
+
 	return node;
 
  err_prop:
diff --git a/drivers/of/fdt.c b/drivers/of/fdt.c
index e5ce4b59e162..270f31b0c259 100644
--- a/drivers/of/fdt.c
+++ b/drivers/of/fdt.c
@@ -181,6 +181,8 @@ static void populate_properties(const void *blob,
 		const __be32 *val;
 		const char *pname;
 		u32 sz;
+		int prop_is_phandle = 0;
+		int prop_is_ibm_phandle = 0;
 
 		val = fdt_getprop_by_offset(blob, cur, &pname, &sz);
 		if (!val) {
@@ -196,11 +198,6 @@ static void populate_properties(const void *blob,
 		if (!strcmp(pname, "name"))
 			has_name = true;
 
-		pp = unflatten_dt_alloc(mem, sizeof(struct property),
-					__alignof__(struct property));
-		if (dryrun)
-			continue;
-
 		/* We accept flattened tree phandles either in
 		 * ePAPR-style "phandle" properties, or the
 		 * legacy "linux,phandle" properties.  If both
@@ -208,23 +205,34 @@ static void populate_properties(const void *blob,
 		 * will get weird. Don't do that.
 		 */
 		if (!strcmp(pname, "phandle") ||
-		    !strcmp(pname, "linux,phandle")) {
-			if (!np->phandle)
-				np->phandle = be32_to_cpup(val);
-		}
+		    !strcmp(pname, "linux,phandle"))
+			prop_is_phandle = 1;
 
 		/* And we process the "ibm,phandle" property
 		 * used in pSeries dynamic device tree
 		 * stuff
 		 */
-		if (!strcmp(pname, "ibm,phandle"))
-			np->phandle = be32_to_cpup(val);
+		if (!strcmp(pname, "ibm,phandle")) {
+			prop_is_phandle = 1;
+			prop_is_ibm_phandle = 1;
+		}
+
+		if (!prop_is_phandle)
+			pp = unflatten_dt_alloc(mem, sizeof(struct property),
+						__alignof__(struct property));
 
-		pp->name   = (char *)pname;
-		pp->length = sz;
-		pp->value  = (__be32 *)val;
-		*pprev     = pp;
-		pprev      = &pp->next;
+		if (dryrun)
+			continue;
+
+		if (!prop_is_phandle) {
+			pp->name   = (char *)pname;
+			pp->length = sz;
+			pp->value  = (__be32 *)val;
+			*pprev     = pp;
+			pprev      = &pp->next;
+		} else if (prop_is_ibm_phandle || !np->phandle) {
+			np->phandle = be32_to_cpup(val);
+		}
 	}
 
 	/* With version 0x10 we may not have the name property,
diff --git a/drivers/of/of_private.h b/drivers/of/of_private.h
index 18bbb4517e25..33f11a5384f3 100644
--- a/drivers/of/of_private.h
+++ b/drivers/of/of_private.h
@@ -47,6 +47,7 @@ extern int of_property_notify(int action, struct device_node *np,
 extern void of_node_release(struct kobject *kobj);
 extern int __of_changeset_apply(struct of_changeset *ocs);
 extern int __of_changeset_revert(struct of_changeset *ocs);
+extern int __of_add_phandle_sysfs(struct device_node *np);
 #else /* CONFIG_OF_DYNAMIC */
 static inline int of_property_notify(int action, struct device_node *np,
 				     struct property *prop, struct property *old_prop)
diff --git a/drivers/of/overlay.c b/drivers/of/overlay.c
index 7827786718d8..ca0b85f5deb1 100644
--- a/drivers/of/overlay.c
+++ b/drivers/of/overlay.c
@@ -101,9 +101,7 @@ static int of_overlay_apply_single_property(struct of_overlay *ov,
 	tprop = of_find_property(target, prop->name, NULL);
 
 	/* special properties are not meant to be updated (silent NOP) */
-	if (of_prop_cmp(prop->name, "name") == 0 ||
-	    of_prop_cmp(prop->name, "phandle") == 0 ||
-	    of_prop_cmp(prop->name, "linux,phandle") == 0)
+	if (!of_prop_cmp(prop->name, "name"))
 		return 0;
 
 	propn = __of_prop_dup(prop, GFP_KERNEL);
diff --git a/drivers/of/resolver.c b/drivers/of/resolver.c
index 7ae9863cb0a4..624cbaeae0a4 100644
--- a/drivers/of/resolver.c
+++ b/drivers/of/resolver.c
@@ -71,30 +71,11 @@ static void adjust_overlay_phandles(struct device_node *overlay,
 		int phandle_delta)
 {
 	struct device_node *child;
-	struct property *prop;
-	phandle phandle;
 
 	/* adjust node's phandle in node */
 	if (overlay->phandle != 0 && overlay->phandle != OF_PHANDLE_ILLEGAL)
 		overlay->phandle += phandle_delta;
 
-	/* copy adjusted phandle into *phandle properties */
-	for_each_property_of_node(overlay, prop) {
-
-		if (of_prop_cmp(prop->name, "phandle") &&
-		    of_prop_cmp(prop->name, "linux,phandle"))
-			continue;
-
-		if (prop->length < 4)
-			continue;
-
-		phandle = be32_to_cpup(prop->value);
-		if (phandle == OF_PHANDLE_ILLEGAL)
-			continue;
-
-		*(uint32_t *)prop->value = cpu_to_be32(overlay->phandle);
-	}
-
 	for_each_child_of_node(overlay, child)
 		adjust_overlay_phandles(child, phandle_delta);
 }
@@ -197,9 +178,7 @@ static int adjust_local_phandle_references(struct device_node *local_fixups,
 	for_each_property_of_node(local_fixups, prop_fix) {
 
 		/* skip properties added automatically */
-		if (!of_prop_cmp(prop_fix->name, "name") ||
-		    !of_prop_cmp(prop_fix->name, "phandle") ||
-		    !of_prop_cmp(prop_fix->name, "linux,phandle"))
+		if (!of_prop_cmp(prop_fix->name, "name"))
 			continue;
 
 		if ((prop_fix->length % 4) != 0 || prop_fix->length == 0)
diff --git a/include/linux/of.h b/include/linux/of.h
index 21e6323de0f3..4e86e05853f3 100644
--- a/include/linux/of.h
+++ b/include/linux/of.h
@@ -61,6 +61,7 @@ struct device_node {
 	struct	kobject kobj;
 	unsigned long _flags;
 	void	*data;
+	struct bin_attribute attr_phandle;
 #if defined(CONFIG_SPARC)
 	const char *path_component_name;
 	unsigned int unique_id;
-- 
Frank Rowand <frank.rowand-7U/KSKJipcs@public.gmane.org>

--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply related	[flat|nested] 15+ messages in thread

* [PATCH v4 2/4] of: make __of_attach_node() static
@ 2017-05-02  2:46   ` frowand.list-Re5JQEeQqe8AvxtiuMwx3w
  0 siblings, 0 replies; 15+ messages in thread
From: frowand.list @ 2017-05-02  2:46 UTC (permalink / raw)
  To: Rob Herring, stephen.boyd; +Cc: devicetree, linux-kernel

From: Frank Rowand <frank.rowand@sony.com>

__of_attach_node() is not used outside of drivers/of/dynamic.c.  Make
it static and remove it from drivers/of/of_private.h.

Signed-off-by: Frank Rowand <frank.rowand@sony.com>
---
 drivers/of/dynamic.c    | 2 +-
 drivers/of/of_private.h | 1 -
 2 files changed, 1 insertion(+), 2 deletions(-)

diff --git a/drivers/of/dynamic.c b/drivers/of/dynamic.c
index 59545b8fbf46..0b9cf6d5914c 100644
--- a/drivers/of/dynamic.c
+++ b/drivers/of/dynamic.c
@@ -216,7 +216,7 @@ int of_property_notify(int action, struct device_node *np,
 	return of_reconfig_notify(action, &pr);
 }
 
-void __of_attach_node(struct device_node *np)
+static void __of_attach_node(struct device_node *np)
 {
 	np->child = NULL;
 	np->sibling = np->parent->child;
diff --git a/drivers/of/of_private.h b/drivers/of/of_private.h
index 33f11a5384f3..b1ff70e1fdda 100644
--- a/drivers/of/of_private.h
+++ b/drivers/of/of_private.h
@@ -79,7 +79,6 @@ extern int __of_update_property(struct device_node *np,
 extern void __of_update_property_sysfs(struct device_node *np,
 		struct property *newprop, struct property *oldprop);
 
-extern void __of_attach_node(struct device_node *np);
 extern int __of_attach_node_sysfs(struct device_node *np);
 extern void __of_detach_node(struct device_node *np);
 extern void __of_detach_node_sysfs(struct device_node *np);
-- 
Frank Rowand <frank.rowand@sony.com>

^ permalink raw reply related	[flat|nested] 15+ messages in thread

* [PATCH v4 2/4] of: make __of_attach_node() static
@ 2017-05-02  2:46   ` frowand.list-Re5JQEeQqe8AvxtiuMwx3w
  0 siblings, 0 replies; 15+ messages in thread
From: frowand.list-Re5JQEeQqe8AvxtiuMwx3w @ 2017-05-02  2:46 UTC (permalink / raw)
  To: Rob Herring, stephen.boyd-QSEj5FYQhm4dnm+yROfE0A
  Cc: devicetree-u79uwXL29TY76Z2rM5mHXA, linux-kernel-u79uwXL29TY76Z2rM5mHXA

From: Frank Rowand <frank.rowand-7U/KSKJipcs@public.gmane.org>

__of_attach_node() is not used outside of drivers/of/dynamic.c.  Make
it static and remove it from drivers/of/of_private.h.

Signed-off-by: Frank Rowand <frank.rowand-7U/KSKJipcs@public.gmane.org>
---
 drivers/of/dynamic.c    | 2 +-
 drivers/of/of_private.h | 1 -
 2 files changed, 1 insertion(+), 2 deletions(-)

diff --git a/drivers/of/dynamic.c b/drivers/of/dynamic.c
index 59545b8fbf46..0b9cf6d5914c 100644
--- a/drivers/of/dynamic.c
+++ b/drivers/of/dynamic.c
@@ -216,7 +216,7 @@ int of_property_notify(int action, struct device_node *np,
 	return of_reconfig_notify(action, &pr);
 }
 
-void __of_attach_node(struct device_node *np)
+static void __of_attach_node(struct device_node *np)
 {
 	np->child = NULL;
 	np->sibling = np->parent->child;
diff --git a/drivers/of/of_private.h b/drivers/of/of_private.h
index 33f11a5384f3..b1ff70e1fdda 100644
--- a/drivers/of/of_private.h
+++ b/drivers/of/of_private.h
@@ -79,7 +79,6 @@ extern int __of_update_property(struct device_node *np,
 extern void __of_update_property_sysfs(struct device_node *np,
 		struct property *newprop, struct property *oldprop);
 
-extern void __of_attach_node(struct device_node *np);
 extern int __of_attach_node_sysfs(struct device_node *np);
 extern void __of_detach_node(struct device_node *np);
 extern void __of_detach_node_sysfs(struct device_node *np);
-- 
Frank Rowand <frank.rowand-7U/KSKJipcs@public.gmane.org>

--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply related	[flat|nested] 15+ messages in thread

* [PATCH v4 3/4] of: be consistent in form of file mode
@ 2017-05-02  2:46   ` frowand.list-Re5JQEeQqe8AvxtiuMwx3w
  0 siblings, 0 replies; 15+ messages in thread
From: frowand.list @ 2017-05-02  2:46 UTC (permalink / raw)
  To: Rob Herring, stephen.boyd; +Cc: devicetree, linux-kernel

From: Frank Rowand <frank.rowand@sony.com>

checkpatch whined about using S_IRUGO instead of octal equivalent
when adding phandle sysfs code, so used octal in that patch.
Change other instances of the S_* constants in the same file to
the octal form.

Signed-off-by: Frank Rowand <frank.rowand@sony.com>
---
 drivers/of/base.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/of/base.c b/drivers/of/base.c
index 8a0cf9003cf8..8a7ca2a49ba8 100644
--- a/drivers/of/base.c
+++ b/drivers/of/base.c
@@ -168,7 +168,7 @@ int __of_add_property_sysfs(struct device_node *np, struct property *pp)
 
 	sysfs_bin_attr_init(&pp->attr);
 	pp->attr.attr.name = safe_name(&np->kobj, pp->name);
-	pp->attr.attr.mode = secure ? S_IRUSR : S_IRUGO;
+	pp->attr.attr.mode = secure ? 0400 : 0444;
 	pp->attr.size = secure ? 0 : pp->length;
 	pp->attr.read = of_node_property_read;
 
-- 
Frank Rowand <frank.rowand@sony.com>

^ permalink raw reply related	[flat|nested] 15+ messages in thread

* [PATCH v4 3/4] of: be consistent in form of file mode
@ 2017-05-02  2:46   ` frowand.list-Re5JQEeQqe8AvxtiuMwx3w
  0 siblings, 0 replies; 15+ messages in thread
From: frowand.list-Re5JQEeQqe8AvxtiuMwx3w @ 2017-05-02  2:46 UTC (permalink / raw)
  To: Rob Herring, stephen.boyd-QSEj5FYQhm4dnm+yROfE0A
  Cc: devicetree-u79uwXL29TY76Z2rM5mHXA, linux-kernel-u79uwXL29TY76Z2rM5mHXA

From: Frank Rowand <frank.rowand-7U/KSKJipcs@public.gmane.org>

checkpatch whined about using S_IRUGO instead of octal equivalent
when adding phandle sysfs code, so used octal in that patch.
Change other instances of the S_* constants in the same file to
the octal form.

Signed-off-by: Frank Rowand <frank.rowand-7U/KSKJipcs@public.gmane.org>
---
 drivers/of/base.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/of/base.c b/drivers/of/base.c
index 8a0cf9003cf8..8a7ca2a49ba8 100644
--- a/drivers/of/base.c
+++ b/drivers/of/base.c
@@ -168,7 +168,7 @@ int __of_add_property_sysfs(struct device_node *np, struct property *pp)
 
 	sysfs_bin_attr_init(&pp->attr);
 	pp->attr.attr.name = safe_name(&np->kobj, pp->name);
-	pp->attr.attr.mode = secure ? S_IRUSR : S_IRUGO;
+	pp->attr.attr.mode = secure ? 0400 : 0444;
 	pp->attr.size = secure ? 0 : pp->length;
 	pp->attr.read = of_node_property_read;
 
-- 
Frank Rowand <frank.rowand-7U/KSKJipcs@public.gmane.org>

--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply related	[flat|nested] 15+ messages in thread

* [PATCH v4 4/4] of: detect invalid phandle in overlay
  2017-05-02  2:46 ` frowand.list-Re5JQEeQqe8AvxtiuMwx3w
                   ` (3 preceding siblings ...)
  (?)
@ 2017-05-02  2:46 ` frowand.list
  -1 siblings, 0 replies; 15+ messages in thread
From: frowand.list @ 2017-05-02  2:46 UTC (permalink / raw)
  To: Rob Herring, stephen.boyd; +Cc: devicetree, linux-kernel

From: Frank Rowand <frank.rowand@sony.com>

Overlays are not allowed to modify phandle values of previously existing
nodes because there is no information available to allow fixup up
properties that use the previously existing phandle.

Signed-off-by: Frank Rowand <frank.rowand@sony.com>
---
 drivers/of/overlay.c | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/drivers/of/overlay.c b/drivers/of/overlay.c
index ca0b85f5deb1..20ab49d2f7a4 100644
--- a/drivers/of/overlay.c
+++ b/drivers/of/overlay.c
@@ -130,6 +130,10 @@ static int of_overlay_apply_single_device_node(struct of_overlay *ov,
 	/* NOTE: Multiple mods of created nodes not supported */
 	tchild = of_get_child_by_name(target, cname);
 	if (tchild != NULL) {
+		/* new overlay phandle value conflicts with existing value */
+		if (child->phandle)
+			return -EINVAL;
+
 		/* apply overlay recursively */
 		ret = of_overlay_apply_one(ov, tchild, child);
 		of_node_put(tchild);
-- 
Frank Rowand <frank.rowand@sony.com>

^ permalink raw reply related	[flat|nested] 15+ messages in thread

* Re: [PATCH v4 1/4] of: remove *phandle properties from expanded device tree
@ 2017-05-15 22:23     ` Rob Herring
  0 siblings, 0 replies; 15+ messages in thread
From: Rob Herring @ 2017-05-15 22:23 UTC (permalink / raw)
  To: Frank Rowand; +Cc: Stephen Boyd, devicetree, linux-kernel

On Mon, May 1, 2017 at 9:46 PM,  <frowand.list@gmail.com> wrote:
> From: Frank Rowand <frank.rowand@sony.com>
>
> Remove "phandle", "linux,phandle", and "ibm,phandle" properties from
> the internal device tree.  The phandle will still be in the struct
> device_node phandle field.
>
> This is to resolve the issue found by Stephen Boyd [1] when he changed
> the type of struct property.value from void * to const void *.  As
> a result of the type change, the overlay code had compile errors
> where the resolver updates phandle values.
>
>   [1] http://lkml.iu.edu/hypermail/linux/kernel/1702.1/04160.html
>
> - Add sysfs infrastructure to report np->phandle, as if it was a property.
> - Do not create "phandle" "ibm,phandle", and "linux,phandle" properties
>   in the expanded device tree.
> - Remove phandle properties in of_attach_node(), for nodes dynamically
>   attached to the live tree.  Add the phandle sysfs entry for these nodes.
> - When creating an overlay changeset, duplicate the node phandle in
>   __of_node_dup().
> - Remove no longer needed checks to exclude "phandle" and "linux,phandle"
>   properties in several locations.
> - A side effect of these changes is that the obsolete "linux,phandle" and
>   "ibm,phandle" properties will no longer appear in /proc/device-tree (they
>   will appear as "phandle").
>
> Signed-off-by: Frank Rowand <frank.rowand@sony.com>
> ---
>  drivers/of/base.c       | 48 ++++++++++++++++++++++++++++++++++++++++---
>  drivers/of/dynamic.c    | 54 +++++++++++++++++++++++++++++++++++++------------
>  drivers/of/fdt.c        | 40 +++++++++++++++++++++---------------
>  drivers/of/of_private.h |  1 +
>  drivers/of/overlay.c    |  4 +---
>  drivers/of/resolver.c   | 23 +--------------------
>  include/linux/of.h      |  1 +
>  7 files changed, 114 insertions(+), 57 deletions(-)
>
> diff --git a/drivers/of/base.c b/drivers/of/base.c
> index d7c4629a3a2d..8a0cf9003cf8 100644
> --- a/drivers/of/base.c
> +++ b/drivers/of/base.c
> @@ -116,6 +116,19 @@ static ssize_t of_node_property_read(struct file *filp, struct kobject *kobj,
>         return memory_read_from_buffer(buf, count, &offset, pp->value, pp->length);
>  }
>
> +static ssize_t of_node_phandle_read(struct file *filp, struct kobject *kobj,
> +                               struct bin_attribute *bin_attr, char *buf,
> +                               loff_t offset, size_t count)
> +{
> +       phandle phandle;
> +       struct device_node *np;
> +
> +       np = container_of(bin_attr, struct device_node, attr_phandle);
> +       phandle = cpu_to_be32(np->phandle);
> +       return memory_read_from_buffer(buf, count, &offset, &phandle,
> +                                      sizeof(phandle));
> +}
> +
>  /* always return newly allocated name, caller must free after use */
>  static const char *safe_name(struct kobject *kobj, const char *orig_name)
>  {
> @@ -164,6 +177,35 @@ int __of_add_property_sysfs(struct device_node *np, struct property *pp)
>         return rc;
>  }
>
> +/*
> + * In the imported device tree (fdt), phandle is a property.  In the
> + * internal data structure it is instead stored in the struct device_node.
> + * Make phandle visible in sysfs as if it was a property.
> + */
> +int __of_add_phandle_sysfs(struct device_node *np)
> +{
> +       int rc;
> +
> +       if (!IS_ENABLED(CONFIG_SYSFS))
> +               return 0;
> +
> +       if (!of_kset || !of_node_is_attached(np))
> +               return 0;
> +
> +       if (!np->phandle || np->phandle == 0xffffffff)
> +               return 0;
> +
> +       sysfs_bin_attr_init(&np->attr_phandle);
> +       np->attr_phandle.attr.name = "phandle";
> +       np->attr_phandle.attr.mode = 0444;
> +       np->attr_phandle.size = sizeof(np->phandle);
> +       np->attr_phandle.read = of_node_phandle_read;
> +
> +       rc = sysfs_create_bin_file(&np->kobj, &np->attr_phandle);
> +       WARN(rc, "error adding attribute phandle to node %s\n", np->full_name);
> +       return rc;
> +}
> +
>  int __of_attach_node_sysfs(struct device_node *np)
>  {
>         const char *name;
> @@ -193,6 +235,8 @@ int __of_attach_node_sysfs(struct device_node *np)
>         if (rc)
>                 return rc;
>
> +       __of_add_phandle_sysfs(np);
> +
>         for_each_property_of_node(np, pp)
>                 __of_add_property_sysfs(np, pp);
>
> @@ -2097,9 +2141,7 @@ void of_alias_scan(void * (*dt_alloc)(u64 size, u64 align))
>                 int id, len;
>
>                 /* Skip those we do not want to proceed */
> -               if (!strcmp(pp->name, "name") ||
> -                   !strcmp(pp->name, "phandle") ||
> -                   !strcmp(pp->name, "linux,phandle"))
> +               if (!strcmp(pp->name, "name"))
>                         continue;
>
>                 np = of_find_node_by_path(pp->value);
> diff --git a/drivers/of/dynamic.c b/drivers/of/dynamic.c
> index 888fdbc09992..59545b8fbf46 100644
> --- a/drivers/of/dynamic.c
> +++ b/drivers/of/dynamic.c
> @@ -218,19 +218,6 @@ int of_property_notify(int action, struct device_node *np,
>
>  void __of_attach_node(struct device_node *np)
>  {
> -       const __be32 *phandle;
> -       int sz;
> -
> -       np->name = __of_get_property(np, "name", NULL) ? : "<NULL>";
> -       np->type = __of_get_property(np, "device_type", NULL) ? : "<NULL>";
> -
> -       phandle = __of_get_property(np, "phandle", &sz);
> -       if (!phandle)
> -               phandle = __of_get_property(np, "linux,phandle", &sz);
> -       if (IS_ENABLED(CONFIG_PPC_PSERIES) && !phandle)
> -               phandle = __of_get_property(np, "ibm,phandle", &sz);
> -       np->phandle = (phandle && (sz >= 4)) ? be32_to_cpup(phandle) : 0;
> -
>         np->child = NULL;
>         np->sibling = np->parent->child;
>         np->parent->child = np;
> @@ -243,11 +230,47 @@ void __of_attach_node(struct device_node *np)
>  int of_attach_node(struct device_node *np)
>  {
>         struct of_reconfig_data rd;
> +       struct property *prev;
> +       struct property *prop;
> +       struct property *save_next;
>         unsigned long flags;
> +       const __be32 *phandle;
> +       int sz;
>
>         memset(&rd, 0, sizeof(rd));
>         rd.dn = np;
>
> +       np->name = __of_get_property(np, "name", NULL) ? : "<NULL>";
> +       np->type = __of_get_property(np, "device_type", NULL) ? : "<NULL>";

Why can't we just store NULL here? I know you're just moving this
existing code, but now we have it twice. I assume there was some
reason, so at least a comment why would be good. (I'm guessing it's
because strcmp won't take a NULL).

> +
> +       phandle = __of_get_property(np, "phandle", &sz);
> +       if (!phandle)
> +               phandle = __of_get_property(np, "linux,phandle", &sz);
> +       if (IS_ENABLED(CONFIG_PPC_PSERIES) && !phandle)
> +               phandle = __of_get_property(np, "ibm,phandle", &sz);
> +       np->phandle = (phandle && (sz >= 4)) ? be32_to_cpup(phandle) : 0;
> +
> +       /* remove phandle properties from node */
> +       prev = NULL;
> +       for (prop = np->properties; prop != NULL; ) {
> +               save_next = prop->next;
> +               if (!strcmp(prop->name, "phandle") ||
> +                   !strcmp(prop->name, "ibm,phandle") ||
> +                   !strcmp(prop->name, "linux,phandle")) {
> +                       if (prev)
> +                               prev->next = prop->next;
> +                       else
> +                               np->properties = prop->next;
> +                       prop->next = np->deadprops;
> +                       np->deadprops = prop;
> +               } else {
> +                       prev = prop;
> +               }
> +               prop = save_next;
> +       }
> +
> +       __of_add_phandle_sysfs(np);
> +
>         mutex_lock(&of_mutex);
>         raw_spin_lock_irqsave(&devtree_lock, flags);
>         __of_attach_node(np);
> @@ -429,6 +452,7 @@ struct device_node *__of_node_dup(const struct device_node *np, const char *fmt,
>         /* Iterate over and duplicate all properties */
>         if (np) {
>                 struct property *pp, *new_pp;
> +               node->phandle = np->phandle;
>                 for_each_property_of_node(np, pp) {
>                         new_pp = __of_prop_dup(pp, GFP_KERNEL);
>                         if (!new_pp)
> @@ -441,6 +465,10 @@ struct device_node *__of_node_dup(const struct device_node *np, const char *fmt,
>                         }
>                 }
>         }
> +
> +       node->name = __of_get_property(node, "name", NULL) ? : "<NULL>";
> +       node->type = __of_get_property(node, "device_type", NULL) ? : "<NULL>";
> +
>         return node;
>
>   err_prop:
> diff --git a/drivers/of/fdt.c b/drivers/of/fdt.c
> index e5ce4b59e162..270f31b0c259 100644
> --- a/drivers/of/fdt.c
> +++ b/drivers/of/fdt.c
> @@ -181,6 +181,8 @@ static void populate_properties(const void *blob,
>                 const __be32 *val;
>                 const char *pname;
>                 u32 sz;
> +               int prop_is_phandle = 0;
> +               int prop_is_ibm_phandle = 0;

Can be bool.

>
>                 val = fdt_getprop_by_offset(blob, cur, &pname, &sz);
>                 if (!val) {
> @@ -196,11 +198,6 @@ static void populate_properties(const void *blob,
>                 if (!strcmp(pname, "name"))
>                         has_name = true;
>
> -               pp = unflatten_dt_alloc(mem, sizeof(struct property),
> -                                       __alignof__(struct property));
> -               if (dryrun)
> -                       continue;
> -
>                 /* We accept flattened tree phandles either in
>                  * ePAPR-style "phandle" properties, or the
>                  * legacy "linux,phandle" properties.  If both
> @@ -208,23 +205,34 @@ static void populate_properties(const void *blob,
>                  * will get weird. Don't do that.
>                  */
>                 if (!strcmp(pname, "phandle") ||
> -                   !strcmp(pname, "linux,phandle")) {
> -                       if (!np->phandle)
> -                               np->phandle = be32_to_cpup(val);
> -               }
> +                   !strcmp(pname, "linux,phandle"))
> +                       prop_is_phandle = 1;
>
>                 /* And we process the "ibm,phandle" property
>                  * used in pSeries dynamic device tree
>                  * stuff
>                  */
> -               if (!strcmp(pname, "ibm,phandle"))
> -                       np->phandle = be32_to_cpup(val);
> +               if (!strcmp(pname, "ibm,phandle")) {
> +                       prop_is_phandle = 1;
> +                       prop_is_ibm_phandle = 1;
> +               }
> +
> +               if (!prop_is_phandle)
> +                       pp = unflatten_dt_alloc(mem, sizeof(struct property),
> +                                               __alignof__(struct property));
>
> -               pp->name   = (char *)pname;
> -               pp->length = sz;
> -               pp->value  = (__be32 *)val;
> -               *pprev     = pp;
> -               pprev      = &pp->next;
> +               if (dryrun)
> +                       continue;
> +
> +               if (!prop_is_phandle) {
> +                       pp->name   = (char *)pname;
> +                       pp->length = sz;
> +                       pp->value  = (__be32 *)val;
> +                       *pprev     = pp;
> +                       pprev      = &pp->next;
> +               } else if (prop_is_ibm_phandle || !np->phandle) {

This logic is a bit strange. I think it would be a bit better if we
can keep all the phandle code together and end with a continue, then
have the property handling code at the end of the loop.

> +                       np->phandle = be32_to_cpup(val);
> +               }
>         }
>
>         /* With version 0x10 we may not have the name property,
> diff --git a/drivers/of/of_private.h b/drivers/of/of_private.h
> index 18bbb4517e25..33f11a5384f3 100644
> --- a/drivers/of/of_private.h
> +++ b/drivers/of/of_private.h
> @@ -47,6 +47,7 @@ extern int of_property_notify(int action, struct device_node *np,
>  extern void of_node_release(struct kobject *kobj);
>  extern int __of_changeset_apply(struct of_changeset *ocs);
>  extern int __of_changeset_revert(struct of_changeset *ocs);
> +extern int __of_add_phandle_sysfs(struct device_node *np);
>  #else /* CONFIG_OF_DYNAMIC */
>  static inline int of_property_notify(int action, struct device_node *np,
>                                      struct property *prop, struct property *old_prop)
> diff --git a/drivers/of/overlay.c b/drivers/of/overlay.c
> index 7827786718d8..ca0b85f5deb1 100644
> --- a/drivers/of/overlay.c
> +++ b/drivers/of/overlay.c
> @@ -101,9 +101,7 @@ static int of_overlay_apply_single_property(struct of_overlay *ov,
>         tprop = of_find_property(target, prop->name, NULL);
>
>         /* special properties are not meant to be updated (silent NOP) */
> -       if (of_prop_cmp(prop->name, "name") == 0 ||
> -           of_prop_cmp(prop->name, "phandle") == 0 ||
> -           of_prop_cmp(prop->name, "linux,phandle") == 0)
> +       if (!of_prop_cmp(prop->name, "name"))
>                 return 0;
>
>         propn = __of_prop_dup(prop, GFP_KERNEL);
> diff --git a/drivers/of/resolver.c b/drivers/of/resolver.c
> index 7ae9863cb0a4..624cbaeae0a4 100644
> --- a/drivers/of/resolver.c
> +++ b/drivers/of/resolver.c
> @@ -71,30 +71,11 @@ static void adjust_overlay_phandles(struct device_node *overlay,
>                 int phandle_delta)
>  {
>         struct device_node *child;
> -       struct property *prop;
> -       phandle phandle;
>
>         /* adjust node's phandle in node */
>         if (overlay->phandle != 0 && overlay->phandle != OF_PHANDLE_ILLEGAL)
>                 overlay->phandle += phandle_delta;
>
> -       /* copy adjusted phandle into *phandle properties */
> -       for_each_property_of_node(overlay, prop) {
> -
> -               if (of_prop_cmp(prop->name, "phandle") &&
> -                   of_prop_cmp(prop->name, "linux,phandle"))
> -                       continue;
> -
> -               if (prop->length < 4)
> -                       continue;
> -
> -               phandle = be32_to_cpup(prop->value);
> -               if (phandle == OF_PHANDLE_ILLEGAL)
> -                       continue;
> -
> -               *(uint32_t *)prop->value = cpu_to_be32(overlay->phandle);
> -       }
> -
>         for_each_child_of_node(overlay, child)
>                 adjust_overlay_phandles(child, phandle_delta);
>  }
> @@ -197,9 +178,7 @@ static int adjust_local_phandle_references(struct device_node *local_fixups,
>         for_each_property_of_node(local_fixups, prop_fix) {
>
>                 /* skip properties added automatically */
> -               if (!of_prop_cmp(prop_fix->name, "name") ||
> -                   !of_prop_cmp(prop_fix->name, "phandle") ||
> -                   !of_prop_cmp(prop_fix->name, "linux,phandle"))
> +               if (!of_prop_cmp(prop_fix->name, "name"))
>                         continue;
>
>                 if ((prop_fix->length % 4) != 0 || prop_fix->length == 0)
> diff --git a/include/linux/of.h b/include/linux/of.h
> index 21e6323de0f3..4e86e05853f3 100644
> --- a/include/linux/of.h
> +++ b/include/linux/of.h
> @@ -61,6 +61,7 @@ struct device_node {
>         struct  kobject kobj;
>         unsigned long _flags;
>         void    *data;
> +       struct bin_attribute attr_phandle;
>  #if defined(CONFIG_SPARC)
>         const char *path_component_name;
>         unsigned int unique_id;
> --
> Frank Rowand <frank.rowand@sony.com>
>

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [PATCH v4 1/4] of: remove *phandle properties from expanded device tree
@ 2017-05-15 22:23     ` Rob Herring
  0 siblings, 0 replies; 15+ messages in thread
From: Rob Herring @ 2017-05-15 22:23 UTC (permalink / raw)
  To: Frank Rowand
  Cc: Stephen Boyd, devicetree-u79uwXL29TY76Z2rM5mHXA,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA

On Mon, May 1, 2017 at 9:46 PM,  <frowand.list-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> wrote:
> From: Frank Rowand <frank.rowand-7U/KSKJipcs@public.gmane.org>
>
> Remove "phandle", "linux,phandle", and "ibm,phandle" properties from
> the internal device tree.  The phandle will still be in the struct
> device_node phandle field.
>
> This is to resolve the issue found by Stephen Boyd [1] when he changed
> the type of struct property.value from void * to const void *.  As
> a result of the type change, the overlay code had compile errors
> where the resolver updates phandle values.
>
>   [1] http://lkml.iu.edu/hypermail/linux/kernel/1702.1/04160.html
>
> - Add sysfs infrastructure to report np->phandle, as if it was a property.
> - Do not create "phandle" "ibm,phandle", and "linux,phandle" properties
>   in the expanded device tree.
> - Remove phandle properties in of_attach_node(), for nodes dynamically
>   attached to the live tree.  Add the phandle sysfs entry for these nodes.
> - When creating an overlay changeset, duplicate the node phandle in
>   __of_node_dup().
> - Remove no longer needed checks to exclude "phandle" and "linux,phandle"
>   properties in several locations.
> - A side effect of these changes is that the obsolete "linux,phandle" and
>   "ibm,phandle" properties will no longer appear in /proc/device-tree (they
>   will appear as "phandle").
>
> Signed-off-by: Frank Rowand <frank.rowand-7U/KSKJipcs@public.gmane.org>
> ---
>  drivers/of/base.c       | 48 ++++++++++++++++++++++++++++++++++++++++---
>  drivers/of/dynamic.c    | 54 +++++++++++++++++++++++++++++++++++++------------
>  drivers/of/fdt.c        | 40 +++++++++++++++++++++---------------
>  drivers/of/of_private.h |  1 +
>  drivers/of/overlay.c    |  4 +---
>  drivers/of/resolver.c   | 23 +--------------------
>  include/linux/of.h      |  1 +
>  7 files changed, 114 insertions(+), 57 deletions(-)
>
> diff --git a/drivers/of/base.c b/drivers/of/base.c
> index d7c4629a3a2d..8a0cf9003cf8 100644
> --- a/drivers/of/base.c
> +++ b/drivers/of/base.c
> @@ -116,6 +116,19 @@ static ssize_t of_node_property_read(struct file *filp, struct kobject *kobj,
>         return memory_read_from_buffer(buf, count, &offset, pp->value, pp->length);
>  }
>
> +static ssize_t of_node_phandle_read(struct file *filp, struct kobject *kobj,
> +                               struct bin_attribute *bin_attr, char *buf,
> +                               loff_t offset, size_t count)
> +{
> +       phandle phandle;
> +       struct device_node *np;
> +
> +       np = container_of(bin_attr, struct device_node, attr_phandle);
> +       phandle = cpu_to_be32(np->phandle);
> +       return memory_read_from_buffer(buf, count, &offset, &phandle,
> +                                      sizeof(phandle));
> +}
> +
>  /* always return newly allocated name, caller must free after use */
>  static const char *safe_name(struct kobject *kobj, const char *orig_name)
>  {
> @@ -164,6 +177,35 @@ int __of_add_property_sysfs(struct device_node *np, struct property *pp)
>         return rc;
>  }
>
> +/*
> + * In the imported device tree (fdt), phandle is a property.  In the
> + * internal data structure it is instead stored in the struct device_node.
> + * Make phandle visible in sysfs as if it was a property.
> + */
> +int __of_add_phandle_sysfs(struct device_node *np)
> +{
> +       int rc;
> +
> +       if (!IS_ENABLED(CONFIG_SYSFS))
> +               return 0;
> +
> +       if (!of_kset || !of_node_is_attached(np))
> +               return 0;
> +
> +       if (!np->phandle || np->phandle == 0xffffffff)
> +               return 0;
> +
> +       sysfs_bin_attr_init(&np->attr_phandle);
> +       np->attr_phandle.attr.name = "phandle";
> +       np->attr_phandle.attr.mode = 0444;
> +       np->attr_phandle.size = sizeof(np->phandle);
> +       np->attr_phandle.read = of_node_phandle_read;
> +
> +       rc = sysfs_create_bin_file(&np->kobj, &np->attr_phandle);
> +       WARN(rc, "error adding attribute phandle to node %s\n", np->full_name);
> +       return rc;
> +}
> +
>  int __of_attach_node_sysfs(struct device_node *np)
>  {
>         const char *name;
> @@ -193,6 +235,8 @@ int __of_attach_node_sysfs(struct device_node *np)
>         if (rc)
>                 return rc;
>
> +       __of_add_phandle_sysfs(np);
> +
>         for_each_property_of_node(np, pp)
>                 __of_add_property_sysfs(np, pp);
>
> @@ -2097,9 +2141,7 @@ void of_alias_scan(void * (*dt_alloc)(u64 size, u64 align))
>                 int id, len;
>
>                 /* Skip those we do not want to proceed */
> -               if (!strcmp(pp->name, "name") ||
> -                   !strcmp(pp->name, "phandle") ||
> -                   !strcmp(pp->name, "linux,phandle"))
> +               if (!strcmp(pp->name, "name"))
>                         continue;
>
>                 np = of_find_node_by_path(pp->value);
> diff --git a/drivers/of/dynamic.c b/drivers/of/dynamic.c
> index 888fdbc09992..59545b8fbf46 100644
> --- a/drivers/of/dynamic.c
> +++ b/drivers/of/dynamic.c
> @@ -218,19 +218,6 @@ int of_property_notify(int action, struct device_node *np,
>
>  void __of_attach_node(struct device_node *np)
>  {
> -       const __be32 *phandle;
> -       int sz;
> -
> -       np->name = __of_get_property(np, "name", NULL) ? : "<NULL>";
> -       np->type = __of_get_property(np, "device_type", NULL) ? : "<NULL>";
> -
> -       phandle = __of_get_property(np, "phandle", &sz);
> -       if (!phandle)
> -               phandle = __of_get_property(np, "linux,phandle", &sz);
> -       if (IS_ENABLED(CONFIG_PPC_PSERIES) && !phandle)
> -               phandle = __of_get_property(np, "ibm,phandle", &sz);
> -       np->phandle = (phandle && (sz >= 4)) ? be32_to_cpup(phandle) : 0;
> -
>         np->child = NULL;
>         np->sibling = np->parent->child;
>         np->parent->child = np;
> @@ -243,11 +230,47 @@ void __of_attach_node(struct device_node *np)
>  int of_attach_node(struct device_node *np)
>  {
>         struct of_reconfig_data rd;
> +       struct property *prev;
> +       struct property *prop;
> +       struct property *save_next;
>         unsigned long flags;
> +       const __be32 *phandle;
> +       int sz;
>
>         memset(&rd, 0, sizeof(rd));
>         rd.dn = np;
>
> +       np->name = __of_get_property(np, "name", NULL) ? : "<NULL>";
> +       np->type = __of_get_property(np, "device_type", NULL) ? : "<NULL>";

Why can't we just store NULL here? I know you're just moving this
existing code, but now we have it twice. I assume there was some
reason, so at least a comment why would be good. (I'm guessing it's
because strcmp won't take a NULL).

> +
> +       phandle = __of_get_property(np, "phandle", &sz);
> +       if (!phandle)
> +               phandle = __of_get_property(np, "linux,phandle", &sz);
> +       if (IS_ENABLED(CONFIG_PPC_PSERIES) && !phandle)
> +               phandle = __of_get_property(np, "ibm,phandle", &sz);
> +       np->phandle = (phandle && (sz >= 4)) ? be32_to_cpup(phandle) : 0;
> +
> +       /* remove phandle properties from node */
> +       prev = NULL;
> +       for (prop = np->properties; prop != NULL; ) {
> +               save_next = prop->next;
> +               if (!strcmp(prop->name, "phandle") ||
> +                   !strcmp(prop->name, "ibm,phandle") ||
> +                   !strcmp(prop->name, "linux,phandle")) {
> +                       if (prev)
> +                               prev->next = prop->next;
> +                       else
> +                               np->properties = prop->next;
> +                       prop->next = np->deadprops;
> +                       np->deadprops = prop;
> +               } else {
> +                       prev = prop;
> +               }
> +               prop = save_next;
> +       }
> +
> +       __of_add_phandle_sysfs(np);
> +
>         mutex_lock(&of_mutex);
>         raw_spin_lock_irqsave(&devtree_lock, flags);
>         __of_attach_node(np);
> @@ -429,6 +452,7 @@ struct device_node *__of_node_dup(const struct device_node *np, const char *fmt,
>         /* Iterate over and duplicate all properties */
>         if (np) {
>                 struct property *pp, *new_pp;
> +               node->phandle = np->phandle;
>                 for_each_property_of_node(np, pp) {
>                         new_pp = __of_prop_dup(pp, GFP_KERNEL);
>                         if (!new_pp)
> @@ -441,6 +465,10 @@ struct device_node *__of_node_dup(const struct device_node *np, const char *fmt,
>                         }
>                 }
>         }
> +
> +       node->name = __of_get_property(node, "name", NULL) ? : "<NULL>";
> +       node->type = __of_get_property(node, "device_type", NULL) ? : "<NULL>";
> +
>         return node;
>
>   err_prop:
> diff --git a/drivers/of/fdt.c b/drivers/of/fdt.c
> index e5ce4b59e162..270f31b0c259 100644
> --- a/drivers/of/fdt.c
> +++ b/drivers/of/fdt.c
> @@ -181,6 +181,8 @@ static void populate_properties(const void *blob,
>                 const __be32 *val;
>                 const char *pname;
>                 u32 sz;
> +               int prop_is_phandle = 0;
> +               int prop_is_ibm_phandle = 0;

Can be bool.

>
>                 val = fdt_getprop_by_offset(blob, cur, &pname, &sz);
>                 if (!val) {
> @@ -196,11 +198,6 @@ static void populate_properties(const void *blob,
>                 if (!strcmp(pname, "name"))
>                         has_name = true;
>
> -               pp = unflatten_dt_alloc(mem, sizeof(struct property),
> -                                       __alignof__(struct property));
> -               if (dryrun)
> -                       continue;
> -
>                 /* We accept flattened tree phandles either in
>                  * ePAPR-style "phandle" properties, or the
>                  * legacy "linux,phandle" properties.  If both
> @@ -208,23 +205,34 @@ static void populate_properties(const void *blob,
>                  * will get weird. Don't do that.
>                  */
>                 if (!strcmp(pname, "phandle") ||
> -                   !strcmp(pname, "linux,phandle")) {
> -                       if (!np->phandle)
> -                               np->phandle = be32_to_cpup(val);
> -               }
> +                   !strcmp(pname, "linux,phandle"))
> +                       prop_is_phandle = 1;
>
>                 /* And we process the "ibm,phandle" property
>                  * used in pSeries dynamic device tree
>                  * stuff
>                  */
> -               if (!strcmp(pname, "ibm,phandle"))
> -                       np->phandle = be32_to_cpup(val);
> +               if (!strcmp(pname, "ibm,phandle")) {
> +                       prop_is_phandle = 1;
> +                       prop_is_ibm_phandle = 1;
> +               }
> +
> +               if (!prop_is_phandle)
> +                       pp = unflatten_dt_alloc(mem, sizeof(struct property),
> +                                               __alignof__(struct property));
>
> -               pp->name   = (char *)pname;
> -               pp->length = sz;
> -               pp->value  = (__be32 *)val;
> -               *pprev     = pp;
> -               pprev      = &pp->next;
> +               if (dryrun)
> +                       continue;
> +
> +               if (!prop_is_phandle) {
> +                       pp->name   = (char *)pname;
> +                       pp->length = sz;
> +                       pp->value  = (__be32 *)val;
> +                       *pprev     = pp;
> +                       pprev      = &pp->next;
> +               } else if (prop_is_ibm_phandle || !np->phandle) {

This logic is a bit strange. I think it would be a bit better if we
can keep all the phandle code together and end with a continue, then
have the property handling code at the end of the loop.

> +                       np->phandle = be32_to_cpup(val);
> +               }
>         }
>
>         /* With version 0x10 we may not have the name property,
> diff --git a/drivers/of/of_private.h b/drivers/of/of_private.h
> index 18bbb4517e25..33f11a5384f3 100644
> --- a/drivers/of/of_private.h
> +++ b/drivers/of/of_private.h
> @@ -47,6 +47,7 @@ extern int of_property_notify(int action, struct device_node *np,
>  extern void of_node_release(struct kobject *kobj);
>  extern int __of_changeset_apply(struct of_changeset *ocs);
>  extern int __of_changeset_revert(struct of_changeset *ocs);
> +extern int __of_add_phandle_sysfs(struct device_node *np);
>  #else /* CONFIG_OF_DYNAMIC */
>  static inline int of_property_notify(int action, struct device_node *np,
>                                      struct property *prop, struct property *old_prop)
> diff --git a/drivers/of/overlay.c b/drivers/of/overlay.c
> index 7827786718d8..ca0b85f5deb1 100644
> --- a/drivers/of/overlay.c
> +++ b/drivers/of/overlay.c
> @@ -101,9 +101,7 @@ static int of_overlay_apply_single_property(struct of_overlay *ov,
>         tprop = of_find_property(target, prop->name, NULL);
>
>         /* special properties are not meant to be updated (silent NOP) */
> -       if (of_prop_cmp(prop->name, "name") == 0 ||
> -           of_prop_cmp(prop->name, "phandle") == 0 ||
> -           of_prop_cmp(prop->name, "linux,phandle") == 0)
> +       if (!of_prop_cmp(prop->name, "name"))
>                 return 0;
>
>         propn = __of_prop_dup(prop, GFP_KERNEL);
> diff --git a/drivers/of/resolver.c b/drivers/of/resolver.c
> index 7ae9863cb0a4..624cbaeae0a4 100644
> --- a/drivers/of/resolver.c
> +++ b/drivers/of/resolver.c
> @@ -71,30 +71,11 @@ static void adjust_overlay_phandles(struct device_node *overlay,
>                 int phandle_delta)
>  {
>         struct device_node *child;
> -       struct property *prop;
> -       phandle phandle;
>
>         /* adjust node's phandle in node */
>         if (overlay->phandle != 0 && overlay->phandle != OF_PHANDLE_ILLEGAL)
>                 overlay->phandle += phandle_delta;
>
> -       /* copy adjusted phandle into *phandle properties */
> -       for_each_property_of_node(overlay, prop) {
> -
> -               if (of_prop_cmp(prop->name, "phandle") &&
> -                   of_prop_cmp(prop->name, "linux,phandle"))
> -                       continue;
> -
> -               if (prop->length < 4)
> -                       continue;
> -
> -               phandle = be32_to_cpup(prop->value);
> -               if (phandle == OF_PHANDLE_ILLEGAL)
> -                       continue;
> -
> -               *(uint32_t *)prop->value = cpu_to_be32(overlay->phandle);
> -       }
> -
>         for_each_child_of_node(overlay, child)
>                 adjust_overlay_phandles(child, phandle_delta);
>  }
> @@ -197,9 +178,7 @@ static int adjust_local_phandle_references(struct device_node *local_fixups,
>         for_each_property_of_node(local_fixups, prop_fix) {
>
>                 /* skip properties added automatically */
> -               if (!of_prop_cmp(prop_fix->name, "name") ||
> -                   !of_prop_cmp(prop_fix->name, "phandle") ||
> -                   !of_prop_cmp(prop_fix->name, "linux,phandle"))
> +               if (!of_prop_cmp(prop_fix->name, "name"))
>                         continue;
>
>                 if ((prop_fix->length % 4) != 0 || prop_fix->length == 0)
> diff --git a/include/linux/of.h b/include/linux/of.h
> index 21e6323de0f3..4e86e05853f3 100644
> --- a/include/linux/of.h
> +++ b/include/linux/of.h
> @@ -61,6 +61,7 @@ struct device_node {
>         struct  kobject kobj;
>         unsigned long _flags;
>         void    *data;
> +       struct bin_attribute attr_phandle;
>  #if defined(CONFIG_SPARC)
>         const char *path_component_name;
>         unsigned int unique_id;
> --
> Frank Rowand <frank.rowand-7U/KSKJipcs@public.gmane.org>
>
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [PATCH v4 1/4] of: remove *phandle properties from expanded device tree
@ 2017-06-10  2:35       ` Frank Rowand
  0 siblings, 0 replies; 15+ messages in thread
From: Frank Rowand @ 2017-06-10  2:35 UTC (permalink / raw)
  To: Rob Herring; +Cc: Stephen Boyd, devicetree, linux-kernel

On 05/15/17 15:23, Rob Herring wrote:
> On Mon, May 1, 2017 at 9:46 PM,  <frowand.list@gmail.com> wrote:
>> From: Frank Rowand <frank.rowand@sony.com>
>>
>> Remove "phandle", "linux,phandle", and "ibm,phandle" properties from
>> the internal device tree.  The phandle will still be in the struct
>> device_node phandle field.
>>
>> This is to resolve the issue found by Stephen Boyd [1] when he changed
>> the type of struct property.value from void * to const void *.  As
>> a result of the type change, the overlay code had compile errors
>> where the resolver updates phandle values.
>>
>>   [1] http://lkml.iu.edu/hypermail/linux/kernel/1702.1/04160.html
>>
>> - Add sysfs infrastructure to report np->phandle, as if it was a property.
>> - Do not create "phandle" "ibm,phandle", and "linux,phandle" properties
>>   in the expanded device tree.
>> - Remove phandle properties in of_attach_node(), for nodes dynamically
>>   attached to the live tree.  Add the phandle sysfs entry for these nodes.
>> - When creating an overlay changeset, duplicate the node phandle in
>>   __of_node_dup().
>> - Remove no longer needed checks to exclude "phandle" and "linux,phandle"
>>   properties in several locations.
>> - A side effect of these changes is that the obsolete "linux,phandle" and
>>   "ibm,phandle" properties will no longer appear in /proc/device-tree (they
>>   will appear as "phandle").
>>
>> Signed-off-by: Frank Rowand <frank.rowand@sony.com>
>> ---
>>  drivers/of/base.c       | 48 ++++++++++++++++++++++++++++++++++++++++---
>>  drivers/of/dynamic.c    | 54 +++++++++++++++++++++++++++++++++++++------------
>>  drivers/of/fdt.c        | 40 +++++++++++++++++++++---------------
>>  drivers/of/of_private.h |  1 +
>>  drivers/of/overlay.c    |  4 +---
>>  drivers/of/resolver.c   | 23 +--------------------
>>  include/linux/of.h      |  1 +
>>  7 files changed, 114 insertions(+), 57 deletions(-)
>>
>> diff --git a/drivers/of/base.c b/drivers/of/base.c
>> index d7c4629a3a2d..8a0cf9003cf8 100644
>> --- a/drivers/of/base.c
>> +++ b/drivers/of/base.c
>> @@ -116,6 +116,19 @@ static ssize_t of_node_property_read(struct file *filp, struct kobject *kobj,
>>         return memory_read_from_buffer(buf, count, &offset, pp->value, pp->length);
>>  }
>>
>> +static ssize_t of_node_phandle_read(struct file *filp, struct kobject *kobj,
>> +                               struct bin_attribute *bin_attr, char *buf,
>> +                               loff_t offset, size_t count)
>> +{
>> +       phandle phandle;
>> +       struct device_node *np;
>> +
>> +       np = container_of(bin_attr, struct device_node, attr_phandle);
>> +       phandle = cpu_to_be32(np->phandle);
>> +       return memory_read_from_buffer(buf, count, &offset, &phandle,
>> +                                      sizeof(phandle));
>> +}
>> +
>>  /* always return newly allocated name, caller must free after use */
>>  static const char *safe_name(struct kobject *kobj, const char *orig_name)
>>  {
>> @@ -164,6 +177,35 @@ int __of_add_property_sysfs(struct device_node *np, struct property *pp)
>>         return rc;
>>  }
>>
>> +/*
>> + * In the imported device tree (fdt), phandle is a property.  In the
>> + * internal data structure it is instead stored in the struct device_node.
>> + * Make phandle visible in sysfs as if it was a property.
>> + */
>> +int __of_add_phandle_sysfs(struct device_node *np)
>> +{
>> +       int rc;
>> +
>> +       if (!IS_ENABLED(CONFIG_SYSFS))
>> +               return 0;
>> +
>> +       if (!of_kset || !of_node_is_attached(np))
>> +               return 0;
>> +
>> +       if (!np->phandle || np->phandle == 0xffffffff)
>> +               return 0;
>> +
>> +       sysfs_bin_attr_init(&np->attr_phandle);
>> +       np->attr_phandle.attr.name = "phandle";
>> +       np->attr_phandle.attr.mode = 0444;
>> +       np->attr_phandle.size = sizeof(np->phandle);
>> +       np->attr_phandle.read = of_node_phandle_read;
>> +
>> +       rc = sysfs_create_bin_file(&np->kobj, &np->attr_phandle);
>> +       WARN(rc, "error adding attribute phandle to node %s\n", np->full_name);
>> +       return rc;
>> +}
>> +
>>  int __of_attach_node_sysfs(struct device_node *np)
>>  {
>>         const char *name;
>> @@ -193,6 +235,8 @@ int __of_attach_node_sysfs(struct device_node *np)
>>         if (rc)
>>                 return rc;
>>
>> +       __of_add_phandle_sysfs(np);
>> +
>>         for_each_property_of_node(np, pp)
>>                 __of_add_property_sysfs(np, pp);
>>
>> @@ -2097,9 +2141,7 @@ void of_alias_scan(void * (*dt_alloc)(u64 size, u64 align))
>>                 int id, len;
>>
>>                 /* Skip those we do not want to proceed */
>> -               if (!strcmp(pp->name, "name") ||
>> -                   !strcmp(pp->name, "phandle") ||
>> -                   !strcmp(pp->name, "linux,phandle"))
>> +               if (!strcmp(pp->name, "name"))
>>                         continue;
>>
>>                 np = of_find_node_by_path(pp->value);
>> diff --git a/drivers/of/dynamic.c b/drivers/of/dynamic.c
>> index 888fdbc09992..59545b8fbf46 100644
>> --- a/drivers/of/dynamic.c
>> +++ b/drivers/of/dynamic.c
>> @@ -218,19 +218,6 @@ int of_property_notify(int action, struct device_node *np,
>>
>>  void __of_attach_node(struct device_node *np)
>>  {
>> -       const __be32 *phandle;
>> -       int sz;
>> -
>> -       np->name = __of_get_property(np, "name", NULL) ? : "<NULL>";
>> -       np->type = __of_get_property(np, "device_type", NULL) ? : "<NULL>";
>> -
>> -       phandle = __of_get_property(np, "phandle", &sz);
>> -       if (!phandle)
>> -               phandle = __of_get_property(np, "linux,phandle", &sz);
>> -       if (IS_ENABLED(CONFIG_PPC_PSERIES) && !phandle)
>> -               phandle = __of_get_property(np, "ibm,phandle", &sz);
>> -       np->phandle = (phandle && (sz >= 4)) ? be32_to_cpup(phandle) : 0;
>> -
>>         np->child = NULL;
>>         np->sibling = np->parent->child;
>>         np->parent->child = np;
>> @@ -243,11 +230,47 @@ void __of_attach_node(struct device_node *np)
>>  int of_attach_node(struct device_node *np)
>>  {
>>         struct of_reconfig_data rd;
>> +       struct property *prev;
>> +       struct property *prop;
>> +       struct property *save_next;
>>         unsigned long flags;
>> +       const __be32 *phandle;
>> +       int sz;
>>
>>         memset(&rd, 0, sizeof(rd));
>>         rd.dn = np;
>>
>> +       np->name = __of_get_property(np, "name", NULL) ? : "<NULL>";
>> +       np->type = __of_get_property(np, "device_type", NULL) ? : "<NULL>";
> 
> Why can't we just store NULL here? I know you're just moving this
> existing code, but now we have it twice. I assume there was some
> reason, so at least a comment why would be good. (I'm guessing it's
> because strcmp won't take a NULL).

Comment added.

(Yes, the users of the string pointer are not expecting NULL.)


>> +
>> +       phandle = __of_get_property(np, "phandle", &sz);
>> +       if (!phandle)
>> +               phandle = __of_get_property(np, "linux,phandle", &sz);
>> +       if (IS_ENABLED(CONFIG_PPC_PSERIES) && !phandle)
>> +               phandle = __of_get_property(np, "ibm,phandle", &sz);
>> +       np->phandle = (phandle && (sz >= 4)) ? be32_to_cpup(phandle) : 0;
>> +
>> +       /* remove phandle properties from node */
>> +       prev = NULL;
>> +       for (prop = np->properties; prop != NULL; ) {
>> +               save_next = prop->next;
>> +               if (!strcmp(prop->name, "phandle") ||
>> +                   !strcmp(prop->name, "ibm,phandle") ||
>> +                   !strcmp(prop->name, "linux,phandle")) {
>> +                       if (prev)
>> +                               prev->next = prop->next;
>> +                       else
>> +                               np->properties = prop->next;
>> +                       prop->next = np->deadprops;
>> +                       np->deadprops = prop;
>> +               } else {
>> +                       prev = prop;
>> +               }
>> +               prop = save_next;
>> +       }
>> +
>> +       __of_add_phandle_sysfs(np);
>> +
>>         mutex_lock(&of_mutex);
>>         raw_spin_lock_irqsave(&devtree_lock, flags);
>>         __of_attach_node(np);
>> @@ -429,6 +452,7 @@ struct device_node *__of_node_dup(const struct device_node *np, const char *fmt,
>>         /* Iterate over and duplicate all properties */
>>         if (np) {
>>                 struct property *pp, *new_pp;
>> +               node->phandle = np->phandle;
>>                 for_each_property_of_node(np, pp) {
>>                         new_pp = __of_prop_dup(pp, GFP_KERNEL);
>>                         if (!new_pp)
>> @@ -441,6 +465,10 @@ struct device_node *__of_node_dup(const struct device_node *np, const char *fmt,
>>                         }
>>                 }
>>         }
>> +
>> +       node->name = __of_get_property(node, "name", NULL) ? : "<NULL>";
>> +       node->type = __of_get_property(node, "device_type", NULL) ? : "<NULL>";
>> +
>>         return node;
>>
>>   err_prop:
>> diff --git a/drivers/of/fdt.c b/drivers/of/fdt.c
>> index e5ce4b59e162..270f31b0c259 100644
>> --- a/drivers/of/fdt.c
>> +++ b/drivers/of/fdt.c
>> @@ -181,6 +181,8 @@ static void populate_properties(const void *blob,
>>                 const __be32 *val;
>>                 const char *pname;
>>                 u32 sz;
>> +               int prop_is_phandle = 0;
>> +               int prop_is_ibm_phandle = 0;
> 
> Can be bool.

These two variables eliminated while addressing the next comment.


>>
>>                 val = fdt_getprop_by_offset(blob, cur, &pname, &sz);
>>                 if (!val) {
>> @@ -196,11 +198,6 @@ static void populate_properties(const void *blob,
>>                 if (!strcmp(pname, "name"))
>>                         has_name = true;
>>
>> -               pp = unflatten_dt_alloc(mem, sizeof(struct property),
>> -                                       __alignof__(struct property));
>> -               if (dryrun)
>> -                       continue;
>> -
>>                 /* We accept flattened tree phandles either in
>>                  * ePAPR-style "phandle" properties, or the
>>                  * legacy "linux,phandle" properties.  If both
>> @@ -208,23 +205,34 @@ static void populate_properties(const void *blob,
>>                  * will get weird. Don't do that.
>>                  */
>>                 if (!strcmp(pname, "phandle") ||
>> -                   !strcmp(pname, "linux,phandle")) {
>> -                       if (!np->phandle)
>> -                               np->phandle = be32_to_cpup(val);
>> -               }
>> +                   !strcmp(pname, "linux,phandle"))
>> +                       prop_is_phandle = 1;
>>
>>                 /* And we process the "ibm,phandle" property
>>                  * used in pSeries dynamic device tree
>>                  * stuff
>>                  */
>> -               if (!strcmp(pname, "ibm,phandle"))
>> -                       np->phandle = be32_to_cpup(val);
>> +               if (!strcmp(pname, "ibm,phandle")) {
>> +                       prop_is_phandle = 1;
>> +                       prop_is_ibm_phandle = 1;
>> +               }
>> +
>> +               if (!prop_is_phandle)
>> +                       pp = unflatten_dt_alloc(mem, sizeof(struct property),
>> +                                               __alignof__(struct property));
>>
>> -               pp->name   = (char *)pname;
>> -               pp->length = sz;
>> -               pp->value  = (__be32 *)val;
>> -               *pprev     = pp;
>> -               pprev      = &pp->next;
>> +               if (dryrun)
>> +                       continue;
>> +
>> +               if (!prop_is_phandle) {
>> +                       pp->name   = (char *)pname;
>> +                       pp->length = sz;
>> +                       pp->value  = (__be32 *)val;
>> +                       *pprev     = pp;
>> +                       pprev      = &pp->next;
>> +               } else if (prop_is_ibm_phandle || !np->phandle) {
> 
> This logic is a bit strange. I think it would be a bit better if we
> can keep all the phandle code together and end with a continue, then
> have the property handling code at the end of the loop.

I will do this.  One side effect will be that the value of property
"ibm,phandle" will no longer override the value of properties "phandle"
and "linux,phandle".


>> +                       np->phandle = be32_to_cpup(val);
>> +               }
>>         }
>>
>>         /* With version 0x10 we may not have the name property,
>> diff --git a/drivers/of/of_private.h b/drivers/of/of_private.h
>> index 18bbb4517e25..33f11a5384f3 100644
>> --- a/drivers/of/of_private.h
>> +++ b/drivers/of/of_private.h
>> @@ -47,6 +47,7 @@ extern int of_property_notify(int action, struct device_node *np,
>>  extern void of_node_release(struct kobject *kobj);
>>  extern int __of_changeset_apply(struct of_changeset *ocs);
>>  extern int __of_changeset_revert(struct of_changeset *ocs);
>> +extern int __of_add_phandle_sysfs(struct device_node *np);
>>  #else /* CONFIG_OF_DYNAMIC */
>>  static inline int of_property_notify(int action, struct device_node *np,
>>                                      struct property *prop, struct property *old_prop)
>> diff --git a/drivers/of/overlay.c b/drivers/of/overlay.c
>> index 7827786718d8..ca0b85f5deb1 100644
>> --- a/drivers/of/overlay.c
>> +++ b/drivers/of/overlay.c
>> @@ -101,9 +101,7 @@ static int of_overlay_apply_single_property(struct of_overlay *ov,
>>         tprop = of_find_property(target, prop->name, NULL);
>>
>>         /* special properties are not meant to be updated (silent NOP) */
>> -       if (of_prop_cmp(prop->name, "name") == 0 ||
>> -           of_prop_cmp(prop->name, "phandle") == 0 ||
>> -           of_prop_cmp(prop->name, "linux,phandle") == 0)
>> +       if (!of_prop_cmp(prop->name, "name"))
>>                 return 0;
>>
>>         propn = __of_prop_dup(prop, GFP_KERNEL);
>> diff --git a/drivers/of/resolver.c b/drivers/of/resolver.c
>> index 7ae9863cb0a4..624cbaeae0a4 100644
>> --- a/drivers/of/resolver.c
>> +++ b/drivers/of/resolver.c
>> @@ -71,30 +71,11 @@ static void adjust_overlay_phandles(struct device_node *overlay,
>>                 int phandle_delta)
>>  {
>>         struct device_node *child;
>> -       struct property *prop;
>> -       phandle phandle;
>>
>>         /* adjust node's phandle in node */
>>         if (overlay->phandle != 0 && overlay->phandle != OF_PHANDLE_ILLEGAL)
>>                 overlay->phandle += phandle_delta;
>>
>> -       /* copy adjusted phandle into *phandle properties */
>> -       for_each_property_of_node(overlay, prop) {
>> -
>> -               if (of_prop_cmp(prop->name, "phandle") &&
>> -                   of_prop_cmp(prop->name, "linux,phandle"))
>> -                       continue;
>> -
>> -               if (prop->length < 4)
>> -                       continue;
>> -
>> -               phandle = be32_to_cpup(prop->value);
>> -               if (phandle == OF_PHANDLE_ILLEGAL)
>> -                       continue;
>> -
>> -               *(uint32_t *)prop->value = cpu_to_be32(overlay->phandle);
>> -       }
>> -
>>         for_each_child_of_node(overlay, child)
>>                 adjust_overlay_phandles(child, phandle_delta);
>>  }
>> @@ -197,9 +178,7 @@ static int adjust_local_phandle_references(struct device_node *local_fixups,
>>         for_each_property_of_node(local_fixups, prop_fix) {
>>
>>                 /* skip properties added automatically */
>> -               if (!of_prop_cmp(prop_fix->name, "name") ||
>> -                   !of_prop_cmp(prop_fix->name, "phandle") ||
>> -                   !of_prop_cmp(prop_fix->name, "linux,phandle"))
>> +               if (!of_prop_cmp(prop_fix->name, "name"))
>>                         continue;
>>
>>                 if ((prop_fix->length % 4) != 0 || prop_fix->length == 0)
>> diff --git a/include/linux/of.h b/include/linux/of.h
>> index 21e6323de0f3..4e86e05853f3 100644
>> --- a/include/linux/of.h
>> +++ b/include/linux/of.h
>> @@ -61,6 +61,7 @@ struct device_node {
>>         struct  kobject kobj;
>>         unsigned long _flags;
>>         void    *data;
>> +       struct bin_attribute attr_phandle;
>>  #if defined(CONFIG_SPARC)
>>         const char *path_component_name;
>>         unsigned int unique_id;
>> --
>> Frank Rowand <frank.rowand@sony.com>

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [PATCH v4 1/4] of: remove *phandle properties from expanded device tree
@ 2017-06-10  2:35       ` Frank Rowand
  0 siblings, 0 replies; 15+ messages in thread
From: Frank Rowand @ 2017-06-10  2:35 UTC (permalink / raw)
  To: Rob Herring
  Cc: Stephen Boyd, devicetree-u79uwXL29TY76Z2rM5mHXA,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA

On 05/15/17 15:23, Rob Herring wrote:
> On Mon, May 1, 2017 at 9:46 PM,  <frowand.list-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> wrote:
>> From: Frank Rowand <frank.rowand-7U/KSKJipcs@public.gmane.org>
>>
>> Remove "phandle", "linux,phandle", and "ibm,phandle" properties from
>> the internal device tree.  The phandle will still be in the struct
>> device_node phandle field.
>>
>> This is to resolve the issue found by Stephen Boyd [1] when he changed
>> the type of struct property.value from void * to const void *.  As
>> a result of the type change, the overlay code had compile errors
>> where the resolver updates phandle values.
>>
>>   [1] http://lkml.iu.edu/hypermail/linux/kernel/1702.1/04160.html
>>
>> - Add sysfs infrastructure to report np->phandle, as if it was a property.
>> - Do not create "phandle" "ibm,phandle", and "linux,phandle" properties
>>   in the expanded device tree.
>> - Remove phandle properties in of_attach_node(), for nodes dynamically
>>   attached to the live tree.  Add the phandle sysfs entry for these nodes.
>> - When creating an overlay changeset, duplicate the node phandle in
>>   __of_node_dup().
>> - Remove no longer needed checks to exclude "phandle" and "linux,phandle"
>>   properties in several locations.
>> - A side effect of these changes is that the obsolete "linux,phandle" and
>>   "ibm,phandle" properties will no longer appear in /proc/device-tree (they
>>   will appear as "phandle").
>>
>> Signed-off-by: Frank Rowand <frank.rowand-7U/KSKJipcs@public.gmane.org>
>> ---
>>  drivers/of/base.c       | 48 ++++++++++++++++++++++++++++++++++++++++---
>>  drivers/of/dynamic.c    | 54 +++++++++++++++++++++++++++++++++++++------------
>>  drivers/of/fdt.c        | 40 +++++++++++++++++++++---------------
>>  drivers/of/of_private.h |  1 +
>>  drivers/of/overlay.c    |  4 +---
>>  drivers/of/resolver.c   | 23 +--------------------
>>  include/linux/of.h      |  1 +
>>  7 files changed, 114 insertions(+), 57 deletions(-)
>>
>> diff --git a/drivers/of/base.c b/drivers/of/base.c
>> index d7c4629a3a2d..8a0cf9003cf8 100644
>> --- a/drivers/of/base.c
>> +++ b/drivers/of/base.c
>> @@ -116,6 +116,19 @@ static ssize_t of_node_property_read(struct file *filp, struct kobject *kobj,
>>         return memory_read_from_buffer(buf, count, &offset, pp->value, pp->length);
>>  }
>>
>> +static ssize_t of_node_phandle_read(struct file *filp, struct kobject *kobj,
>> +                               struct bin_attribute *bin_attr, char *buf,
>> +                               loff_t offset, size_t count)
>> +{
>> +       phandle phandle;
>> +       struct device_node *np;
>> +
>> +       np = container_of(bin_attr, struct device_node, attr_phandle);
>> +       phandle = cpu_to_be32(np->phandle);
>> +       return memory_read_from_buffer(buf, count, &offset, &phandle,
>> +                                      sizeof(phandle));
>> +}
>> +
>>  /* always return newly allocated name, caller must free after use */
>>  static const char *safe_name(struct kobject *kobj, const char *orig_name)
>>  {
>> @@ -164,6 +177,35 @@ int __of_add_property_sysfs(struct device_node *np, struct property *pp)
>>         return rc;
>>  }
>>
>> +/*
>> + * In the imported device tree (fdt), phandle is a property.  In the
>> + * internal data structure it is instead stored in the struct device_node.
>> + * Make phandle visible in sysfs as if it was a property.
>> + */
>> +int __of_add_phandle_sysfs(struct device_node *np)
>> +{
>> +       int rc;
>> +
>> +       if (!IS_ENABLED(CONFIG_SYSFS))
>> +               return 0;
>> +
>> +       if (!of_kset || !of_node_is_attached(np))
>> +               return 0;
>> +
>> +       if (!np->phandle || np->phandle == 0xffffffff)
>> +               return 0;
>> +
>> +       sysfs_bin_attr_init(&np->attr_phandle);
>> +       np->attr_phandle.attr.name = "phandle";
>> +       np->attr_phandle.attr.mode = 0444;
>> +       np->attr_phandle.size = sizeof(np->phandle);
>> +       np->attr_phandle.read = of_node_phandle_read;
>> +
>> +       rc = sysfs_create_bin_file(&np->kobj, &np->attr_phandle);
>> +       WARN(rc, "error adding attribute phandle to node %s\n", np->full_name);
>> +       return rc;
>> +}
>> +
>>  int __of_attach_node_sysfs(struct device_node *np)
>>  {
>>         const char *name;
>> @@ -193,6 +235,8 @@ int __of_attach_node_sysfs(struct device_node *np)
>>         if (rc)
>>                 return rc;
>>
>> +       __of_add_phandle_sysfs(np);
>> +
>>         for_each_property_of_node(np, pp)
>>                 __of_add_property_sysfs(np, pp);
>>
>> @@ -2097,9 +2141,7 @@ void of_alias_scan(void * (*dt_alloc)(u64 size, u64 align))
>>                 int id, len;
>>
>>                 /* Skip those we do not want to proceed */
>> -               if (!strcmp(pp->name, "name") ||
>> -                   !strcmp(pp->name, "phandle") ||
>> -                   !strcmp(pp->name, "linux,phandle"))
>> +               if (!strcmp(pp->name, "name"))
>>                         continue;
>>
>>                 np = of_find_node_by_path(pp->value);
>> diff --git a/drivers/of/dynamic.c b/drivers/of/dynamic.c
>> index 888fdbc09992..59545b8fbf46 100644
>> --- a/drivers/of/dynamic.c
>> +++ b/drivers/of/dynamic.c
>> @@ -218,19 +218,6 @@ int of_property_notify(int action, struct device_node *np,
>>
>>  void __of_attach_node(struct device_node *np)
>>  {
>> -       const __be32 *phandle;
>> -       int sz;
>> -
>> -       np->name = __of_get_property(np, "name", NULL) ? : "<NULL>";
>> -       np->type = __of_get_property(np, "device_type", NULL) ? : "<NULL>";
>> -
>> -       phandle = __of_get_property(np, "phandle", &sz);
>> -       if (!phandle)
>> -               phandle = __of_get_property(np, "linux,phandle", &sz);
>> -       if (IS_ENABLED(CONFIG_PPC_PSERIES) && !phandle)
>> -               phandle = __of_get_property(np, "ibm,phandle", &sz);
>> -       np->phandle = (phandle && (sz >= 4)) ? be32_to_cpup(phandle) : 0;
>> -
>>         np->child = NULL;
>>         np->sibling = np->parent->child;
>>         np->parent->child = np;
>> @@ -243,11 +230,47 @@ void __of_attach_node(struct device_node *np)
>>  int of_attach_node(struct device_node *np)
>>  {
>>         struct of_reconfig_data rd;
>> +       struct property *prev;
>> +       struct property *prop;
>> +       struct property *save_next;
>>         unsigned long flags;
>> +       const __be32 *phandle;
>> +       int sz;
>>
>>         memset(&rd, 0, sizeof(rd));
>>         rd.dn = np;
>>
>> +       np->name = __of_get_property(np, "name", NULL) ? : "<NULL>";
>> +       np->type = __of_get_property(np, "device_type", NULL) ? : "<NULL>";
> 
> Why can't we just store NULL here? I know you're just moving this
> existing code, but now we have it twice. I assume there was some
> reason, so at least a comment why would be good. (I'm guessing it's
> because strcmp won't take a NULL).

Comment added.

(Yes, the users of the string pointer are not expecting NULL.)


>> +
>> +       phandle = __of_get_property(np, "phandle", &sz);
>> +       if (!phandle)
>> +               phandle = __of_get_property(np, "linux,phandle", &sz);
>> +       if (IS_ENABLED(CONFIG_PPC_PSERIES) && !phandle)
>> +               phandle = __of_get_property(np, "ibm,phandle", &sz);
>> +       np->phandle = (phandle && (sz >= 4)) ? be32_to_cpup(phandle) : 0;
>> +
>> +       /* remove phandle properties from node */
>> +       prev = NULL;
>> +       for (prop = np->properties; prop != NULL; ) {
>> +               save_next = prop->next;
>> +               if (!strcmp(prop->name, "phandle") ||
>> +                   !strcmp(prop->name, "ibm,phandle") ||
>> +                   !strcmp(prop->name, "linux,phandle")) {
>> +                       if (prev)
>> +                               prev->next = prop->next;
>> +                       else
>> +                               np->properties = prop->next;
>> +                       prop->next = np->deadprops;
>> +                       np->deadprops = prop;
>> +               } else {
>> +                       prev = prop;
>> +               }
>> +               prop = save_next;
>> +       }
>> +
>> +       __of_add_phandle_sysfs(np);
>> +
>>         mutex_lock(&of_mutex);
>>         raw_spin_lock_irqsave(&devtree_lock, flags);
>>         __of_attach_node(np);
>> @@ -429,6 +452,7 @@ struct device_node *__of_node_dup(const struct device_node *np, const char *fmt,
>>         /* Iterate over and duplicate all properties */
>>         if (np) {
>>                 struct property *pp, *new_pp;
>> +               node->phandle = np->phandle;
>>                 for_each_property_of_node(np, pp) {
>>                         new_pp = __of_prop_dup(pp, GFP_KERNEL);
>>                         if (!new_pp)
>> @@ -441,6 +465,10 @@ struct device_node *__of_node_dup(const struct device_node *np, const char *fmt,
>>                         }
>>                 }
>>         }
>> +
>> +       node->name = __of_get_property(node, "name", NULL) ? : "<NULL>";
>> +       node->type = __of_get_property(node, "device_type", NULL) ? : "<NULL>";
>> +
>>         return node;
>>
>>   err_prop:
>> diff --git a/drivers/of/fdt.c b/drivers/of/fdt.c
>> index e5ce4b59e162..270f31b0c259 100644
>> --- a/drivers/of/fdt.c
>> +++ b/drivers/of/fdt.c
>> @@ -181,6 +181,8 @@ static void populate_properties(const void *blob,
>>                 const __be32 *val;
>>                 const char *pname;
>>                 u32 sz;
>> +               int prop_is_phandle = 0;
>> +               int prop_is_ibm_phandle = 0;
> 
> Can be bool.

These two variables eliminated while addressing the next comment.


>>
>>                 val = fdt_getprop_by_offset(blob, cur, &pname, &sz);
>>                 if (!val) {
>> @@ -196,11 +198,6 @@ static void populate_properties(const void *blob,
>>                 if (!strcmp(pname, "name"))
>>                         has_name = true;
>>
>> -               pp = unflatten_dt_alloc(mem, sizeof(struct property),
>> -                                       __alignof__(struct property));
>> -               if (dryrun)
>> -                       continue;
>> -
>>                 /* We accept flattened tree phandles either in
>>                  * ePAPR-style "phandle" properties, or the
>>                  * legacy "linux,phandle" properties.  If both
>> @@ -208,23 +205,34 @@ static void populate_properties(const void *blob,
>>                  * will get weird. Don't do that.
>>                  */
>>                 if (!strcmp(pname, "phandle") ||
>> -                   !strcmp(pname, "linux,phandle")) {
>> -                       if (!np->phandle)
>> -                               np->phandle = be32_to_cpup(val);
>> -               }
>> +                   !strcmp(pname, "linux,phandle"))
>> +                       prop_is_phandle = 1;
>>
>>                 /* And we process the "ibm,phandle" property
>>                  * used in pSeries dynamic device tree
>>                  * stuff
>>                  */
>> -               if (!strcmp(pname, "ibm,phandle"))
>> -                       np->phandle = be32_to_cpup(val);
>> +               if (!strcmp(pname, "ibm,phandle")) {
>> +                       prop_is_phandle = 1;
>> +                       prop_is_ibm_phandle = 1;
>> +               }
>> +
>> +               if (!prop_is_phandle)
>> +                       pp = unflatten_dt_alloc(mem, sizeof(struct property),
>> +                                               __alignof__(struct property));
>>
>> -               pp->name   = (char *)pname;
>> -               pp->length = sz;
>> -               pp->value  = (__be32 *)val;
>> -               *pprev     = pp;
>> -               pprev      = &pp->next;
>> +               if (dryrun)
>> +                       continue;
>> +
>> +               if (!prop_is_phandle) {
>> +                       pp->name   = (char *)pname;
>> +                       pp->length = sz;
>> +                       pp->value  = (__be32 *)val;
>> +                       *pprev     = pp;
>> +                       pprev      = &pp->next;
>> +               } else if (prop_is_ibm_phandle || !np->phandle) {
> 
> This logic is a bit strange. I think it would be a bit better if we
> can keep all the phandle code together and end with a continue, then
> have the property handling code at the end of the loop.

I will do this.  One side effect will be that the value of property
"ibm,phandle" will no longer override the value of properties "phandle"
and "linux,phandle".


>> +                       np->phandle = be32_to_cpup(val);
>> +               }
>>         }
>>
>>         /* With version 0x10 we may not have the name property,
>> diff --git a/drivers/of/of_private.h b/drivers/of/of_private.h
>> index 18bbb4517e25..33f11a5384f3 100644
>> --- a/drivers/of/of_private.h
>> +++ b/drivers/of/of_private.h
>> @@ -47,6 +47,7 @@ extern int of_property_notify(int action, struct device_node *np,
>>  extern void of_node_release(struct kobject *kobj);
>>  extern int __of_changeset_apply(struct of_changeset *ocs);
>>  extern int __of_changeset_revert(struct of_changeset *ocs);
>> +extern int __of_add_phandle_sysfs(struct device_node *np);
>>  #else /* CONFIG_OF_DYNAMIC */
>>  static inline int of_property_notify(int action, struct device_node *np,
>>                                      struct property *prop, struct property *old_prop)
>> diff --git a/drivers/of/overlay.c b/drivers/of/overlay.c
>> index 7827786718d8..ca0b85f5deb1 100644
>> --- a/drivers/of/overlay.c
>> +++ b/drivers/of/overlay.c
>> @@ -101,9 +101,7 @@ static int of_overlay_apply_single_property(struct of_overlay *ov,
>>         tprop = of_find_property(target, prop->name, NULL);
>>
>>         /* special properties are not meant to be updated (silent NOP) */
>> -       if (of_prop_cmp(prop->name, "name") == 0 ||
>> -           of_prop_cmp(prop->name, "phandle") == 0 ||
>> -           of_prop_cmp(prop->name, "linux,phandle") == 0)
>> +       if (!of_prop_cmp(prop->name, "name"))
>>                 return 0;
>>
>>         propn = __of_prop_dup(prop, GFP_KERNEL);
>> diff --git a/drivers/of/resolver.c b/drivers/of/resolver.c
>> index 7ae9863cb0a4..624cbaeae0a4 100644
>> --- a/drivers/of/resolver.c
>> +++ b/drivers/of/resolver.c
>> @@ -71,30 +71,11 @@ static void adjust_overlay_phandles(struct device_node *overlay,
>>                 int phandle_delta)
>>  {
>>         struct device_node *child;
>> -       struct property *prop;
>> -       phandle phandle;
>>
>>         /* adjust node's phandle in node */
>>         if (overlay->phandle != 0 && overlay->phandle != OF_PHANDLE_ILLEGAL)
>>                 overlay->phandle += phandle_delta;
>>
>> -       /* copy adjusted phandle into *phandle properties */
>> -       for_each_property_of_node(overlay, prop) {
>> -
>> -               if (of_prop_cmp(prop->name, "phandle") &&
>> -                   of_prop_cmp(prop->name, "linux,phandle"))
>> -                       continue;
>> -
>> -               if (prop->length < 4)
>> -                       continue;
>> -
>> -               phandle = be32_to_cpup(prop->value);
>> -               if (phandle == OF_PHANDLE_ILLEGAL)
>> -                       continue;
>> -
>> -               *(uint32_t *)prop->value = cpu_to_be32(overlay->phandle);
>> -       }
>> -
>>         for_each_child_of_node(overlay, child)
>>                 adjust_overlay_phandles(child, phandle_delta);
>>  }
>> @@ -197,9 +178,7 @@ static int adjust_local_phandle_references(struct device_node *local_fixups,
>>         for_each_property_of_node(local_fixups, prop_fix) {
>>
>>                 /* skip properties added automatically */
>> -               if (!of_prop_cmp(prop_fix->name, "name") ||
>> -                   !of_prop_cmp(prop_fix->name, "phandle") ||
>> -                   !of_prop_cmp(prop_fix->name, "linux,phandle"))
>> +               if (!of_prop_cmp(prop_fix->name, "name"))
>>                         continue;
>>
>>                 if ((prop_fix->length % 4) != 0 || prop_fix->length == 0)
>> diff --git a/include/linux/of.h b/include/linux/of.h
>> index 21e6323de0f3..4e86e05853f3 100644
>> --- a/include/linux/of.h
>> +++ b/include/linux/of.h
>> @@ -61,6 +61,7 @@ struct device_node {
>>         struct  kobject kobj;
>>         unsigned long _flags;
>>         void    *data;
>> +       struct bin_attribute attr_phandle;
>>  #if defined(CONFIG_SPARC)
>>         const char *path_component_name;
>>         unsigned int unique_id;
>> --
>> Frank Rowand <frank.rowand-7U/KSKJipcs@public.gmane.org>

--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [PATCH v4 1/4] of: remove *phandle properties from expanded device tree
@ 2017-06-10  4:38         ` Frank Rowand
  0 siblings, 0 replies; 15+ messages in thread
From: Frank Rowand @ 2017-06-10  4:38 UTC (permalink / raw)
  To: Rob Herring; +Cc: Stephen Boyd, devicetree, linux-kernel

On 06/09/17 19:35, Frank Rowand wrote:
> On 05/15/17 15:23, Rob Herring wrote:
>> On Mon, May 1, 2017 at 9:46 PM,  <frowand.list@gmail.com> wrote:
>>> From: Frank Rowand <frank.rowand@sony.com>
>>>
>>> Remove "phandle", "linux,phandle", and "ibm,phandle" properties from
>>> the internal device tree.  The phandle will still be in the struct
>>> device_node phandle field.
>>>
>>> This is to resolve the issue found by Stephen Boyd [1] when he changed
>>> the type of struct property.value from void * to const void *.  As
>>> a result of the type change, the overlay code had compile errors
>>> where the resolver updates phandle values.
>>>
>>>   [1] http://lkml.iu.edu/hypermail/linux/kernel/1702.1/04160.html
>>>
>>> - Add sysfs infrastructure to report np->phandle, as if it was a property.
>>> - Do not create "phandle" "ibm,phandle", and "linux,phandle" properties
>>>   in the expanded device tree.
>>> - Remove phandle properties in of_attach_node(), for nodes dynamically
>>>   attached to the live tree.  Add the phandle sysfs entry for these nodes.
>>> - When creating an overlay changeset, duplicate the node phandle in
>>>   __of_node_dup().
>>> - Remove no longer needed checks to exclude "phandle" and "linux,phandle"
>>>   properties in several locations.
>>> - A side effect of these changes is that the obsolete "linux,phandle" and
>>>   "ibm,phandle" properties will no longer appear in /proc/device-tree (they
>>>   will appear as "phandle").
>>>
>>> Signed-off-by: Frank Rowand <frank.rowand@sony.com>
>>> ---
>>>  drivers/of/base.c       | 48 ++++++++++++++++++++++++++++++++++++++++---
>>>  drivers/of/dynamic.c    | 54 +++++++++++++++++++++++++++++++++++++------------
>>>  drivers/of/fdt.c        | 40 +++++++++++++++++++++---------------
>>>  drivers/of/of_private.h |  1 +
>>>  drivers/of/overlay.c    |  4 +---
>>>  drivers/of/resolver.c   | 23 +--------------------
>>>  include/linux/of.h      |  1 +
>>>  7 files changed, 114 insertions(+), 57 deletions(-)
>>>
>>> diff --git a/drivers/of/base.c b/drivers/of/base.c
>>> index d7c4629a3a2d..8a0cf9003cf8 100644
>>> --- a/drivers/of/base.c
>>> +++ b/drivers/of/base.c
>>> @@ -116,6 +116,19 @@ static ssize_t of_node_property_read(struct file *filp, struct kobject *kobj,
>>>         return memory_read_from_buffer(buf, count, &offset, pp->value, pp->length);
>>>  }
>>>
>>> +static ssize_t of_node_phandle_read(struct file *filp, struct kobject *kobj,
>>> +                               struct bin_attribute *bin_attr, char *buf,
>>> +                               loff_t offset, size_t count)
>>> +{
>>> +       phandle phandle;
>>> +       struct device_node *np;
>>> +
>>> +       np = container_of(bin_attr, struct device_node, attr_phandle);
>>> +       phandle = cpu_to_be32(np->phandle);
>>> +       return memory_read_from_buffer(buf, count, &offset, &phandle,
>>> +                                      sizeof(phandle));
>>> +}
>>> +
>>>  /* always return newly allocated name, caller must free after use */
>>>  static const char *safe_name(struct kobject *kobj, const char *orig_name)
>>>  {
>>> @@ -164,6 +177,35 @@ int __of_add_property_sysfs(struct device_node *np, struct property *pp)
>>>         return rc;
>>>  }
>>>
>>> +/*
>>> + * In the imported device tree (fdt), phandle is a property.  In the
>>> + * internal data structure it is instead stored in the struct device_node.
>>> + * Make phandle visible in sysfs as if it was a property.
>>> + */
>>> +int __of_add_phandle_sysfs(struct device_node *np)
>>> +{
>>> +       int rc;
>>> +
>>> +       if (!IS_ENABLED(CONFIG_SYSFS))
>>> +               return 0;
>>> +
>>> +       if (!of_kset || !of_node_is_attached(np))
>>> +               return 0;
>>> +
>>> +       if (!np->phandle || np->phandle == 0xffffffff)
>>> +               return 0;
>>> +
>>> +       sysfs_bin_attr_init(&np->attr_phandle);
>>> +       np->attr_phandle.attr.name = "phandle";
>>> +       np->attr_phandle.attr.mode = 0444;
>>> +       np->attr_phandle.size = sizeof(np->phandle);
>>> +       np->attr_phandle.read = of_node_phandle_read;
>>> +
>>> +       rc = sysfs_create_bin_file(&np->kobj, &np->attr_phandle);
>>> +       WARN(rc, "error adding attribute phandle to node %s\n", np->full_name);
>>> +       return rc;
>>> +}
>>> +
>>>  int __of_attach_node_sysfs(struct device_node *np)
>>>  {
>>>         const char *name;
>>> @@ -193,6 +235,8 @@ int __of_attach_node_sysfs(struct device_node *np)
>>>         if (rc)
>>>                 return rc;
>>>
>>> +       __of_add_phandle_sysfs(np);
>>> +
>>>         for_each_property_of_node(np, pp)
>>>                 __of_add_property_sysfs(np, pp);
>>>
>>> @@ -2097,9 +2141,7 @@ void of_alias_scan(void * (*dt_alloc)(u64 size, u64 align))
>>>                 int id, len;
>>>
>>>                 /* Skip those we do not want to proceed */
>>> -               if (!strcmp(pp->name, "name") ||
>>> -                   !strcmp(pp->name, "phandle") ||
>>> -                   !strcmp(pp->name, "linux,phandle"))
>>> +               if (!strcmp(pp->name, "name"))
>>>                         continue;
>>>
>>>                 np = of_find_node_by_path(pp->value);
>>> diff --git a/drivers/of/dynamic.c b/drivers/of/dynamic.c
>>> index 888fdbc09992..59545b8fbf46 100644
>>> --- a/drivers/of/dynamic.c
>>> +++ b/drivers/of/dynamic.c
>>> @@ -218,19 +218,6 @@ int of_property_notify(int action, struct device_node *np,
>>>
>>>  void __of_attach_node(struct device_node *np)
>>>  {
>>> -       const __be32 *phandle;
>>> -       int sz;
>>> -
>>> -       np->name = __of_get_property(np, "name", NULL) ? : "<NULL>";
>>> -       np->type = __of_get_property(np, "device_type", NULL) ? : "<NULL>";
>>> -
>>> -       phandle = __of_get_property(np, "phandle", &sz);
>>> -       if (!phandle)
>>> -               phandle = __of_get_property(np, "linux,phandle", &sz);
>>> -       if (IS_ENABLED(CONFIG_PPC_PSERIES) && !phandle)
>>> -               phandle = __of_get_property(np, "ibm,phandle", &sz);
>>> -       np->phandle = (phandle && (sz >= 4)) ? be32_to_cpup(phandle) : 0;
>>> -
>>>         np->child = NULL;
>>>         np->sibling = np->parent->child;
>>>         np->parent->child = np;
>>> @@ -243,11 +230,47 @@ void __of_attach_node(struct device_node *np)
>>>  int of_attach_node(struct device_node *np)
>>>  {
>>>         struct of_reconfig_data rd;
>>> +       struct property *prev;
>>> +       struct property *prop;
>>> +       struct property *save_next;
>>>         unsigned long flags;
>>> +       const __be32 *phandle;
>>> +       int sz;
>>>
>>>         memset(&rd, 0, sizeof(rd));
>>>         rd.dn = np;
>>>
>>> +       np->name = __of_get_property(np, "name", NULL) ? : "<NULL>";
>>> +       np->type = __of_get_property(np, "device_type", NULL) ? : "<NULL>";
>>
>> Why can't we just store NULL here? I know you're just moving this
>> existing code, but now we have it twice. I assume there was some
>> reason, so at least a comment why would be good. (I'm guessing it's
>> because strcmp won't take a NULL).
> 
> Comment added.
> 
> (Yes, the users of the string pointer are not expecting NULL.)
> 
> 
>>> +
>>> +       phandle = __of_get_property(np, "phandle", &sz);
>>> +       if (!phandle)
>>> +               phandle = __of_get_property(np, "linux,phandle", &sz);
>>> +       if (IS_ENABLED(CONFIG_PPC_PSERIES) && !phandle)
>>> +               phandle = __of_get_property(np, "ibm,phandle", &sz);
>>> +       np->phandle = (phandle && (sz >= 4)) ? be32_to_cpup(phandle) : 0;
>>> +
>>> +       /* remove phandle properties from node */
>>> +       prev = NULL;
>>> +       for (prop = np->properties; prop != NULL; ) {
>>> +               save_next = prop->next;
>>> +               if (!strcmp(prop->name, "phandle") ||
>>> +                   !strcmp(prop->name, "ibm,phandle") ||
>>> +                   !strcmp(prop->name, "linux,phandle")) {
>>> +                       if (prev)
>>> +                               prev->next = prop->next;
>>> +                       else
>>> +                               np->properties = prop->next;
>>> +                       prop->next = np->deadprops;
>>> +                       np->deadprops = prop;
>>> +               } else {
>>> +                       prev = prop;
>>> +               }
>>> +               prop = save_next;
>>> +       }
>>> +
>>> +       __of_add_phandle_sysfs(np);
>>> +
>>>         mutex_lock(&of_mutex);
>>>         raw_spin_lock_irqsave(&devtree_lock, flags);
>>>         __of_attach_node(np);
>>> @@ -429,6 +452,7 @@ struct device_node *__of_node_dup(const struct device_node *np, const char *fmt,
>>>         /* Iterate over and duplicate all properties */
>>>         if (np) {
>>>                 struct property *pp, *new_pp;
>>> +               node->phandle = np->phandle;
>>>                 for_each_property_of_node(np, pp) {
>>>                         new_pp = __of_prop_dup(pp, GFP_KERNEL);
>>>                         if (!new_pp)
>>> @@ -441,6 +465,10 @@ struct device_node *__of_node_dup(const struct device_node *np, const char *fmt,
>>>                         }
>>>                 }
>>>         }
>>> +
>>> +       node->name = __of_get_property(node, "name", NULL) ? : "<NULL>";
>>> +       node->type = __of_get_property(node, "device_type", NULL) ? : "<NULL>";
>>> +
>>>         return node;
>>>
>>>   err_prop:
>>> diff --git a/drivers/of/fdt.c b/drivers/of/fdt.c
>>> index e5ce4b59e162..270f31b0c259 100644
>>> --- a/drivers/of/fdt.c
>>> +++ b/drivers/of/fdt.c
>>> @@ -181,6 +181,8 @@ static void populate_properties(const void *blob,
>>>                 const __be32 *val;
>>>                 const char *pname;
>>>                 u32 sz;
>>> +               int prop_is_phandle = 0;
>>> +               int prop_is_ibm_phandle = 0;
>>
>> Can be bool.
> 
> These two variables eliminated while addressing the next comment.

That change resulted in a warning for "make W=2", so
prop_is_phandle added back, changed to bool.


>>>
>>>                 val = fdt_getprop_by_offset(blob, cur, &pname, &sz);
>>>                 if (!val) {
>>> @@ -196,11 +198,6 @@ static void populate_properties(const void *blob,
>>>                 if (!strcmp(pname, "name"))
>>>                         has_name = true;
>>>
>>> -               pp = unflatten_dt_alloc(mem, sizeof(struct property),
>>> -                                       __alignof__(struct property));
>>> -               if (dryrun)
>>> -                       continue;
>>> -
>>>                 /* We accept flattened tree phandles either in
>>>                  * ePAPR-style "phandle" properties, or the
>>>                  * legacy "linux,phandle" properties.  If both
>>> @@ -208,23 +205,34 @@ static void populate_properties(const void *blob,
>>>                  * will get weird. Don't do that.
>>>                  */
>>>                 if (!strcmp(pname, "phandle") ||
>>> -                   !strcmp(pname, "linux,phandle")) {
>>> -                       if (!np->phandle)
>>> -                               np->phandle = be32_to_cpup(val);
>>> -               }
>>> +                   !strcmp(pname, "linux,phandle"))
>>> +                       prop_is_phandle = 1;
>>>
>>>                 /* And we process the "ibm,phandle" property
>>>                  * used in pSeries dynamic device tree
>>>                  * stuff
>>>                  */
>>> -               if (!strcmp(pname, "ibm,phandle"))
>>> -                       np->phandle = be32_to_cpup(val);
>>> +               if (!strcmp(pname, "ibm,phandle")) {
>>> +                       prop_is_phandle = 1;
>>> +                       prop_is_ibm_phandle = 1;
>>> +               }
>>> +
>>> +               if (!prop_is_phandle)
>>> +                       pp = unflatten_dt_alloc(mem, sizeof(struct property),
>>> +                                               __alignof__(struct property));
>>>
>>> -               pp->name   = (char *)pname;
>>> -               pp->length = sz;
>>> -               pp->value  = (__be32 *)val;
>>> -               *pprev     = pp;
>>> -               pprev      = &pp->next;
>>> +               if (dryrun)
>>> +                       continue;
>>> +
>>> +               if (!prop_is_phandle) {
>>> +                       pp->name   = (char *)pname;
>>> +                       pp->length = sz;
>>> +                       pp->value  = (__be32 *)val;
>>> +                       *pprev     = pp;
>>> +                       pprev      = &pp->next;
>>> +               } else if (prop_is_ibm_phandle || !np->phandle) {
>>
>> This logic is a bit strange. I think it would be a bit better if we
>> can keep all the phandle code together and end with a continue, then
>> have the property handling code at the end of the loop.
> 
> I will do this.  One side effect will be that the value of property
> "ibm,phandle" will no longer override the value of properties "phandle"
> and "linux,phandle".
> 
> 
>>> +                       np->phandle = be32_to_cpup(val);
>>> +               }
>>>         }
>>>
>>>         /* With version 0x10 we may not have the name property,
>>> diff --git a/drivers/of/of_private.h b/drivers/of/of_private.h
>>> index 18bbb4517e25..33f11a5384f3 100644
>>> --- a/drivers/of/of_private.h
>>> +++ b/drivers/of/of_private.h
>>> @@ -47,6 +47,7 @@ extern int of_property_notify(int action, struct device_node *np,
>>>  extern void of_node_release(struct kobject *kobj);
>>>  extern int __of_changeset_apply(struct of_changeset *ocs);
>>>  extern int __of_changeset_revert(struct of_changeset *ocs);
>>> +extern int __of_add_phandle_sysfs(struct device_node *np);
>>>  #else /* CONFIG_OF_DYNAMIC */
>>>  static inline int of_property_notify(int action, struct device_node *np,
>>>                                      struct property *prop, struct property *old_prop)
>>> diff --git a/drivers/of/overlay.c b/drivers/of/overlay.c
>>> index 7827786718d8..ca0b85f5deb1 100644
>>> --- a/drivers/of/overlay.c
>>> +++ b/drivers/of/overlay.c
>>> @@ -101,9 +101,7 @@ static int of_overlay_apply_single_property(struct of_overlay *ov,
>>>         tprop = of_find_property(target, prop->name, NULL);
>>>
>>>         /* special properties are not meant to be updated (silent NOP) */
>>> -       if (of_prop_cmp(prop->name, "name") == 0 ||
>>> -           of_prop_cmp(prop->name, "phandle") == 0 ||
>>> -           of_prop_cmp(prop->name, "linux,phandle") == 0)
>>> +       if (!of_prop_cmp(prop->name, "name"))
>>>                 return 0;
>>>
>>>         propn = __of_prop_dup(prop, GFP_KERNEL);
>>> diff --git a/drivers/of/resolver.c b/drivers/of/resolver.c
>>> index 7ae9863cb0a4..624cbaeae0a4 100644
>>> --- a/drivers/of/resolver.c
>>> +++ b/drivers/of/resolver.c
>>> @@ -71,30 +71,11 @@ static void adjust_overlay_phandles(struct device_node *overlay,
>>>                 int phandle_delta)
>>>  {
>>>         struct device_node *child;
>>> -       struct property *prop;
>>> -       phandle phandle;
>>>
>>>         /* adjust node's phandle in node */
>>>         if (overlay->phandle != 0 && overlay->phandle != OF_PHANDLE_ILLEGAL)
>>>                 overlay->phandle += phandle_delta;
>>>
>>> -       /* copy adjusted phandle into *phandle properties */
>>> -       for_each_property_of_node(overlay, prop) {
>>> -
>>> -               if (of_prop_cmp(prop->name, "phandle") &&
>>> -                   of_prop_cmp(prop->name, "linux,phandle"))
>>> -                       continue;
>>> -
>>> -               if (prop->length < 4)
>>> -                       continue;
>>> -
>>> -               phandle = be32_to_cpup(prop->value);
>>> -               if (phandle == OF_PHANDLE_ILLEGAL)
>>> -                       continue;
>>> -
>>> -               *(uint32_t *)prop->value = cpu_to_be32(overlay->phandle);
>>> -       }
>>> -
>>>         for_each_child_of_node(overlay, child)
>>>                 adjust_overlay_phandles(child, phandle_delta);
>>>  }
>>> @@ -197,9 +178,7 @@ static int adjust_local_phandle_references(struct device_node *local_fixups,
>>>         for_each_property_of_node(local_fixups, prop_fix) {
>>>
>>>                 /* skip properties added automatically */
>>> -               if (!of_prop_cmp(prop_fix->name, "name") ||
>>> -                   !of_prop_cmp(prop_fix->name, "phandle") ||
>>> -                   !of_prop_cmp(prop_fix->name, "linux,phandle"))
>>> +               if (!of_prop_cmp(prop_fix->name, "name"))
>>>                         continue;
>>>
>>>                 if ((prop_fix->length % 4) != 0 || prop_fix->length == 0)
>>> diff --git a/include/linux/of.h b/include/linux/of.h
>>> index 21e6323de0f3..4e86e05853f3 100644
>>> --- a/include/linux/of.h
>>> +++ b/include/linux/of.h
>>> @@ -61,6 +61,7 @@ struct device_node {
>>>         struct  kobject kobj;
>>>         unsigned long _flags;
>>>         void    *data;
>>> +       struct bin_attribute attr_phandle;
>>>  #if defined(CONFIG_SPARC)
>>>         const char *path_component_name;
>>>         unsigned int unique_id;
>>> --
>>> Frank Rowand <frank.rowand@sony.com>
> 
> 

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [PATCH v4 1/4] of: remove *phandle properties from expanded device tree
@ 2017-06-10  4:38         ` Frank Rowand
  0 siblings, 0 replies; 15+ messages in thread
From: Frank Rowand @ 2017-06-10  4:38 UTC (permalink / raw)
  To: Rob Herring
  Cc: Stephen Boyd, devicetree-u79uwXL29TY76Z2rM5mHXA,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA

On 06/09/17 19:35, Frank Rowand wrote:
> On 05/15/17 15:23, Rob Herring wrote:
>> On Mon, May 1, 2017 at 9:46 PM,  <frowand.list-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> wrote:
>>> From: Frank Rowand <frank.rowand-7U/KSKJipcs@public.gmane.org>
>>>
>>> Remove "phandle", "linux,phandle", and "ibm,phandle" properties from
>>> the internal device tree.  The phandle will still be in the struct
>>> device_node phandle field.
>>>
>>> This is to resolve the issue found by Stephen Boyd [1] when he changed
>>> the type of struct property.value from void * to const void *.  As
>>> a result of the type change, the overlay code had compile errors
>>> where the resolver updates phandle values.
>>>
>>>   [1] http://lkml.iu.edu/hypermail/linux/kernel/1702.1/04160.html
>>>
>>> - Add sysfs infrastructure to report np->phandle, as if it was a property.
>>> - Do not create "phandle" "ibm,phandle", and "linux,phandle" properties
>>>   in the expanded device tree.
>>> - Remove phandle properties in of_attach_node(), for nodes dynamically
>>>   attached to the live tree.  Add the phandle sysfs entry for these nodes.
>>> - When creating an overlay changeset, duplicate the node phandle in
>>>   __of_node_dup().
>>> - Remove no longer needed checks to exclude "phandle" and "linux,phandle"
>>>   properties in several locations.
>>> - A side effect of these changes is that the obsolete "linux,phandle" and
>>>   "ibm,phandle" properties will no longer appear in /proc/device-tree (they
>>>   will appear as "phandle").
>>>
>>> Signed-off-by: Frank Rowand <frank.rowand-7U/KSKJipcs@public.gmane.org>
>>> ---
>>>  drivers/of/base.c       | 48 ++++++++++++++++++++++++++++++++++++++++---
>>>  drivers/of/dynamic.c    | 54 +++++++++++++++++++++++++++++++++++++------------
>>>  drivers/of/fdt.c        | 40 +++++++++++++++++++++---------------
>>>  drivers/of/of_private.h |  1 +
>>>  drivers/of/overlay.c    |  4 +---
>>>  drivers/of/resolver.c   | 23 +--------------------
>>>  include/linux/of.h      |  1 +
>>>  7 files changed, 114 insertions(+), 57 deletions(-)
>>>
>>> diff --git a/drivers/of/base.c b/drivers/of/base.c
>>> index d7c4629a3a2d..8a0cf9003cf8 100644
>>> --- a/drivers/of/base.c
>>> +++ b/drivers/of/base.c
>>> @@ -116,6 +116,19 @@ static ssize_t of_node_property_read(struct file *filp, struct kobject *kobj,
>>>         return memory_read_from_buffer(buf, count, &offset, pp->value, pp->length);
>>>  }
>>>
>>> +static ssize_t of_node_phandle_read(struct file *filp, struct kobject *kobj,
>>> +                               struct bin_attribute *bin_attr, char *buf,
>>> +                               loff_t offset, size_t count)
>>> +{
>>> +       phandle phandle;
>>> +       struct device_node *np;
>>> +
>>> +       np = container_of(bin_attr, struct device_node, attr_phandle);
>>> +       phandle = cpu_to_be32(np->phandle);
>>> +       return memory_read_from_buffer(buf, count, &offset, &phandle,
>>> +                                      sizeof(phandle));
>>> +}
>>> +
>>>  /* always return newly allocated name, caller must free after use */
>>>  static const char *safe_name(struct kobject *kobj, const char *orig_name)
>>>  {
>>> @@ -164,6 +177,35 @@ int __of_add_property_sysfs(struct device_node *np, struct property *pp)
>>>         return rc;
>>>  }
>>>
>>> +/*
>>> + * In the imported device tree (fdt), phandle is a property.  In the
>>> + * internal data structure it is instead stored in the struct device_node.
>>> + * Make phandle visible in sysfs as if it was a property.
>>> + */
>>> +int __of_add_phandle_sysfs(struct device_node *np)
>>> +{
>>> +       int rc;
>>> +
>>> +       if (!IS_ENABLED(CONFIG_SYSFS))
>>> +               return 0;
>>> +
>>> +       if (!of_kset || !of_node_is_attached(np))
>>> +               return 0;
>>> +
>>> +       if (!np->phandle || np->phandle == 0xffffffff)
>>> +               return 0;
>>> +
>>> +       sysfs_bin_attr_init(&np->attr_phandle);
>>> +       np->attr_phandle.attr.name = "phandle";
>>> +       np->attr_phandle.attr.mode = 0444;
>>> +       np->attr_phandle.size = sizeof(np->phandle);
>>> +       np->attr_phandle.read = of_node_phandle_read;
>>> +
>>> +       rc = sysfs_create_bin_file(&np->kobj, &np->attr_phandle);
>>> +       WARN(rc, "error adding attribute phandle to node %s\n", np->full_name);
>>> +       return rc;
>>> +}
>>> +
>>>  int __of_attach_node_sysfs(struct device_node *np)
>>>  {
>>>         const char *name;
>>> @@ -193,6 +235,8 @@ int __of_attach_node_sysfs(struct device_node *np)
>>>         if (rc)
>>>                 return rc;
>>>
>>> +       __of_add_phandle_sysfs(np);
>>> +
>>>         for_each_property_of_node(np, pp)
>>>                 __of_add_property_sysfs(np, pp);
>>>
>>> @@ -2097,9 +2141,7 @@ void of_alias_scan(void * (*dt_alloc)(u64 size, u64 align))
>>>                 int id, len;
>>>
>>>                 /* Skip those we do not want to proceed */
>>> -               if (!strcmp(pp->name, "name") ||
>>> -                   !strcmp(pp->name, "phandle") ||
>>> -                   !strcmp(pp->name, "linux,phandle"))
>>> +               if (!strcmp(pp->name, "name"))
>>>                         continue;
>>>
>>>                 np = of_find_node_by_path(pp->value);
>>> diff --git a/drivers/of/dynamic.c b/drivers/of/dynamic.c
>>> index 888fdbc09992..59545b8fbf46 100644
>>> --- a/drivers/of/dynamic.c
>>> +++ b/drivers/of/dynamic.c
>>> @@ -218,19 +218,6 @@ int of_property_notify(int action, struct device_node *np,
>>>
>>>  void __of_attach_node(struct device_node *np)
>>>  {
>>> -       const __be32 *phandle;
>>> -       int sz;
>>> -
>>> -       np->name = __of_get_property(np, "name", NULL) ? : "<NULL>";
>>> -       np->type = __of_get_property(np, "device_type", NULL) ? : "<NULL>";
>>> -
>>> -       phandle = __of_get_property(np, "phandle", &sz);
>>> -       if (!phandle)
>>> -               phandle = __of_get_property(np, "linux,phandle", &sz);
>>> -       if (IS_ENABLED(CONFIG_PPC_PSERIES) && !phandle)
>>> -               phandle = __of_get_property(np, "ibm,phandle", &sz);
>>> -       np->phandle = (phandle && (sz >= 4)) ? be32_to_cpup(phandle) : 0;
>>> -
>>>         np->child = NULL;
>>>         np->sibling = np->parent->child;
>>>         np->parent->child = np;
>>> @@ -243,11 +230,47 @@ void __of_attach_node(struct device_node *np)
>>>  int of_attach_node(struct device_node *np)
>>>  {
>>>         struct of_reconfig_data rd;
>>> +       struct property *prev;
>>> +       struct property *prop;
>>> +       struct property *save_next;
>>>         unsigned long flags;
>>> +       const __be32 *phandle;
>>> +       int sz;
>>>
>>>         memset(&rd, 0, sizeof(rd));
>>>         rd.dn = np;
>>>
>>> +       np->name = __of_get_property(np, "name", NULL) ? : "<NULL>";
>>> +       np->type = __of_get_property(np, "device_type", NULL) ? : "<NULL>";
>>
>> Why can't we just store NULL here? I know you're just moving this
>> existing code, but now we have it twice. I assume there was some
>> reason, so at least a comment why would be good. (I'm guessing it's
>> because strcmp won't take a NULL).
> 
> Comment added.
> 
> (Yes, the users of the string pointer are not expecting NULL.)
> 
> 
>>> +
>>> +       phandle = __of_get_property(np, "phandle", &sz);
>>> +       if (!phandle)
>>> +               phandle = __of_get_property(np, "linux,phandle", &sz);
>>> +       if (IS_ENABLED(CONFIG_PPC_PSERIES) && !phandle)
>>> +               phandle = __of_get_property(np, "ibm,phandle", &sz);
>>> +       np->phandle = (phandle && (sz >= 4)) ? be32_to_cpup(phandle) : 0;
>>> +
>>> +       /* remove phandle properties from node */
>>> +       prev = NULL;
>>> +       for (prop = np->properties; prop != NULL; ) {
>>> +               save_next = prop->next;
>>> +               if (!strcmp(prop->name, "phandle") ||
>>> +                   !strcmp(prop->name, "ibm,phandle") ||
>>> +                   !strcmp(prop->name, "linux,phandle")) {
>>> +                       if (prev)
>>> +                               prev->next = prop->next;
>>> +                       else
>>> +                               np->properties = prop->next;
>>> +                       prop->next = np->deadprops;
>>> +                       np->deadprops = prop;
>>> +               } else {
>>> +                       prev = prop;
>>> +               }
>>> +               prop = save_next;
>>> +       }
>>> +
>>> +       __of_add_phandle_sysfs(np);
>>> +
>>>         mutex_lock(&of_mutex);
>>>         raw_spin_lock_irqsave(&devtree_lock, flags);
>>>         __of_attach_node(np);
>>> @@ -429,6 +452,7 @@ struct device_node *__of_node_dup(const struct device_node *np, const char *fmt,
>>>         /* Iterate over and duplicate all properties */
>>>         if (np) {
>>>                 struct property *pp, *new_pp;
>>> +               node->phandle = np->phandle;
>>>                 for_each_property_of_node(np, pp) {
>>>                         new_pp = __of_prop_dup(pp, GFP_KERNEL);
>>>                         if (!new_pp)
>>> @@ -441,6 +465,10 @@ struct device_node *__of_node_dup(const struct device_node *np, const char *fmt,
>>>                         }
>>>                 }
>>>         }
>>> +
>>> +       node->name = __of_get_property(node, "name", NULL) ? : "<NULL>";
>>> +       node->type = __of_get_property(node, "device_type", NULL) ? : "<NULL>";
>>> +
>>>         return node;
>>>
>>>   err_prop:
>>> diff --git a/drivers/of/fdt.c b/drivers/of/fdt.c
>>> index e5ce4b59e162..270f31b0c259 100644
>>> --- a/drivers/of/fdt.c
>>> +++ b/drivers/of/fdt.c
>>> @@ -181,6 +181,8 @@ static void populate_properties(const void *blob,
>>>                 const __be32 *val;
>>>                 const char *pname;
>>>                 u32 sz;
>>> +               int prop_is_phandle = 0;
>>> +               int prop_is_ibm_phandle = 0;
>>
>> Can be bool.
> 
> These two variables eliminated while addressing the next comment.

That change resulted in a warning for "make W=2", so
prop_is_phandle added back, changed to bool.


>>>
>>>                 val = fdt_getprop_by_offset(blob, cur, &pname, &sz);
>>>                 if (!val) {
>>> @@ -196,11 +198,6 @@ static void populate_properties(const void *blob,
>>>                 if (!strcmp(pname, "name"))
>>>                         has_name = true;
>>>
>>> -               pp = unflatten_dt_alloc(mem, sizeof(struct property),
>>> -                                       __alignof__(struct property));
>>> -               if (dryrun)
>>> -                       continue;
>>> -
>>>                 /* We accept flattened tree phandles either in
>>>                  * ePAPR-style "phandle" properties, or the
>>>                  * legacy "linux,phandle" properties.  If both
>>> @@ -208,23 +205,34 @@ static void populate_properties(const void *blob,
>>>                  * will get weird. Don't do that.
>>>                  */
>>>                 if (!strcmp(pname, "phandle") ||
>>> -                   !strcmp(pname, "linux,phandle")) {
>>> -                       if (!np->phandle)
>>> -                               np->phandle = be32_to_cpup(val);
>>> -               }
>>> +                   !strcmp(pname, "linux,phandle"))
>>> +                       prop_is_phandle = 1;
>>>
>>>                 /* And we process the "ibm,phandle" property
>>>                  * used in pSeries dynamic device tree
>>>                  * stuff
>>>                  */
>>> -               if (!strcmp(pname, "ibm,phandle"))
>>> -                       np->phandle = be32_to_cpup(val);
>>> +               if (!strcmp(pname, "ibm,phandle")) {
>>> +                       prop_is_phandle = 1;
>>> +                       prop_is_ibm_phandle = 1;
>>> +               }
>>> +
>>> +               if (!prop_is_phandle)
>>> +                       pp = unflatten_dt_alloc(mem, sizeof(struct property),
>>> +                                               __alignof__(struct property));
>>>
>>> -               pp->name   = (char *)pname;
>>> -               pp->length = sz;
>>> -               pp->value  = (__be32 *)val;
>>> -               *pprev     = pp;
>>> -               pprev      = &pp->next;
>>> +               if (dryrun)
>>> +                       continue;
>>> +
>>> +               if (!prop_is_phandle) {
>>> +                       pp->name   = (char *)pname;
>>> +                       pp->length = sz;
>>> +                       pp->value  = (__be32 *)val;
>>> +                       *pprev     = pp;
>>> +                       pprev      = &pp->next;
>>> +               } else if (prop_is_ibm_phandle || !np->phandle) {
>>
>> This logic is a bit strange. I think it would be a bit better if we
>> can keep all the phandle code together and end with a continue, then
>> have the property handling code at the end of the loop.
> 
> I will do this.  One side effect will be that the value of property
> "ibm,phandle" will no longer override the value of properties "phandle"
> and "linux,phandle".
> 
> 
>>> +                       np->phandle = be32_to_cpup(val);
>>> +               }
>>>         }
>>>
>>>         /* With version 0x10 we may not have the name property,
>>> diff --git a/drivers/of/of_private.h b/drivers/of/of_private.h
>>> index 18bbb4517e25..33f11a5384f3 100644
>>> --- a/drivers/of/of_private.h
>>> +++ b/drivers/of/of_private.h
>>> @@ -47,6 +47,7 @@ extern int of_property_notify(int action, struct device_node *np,
>>>  extern void of_node_release(struct kobject *kobj);
>>>  extern int __of_changeset_apply(struct of_changeset *ocs);
>>>  extern int __of_changeset_revert(struct of_changeset *ocs);
>>> +extern int __of_add_phandle_sysfs(struct device_node *np);
>>>  #else /* CONFIG_OF_DYNAMIC */
>>>  static inline int of_property_notify(int action, struct device_node *np,
>>>                                      struct property *prop, struct property *old_prop)
>>> diff --git a/drivers/of/overlay.c b/drivers/of/overlay.c
>>> index 7827786718d8..ca0b85f5deb1 100644
>>> --- a/drivers/of/overlay.c
>>> +++ b/drivers/of/overlay.c
>>> @@ -101,9 +101,7 @@ static int of_overlay_apply_single_property(struct of_overlay *ov,
>>>         tprop = of_find_property(target, prop->name, NULL);
>>>
>>>         /* special properties are not meant to be updated (silent NOP) */
>>> -       if (of_prop_cmp(prop->name, "name") == 0 ||
>>> -           of_prop_cmp(prop->name, "phandle") == 0 ||
>>> -           of_prop_cmp(prop->name, "linux,phandle") == 0)
>>> +       if (!of_prop_cmp(prop->name, "name"))
>>>                 return 0;
>>>
>>>         propn = __of_prop_dup(prop, GFP_KERNEL);
>>> diff --git a/drivers/of/resolver.c b/drivers/of/resolver.c
>>> index 7ae9863cb0a4..624cbaeae0a4 100644
>>> --- a/drivers/of/resolver.c
>>> +++ b/drivers/of/resolver.c
>>> @@ -71,30 +71,11 @@ static void adjust_overlay_phandles(struct device_node *overlay,
>>>                 int phandle_delta)
>>>  {
>>>         struct device_node *child;
>>> -       struct property *prop;
>>> -       phandle phandle;
>>>
>>>         /* adjust node's phandle in node */
>>>         if (overlay->phandle != 0 && overlay->phandle != OF_PHANDLE_ILLEGAL)
>>>                 overlay->phandle += phandle_delta;
>>>
>>> -       /* copy adjusted phandle into *phandle properties */
>>> -       for_each_property_of_node(overlay, prop) {
>>> -
>>> -               if (of_prop_cmp(prop->name, "phandle") &&
>>> -                   of_prop_cmp(prop->name, "linux,phandle"))
>>> -                       continue;
>>> -
>>> -               if (prop->length < 4)
>>> -                       continue;
>>> -
>>> -               phandle = be32_to_cpup(prop->value);
>>> -               if (phandle == OF_PHANDLE_ILLEGAL)
>>> -                       continue;
>>> -
>>> -               *(uint32_t *)prop->value = cpu_to_be32(overlay->phandle);
>>> -       }
>>> -
>>>         for_each_child_of_node(overlay, child)
>>>                 adjust_overlay_phandles(child, phandle_delta);
>>>  }
>>> @@ -197,9 +178,7 @@ static int adjust_local_phandle_references(struct device_node *local_fixups,
>>>         for_each_property_of_node(local_fixups, prop_fix) {
>>>
>>>                 /* skip properties added automatically */
>>> -               if (!of_prop_cmp(prop_fix->name, "name") ||
>>> -                   !of_prop_cmp(prop_fix->name, "phandle") ||
>>> -                   !of_prop_cmp(prop_fix->name, "linux,phandle"))
>>> +               if (!of_prop_cmp(prop_fix->name, "name"))
>>>                         continue;
>>>
>>>                 if ((prop_fix->length % 4) != 0 || prop_fix->length == 0)
>>> diff --git a/include/linux/of.h b/include/linux/of.h
>>> index 21e6323de0f3..4e86e05853f3 100644
>>> --- a/include/linux/of.h
>>> +++ b/include/linux/of.h
>>> @@ -61,6 +61,7 @@ struct device_node {
>>>         struct  kobject kobj;
>>>         unsigned long _flags;
>>>         void    *data;
>>> +       struct bin_attribute attr_phandle;
>>>  #if defined(CONFIG_SPARC)
>>>         const char *path_component_name;
>>>         unsigned int unique_id;
>>> --
>>> Frank Rowand <frank.rowand-7U/KSKJipcs@public.gmane.org>
> 
> 

--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply	[flat|nested] 15+ messages in thread

end of thread, other threads:[~2017-06-10  4:39 UTC | newest]

Thread overview: 15+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2017-05-02  2:46 [PATCH v4 0/4] of: remove *phandle properties from expanded device tree frowand.list
2017-05-02  2:46 ` frowand.list-Re5JQEeQqe8AvxtiuMwx3w
2017-05-02  2:46 ` [PATCH v4 1/4] " frowand.list
2017-05-02  2:46   ` frowand.list-Re5JQEeQqe8AvxtiuMwx3w
2017-05-15 22:23   ` Rob Herring
2017-05-15 22:23     ` Rob Herring
2017-06-10  2:35     ` Frank Rowand
2017-06-10  2:35       ` Frank Rowand
2017-06-10  4:38       ` Frank Rowand
2017-06-10  4:38         ` Frank Rowand
2017-05-02  2:46 ` [PATCH v4 2/4] of: make __of_attach_node() static frowand.list
2017-05-02  2:46   ` frowand.list-Re5JQEeQqe8AvxtiuMwx3w
2017-05-02  2:46 ` [PATCH v4 3/4] of: be consistent in form of file mode frowand.list
2017-05-02  2:46   ` frowand.list-Re5JQEeQqe8AvxtiuMwx3w
2017-05-02  2:46 ` [PATCH v4 4/4] of: detect invalid phandle in overlay frowand.list

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.