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 <m...@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;
+}

Reply via email to