From b8ab373035984dd8aba29f1a0c03dcef6546f004 Mon Sep 17 00:00:00 2001
From: Haren Myneni <haren@linux.ibm.com>
Date: Tue, 13 Aug 2024 14:40:24 -0700
Subject: [PATCH 4/4] drmgr/phb: Add kernel interface support for device tree
 update

Use the following kernel interfaces for PHB device type to update
the device tree if this feature is enabled in the kernel.

dt add index <DRC index>  --> for IO add
dt remove index <DRC index> --> for IO remove

Signed-off-by: Haren Myneni <haren@linux.ibm.com>
---
 src/drmgr/common_pci.c      | 29 +++++++++++++++++++++-------
 src/drmgr/drslot_chrp_phb.c | 38 ++++++++++++++++++++-----------------
 2 files changed, 43 insertions(+), 24 deletions(-)

diff --git a/src/drmgr/common_pci.c b/src/drmgr/common_pci.c
index 374129cf33e0..540864574569 100644
--- a/src/drmgr/common_pci.c
+++ b/src/drmgr/common_pci.c
@@ -1390,7 +1390,6 @@ print_node_list(struct dr_node *first_node)
 static int
 acquire_hp_resource(struct dr_connector *drc, char *of_path)
 {
-	struct of_node *new_nodes;
 	int state;
 	int rc;
 
@@ -1429,12 +1428,21 @@ acquire_hp_resource(struct dr_connector *drc, char *of_path)
 	}
 
 	if (state == PRESENT) {
-		new_nodes = configure_connector(drc->index);
-		if (new_nodes == NULL)
-			return -1;
+		/*
+		 * Use kernel DLPAR interface if it is enabled
+		 */
+		if (kernel_dlpar_exists()) {
+			rc = do_dt_kernel_dlpar(drc->index, ADD);
+		} else {
+			struct of_node *new_nodes;
+
+			new_nodes = configure_connector(drc->index);
+			if (new_nodes == NULL)
+				return -1;
 
-		rc = add_device_tree_nodes(of_path, new_nodes);
-		free_of_node(new_nodes);
+			rc = add_device_tree_nodes(of_path, new_nodes);
+			free_of_node(new_nodes);
+		}
 		if (rc) {
 			say(ERROR, "add nodes failed for 0x%x\n", drc->index);
 			return rc;
@@ -1490,7 +1498,14 @@ release_hp_resource(struct dr_node *node)
 {
 	int rc;
 
-	rc = remove_device_tree_nodes(node->ofdt_path);
+	/*
+	 * Use kernel DLPAR interface if it is enabled
+	 */
+	if (kernel_dlpar_exists())
+		rc = do_dt_kernel_dlpar(node->drc_index, REMOVE);
+	else
+		rc = remove_device_tree_nodes(node->ofdt_path);
+
 	if (rc) {
 		say(ERROR, "failed to remove kernel nodes for index 0x%x\n",
 		    node->drc_index);
diff --git a/src/drmgr/drslot_chrp_phb.c b/src/drmgr/drslot_chrp_phb.c
index f59baa4f9e27..ffa17d8f6b7d 100644
--- a/src/drmgr/drslot_chrp_phb.c
+++ b/src/drmgr/drslot_chrp_phb.c
@@ -108,17 +108,16 @@ release_phb(struct dr_node *phb)
 {
 	int rc;
 
-	rc = remove_device_tree_nodes(phb->ofdt_path);
-	if (rc)
-		return rc;
-
-	if (phb->phb_ic_ofdt_path[0] != '\0') {
-		rc = remove_device_tree_nodes(phb->phb_ic_ofdt_path);
-		if (rc)
-			return rc;
+	if (kernel_dlpar_exists())
+		rc = do_dt_kernel_dlpar(phb->drc_index, REMOVE);
+	else {
+		rc = remove_device_tree_nodes(phb->ofdt_path);
+		if (!rc && (phb->phb_ic_ofdt_path[0] != '\0'))
+			rc = remove_device_tree_nodes(phb->phb_ic_ofdt_path);
 	}
 
-	rc = release_drc(phb->drc_index, PHB_DEV);
+	if (!rc)
+		rc = release_drc(phb->drc_index, PHB_DEV);
 
 	return rc;
 }
@@ -371,7 +370,6 @@ phb_remove_error:
 static int acquire_phb(char *drc_name, struct dr_node **phb)
 {
 	struct dr_connector drc;
-	struct of_node *of_nodes;
 	char path[DR_PATH_MAX];
 	int rc;
 
@@ -386,14 +384,20 @@ static int acquire_phb(char *drc_name, struct dr_node **phb)
 	if (rc)
 		return rc;
 
-	of_nodes = configure_connector(drc.index);
-	if (of_nodes == NULL) {
-		release_drc(drc.index, PHB_DEV);
-		return -1;
-	}
+	if (kernel_dlpar_exists()) {
+		rc = do_dt_kernel_dlpar(drc.index, ADD);
+	} else {
+		struct of_node *of_nodes;
 
-	rc = add_device_tree_nodes(path, of_nodes);
-	free_of_node(of_nodes);
+		of_nodes = configure_connector(drc.index);
+		if (of_nodes == NULL) {
+			release_drc(drc.index, PHB_DEV);
+			return -1;
+		}
+
+		rc = add_device_tree_nodes(path, of_nodes);
+		free_of_node(of_nodes);
+	}
 	if (rc) {
 		say(ERROR, "add_device_tree_nodes failed at %s\n", path);
 		release_drc(drc.index, PHB_DEV);
-- 
2.46.0

