linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH v4 0/4] of: remove *phandle properties from expanded device tree
@ 2017-05-02  2:46 frowand.list
  2017-05-02  2:46 ` [PATCH v4 1/4] " frowand.list
                   ` (3 more replies)
  0 siblings, 4 replies; 8+ 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] 8+ messages in thread

* [PATCH v4 1/4] of: remove *phandle properties from expanded device tree
  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
  2017-05-15 22:23   ` Rob Herring
  2017-05-02  2:46 ` [PATCH v4 2/4] of: make __of_attach_node() static frowand.list
                   ` (2 subsequent siblings)
  3 siblings, 1 reply; 8+ 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] 8+ messages in thread

* [PATCH v4 2/4] of: make __of_attach_node() static
  2017-05-02  2:46 [PATCH v4 0/4] of: remove *phandle properties from expanded device tree frowand.list
  2017-05-02  2:46 ` [PATCH v4 1/4] " frowand.list
@ 2017-05-02  2:46 ` frowand.list
  2017-05-02  2:46 ` [PATCH v4 3/4] of: be consistent in form of file mode frowand.list
  2017-05-02  2:46 ` [PATCH v4 4/4] of: detect invalid phandle in overlay frowand.list
  3 siblings, 0 replies; 8+ 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] 8+ messages in thread

* [PATCH v4 3/4] of: be consistent in form of file mode
  2017-05-02  2:46 [PATCH v4 0/4] of: remove *phandle properties from expanded device tree frowand.list
  2017-05-02  2:46 ` [PATCH v4 1/4] " frowand.list
  2017-05-02  2:46 ` [PATCH v4 2/4] of: make __of_attach_node() static frowand.list
@ 2017-05-02  2:46 ` frowand.list
  2017-05-02  2:46 ` [PATCH v4 4/4] of: detect invalid phandle in overlay frowand.list
  3 siblings, 0 replies; 8+ 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] 8+ messages in thread

* [PATCH v4 4/4] of: detect invalid phandle in overlay
  2017-05-02  2:46 [PATCH v4 0/4] of: remove *phandle properties from expanded device tree frowand.list
                   ` (2 preceding siblings ...)
  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
  3 siblings, 0 replies; 8+ 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] 8+ messages in thread

* Re: [PATCH v4 1/4] of: remove *phandle properties from expanded device tree
  2017-05-02  2:46 ` [PATCH v4 1/4] " frowand.list
@ 2017-05-15 22:23   ` Rob Herring
  2017-06-10  2:35     ` Frank Rowand
  0 siblings, 1 reply; 8+ 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] 8+ messages in thread

* Re: [PATCH v4 1/4] of: remove *phandle properties from expanded device tree
  2017-05-15 22:23   ` Rob Herring
@ 2017-06-10  2:35     ` Frank Rowand
  2017-06-10  4:38       ` Frank Rowand
  0 siblings, 1 reply; 8+ 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] 8+ messages in thread

* Re: [PATCH v4 1/4] of: remove *phandle properties from expanded device tree
  2017-06-10  2:35     ` Frank Rowand
@ 2017-06-10  4:38       ` Frank Rowand
  0 siblings, 0 replies; 8+ 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] 8+ messages in thread

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

Thread overview: 8+ 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 ` [PATCH v4 1/4] " frowand.list
2017-05-15 22:23   ` Rob Herring
2017-06-10  2:35     ` 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 ` [PATCH v4 3/4] of: be consistent in form of file mode frowand.list
2017-05-02  2:46 ` [PATCH v4 4/4] of: detect invalid phandle in overlay frowand.list

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).