]> git.itanic.dy.fi Git - linux-stable/commitdiff
powerpc/pseries/mobility: refactor node lookup during DT update
authorNathan Lynch <nathanl@linux.ibm.com>
Mon, 7 Dec 2020 21:52:00 +0000 (15:52 -0600)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Fri, 23 Sep 2022 12:16:56 +0000 (14:16 +0200)
[ Upstream commit 2efd7f6eb9b7107e469837d8452e750d7d080a5d ]

In pseries_devicetree_update(), with each call to ibm,update-nodes the
partition firmware communicates the node to be deleted or updated by
placing its phandle in the work buffer. Each of delete_dt_node(),
update_dt_node(), and add_dt_node() have duplicate lookups using the
phandle value and corresponding refcount management.

Move the lookup and of_node_put() into pseries_devicetree_update(),
and emit a warning on any failed lookups.

Signed-off-by: Nathan Lynch <nathanl@linux.ibm.com>
Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
Link: https://lore.kernel.org/r/20201207215200.1785968-29-nathanl@linux.ibm.com
Stable-dep-of: 319fa1a52e43 ("powerpc/pseries/mobility: ignore ibm, platform-facilities updates")
Signed-off-by: Sasha Levin <sashal@kernel.org>
arch/powerpc/platforms/pseries/mobility.c

index 2f73cb5bf12d5635f81a63a5fdb7ab7e53dda0d3..acf1664d1ad7f32e0e5e23513d34cfa2a2db89c0 100644 (file)
@@ -59,18 +59,10 @@ static int mobility_rtas_call(int token, char *buf, s32 scope)
        return rc;
 }
 
-static int delete_dt_node(__be32 phandle)
+static int delete_dt_node(struct device_node *dn)
 {
-       struct device_node *dn;
-
-       dn = of_find_node_by_phandle(be32_to_cpu(phandle));
-       if (!dn)
-               return -ENOENT;
-
        pr_debug("removing node %pOFfp\n", dn);
-
        dlpar_detach_node(dn);
-       of_node_put(dn);
        return 0;
 }
 
@@ -135,10 +127,9 @@ static int update_dt_property(struct device_node *dn, struct property **prop,
        return 0;
 }
 
-static int update_dt_node(__be32 phandle, s32 scope)
+static int update_dt_node(struct device_node *dn, s32 scope)
 {
        struct update_props_workarea *upwa;
-       struct device_node *dn;
        struct property *prop = NULL;
        int i, rc, rtas_rc;
        char *prop_data;
@@ -155,14 +146,8 @@ static int update_dt_node(__be32 phandle, s32 scope)
        if (!rtas_buf)
                return -ENOMEM;
 
-       dn = of_find_node_by_phandle(be32_to_cpu(phandle));
-       if (!dn) {
-               kfree(rtas_buf);
-               return -ENOENT;
-       }
-
        upwa = (struct update_props_workarea *)&rtas_buf[0];
-       upwa->phandle = phandle;
+       upwa->phandle = cpu_to_be32(dn->phandle);
 
        do {
                rtas_rc = mobility_rtas_call(update_properties_token, rtas_buf,
@@ -221,26 +206,18 @@ static int update_dt_node(__be32 phandle, s32 scope)
                cond_resched();
        } while (rtas_rc == 1);
 
-       of_node_put(dn);
        kfree(rtas_buf);
        return 0;
 }
 
-static int add_dt_node(__be32 parent_phandle, __be32 drc_index)
+static int add_dt_node(struct device_node *parent_dn, __be32 drc_index)
 {
        struct device_node *dn;
-       struct device_node *parent_dn;
        int rc;
 
-       parent_dn = of_find_node_by_phandle(be32_to_cpu(parent_phandle));
-       if (!parent_dn)
-               return -ENOENT;
-
        dn = dlpar_configure_connector(drc_index, parent_dn);
-       if (!dn) {
-               of_node_put(parent_dn);
+       if (!dn)
                return -ENOENT;
-       }
 
        rc = dlpar_attach_node(dn, parent_dn);
        if (rc)
@@ -248,7 +225,6 @@ static int add_dt_node(__be32 parent_phandle, __be32 drc_index)
 
        pr_debug("added node %pOFfp\n", dn);
 
-       of_node_put(parent_dn);
        return rc;
 }
 
@@ -281,22 +257,31 @@ int pseries_devicetree_update(s32 scope)
                        data++;
 
                        for (i = 0; i < node_count; i++) {
+                               struct device_node *np;
                                __be32 phandle = *data++;
                                __be32 drc_index;
 
+                               np = of_find_node_by_phandle(be32_to_cpu(phandle));
+                               if (!np) {
+                                       pr_warn("Failed lookup: phandle 0x%x for action 0x%x\n",
+                                               be32_to_cpu(phandle), action);
+                                       continue;
+                               }
+
                                switch (action) {
                                case DELETE_DT_NODE:
-                                       delete_dt_node(phandle);
+                                       delete_dt_node(np);
                                        break;
                                case UPDATE_DT_NODE:
-                                       update_dt_node(phandle, scope);
+                                       update_dt_node(np, scope);
                                        break;
                                case ADD_DT_NODE:
                                        drc_index = *data++;
-                                       add_dt_node(phandle, drc_index);
+                                       add_dt_node(np, drc_index);
                                        break;
                                }
 
+                               of_node_put(np);
                                cond_resched();
                        }
                }