Commit 2efd7f6e authored by Nathan Lynch's avatar Nathan Lynch Committed by Michael Ellerman

powerpc/pseries/mobility: refactor node lookup during DT update

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: default avatarNathan Lynch <nathanl@linux.ibm.com>
Signed-off-by: default avatarMichael Ellerman <mpe@ellerman.id.au>
Link: https://lore.kernel.org/r/20201207215200.1785968-29-nathanl@linux.ibm.com
parent 87b57ea7
...@@ -61,18 +61,10 @@ static int mobility_rtas_call(int token, char *buf, s32 scope) ...@@ -61,18 +61,10 @@ static int mobility_rtas_call(int token, char *buf, s32 scope)
return rc; 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); pr_debug("removing node %pOFfp\n", dn);
dlpar_detach_node(dn); dlpar_detach_node(dn);
of_node_put(dn);
return 0; return 0;
} }
...@@ -137,10 +129,9 @@ static int update_dt_property(struct device_node *dn, struct property **prop, ...@@ -137,10 +129,9 @@ static int update_dt_property(struct device_node *dn, struct property **prop,
return 0; 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 update_props_workarea *upwa;
struct device_node *dn;
struct property *prop = NULL; struct property *prop = NULL;
int i, rc, rtas_rc; int i, rc, rtas_rc;
char *prop_data; char *prop_data;
...@@ -157,14 +148,8 @@ static int update_dt_node(__be32 phandle, s32 scope) ...@@ -157,14 +148,8 @@ static int update_dt_node(__be32 phandle, s32 scope)
if (!rtas_buf) if (!rtas_buf)
return -ENOMEM; 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 = (struct update_props_workarea *)&rtas_buf[0];
upwa->phandle = phandle; upwa->phandle = cpu_to_be32(dn->phandle);
do { do {
rtas_rc = mobility_rtas_call(update_properties_token, rtas_buf, rtas_rc = mobility_rtas_call(update_properties_token, rtas_buf,
...@@ -224,26 +209,18 @@ static int update_dt_node(__be32 phandle, s32 scope) ...@@ -224,26 +209,18 @@ static int update_dt_node(__be32 phandle, s32 scope)
cond_resched(); cond_resched();
} while (rtas_rc == 1); } while (rtas_rc == 1);
of_node_put(dn);
kfree(rtas_buf); kfree(rtas_buf);
return 0; 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 *dn;
struct device_node *parent_dn;
int rc; 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); dn = dlpar_configure_connector(drc_index, parent_dn);
if (!dn) { if (!dn)
of_node_put(parent_dn);
return -ENOENT; return -ENOENT;
}
rc = dlpar_attach_node(dn, parent_dn); rc = dlpar_attach_node(dn, parent_dn);
if (rc) if (rc)
...@@ -251,7 +228,6 @@ static int add_dt_node(__be32 parent_phandle, __be32 drc_index) ...@@ -251,7 +228,6 @@ static int add_dt_node(__be32 parent_phandle, __be32 drc_index)
pr_debug("added node %pOFfp\n", dn); pr_debug("added node %pOFfp\n", dn);
of_node_put(parent_dn);
return rc; return rc;
} }
...@@ -284,22 +260,31 @@ int pseries_devicetree_update(s32 scope) ...@@ -284,22 +260,31 @@ int pseries_devicetree_update(s32 scope)
data++; data++;
for (i = 0; i < node_count; i++) { for (i = 0; i < node_count; i++) {
struct device_node *np;
__be32 phandle = *data++; __be32 phandle = *data++;
__be32 drc_index; __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) { switch (action) {
case DELETE_DT_NODE: case DELETE_DT_NODE:
delete_dt_node(phandle); delete_dt_node(np);
break; break;
case UPDATE_DT_NODE: case UPDATE_DT_NODE:
update_dt_node(phandle, scope); update_dt_node(np, scope);
break; break;
case ADD_DT_NODE: case ADD_DT_NODE:
drc_index = *data++; drc_index = *data++;
add_dt_node(phandle, drc_index); add_dt_node(np, drc_index);
break; break;
} }
of_node_put(np);
cond_resched(); cond_resched();
} }
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment