[PATCH 2/4] powerpc/pseries: Move DRMEM processing out of prom.c

Michael Bringmann mwb at linux.vnet.ibm.com
Wed Nov 28 07:35:21 AEDT 2018


The implementation of the pseries-specific dynamic memory features
is currently implemented in several non-pseries-specific files.
This patch set moves the implementation of the device-tree parsing
code for the properties ibm,dynamic-memory, ibm,dynamic-memory-v2,
and its representation in the kernel into the platform-specific
directory to the Pseries features.

This patch refactors references to drmem features out of prom.c, so
that they can be moved to drmem.c.  Changes include creating a
platform function platform_early_init_dt_scan_memory_ppc that any
powerpc platform may implement, and moving a support function to
powerpc/include/asm/sparsemem.h

Signed-off-by: Michael Bringmann <mwb at linux.vnet.ibm.com>
---
 arch/powerpc/include/asm/platform.h    |   23 ++++++++
 arch/powerpc/include/asm/prom.h        |    3 +
 arch/powerpc/include/asm/sparsemem.h   |   19 +++++++
 arch/powerpc/kernel/prom.c             |   90 +-------------------------------
 arch/powerpc/platforms/pseries/drmem.c |   73 ++++++++++++++++++++++++++
 5 files changed, 122 insertions(+), 86 deletions(-)
 create mode 100644 arch/powerpc/include/asm/platform.h

diff --git a/arch/powerpc/include/asm/platform.h b/arch/powerpc/include/asm/platform.h
new file mode 100644
index 0000000..36f0f9e
--- /dev/null
+++ b/arch/powerpc/include/asm/platform.h
@@ -0,0 +1,23 @@
+#ifndef _POWERPC_PLATFORM_H
+#define _POWERPC_PLATFORM_H
+#ifdef __KERNEL__
+
+/*
+ * Definitions for talking to the Platform-specific functions of PowerPC
+ *
+ * Copyright (C) 2018 Michael Bringmann, IBM Corp.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+#include <linux/types.h>
+
+/* Memory initialization support */
+extern int platform_early_init_dt_scan_memory_ppc(unsigned long node,
+						const char *uname,
+						int depth, void *data);
+
+#endif /* __KERNEL__ */
+#endif /* _POWERPC_PLATFORM_H */
diff --git a/arch/powerpc/include/asm/prom.h b/arch/powerpc/include/asm/prom.h
index b04c5ce..4504773 100644
--- a/arch/powerpc/include/asm/prom.h
+++ b/arch/powerpc/include/asm/prom.h
@@ -180,5 +180,8 @@ extern int of_read_drc_info_cell(struct property **prop,
 /* Option Vector 6: IBM PAPR hints */
 #define OV6_LINUX		0x02	/* Linux is our OS */
 
+/* Other functions */
+extern bool validate_mem_limit(u64 base, u64 *size);
+
 #endif /* __KERNEL__ */
 #endif /* _POWERPC_PROM_H */
diff --git a/arch/powerpc/include/asm/sparsemem.h b/arch/powerpc/include/asm/sparsemem.h
index 68da493..25edfc2 100644
--- a/arch/powerpc/include/asm/sparsemem.h
+++ b/arch/powerpc/include/asm/sparsemem.h
@@ -32,5 +32,24 @@ static inline int hot_add_scn_to_nid(unsigned long scn_addr)
 #endif /* CONFIG_NUMA */
 #endif /* CONFIG_MEMORY_HOTPLUG */
 
+
+#ifdef CONFIG_SPARSEMEM
+static inline bool validate_mem_limit(u64 base, u64 *size) 
+{
+	u64 max_mem = 1UL << (MAX_PHYSMEM_BITS);
+
+	if (base >= max_mem)
+		return false;
+	if ((base + *size) > max_mem)
+		*size = max_mem - base;
+	return true;
+}
+#else
+static inline bool validate_mem_limit(u64 base, u64 *size) 
+{
+	return true;
+}
+#endif
+
 #endif /* __KERNEL__ */
 #endif /* _ASM_POWERPC_SPARSEMEM_H */
diff --git a/arch/powerpc/kernel/prom.c b/arch/powerpc/kernel/prom.c
index fe758ce..ea32fee 100644
--- a/arch/powerpc/kernel/prom.c
+++ b/arch/powerpc/kernel/prom.c
@@ -58,7 +58,7 @@
 #include <asm/epapr_hcalls.h>
 #include <asm/firmware.h>
 #include <asm/dt_cpu_ftrs.h>
-#include <asm/drmem.h>
+#include <asm/platform.h>
 
 #include <mm/mmu_decl.h>
 
@@ -444,96 +444,14 @@ static int __init early_init_dt_scan_chosen_ppc(unsigned long node,
  * size if it cross the limit.
  */
 
-#ifdef CONFIG_SPARSEMEM
-static bool validate_mem_limit(u64 base, u64 *size)
-{
-	u64 max_mem = 1UL << (MAX_PHYSMEM_BITS);
-
-	if (base >= max_mem)
-		return false;
-	if ((base + *size) > max_mem)
-		*size = max_mem - base;
-	return true;
-}
-#else
-static bool validate_mem_limit(u64 base, u64 *size)
-{
-	return true;
-}
-#endif
-
-#ifdef CONFIG_PPC_PSERIES
-/*
- * Interpret the ibm dynamic reconfiguration memory LMBs.
- * This contains a list of memory blocks along with NUMA affinity
- * information.
- */
-static void __init early_init_drmem_lmb(struct drmem_lmb *lmb,
-					const __be32 **usm)
-{
-	u64 base, size;
-	int is_kexec_kdump = 0, rngs;
-
-	base = lmb->base_addr;
-	size = drmem_lmb_size();
-	rngs = 1;
-
-	/*
-	 * Skip this block if the reserved bit is set in flags
-	 * or if the block is not assigned to this partition.
-	 */
-	if ((lmb->flags & DRCONF_MEM_RESERVED) ||
-	    !(lmb->flags & DRCONF_MEM_ASSIGNED))
-		return;
-
-	if (*usm)
-		is_kexec_kdump = 1;
-
-	if (is_kexec_kdump) {
-		/*
-		 * For each memblock in ibm,dynamic-memory, a
-		 * corresponding entry in linux,drconf-usable-memory
-		 * property contains a counter 'p' followed by 'p'
-		 * (base, size) duple. Now read the counter from
-		 * linux,drconf-usable-memory property
-		 */
-		rngs = dt_mem_next_cell(dt_root_size_cells, usm);
-		if (!rngs) /* there are no (base, size) duple */
-			return;
-	}
-
-	do {
-		if (is_kexec_kdump) {
-			base = dt_mem_next_cell(dt_root_addr_cells, usm);
-			size = dt_mem_next_cell(dt_root_size_cells, usm);
-		}
-
-		if (iommu_is_off) {
-			if (base >= 0x80000000ul)
-				continue;
-			if ((base + size) > 0x80000000ul)
-				size = 0x80000000ul - base;
-		}
-
-		DBG("Adding: %llx -> %llx\n", base, size);
-		if (validate_mem_limit(base, &size))
-			memblock_add(base, size);
-	} while (--rngs);
-}
-#endif /* CONFIG_PPC_PSERIES */
-
 static int __init early_init_dt_scan_memory_ppc(unsigned long node,
 						const char *uname,
 						int depth, void *data)
 {
-#ifdef CONFIG_PPC_PSERIES
-	if (depth == 1 &&
-	    strcmp(uname, "ibm,dynamic-reconfiguration-memory") == 0) {
-		walk_drmem_lmbs_early(node, early_init_drmem_lmb);
+	if (!platform_early_init_dt_scan_memory_ppc(node, uname,
+						depth, data))
 		return 0;
-	}
-#endif
-	
+
 	return early_init_dt_scan_memory(node, uname, depth, data);
 }
 
diff --git a/arch/powerpc/platforms/pseries/drmem.c b/arch/powerpc/platforms/pseries/drmem.c
index 3f18036..ccb0d3b 100644
--- a/arch/powerpc/platforms/pseries/drmem.c
+++ b/arch/powerpc/platforms/pseries/drmem.c
@@ -17,6 +17,7 @@
 #include <linux/memblock.h>
 #include <asm/prom.h>
 #include <asm/drmem.h>
+#include <asm/platform.h>
 
 static struct drmem_lmb_info __drmem_info;
 struct drmem_lmb_info *drmem_info = &__drmem_info;
@@ -445,3 +446,75 @@ static int __init drmem_init(void)
 	return 0;
 }
 late_initcall(drmem_init);
+
+
+/*
+ * Interpret the ibm dynamic reconfiguration memory LMBs.
+ * This contains a list of memory blocks along with NUMA affinity
+ * information.
+ */
+static void __init early_init_drmem_lmb(struct drmem_lmb *lmb,
+					const __be32 **usm)
+{
+	u64 base, size;
+	int is_kexec_kdump = 0, rngs;
+
+	base = lmb->base_addr;
+	size = drmem_lmb_size();
+	rngs = 1;
+
+	/*
+	 * Skip this block if the reserved bit is set in flags
+	 * or if the block is not assigned to this partition.
+	 */
+	if ((lmb->flags & DRCONF_MEM_RESERVED) ||
+	    !(lmb->flags & DRCONF_MEM_ASSIGNED))
+		return;
+
+	if (*usm)
+		is_kexec_kdump = 1;
+
+	if (is_kexec_kdump) {
+		/*
+		 * For each memblock in ibm,dynamic-memory, a
+		 * corresponding entry in linux,drconf-usable-memory
+		 * property contains a counter 'p' followed by 'p'
+		 * (base, size) duple. Now read the counter from
+		 * linux,drconf-usable-memory property
+		 */
+		rngs = dt_mem_next_cell(dt_root_size_cells, usm);
+		if (!rngs) /* there are no (base, size) duple */
+			return;
+	}
+
+	do {
+		if (is_kexec_kdump) {
+			base = dt_mem_next_cell(dt_root_addr_cells, usm);
+			size = dt_mem_next_cell(dt_root_size_cells, usm);
+		}
+
+		if (iommu_is_off) {
+			if (base >= 0x80000000ul)
+				continue;
+			if ((base + size) > 0x80000000ul)
+				size = 0x80000000ul - base;
+		}
+
+		DBG("Adding: %llx -> %llx\n", base, size);
+		if (validate_mem_limit(base, &size))
+			memblock_add(base, size);
+	} while (--rngs);
+}
+
+int __init platform_early_init_dt_scan_memory_ppc(unsigned long node,
+						const char *uname,
+						int depth, void *data)
+{
+	if (depth == 1 &&
+	    strcmp(uname, "ibm,dynamic-reconfiguration-memory") == 0) {
+		walk_drmem_lmbs_early(node, early_init_drmem_lmb);
+		return 0;
+	}
+
+	return -ENODEV;
+}



More information about the Linuxppc-dev mailing list