--- /dev/null
+From f96278810150fc39085d1872e5b39ea06366d03e Mon Sep 17 00:00:00 2001
+From: Frank Rowand <frank.rowand@sony.com>
+Date: Fri, 12 Oct 2018 19:21:16 -0700
+Subject: of: overlay: set node fields from properties when add new overlay node
+
+From: Frank Rowand <frank.rowand@sony.com>
+
+commit f96278810150fc39085d1872e5b39ea06366d03e upstream.
+
+Overlay nodes added by add_changeset_node() do not have the node
+fields name, phandle, and type set.
+
+The node passed to __of_attach_node() when the add node changeset
+entry is processed does not contain any properties. The node's
+properties are located in add property changeset entries that will
+be processed after the add node changeset is applied.
+
+Set the node's fields in the node contained in the add node
+changeset entry and do not set them to incorrect values in
+add_changeset_node().
+
+A visible symptom that is fixed by this patch is the names of nodes
+added by overlays that have an entry in /sys/bus/platform/drivers/*/
+will contain the unit-address but the node-name will be <NULL>, for
+example, "fc4ab000.<NULL>". After applying the patch the name, in
+this example, for node restart@fc4ab000 is "fc4ab000.restart".
+
+Tested-by: Alan Tull <atull@kernel.org>
+Signed-off-by: Frank Rowand <frank.rowand@sony.com>
+Cc: Phil Elwell <phil@raspberrypi.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/of/dynamic.c | 25 +++++++++++++++++--------
+ drivers/of/overlay.c | 29 ++++++++++++++++++++++++-----
+ 2 files changed, 41 insertions(+), 13 deletions(-)
+
+--- a/drivers/of/dynamic.c
++++ b/drivers/of/dynamic.c
+@@ -205,15 +205,24 @@ static void __of_attach_node(struct devi
+ const __be32 *phandle;
+ int sz;
+
+- np->name = __of_get_property(np, "name", NULL) ? : "<NULL>";
+- np->type = __of_get_property(np, "device_type", NULL) ? : "<NULL>";
++ if (!of_node_check_flag(np, OF_OVERLAY)) {
++ np->name = __of_get_property(np, "name", NULL);
++ np->type = __of_get_property(np, "device_type", NULL);
++ if (!np->name)
++ np->name = "<NULL>";
++ if (!np->type)
++ np->type = "<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;
++ 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);
++ if (phandle && (sz >= 4))
++ np->phandle = be32_to_cpup(phandle);
++ else
++ np->phandle = 0;
++ }
+
+ np->child = NULL;
+ np->sibling = np->parent->child;
+--- a/drivers/of/overlay.c
++++ b/drivers/of/overlay.c
+@@ -307,10 +307,11 @@ static int add_changeset_property(struct
+ int ret = 0;
+ bool check_for_non_overlay_node = false;
+
+- if (!of_prop_cmp(overlay_prop->name, "name") ||
+- !of_prop_cmp(overlay_prop->name, "phandle") ||
+- !of_prop_cmp(overlay_prop->name, "linux,phandle"))
+- return 0;
++ if (target->in_livetree)
++ if (!of_prop_cmp(overlay_prop->name, "name") ||
++ !of_prop_cmp(overlay_prop->name, "phandle") ||
++ !of_prop_cmp(overlay_prop->name, "linux,phandle"))
++ return 0;
+
+ if (target->in_livetree)
+ prop = of_find_property(target->np, overlay_prop->name, NULL);
+@@ -330,6 +331,10 @@ static int add_changeset_property(struct
+
+ if (!prop) {
+ check_for_non_overlay_node = true;
++ if (!target->in_livetree) {
++ new_prop->next = target->np->deadprops;
++ target->np->deadprops = new_prop;
++ }
+ ret = of_changeset_add_property(&ovcs->cset, target->np,
+ new_prop);
+ } else if (!of_prop_cmp(prop->name, "#address-cells")) {
+@@ -408,9 +413,10 @@ static int add_changeset_node(struct ove
+ struct target *target, struct device_node *node)
+ {
+ const char *node_kbasename;
++ const __be32 *phandle;
+ struct device_node *tchild;
+ struct target target_child;
+- int ret = 0;
++ int ret = 0, size;
+
+ node_kbasename = kbasename(node->full_name);
+
+@@ -424,6 +430,19 @@ static int add_changeset_node(struct ove
+ return -ENOMEM;
+
+ tchild->parent = target->np;
++ tchild->name = __of_get_property(node, "name", NULL);
++ tchild->type = __of_get_property(node, "device_type", NULL);
++
++ if (!tchild->name)
++ tchild->name = "<NULL>";
++ if (!tchild->type)
++ tchild->type = "<NULL>";
++
++ /* ignore obsolete "linux,phandle" */
++ phandle = __of_get_property(node, "phandle", &size);
++ if (phandle && (size == 4))
++ tchild->phandle = be32_to_cpup(phandle);
++
+ of_node_set_flag(tchild, OF_OVERLAY);
+
+ ret = of_changeset_attach_node(&ovcs->cset, tchild);
--- /dev/null
+From 6f75118800acf77f8ad6afec61ca1b2349ade371 Mon Sep 17 00:00:00 2001
+From: Frank Rowand <frank.rowand@sony.com>
+Date: Thu, 4 Oct 2018 20:32:04 -0700
+Subject: of: overlay: validate overlay properties #address-cells and #size-cells
+
+From: Frank Rowand <frank.rowand@sony.com>
+
+commit 6f75118800acf77f8ad6afec61ca1b2349ade371 upstream.
+
+If overlay properties #address-cells or #size-cells are already in
+the live devicetree for any given node, then the values in the
+overlay must match the values in the live tree.
+
+If the properties are already in the live tree then there is no
+need to create a changeset entry to add them since they must
+have the same value. This reduces the memory used by the
+changeset and eliminates a possible memory leak.
+
+Tested-by: Alan Tull <atull@kernel.org>
+Signed-off-by: Frank Rowand <frank.rowand@sony.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/of/overlay.c | 32 +++++++++++++++++++++++++++++---
+ include/linux/of.h | 6 ++++++
+ 2 files changed, 35 insertions(+), 3 deletions(-)
+
+--- a/drivers/of/overlay.c
++++ b/drivers/of/overlay.c
+@@ -287,7 +287,12 @@ err_free_target_path:
+ * @target may be either in the live devicetree or in a new subtree that
+ * is contained in the changeset.
+ *
+- * Some special properties are not updated (no error returned).
++ * Some special properties are not added or updated (no error returned):
++ * "name", "phandle", "linux,phandle".
++ *
++ * Properties "#address-cells" and "#size-cells" are not updated if they
++ * are already in the live tree, but if present in the live tree, the values
++ * in the overlay must match the values in the live tree.
+ *
+ * Update of property in symbols node is not allowed.
+ *
+@@ -300,6 +305,7 @@ static int add_changeset_property(struct
+ {
+ struct property *new_prop = NULL, *prop;
+ int ret = 0;
++ bool check_for_non_overlay_node = false;
+
+ if (!of_prop_cmp(overlay_prop->name, "name") ||
+ !of_prop_cmp(overlay_prop->name, "phandle") ||
+@@ -322,12 +328,32 @@ static int add_changeset_property(struct
+ if (!new_prop)
+ return -ENOMEM;
+
+- if (!prop)
++ if (!prop) {
++ check_for_non_overlay_node = true;
+ ret = of_changeset_add_property(&ovcs->cset, target->np,
+ new_prop);
+- else
++ } else if (!of_prop_cmp(prop->name, "#address-cells")) {
++ if (!of_prop_val_eq(prop, new_prop)) {
++ pr_err("ERROR: changing value of #address-cells is not allowed in %pOF\n",
++ target->np);
++ ret = -EINVAL;
++ }
++ } else if (!of_prop_cmp(prop->name, "#size-cells")) {
++ if (!of_prop_val_eq(prop, new_prop)) {
++ pr_err("ERROR: changing value of #size-cells is not allowed in %pOF\n",
++ target->np);
++ ret = -EINVAL;
++ }
++ } else {
++ check_for_non_overlay_node = true;
+ ret = of_changeset_update_property(&ovcs->cset, target->np,
+ new_prop);
++ }
++
++ if (check_for_non_overlay_node &&
++ !of_node_check_flag(target->np, OF_OVERLAY))
++ pr_err("WARNING: memory leak will occur if overlay removed, property: %pOF/%s\n",
++ target->np, new_prop->name);
+
+ if (ret) {
+ kfree(new_prop->name);
+--- a/include/linux/of.h
++++ b/include/linux/of.h
+@@ -968,6 +968,12 @@ static inline int of_cpu_node_to_id(stru
+ #define of_node_cmp(s1, s2) strcasecmp((s1), (s2))
+ #endif
+
++static inline int of_prop_val_eq(struct property *p1, struct property *p2)
++{
++ return p1->length == p2->length &&
++ !memcmp(p1->value, p2->value, (size_t)p1->length);
++}
++
+ #if defined(CONFIG_OF) && defined(CONFIG_NUMA)
+ extern int of_node_to_nid(struct device_node *np);
+ #else