[RFC 4/6] powerpc/pseries: Use common drcinfo parsing

Michael Bringmann mwb at linux.vnet.ibm.com
Sat Dec 15 07:51:15 AEDT 2018


The implementation of the pseries-specific drc info properties
is currently implemented in pseries-specific and non-pseries-specific
files.  This patch set uses a new implementation of the device-tree
parsing code for the properties.

This patch refactors parsing of the drc-info properties out of
pseries_energy.c and hotplug-cpu.c to use the common parser.
Changes include creating appropriate callback functions and
passing callback-specific data blocks into arch_find_drc_match.

Signed-off-by: Michael Bringmann <mwb at linux.vnet.ibm.com>
---
 arch/powerpc/platforms/pseries/hotplug-cpu.c    |   83 +++++++-----
 arch/powerpc/platforms/pseries/pseries_energy.c |  157 ++++++++---------------
 2 files changed, 107 insertions(+), 133 deletions(-)

diff --git a/arch/powerpc/platforms/pseries/hotplug-cpu.c b/arch/powerpc/platforms/pseries/hotplug-cpu.c
index 2f8e621..ee3028c 100644
--- a/arch/powerpc/platforms/pseries/hotplug-cpu.c
+++ b/arch/powerpc/platforms/pseries/hotplug-cpu.c
@@ -411,23 +411,29 @@ static bool dlpar_cpu_exists(struct device_node *parent, u32 drc_index)
 	return found;
 }
 
-static bool valid_cpu_drc_index(struct device_node *parent, u32 drc_index)
+struct cpu_drc_index_struct {
+	u32 drc_index;
+};
+
+bool cpu_drc_index_cb(struct device_node *dn,
+			u32 drc_index, char *drc_name,
+			char *drc_type, u32 drc_power_domain,
+			void *data)
 {
-	bool found = false;
-	int rc, index;
+	struct cpu_drc_index_struct *cdata = data;
 
-	index = 0;
-	while (!found) {
-		u32 drc;
+	if (drc_index == cdata->drc_index)
+		return true;
+	return false;
+}
 
-		rc = of_property_read_u32_index(parent, "ibm,drc-indexes",
-						index++, &drc);
-		if (rc)
-			break;
+static bool valid_cpu_drc_index(struct device_node *parent, u32 drc_index)
+{
+	struct cpu_drc_index_struct cdata = { drc_index };
+	bool found = false;
 
-		if (drc == drc_index)
-			found = true;
-	}
+	found = arch_find_drc_match(parent, cpu_drc_index_cb,
+			"CPU", NULL, false, false, &cdata);
 
 	return found;
 }
@@ -721,11 +727,34 @@ static int dlpar_cpu_remove_by_count(u32 cpus_to_remove)
 	return rc;
 }
 
+struct cpus_to_add_cb_struct {
+	struct device_node *parent;
+	u32 *cpu_drcs;
+	u32 cpus_to_add;
+	u32 cpus_found;
+};
+
+static bool cpus_to_add_cb(struct device_node *dn,
+			u32 drc_index, char *drc_name,
+			char *drc_type, u32 drc_power_domain,
+			void *data)
+{
+	struct cpus_to_add_cb_struct *cdata = data;
+
+	if (cdata->cpus_found < cdata->cpus_to_add) {
+		if (!dlpar_cpu_exists(cdata->parent, drc_index))
+			cdata->cpu_drcs[cdata->cpus_found++] = drc_index;
+	}
+
+	return !(cdata->cpus_found < cdata->cpus_to_add);
+}
+
 static int find_dlpar_cpus_to_add(u32 *cpu_drcs, u32 cpus_to_add)
 {
 	struct device_node *parent;
-	int cpus_found = 0;
-	int index, rc;
+	struct cpus_to_add_cb_struct cdata = {
+		NULL, cpu_drcs, cpus_to_add, 0 };
+	int cpus_found;
 
 	parent = of_find_node_by_path("/cpus");
 	if (!parent) {
@@ -734,25 +763,13 @@ static int find_dlpar_cpus_to_add(u32 *cpu_drcs, u32 cpus_to_add)
 		return -1;
 	}
 
-	/* Search the ibm,drc-indexes array for possible CPU drcs to
-	 * add. Note that the format of the ibm,drc-indexes array is
-	 * the number of entries in the array followed by the array
-	 * of drc values so we start looking at index = 1.
+	/* Search the appropriate property for possible CPU drcs
+	 * to add.
 	 */
-	index = 1;
-	while (cpus_found < cpus_to_add) {
-		u32 drc;
-
-		rc = of_property_read_u32_index(parent, "ibm,drc-indexes",
-						index++, &drc);
-		if (rc)
-			break;
-
-		if (dlpar_cpu_exists(parent, drc))
-			continue;
-
-		cpu_drcs[cpus_found++] = drc;
-	}
+	cdata.parent = parent;
+	arch_find_drc_match(parent, cpus_to_add_cb, "CPU",
+			NULL, false, false, &cdata);
+	cpus_found = cdata.cpus_found;
 
 	of_node_put(parent);
 	return cpus_found;
diff --git a/arch/powerpc/platforms/pseries/pseries_energy.c b/arch/powerpc/platforms/pseries/pseries_energy.c
index 6ed2212..f7b9d86 100644
--- a/arch/powerpc/platforms/pseries/pseries_energy.c
+++ b/arch/powerpc/platforms/pseries/pseries_energy.c
@@ -23,6 +23,7 @@
 #include <asm/hvcall.h>
 #include <asm/firmware.h>
 #include <asm/prom.h>
+#include <asm/topology.h>
 
 
 #define MODULE_VERS "1.0"
@@ -36,60 +37,43 @@
 
 /* Helper Routines to convert between drc_index to cpu numbers */
 
+struct cpu_to_drc_index_struct {
+	u32	thread_index;
+	u32	drc_index;
+	int	counter;
+};
+
+static bool cpu_to_drc_index_cb(struct device_node *dn,
+				u32 drc_index, char *drc_name,
+				char *drc_type, u32 drc_power_domain,
+				void *data)
+{
+	struct cpu_to_drc_index_struct *cdata = data;
+
+	if (cdata->thread_index == cdata->counter++) {
+		cdata->drc_index = drc_index;
+		return true;
+	}
+	return false;
+}
+
 static u32 cpu_to_drc_index(int cpu)
 {
 	struct device_node *dn = NULL;
-	int thread_index;
+	struct cpu_to_drc_index_struct cdata = { 0, 0, 0 };
 	int rc = 1;
-	u32 ret = 0;
 
 	dn = of_find_node_by_path("/cpus");
 	if (dn == NULL)
 		goto err;
 
 	/* Convert logical cpu number to core number */
-	thread_index = cpu_core_index_of_thread(cpu);
-
-	if (firmware_has_feature(FW_FEATURE_DRC_INFO)) {
-		struct property *info = NULL;
-		struct of_drc_info drc;
-		int j;
-		u32 num_set_entries;
-		const __be32 *value;
-
-		info = of_find_property(dn, "ibm,drc-info", NULL);
-		if (info == NULL)
-			goto err_of_node_put;
-
-		value = of_prop_next_u32(info, NULL, &num_set_entries);
-		if (!value)
-			goto err_of_node_put;
-
-		for (j = 0; j < num_set_entries; j++) {
-
-			of_read_drc_info_cell(&info, &value, &drc);
-			if (strncmp(drc.drc_type, "CPU", 3))
-				goto err;
-
-			if (thread_index < drc.last_drc_index)
-				break;
-		}
-
-		ret = drc.drc_index_start + (thread_index * drc.sequential_inc);
-	} else {
-		const __be32 *indexes;
-
-		indexes = of_get_property(dn, "ibm,drc-indexes", NULL);
-		if (indexes == NULL)
-			goto err_of_node_put;
-
-		/*
-		 * The first element indexes[0] is the number of drc_indexes
-		 * returned in the list.  Hence thread_index+1 will get the
-		 * drc_index corresponding to core number thread_index.
-		 */
-		ret = indexes[thread_index + 1];
-	}
+	cdata.thread_index = cpu_core_index_of_thread(cpu);
+
+	rc = arch_find_drc_match(dn, cpu_to_drc_index_cb,
+			"CPU", NULL, false, false, &cdata);
+	if (rc < 0)
+		goto err_of_node_put;
 
 	rc = 0;
 
@@ -98,78 +82,51 @@ static u32 cpu_to_drc_index(int cpu)
 err:
 	if (rc)
 		printk(KERN_WARNING "cpu_to_drc_index(%d) failed", cpu);
-	return ret;
+	return cdata.drc_index;
+}
+
+struct drc_index_to_cpu_struct {
+	u32	drc_index;
+	u32	thread_index;
+	int	counter;
+};
+
+static bool drc_index_to_cpu_cb(struct device_node *dn,
+				u32 drc_index, char *drc_name,
+				char *drc_type, u32 drc_power_domain,
+				void *data)
+{
+	struct drc_index_to_cpu_struct *cdata = data;
+
+	if (cdata->drc_index == drc_index) {
+		cdata->thread_index = cpu_first_thread_of_core(cdata->counter);
+		return true;
+	}
+	cdata->counter++;
+
+	return false;
 }
 
 static int drc_index_to_cpu(u32 drc_index)
 {
 	struct device_node *dn = NULL;
-	const int *indexes;
-	int thread_index = 0, cpu = 0;
+	struct drc_index_to_cpu_struct cdata = {
+			drc_index, 0, 0 };
 	int rc = 1;
 
 	dn = of_find_node_by_path("/cpus");
 	if (dn == NULL)
 		goto err;
 
-	if (firmware_has_feature(FW_FEATURE_DRC_INFO)) {
-		struct property *info = NULL;
-		struct of_drc_info drc;
-		int j;
-		u32 num_set_entries;
-		const __be32 *value;
-
-		info = of_find_property(dn, "ibm,drc-info", NULL);
-		if (info == NULL)
-			goto err_of_node_put;
-
-		value = of_prop_next_u32(info, NULL, &num_set_entries);
-		if (!value)
-			goto err_of_node_put;
-
-		for (j = 0; j < num_set_entries; j++) {
-
-			of_read_drc_info_cell(&info, &value, &drc);
-			if (strncmp(drc.drc_type, "CPU", 3))
-				goto err;
+	rc = arch_find_drc_match(dn, drc_index_to_cpu_cb,
+		   "CPU", NULL, false, false, &cdata);
 
-			if (drc_index > drc.last_drc_index) {
-				cpu += drc.num_sequential_elems;
-				continue;
-			}
-			cpu += ((drc_index - drc.drc_index_start) /
-				drc.sequential_inc);
-
-			thread_index = cpu_first_thread_of_core(cpu);
-			rc = 0;
-			break;
-		}
-	} else {
-		unsigned long int i;
-
-		indexes = of_get_property(dn, "ibm,drc-indexes", NULL);
-		if (indexes == NULL)
-			goto err_of_node_put;
-		/*
-		 * First element in the array is the number of drc_indexes
-		 * returned.  Search through the list to find the matching
-		 * drc_index and get the core number
-		 */
-		for (i = 0; i < indexes[0]; i++) {
-			if (indexes[i + 1] == drc_index)
-				break;
-		}
-		/* Convert core number to logical cpu number */
-		thread_index = cpu_first_thread_of_core(i);
-		rc = 0;
-	}
-
-err_of_node_put:
 	of_node_put(dn);
+
 err:
 	if (rc)
 		printk(KERN_WARNING "drc_index_to_cpu(%d) failed", drc_index);
-	return thread_index;
+	return cdata.thread_index;
 }
 
 /*



More information about the Linuxppc-dev mailing list