diff options
author | Nathan Fontenot <nfont@austin.ibm.com> | 2011-01-20 11:45:20 -0500 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@suse.de> | 2011-02-03 19:08:57 -0500 |
commit | c540ada2625caabd2dc4dc1e4740bc28765f1b4f (patch) | |
tree | 8f8e1e3cde53d599825d78fd0dfc2ca399d91da5 /arch/powerpc/platforms/pseries/hotplug-memory.c | |
parent | d33601644cd3b09afb2edd9474517edc441c8fad (diff) |
memory hotplug: Define memory_block_size_bytes for powerpc/pseries
Define a version of memory_block_size_bytes() for powerpc/pseries such that
a memory block spans an entire lmb.
Signed-off-by: Nathan Fontenot <nfont@austin.ibm.com>
Reviewed-by: Robin Holt <holt@sgi.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
Diffstat (limited to 'arch/powerpc/platforms/pseries/hotplug-memory.c')
-rw-r--r-- | arch/powerpc/platforms/pseries/hotplug-memory.c | 66 |
1 files changed, 53 insertions, 13 deletions
diff --git a/arch/powerpc/platforms/pseries/hotplug-memory.c b/arch/powerpc/platforms/pseries/hotplug-memory.c index bc8803664140..33867ec4a234 100644 --- a/arch/powerpc/platforms/pseries/hotplug-memory.c +++ b/arch/powerpc/platforms/pseries/hotplug-memory.c | |||
@@ -17,6 +17,54 @@ | |||
17 | #include <asm/pSeries_reconfig.h> | 17 | #include <asm/pSeries_reconfig.h> |
18 | #include <asm/sparsemem.h> | 18 | #include <asm/sparsemem.h> |
19 | 19 | ||
20 | static unsigned long get_memblock_size(void) | ||
21 | { | ||
22 | struct device_node *np; | ||
23 | unsigned int memblock_size = 0; | ||
24 | |||
25 | np = of_find_node_by_path("/ibm,dynamic-reconfiguration-memory"); | ||
26 | if (np) { | ||
27 | const unsigned long *size; | ||
28 | |||
29 | size = of_get_property(np, "ibm,lmb-size", NULL); | ||
30 | memblock_size = size ? *size : 0; | ||
31 | |||
32 | of_node_put(np); | ||
33 | } else { | ||
34 | unsigned int memzero_size = 0; | ||
35 | const unsigned int *regs; | ||
36 | |||
37 | np = of_find_node_by_path("/memory@0"); | ||
38 | if (np) { | ||
39 | regs = of_get_property(np, "reg", NULL); | ||
40 | memzero_size = regs ? regs[3] : 0; | ||
41 | of_node_put(np); | ||
42 | } | ||
43 | |||
44 | if (memzero_size) { | ||
45 | /* We now know the size of memory@0, use this to find | ||
46 | * the first memoryblock and get its size. | ||
47 | */ | ||
48 | char buf[64]; | ||
49 | |||
50 | sprintf(buf, "/memory@%x", memzero_size); | ||
51 | np = of_find_node_by_path(buf); | ||
52 | if (np) { | ||
53 | regs = of_get_property(np, "reg", NULL); | ||
54 | memblock_size = regs ? regs[3] : 0; | ||
55 | of_node_put(np); | ||
56 | } | ||
57 | } | ||
58 | } | ||
59 | |||
60 | return memblock_size; | ||
61 | } | ||
62 | |||
63 | unsigned long memory_block_size_bytes(void) | ||
64 | { | ||
65 | return get_memblock_size(); | ||
66 | } | ||
67 | |||
20 | static int pseries_remove_memblock(unsigned long base, unsigned int memblock_size) | 68 | static int pseries_remove_memblock(unsigned long base, unsigned int memblock_size) |
21 | { | 69 | { |
22 | unsigned long start, start_pfn; | 70 | unsigned long start, start_pfn; |
@@ -127,30 +175,22 @@ static int pseries_add_memory(struct device_node *np) | |||
127 | 175 | ||
128 | static int pseries_drconf_memory(unsigned long *base, unsigned int action) | 176 | static int pseries_drconf_memory(unsigned long *base, unsigned int action) |
129 | { | 177 | { |
130 | struct device_node *np; | 178 | unsigned long memblock_size; |
131 | const unsigned long *lmb_size; | ||
132 | int rc; | 179 | int rc; |
133 | 180 | ||
134 | np = of_find_node_by_path("/ibm,dynamic-reconfiguration-memory"); | 181 | memblock_size = get_memblock_size(); |
135 | if (!np) | 182 | if (!memblock_size) |
136 | return -EINVAL; | 183 | return -EINVAL; |
137 | 184 | ||
138 | lmb_size = of_get_property(np, "ibm,lmb-size", NULL); | ||
139 | if (!lmb_size) { | ||
140 | of_node_put(np); | ||
141 | return -EINVAL; | ||
142 | } | ||
143 | |||
144 | if (action == PSERIES_DRCONF_MEM_ADD) { | 185 | if (action == PSERIES_DRCONF_MEM_ADD) { |
145 | rc = memblock_add(*base, *lmb_size); | 186 | rc = memblock_add(*base, memblock_size); |
146 | rc = (rc < 0) ? -EINVAL : 0; | 187 | rc = (rc < 0) ? -EINVAL : 0; |
147 | } else if (action == PSERIES_DRCONF_MEM_REMOVE) { | 188 | } else if (action == PSERIES_DRCONF_MEM_REMOVE) { |
148 | rc = pseries_remove_memblock(*base, *lmb_size); | 189 | rc = pseries_remove_memblock(*base, memblock_size); |
149 | } else { | 190 | } else { |
150 | rc = -EINVAL; | 191 | rc = -EINVAL; |
151 | } | 192 | } |
152 | 193 | ||
153 | of_node_put(np); | ||
154 | return rc; | 194 | return rc; |
155 | } | 195 | } |
156 | 196 | ||