Michal Suchanek 42c87f
From 2efd7f6eb9b7107e469837d8452e750d7d080a5d Mon Sep 17 00:00:00 2001
Michal Suchanek 42c87f
From: Nathan Lynch <nathanl@linux.ibm.com>
Michal Suchanek 42c87f
Date: Mon, 7 Dec 2020 15:52:00 -0600
Michal Suchanek 42c87f
Subject: [PATCH] powerpc/pseries/mobility: refactor node lookup during DT
Michal Suchanek 42c87f
 update
Michal Suchanek 42c87f
Michal Suchanek 42c87f
References: bsc#1181674 ltc#189159
Michal Suchanek 42c87f
Patch-mainline: v5.11-rc1
Michal Suchanek 42c87f
Git-commit: 2efd7f6eb9b7107e469837d8452e750d7d080a5d
Michal Suchanek 42c87f
Michal Suchanek 42c87f
In pseries_devicetree_update(), with each call to ibm,update-nodes the
Michal Suchanek 42c87f
partition firmware communicates the node to be deleted or updated by
Michal Suchanek 42c87f
placing its phandle in the work buffer. Each of delete_dt_node(),
Michal Suchanek 42c87f
update_dt_node(), and add_dt_node() have duplicate lookups using the
Michal Suchanek 42c87f
phandle value and corresponding refcount management.
Michal Suchanek 42c87f
Michal Suchanek 42c87f
Move the lookup and of_node_put() into pseries_devicetree_update(),
Michal Suchanek 42c87f
and emit a warning on any failed lookups.
Michal Suchanek 42c87f
Michal Suchanek 42c87f
Signed-off-by: Nathan Lynch <nathanl@linux.ibm.com>
Michal Suchanek 42c87f
Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
Michal Suchanek 42c87f
Link: https://lore.kernel.org/r/20201207215200.1785968-29-nathanl@linux.ibm.com
Michal Suchanek 42c87f
Acked-by: Michal Suchanek <msuchanek@suse.de>
Michal Suchanek 42c87f
---
Michal Suchanek 42c87f
 arch/powerpc/platforms/pseries/mobility.c | 49 ++++++++---------------
Michal Suchanek 42c87f
 1 file changed, 17 insertions(+), 32 deletions(-)
Michal Suchanek 42c87f
Michal Suchanek 42c87f
diff --git a/arch/powerpc/platforms/pseries/mobility.c b/arch/powerpc/platforms/pseries/mobility.c
Michal Suchanek 42c87f
index e670180f311d..ea4d6a660e0d 100644
Michal Suchanek 42c87f
--- a/arch/powerpc/platforms/pseries/mobility.c
Michal Suchanek 42c87f
+++ b/arch/powerpc/platforms/pseries/mobility.c
Michal Suchanek 42c87f
@@ -61,18 +61,10 @@ static int mobility_rtas_call(int token, char *buf, s32 scope)
Michal Suchanek 42c87f
 	return rc;
Michal Suchanek 42c87f
 }
Michal Suchanek 42c87f
 
Michal Suchanek 42c87f
-static int delete_dt_node(__be32 phandle)
Michal Suchanek 42c87f
+static int delete_dt_node(struct device_node *dn)
Michal Suchanek 42c87f
 {
Michal Suchanek 42c87f
-	struct device_node *dn;
Michal Suchanek 42c87f
-
Michal Suchanek 42c87f
-	dn = of_find_node_by_phandle(be32_to_cpu(phandle));
Michal Suchanek 42c87f
-	if (!dn)
Michal Suchanek 42c87f
-		return -ENOENT;
Michal Suchanek 42c87f
-
Michal Suchanek 42c87f
 	pr_debug("removing node %pOFfp\n", dn);
Michal Suchanek 42c87f
-
Michal Suchanek 42c87f
 	dlpar_detach_node(dn);
Michal Suchanek 42c87f
-	of_node_put(dn);
Michal Suchanek 42c87f
 	return 0;
Michal Suchanek 42c87f
 }
Michal Suchanek 42c87f
 
Michal Suchanek 42c87f
@@ -137,10 +129,9 @@ static int update_dt_property(struct device_node *dn, struct property **prop,
Michal Suchanek 42c87f
 	return 0;
Michal Suchanek 42c87f
 }
Michal Suchanek 42c87f
 
Michal Suchanek 42c87f
-static int update_dt_node(__be32 phandle, s32 scope)
Michal Suchanek 42c87f
+static int update_dt_node(struct device_node *dn, s32 scope)
Michal Suchanek 42c87f
 {
Michal Suchanek 42c87f
 	struct update_props_workarea *upwa;
Michal Suchanek 42c87f
-	struct device_node *dn;
Michal Suchanek 42c87f
 	struct property *prop = NULL;
Michal Suchanek 42c87f
 	int i, rc, rtas_rc;
Michal Suchanek 42c87f
 	char *prop_data;
Michal Suchanek 42c87f
@@ -157,14 +148,8 @@ static int update_dt_node(__be32 phandle, s32 scope)
Michal Suchanek 42c87f
 	if (!rtas_buf)
Michal Suchanek 42c87f
 		return -ENOMEM;
Michal Suchanek 42c87f
 
Michal Suchanek 42c87f
-	dn = of_find_node_by_phandle(be32_to_cpu(phandle));
Michal Suchanek 42c87f
-	if (!dn) {
Michal Suchanek 42c87f
-		kfree(rtas_buf);
Michal Suchanek 42c87f
-		return -ENOENT;
Michal Suchanek 42c87f
-	}
Michal Suchanek 42c87f
-
Michal Suchanek 42c87f
 	upwa = (struct update_props_workarea *)&rtas_buf[0];
Michal Suchanek 42c87f
-	upwa->phandle = phandle;
Michal Suchanek 42c87f
+	upwa->phandle = cpu_to_be32(dn->phandle);
Michal Suchanek 42c87f
 
Michal Suchanek 42c87f
 	do {
Michal Suchanek 42c87f
 		rtas_rc = mobility_rtas_call(update_properties_token, rtas_buf,
Michal Suchanek 42c87f
@@ -224,26 +209,18 @@ static int update_dt_node(__be32 phandle, s32 scope)
Michal Suchanek 42c87f
 		cond_resched();
Michal Suchanek 42c87f
 	} while (rtas_rc == 1);
Michal Suchanek 42c87f
 
Michal Suchanek 42c87f
-	of_node_put(dn);
Michal Suchanek 42c87f
 	kfree(rtas_buf);
Michal Suchanek 42c87f
 	return 0;
Michal Suchanek 42c87f
 }
Michal Suchanek 42c87f
 
Michal Suchanek 42c87f
-static int add_dt_node(__be32 parent_phandle, __be32 drc_index)
Michal Suchanek 42c87f
+static int add_dt_node(struct device_node *parent_dn, __be32 drc_index)
Michal Suchanek 42c87f
 {
Michal Suchanek 42c87f
 	struct device_node *dn;
Michal Suchanek 42c87f
-	struct device_node *parent_dn;
Michal Suchanek 42c87f
 	int rc;
Michal Suchanek 42c87f
 
Michal Suchanek 42c87f
-	parent_dn = of_find_node_by_phandle(be32_to_cpu(parent_phandle));
Michal Suchanek 42c87f
-	if (!parent_dn)
Michal Suchanek 42c87f
-		return -ENOENT;
Michal Suchanek 42c87f
-
Michal Suchanek 42c87f
 	dn = dlpar_configure_connector(drc_index, parent_dn);
Michal Suchanek 42c87f
-	if (!dn) {
Michal Suchanek 42c87f
-		of_node_put(parent_dn);
Michal Suchanek 42c87f
+	if (!dn)
Michal Suchanek 42c87f
 		return -ENOENT;
Michal Suchanek 42c87f
-	}
Michal Suchanek 42c87f
 
Michal Suchanek 42c87f
 	rc = dlpar_attach_node(dn, parent_dn);
Michal Suchanek 42c87f
 	if (rc)
Michal Suchanek 42c87f
@@ -251,7 +228,6 @@ static int add_dt_node(__be32 parent_phandle, __be32 drc_index)
Michal Suchanek 42c87f
 
Michal Suchanek 42c87f
 	pr_debug("added node %pOFfp\n", dn);
Michal Suchanek 42c87f
 
Michal Suchanek 42c87f
-	of_node_put(parent_dn);
Michal Suchanek 42c87f
 	return rc;
Michal Suchanek 42c87f
 }
Michal Suchanek 42c87f
 
Michal Suchanek 42c87f
@@ -284,22 +260,31 @@ int pseries_devicetree_update(s32 scope)
Michal Suchanek 42c87f
 			data++;
Michal Suchanek 42c87f
 
Michal Suchanek 42c87f
 			for (i = 0; i < node_count; i++) {
Michal Suchanek 42c87f
+				struct device_node *np;
Michal Suchanek 42c87f
 				__be32 phandle = *data++;
Michal Suchanek 42c87f
 				__be32 drc_index;
Michal Suchanek 42c87f
 
Michal Suchanek 42c87f
+				np = of_find_node_by_phandle(be32_to_cpu(phandle));
Michal Suchanek 42c87f
+				if (!np) {
Michal Suchanek 42c87f
+					pr_warn("Failed lookup: phandle 0x%x for action 0x%x\n",
Michal Suchanek 42c87f
+						be32_to_cpu(phandle), action);
Michal Suchanek 42c87f
+					continue;
Michal Suchanek 42c87f
+				}
Michal Suchanek 42c87f
+
Michal Suchanek 42c87f
 				switch (action) {
Michal Suchanek 42c87f
 				case DELETE_DT_NODE:
Michal Suchanek 42c87f
-					delete_dt_node(phandle);
Michal Suchanek 42c87f
+					delete_dt_node(np);
Michal Suchanek 42c87f
 					break;
Michal Suchanek 42c87f
 				case UPDATE_DT_NODE:
Michal Suchanek 42c87f
-					update_dt_node(phandle, scope);
Michal Suchanek 42c87f
+					update_dt_node(np, scope);
Michal Suchanek 42c87f
 					break;
Michal Suchanek 42c87f
 				case ADD_DT_NODE:
Michal Suchanek 42c87f
 					drc_index = *data++;
Michal Suchanek 42c87f
-					add_dt_node(phandle, drc_index);
Michal Suchanek 42c87f
+					add_dt_node(np, drc_index);
Michal Suchanek 42c87f
 					break;
Michal Suchanek 42c87f
 				}
Michal Suchanek 42c87f
 
Michal Suchanek 42c87f
+				of_node_put(np);
Michal Suchanek 42c87f
 				cond_resched();
Michal Suchanek 42c87f
 			}
Michal Suchanek 42c87f
 		}
Michal Suchanek 42c87f
-- 
Michal Suchanek 42c87f
2.26.2
Michal Suchanek 42c87f