aboutsummaryrefslogtreecommitdiffstats
path: root/arch
diff options
context:
space:
mode:
authorBadari Pulavarty <pbadari@us.ibm.com>2008-04-18 16:33:52 -0400
committerPaul Mackerras <paulus@samba.org>2008-04-29 01:57:53 -0400
commit98d5c21c812e4e3b795f5bd912f407ed7c5e4e38 (patch)
tree40c5680e5b8b337fdddd3becf59484a19e2037d5 /arch
parent57b539269e9eef4dedc533d83c94877bc6b4d44d (diff)
[POWERPC] Update lmb data structures for hotplug memory add/remove
The powerpc kernel maintains information about logical memory blocks in the lmb.memory structure, which is initialized and updated at boot time, but not when memory is added or removed while the kernel is running. This adds a hotplug memory notifier which updates lmb.memory when memory is added or removed. This information is useful for eHEA driver to find out the memory layout and holes. NOTE: No special locking is needed for lmb_add() and lmb_remove(). Calls to these are serialized by caller. (pSeries_reconfig_chain). Signed-off-by: Badari Pulavarty <pbadari@us.ibm.com> Cc: Yasunori Goto <y-goto@jp.fujitsu.com> Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org> Cc: "David S. Miller" <davem@davemloft.net> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Paul Mackerras <paulus@samba.org>
Diffstat (limited to 'arch')
-rw-r--r--arch/powerpc/platforms/pseries/hotplug-memory.c43
1 files changed, 43 insertions, 0 deletions
diff --git a/arch/powerpc/platforms/pseries/hotplug-memory.c b/arch/powerpc/platforms/pseries/hotplug-memory.c
index 2d3e9a4bd6ae..3c5727dd5aa5 100644
--- a/arch/powerpc/platforms/pseries/hotplug-memory.c
+++ b/arch/powerpc/platforms/pseries/hotplug-memory.c
@@ -10,6 +10,7 @@
10 */ 10 */
11 11
12#include <linux/of.h> 12#include <linux/of.h>
13#include <linux/lmb.h>
13#include <asm/firmware.h> 14#include <asm/firmware.h>
14#include <asm/machdep.h> 15#include <asm/machdep.h>
15#include <asm/pSeries_reconfig.h> 16#include <asm/pSeries_reconfig.h>
@@ -58,6 +59,11 @@ static int pseries_remove_memory(struct device_node *np)
58 return ret; 59 return ret;
59 60
60 /* 61 /*
62 * Update memory regions for memory remove
63 */
64 lmb_remove(start_pfn << PAGE_SHIFT, regs[3]);
65
66 /*
61 * Remove htab bolted mappings for this section of memory 67 * Remove htab bolted mappings for this section of memory
62 */ 68 */
63 start = (unsigned long)__va(start_pfn << PAGE_SHIFT); 69 start = (unsigned long)__va(start_pfn << PAGE_SHIFT);
@@ -65,6 +71,41 @@ static int pseries_remove_memory(struct device_node *np)
65 return ret; 71 return ret;
66} 72}
67 73
74static int pseries_add_memory(struct device_node *np)
75{
76 const char *type;
77 const unsigned int *my_index;
78 const unsigned int *regs;
79 u64 start_pfn;
80 int ret = -EINVAL;
81
82 /*
83 * Check to see if we are actually adding memory
84 */
85 type = of_get_property(np, "device_type", NULL);
86 if (type == NULL || strcmp(type, "memory") != 0)
87 return 0;
88
89 /*
90 * Find the memory index and size of the added section
91 */
92 my_index = of_get_property(np, "ibm,my-drc-index", NULL);
93 if (!my_index)
94 return ret;
95
96 regs = of_get_property(np, "reg", NULL);
97 if (!regs)
98 return ret;
99
100 start_pfn = section_nr_to_pfn(*my_index & 0xffff);
101
102 /*
103 * Update memory region to represent the memory add
104 */
105 lmb_add(start_pfn << PAGE_SHIFT, regs[3]);
106 return 0;
107}
108
68static int pseries_memory_notifier(struct notifier_block *nb, 109static int pseries_memory_notifier(struct notifier_block *nb,
69 unsigned long action, void *node) 110 unsigned long action, void *node)
70{ 111{
@@ -72,6 +113,8 @@ static int pseries_memory_notifier(struct notifier_block *nb,
72 113
73 switch (action) { 114 switch (action) {
74 case PSERIES_RECONFIG_ADD: 115 case PSERIES_RECONFIG_ADD:
116 if (pseries_add_memory(node))
117 err = NOTIFY_BAD;
75 break; 118 break;
76 case PSERIES_RECONFIG_REMOVE: 119 case PSERIES_RECONFIG_REMOVE:
77 if (pseries_remove_memory(node)) 120 if (pseries_remove_memory(node))