aboutsummaryrefslogtreecommitdiffstats
path: root/arch/powerpc/platforms/pseries/mobility.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/powerpc/platforms/pseries/mobility.c')
-rw-r--r--arch/powerpc/platforms/pseries/mobility.c41
1 files changed, 28 insertions, 13 deletions
diff --git a/arch/powerpc/platforms/pseries/mobility.c b/arch/powerpc/platforms/pseries/mobility.c
index 6573808cc5f3..3d01eee9ffb1 100644
--- a/arch/powerpc/platforms/pseries/mobility.c
+++ b/arch/powerpc/platforms/pseries/mobility.c
@@ -37,14 +37,16 @@ struct update_props_workarea {
37#define UPDATE_DT_NODE 0x02000000 37#define UPDATE_DT_NODE 0x02000000
38#define ADD_DT_NODE 0x03000000 38#define ADD_DT_NODE 0x03000000
39 39
40static int mobility_rtas_call(int token, char *buf) 40#define MIGRATION_SCOPE (1)
41
42static int mobility_rtas_call(int token, char *buf, s32 scope)
41{ 43{
42 int rc; 44 int rc;
43 45
44 spin_lock(&rtas_data_buf_lock); 46 spin_lock(&rtas_data_buf_lock);
45 47
46 memcpy(rtas_data_buf, buf, RTAS_DATA_BUF_SIZE); 48 memcpy(rtas_data_buf, buf, RTAS_DATA_BUF_SIZE);
47 rc = rtas_call(token, 2, 1, NULL, rtas_data_buf, 1); 49 rc = rtas_call(token, 2, 1, NULL, rtas_data_buf, scope);
48 memcpy(buf, rtas_data_buf, RTAS_DATA_BUF_SIZE); 50 memcpy(buf, rtas_data_buf, RTAS_DATA_BUF_SIZE);
49 51
50 spin_unlock(&rtas_data_buf_lock); 52 spin_unlock(&rtas_data_buf_lock);
@@ -123,7 +125,7 @@ static int update_dt_property(struct device_node *dn, struct property **prop,
123 return 0; 125 return 0;
124} 126}
125 127
126static int update_dt_node(u32 phandle) 128static int update_dt_node(u32 phandle, s32 scope)
127{ 129{
128 struct update_props_workarea *upwa; 130 struct update_props_workarea *upwa;
129 struct device_node *dn; 131 struct device_node *dn;
@@ -132,6 +134,7 @@ static int update_dt_node(u32 phandle)
132 char *prop_data; 134 char *prop_data;
133 char *rtas_buf; 135 char *rtas_buf;
134 int update_properties_token; 136 int update_properties_token;
137 u32 vd;
135 138
136 update_properties_token = rtas_token("ibm,update-properties"); 139 update_properties_token = rtas_token("ibm,update-properties");
137 if (update_properties_token == RTAS_UNKNOWN_SERVICE) 140 if (update_properties_token == RTAS_UNKNOWN_SERVICE)
@@ -151,19 +154,31 @@ static int update_dt_node(u32 phandle)
151 upwa->phandle = phandle; 154 upwa->phandle = phandle;
152 155
153 do { 156 do {
154 rc = mobility_rtas_call(update_properties_token, rtas_buf); 157 rc = mobility_rtas_call(update_properties_token, rtas_buf,
158 scope);
155 if (rc < 0) 159 if (rc < 0)
156 break; 160 break;
157 161
158 prop_data = rtas_buf + sizeof(*upwa); 162 prop_data = rtas_buf + sizeof(*upwa);
159 163
160 for (i = 0; i < upwa->nprops; i++) { 164 /* The first element of the buffer is the path of the node
165 * being updated in the form of a 8 byte string length
166 * followed by the string. Skip past this to get to the
167 * properties being updated.
168 */
169 vd = *prop_data++;
170 prop_data += vd;
171
172 /* The path we skipped over is counted as one of the elements
173 * returned so start counting at one.
174 */
175 for (i = 1; i < upwa->nprops; i++) {
161 char *prop_name; 176 char *prop_name;
162 u32 vd;
163 177
164 prop_name = prop_data + 1; 178 prop_name = prop_data;
165 prop_data += strlen(prop_name) + 1; 179 prop_data += strlen(prop_name) + 1;
166 vd = *prop_data++; 180 vd = *(u32 *)prop_data;
181 prop_data += sizeof(vd);
167 182
168 switch (vd) { 183 switch (vd) {
169 case 0x00000000: 184 case 0x00000000:
@@ -219,7 +234,7 @@ static int add_dt_node(u32 parent_phandle, u32 drc_index)
219 return rc; 234 return rc;
220} 235}
221 236
222static int pseries_devicetree_update(void) 237int pseries_devicetree_update(s32 scope)
223{ 238{
224 char *rtas_buf; 239 char *rtas_buf;
225 u32 *data; 240 u32 *data;
@@ -235,7 +250,7 @@ static int pseries_devicetree_update(void)
235 return -ENOMEM; 250 return -ENOMEM;
236 251
237 do { 252 do {
238 rc = mobility_rtas_call(update_nodes_token, rtas_buf); 253 rc = mobility_rtas_call(update_nodes_token, rtas_buf, scope);
239 if (rc && rc != 1) 254 if (rc && rc != 1)
240 break; 255 break;
241 256
@@ -256,7 +271,7 @@ static int pseries_devicetree_update(void)
256 delete_dt_node(phandle); 271 delete_dt_node(phandle);
257 break; 272 break;
258 case UPDATE_DT_NODE: 273 case UPDATE_DT_NODE:
259 update_dt_node(phandle); 274 update_dt_node(phandle, scope);
260 break; 275 break;
261 case ADD_DT_NODE: 276 case ADD_DT_NODE:
262 drc_index = *data++; 277 drc_index = *data++;
@@ -276,7 +291,7 @@ void post_mobility_fixup(void)
276 int rc; 291 int rc;
277 int activate_fw_token; 292 int activate_fw_token;
278 293
279 rc = pseries_devicetree_update(); 294 rc = pseries_devicetree_update(MIGRATION_SCOPE);
280 if (rc) { 295 if (rc) {
281 printk(KERN_ERR "Initial post-mobility device tree update " 296 printk(KERN_ERR "Initial post-mobility device tree update "
282 "failed: %d\n", rc); 297 "failed: %d\n", rc);
@@ -292,7 +307,7 @@ void post_mobility_fixup(void)
292 307
293 rc = rtas_call(activate_fw_token, 0, 1, NULL); 308 rc = rtas_call(activate_fw_token, 0, 1, NULL);
294 if (!rc) { 309 if (!rc) {
295 rc = pseries_devicetree_update(); 310 rc = pseries_devicetree_update(MIGRATION_SCOPE);
296 if (rc) 311 if (rc)
297 printk(KERN_ERR "Secondary post-mobility device tree " 312 printk(KERN_ERR "Secondary post-mobility device tree "
298 "update failed: %d\n", rc); 313 "update failed: %d\n", rc);