diff options
Diffstat (limited to 'arch/powerpc/platforms/pseries/mobility.c')
-rw-r--r-- | arch/powerpc/platforms/pseries/mobility.c | 41 |
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 | ||
40 | static int mobility_rtas_call(int token, char *buf) | 40 | #define MIGRATION_SCOPE (1) |
41 | |||
42 | static 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 | ||
126 | static int update_dt_node(u32 phandle) | 128 | static 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 | ||
222 | static int pseries_devicetree_update(void) | 237 | int 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); |