aboutsummaryrefslogtreecommitdiffstats
path: root/arch/powerpc/platforms/pseries/hotplug-memory.c
diff options
context:
space:
mode:
authorNathan Fontenot <nfont@austin.ibm.com>2008-07-02 23:20:58 -0400
committerPaul Mackerras <paulus@samba.org>2008-07-03 02:58:15 -0400
commit92ecd1790b10e12015070e33a0f70493d51aca50 (patch)
tree963939590411d5c9c04c59bc72d183808d9aa7ba /arch/powerpc/platforms/pseries/hotplug-memory.c
parent4b6e805e4a327c7231ab6a7739d6344d68d231d0 (diff)
powerpc/pseries: Use base address to derive starting page frame number
Use the base address of the lmb to derive the starting page frame number instead of trying to extract it from the drc index of the lmb. The drc index should not be used for this as it will, and did, break. Until this point, systems that have had memory represented in the device tree with a node for each lmb the drc index would (luckily) closely track the base address of the lmb. For example a lmb with a drc index of 8000000a would have a base address of a0000000. This correlation allowed the current code to derive the starting page frame number from the drc inddex Device tree layouts where lmbs are represented under the ibm,dynamic-reconfiguration-memory node in the ibm,dynamic-memory property do not have this correlation between the drc index and base address of the lmb. Signed-off-by: Nathan Fontenot <nfont@austin.ibm.com> Signed-off-by: Paul Mackerras <paulus@samba.org>
Diffstat (limited to 'arch/powerpc/platforms/pseries/hotplug-memory.c')
-rw-r--r--arch/powerpc/platforms/pseries/hotplug-memory.c36
1 files changed, 17 insertions, 19 deletions
diff --git a/arch/powerpc/platforms/pseries/hotplug-memory.c b/arch/powerpc/platforms/pseries/hotplug-memory.c
index 3c5727dd5aa..18a8138ef99 100644
--- a/arch/powerpc/platforms/pseries/hotplug-memory.c
+++ b/arch/powerpc/platforms/pseries/hotplug-memory.c
@@ -18,8 +18,9 @@
18static int pseries_remove_memory(struct device_node *np) 18static int pseries_remove_memory(struct device_node *np)
19{ 19{
20 const char *type; 20 const char *type;
21 const unsigned int *my_index;
22 const unsigned int *regs; 21 const unsigned int *regs;
22 unsigned long base;
23 unsigned int lmb_size;
23 u64 start_pfn, start; 24 u64 start_pfn, start;
24 struct zone *zone; 25 struct zone *zone;
25 int ret = -EINVAL; 26 int ret = -EINVAL;
@@ -32,17 +33,16 @@ static int pseries_remove_memory(struct device_node *np)
32 return 0; 33 return 0;
33 34
34 /* 35 /*
35 * Find the memory index and size of the removing section 36 * Find the bae address and size of the lmb
36 */ 37 */
37 my_index = of_get_property(np, "ibm,my-drc-index", NULL);
38 if (!my_index)
39 return ret;
40
41 regs = of_get_property(np, "reg", NULL); 38 regs = of_get_property(np, "reg", NULL);
42 if (!regs) 39 if (!regs)
43 return ret; 40 return ret;
44 41
45 start_pfn = section_nr_to_pfn(*my_index & 0xffff); 42 base = *(unsigned long *)regs;
43 lmb_size = regs[3];
44
45 start_pfn = base >> PFN_SECTION_SHIFT;
46 zone = page_zone(pfn_to_page(start_pfn)); 46 zone = page_zone(pfn_to_page(start_pfn));
47 47
48 /* 48 /*
@@ -54,28 +54,29 @@ static int pseries_remove_memory(struct device_node *np)
54 * to sysfs "state" file and we can't remove sysfs entries 54 * to sysfs "state" file and we can't remove sysfs entries
55 * while writing to it. So we have to defer it to here. 55 * while writing to it. So we have to defer it to here.
56 */ 56 */
57 ret = __remove_pages(zone, start_pfn, regs[3] >> PAGE_SHIFT); 57 ret = __remove_pages(zone, start_pfn, lmb_size >> PAGE_SHIFT);
58 if (ret) 58 if (ret)
59 return ret; 59 return ret;
60 60
61 /* 61 /*
62 * Update memory regions for memory remove 62 * Update memory regions for memory remove
63 */ 63 */
64 lmb_remove(start_pfn << PAGE_SHIFT, regs[3]); 64 lmb_remove(base, lmb_size);
65 65
66 /* 66 /*
67 * Remove htab bolted mappings for this section of memory 67 * Remove htab bolted mappings for this section of memory
68 */ 68 */
69 start = (unsigned long)__va(start_pfn << PAGE_SHIFT); 69 start = (unsigned long)__va(base);
70 ret = remove_section_mapping(start, start + regs[3]); 70 ret = remove_section_mapping(start, start + lmb_size);
71 return ret; 71 return ret;
72} 72}
73 73
74static int pseries_add_memory(struct device_node *np) 74static int pseries_add_memory(struct device_node *np)
75{ 75{
76 const char *type; 76 const char *type;
77 const unsigned int *my_index;
78 const unsigned int *regs; 77 const unsigned int *regs;
78 unsigned long base;
79 unsigned int lmb_size;
79 u64 start_pfn; 80 u64 start_pfn;
80 int ret = -EINVAL; 81 int ret = -EINVAL;
81 82
@@ -87,22 +88,19 @@ static int pseries_add_memory(struct device_node *np)
87 return 0; 88 return 0;
88 89
89 /* 90 /*
90 * Find the memory index and size of the added section 91 * Find the base and size of the lmb
91 */ 92 */
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); 93 regs = of_get_property(np, "reg", NULL);
97 if (!regs) 94 if (!regs)
98 return ret; 95 return ret;
99 96
100 start_pfn = section_nr_to_pfn(*my_index & 0xffff); 97 base = *(unsigned long *)regs;
98 lmb_size = regs[3];
101 99
102 /* 100 /*
103 * Update memory region to represent the memory add 101 * Update memory region to represent the memory add
104 */ 102 */
105 lmb_add(start_pfn << PAGE_SHIFT, regs[3]); 103 lmb_add(base, lmb_size);
106 return 0; 104 return 0;
107} 105}
108 106