summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorFrank Rowand <frank.rowand@sony.com>2018-10-12 22:21:16 -0400
committerFrank Rowand <frank.rowand@sony.com>2018-11-09 01:12:17 -0500
commitf96278810150fc39085d1872e5b39ea06366d03e (patch)
treee3d8b764a36583111816305b759bd9ab555bf590
parent8c329655c14f9596bb0534492ea740994ded440c (diff)
of: overlay: set node fields from properties when add new overlay node
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>
-rw-r--r--drivers/of/dynamic.c27
-rw-r--r--drivers/of/overlay.c29
2 files changed, 42 insertions, 14 deletions
diff --git a/drivers/of/dynamic.c b/drivers/of/dynamic.c
index 146681540487..b4e5b90cb314 100644
--- a/drivers/of/dynamic.c
+++ b/drivers/of/dynamic.c
@@ -205,15 +205,24 @@ static void __of_attach_node(struct device_node *np)
205 const __be32 *phandle; 205 const __be32 *phandle;
206 int sz; 206 int sz;
207 207
208 np->name = __of_get_property(np, "name", NULL) ? : "<NULL>"; 208 if (!of_node_check_flag(np, OF_OVERLAY)) {
209 np->type = __of_get_property(np, "device_type", NULL) ? : "<NULL>"; 209 np->name = __of_get_property(np, "name", NULL);
210 210 np->type = __of_get_property(np, "device_type", NULL);
211 phandle = __of_get_property(np, "phandle", &sz); 211 if (!np->name)
212 if (!phandle) 212 np->name = "<NULL>";
213 phandle = __of_get_property(np, "linux,phandle", &sz); 213 if (!np->type)
214 if (IS_ENABLED(CONFIG_PPC_PSERIES) && !phandle) 214 np->type = "<NULL>";
215 phandle = __of_get_property(np, "ibm,phandle", &sz); 215
216 np->phandle = (phandle && (sz >= 4)) ? be32_to_cpup(phandle) : 0; 216 phandle = __of_get_property(np, "phandle", &sz);
217 if (!phandle)
218 phandle = __of_get_property(np, "linux,phandle", &sz);
219 if (IS_ENABLED(CONFIG_PPC_PSERIES) && !phandle)
220 phandle = __of_get_property(np, "ibm,phandle", &sz);
221 if (phandle && (sz >= 4))
222 np->phandle = be32_to_cpup(phandle);
223 else
224 np->phandle = 0;
225 }
217 226
218 np->child = NULL; 227 np->child = NULL;
219 np->sibling = np->parent->child; 228 np->sibling = np->parent->child;
diff --git a/drivers/of/overlay.c b/drivers/of/overlay.c
index 184cc2c4a931..2b5ac43a5690 100644
--- a/drivers/of/overlay.c
+++ b/drivers/of/overlay.c
@@ -307,10 +307,11 @@ static int add_changeset_property(struct overlay_changeset *ovcs,
307 int ret = 0; 307 int ret = 0;
308 bool check_for_non_overlay_node = false; 308 bool check_for_non_overlay_node = false;
309 309
310 if (!of_prop_cmp(overlay_prop->name, "name") || 310 if (target->in_livetree)
311 !of_prop_cmp(overlay_prop->name, "phandle") || 311 if (!of_prop_cmp(overlay_prop->name, "name") ||
312 !of_prop_cmp(overlay_prop->name, "linux,phandle")) 312 !of_prop_cmp(overlay_prop->name, "phandle") ||
313 return 0; 313 !of_prop_cmp(overlay_prop->name, "linux,phandle"))
314 return 0;
314 315
315 if (target->in_livetree) 316 if (target->in_livetree)
316 prop = of_find_property(target->np, overlay_prop->name, NULL); 317 prop = of_find_property(target->np, overlay_prop->name, NULL);
@@ -330,6 +331,10 @@ static int add_changeset_property(struct overlay_changeset *ovcs,
330 331
331 if (!prop) { 332 if (!prop) {
332 check_for_non_overlay_node = true; 333 check_for_non_overlay_node = true;
334 if (!target->in_livetree) {
335 new_prop->next = target->np->deadprops;
336 target->np->deadprops = new_prop;
337 }
333 ret = of_changeset_add_property(&ovcs->cset, target->np, 338 ret = of_changeset_add_property(&ovcs->cset, target->np,
334 new_prop); 339 new_prop);
335 } else if (!of_prop_cmp(prop->name, "#address-cells")) { 340 } else if (!of_prop_cmp(prop->name, "#address-cells")) {
@@ -400,9 +405,10 @@ static int add_changeset_node(struct overlay_changeset *ovcs,
400 struct target *target, struct device_node *node) 405 struct target *target, struct device_node *node)
401{ 406{
402 const char *node_kbasename; 407 const char *node_kbasename;
408 const __be32 *phandle;
403 struct device_node *tchild; 409 struct device_node *tchild;
404 struct target target_child; 410 struct target target_child;
405 int ret = 0; 411 int ret = 0, size;
406 412
407 node_kbasename = kbasename(node->full_name); 413 node_kbasename = kbasename(node->full_name);
408 414
@@ -416,6 +422,19 @@ static int add_changeset_node(struct overlay_changeset *ovcs,
416 return -ENOMEM; 422 return -ENOMEM;
417 423
418 tchild->parent = target->np; 424 tchild->parent = target->np;
425 tchild->name = __of_get_property(node, "name", NULL);
426 tchild->type = __of_get_property(node, "device_type", NULL);
427
428 if (!tchild->name)
429 tchild->name = "<NULL>";
430 if (!tchild->type)
431 tchild->type = "<NULL>";
432
433 /* ignore obsolete "linux,phandle" */
434 phandle = __of_get_property(node, "phandle", &size);
435 if (phandle && (size == 4))
436 tchild->phandle = be32_to_cpup(phandle);
437
419 of_node_set_flag(tchild, OF_OVERLAY); 438 of_node_set_flag(tchild, OF_OVERLAY);
420 439
421 ret = of_changeset_attach_node(&ovcs->cset, tchild); 440 ret = of_changeset_attach_node(&ovcs->cset, tchild);