aboutsummaryrefslogtreecommitdiffstats
path: root/arch/powerpc/platforms
diff options
context:
space:
mode:
authorNathan Fontenot <nfont@linux.vnet.ibm.com>2013-04-24 01:47:11 -0400
committerBenjamin Herrenschmidt <benh@kernel.crashing.org>2013-04-26 02:08:19 -0400
commit762ec15707518ad06531841df73ded857886f253 (patch)
tree91e062896d91d13e03469574fd864d322082527c /arch/powerpc/platforms
parent3e96ca7f007ddb06b82a74a68585d1dbafa85ff1 (diff)
powerpc/pseries: Expose pseries devicetree_update()
Newer firmware on Power systems can transparently reassign platform resources (CPU and Memory) in use. For instance, if a processor or memory unit is predicted to fail, the platform may transparently move the processing to an equivalent unused processor or the memory state to an equivalent unused memory unit. However, reassigning resources across NUMA boundaries may alter the performance of the partition. When such reassignment is necessary, the Platform Resource Reassignment Notification (PRRN) option provides a mechanism to inform the Linux kernel of changes to the NUMA affinity of its platform resources. When rtasd receives a PRRN event, it needs to make a series of RTAS calls (ibm,update-nodes and ibm,update-properties) to retrieve the updated device tree information. These calls are already handled in the pseries_devicetree_update() routine used in partition migration. This patch exposes pseries_devicetree_update() to make it accessible to other pseries routines, this patch also updates pseries_devicetree_update() to take a 32-bit scope parameter. The scope value, which was previously hard coded to 1 for partition migration, is used for the RTAS calls ibm,update-nodes/properties to update the device tree. Signed-off-by: Nathan Fontenot <nfont@linux.vnet.ibm.com> Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Diffstat (limited to 'arch/powerpc/platforms')
-rw-r--r--arch/powerpc/platforms/pseries/mobility.c21
1 files changed, 12 insertions, 9 deletions
diff --git a/arch/powerpc/platforms/pseries/mobility.c b/arch/powerpc/platforms/pseries/mobility.c
index 6573808cc5f3..4c184ceb2450 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;
@@ -151,7 +153,8 @@ static int update_dt_node(u32 phandle)
151 upwa->phandle = phandle; 153 upwa->phandle = phandle;
152 154
153 do { 155 do {
154 rc = mobility_rtas_call(update_properties_token, rtas_buf); 156 rc = mobility_rtas_call(update_properties_token, rtas_buf,
157 scope);
155 if (rc < 0) 158 if (rc < 0)
156 break; 159 break;
157 160
@@ -219,7 +222,7 @@ static int add_dt_node(u32 parent_phandle, u32 drc_index)
219 return rc; 222 return rc;
220} 223}
221 224
222static int pseries_devicetree_update(void) 225int pseries_devicetree_update(s32 scope)
223{ 226{
224 char *rtas_buf; 227 char *rtas_buf;
225 u32 *data; 228 u32 *data;
@@ -235,7 +238,7 @@ static int pseries_devicetree_update(void)
235 return -ENOMEM; 238 return -ENOMEM;
236 239
237 do { 240 do {
238 rc = mobility_rtas_call(update_nodes_token, rtas_buf); 241 rc = mobility_rtas_call(update_nodes_token, rtas_buf, scope);
239 if (rc && rc != 1) 242 if (rc && rc != 1)
240 break; 243 break;
241 244
@@ -256,7 +259,7 @@ static int pseries_devicetree_update(void)
256 delete_dt_node(phandle); 259 delete_dt_node(phandle);
257 break; 260 break;
258 case UPDATE_DT_NODE: 261 case UPDATE_DT_NODE:
259 update_dt_node(phandle); 262 update_dt_node(phandle, scope);
260 break; 263 break;
261 case ADD_DT_NODE: 264 case ADD_DT_NODE:
262 drc_index = *data++; 265 drc_index = *data++;
@@ -276,7 +279,7 @@ void post_mobility_fixup(void)
276 int rc; 279 int rc;
277 int activate_fw_token; 280 int activate_fw_token;
278 281
279 rc = pseries_devicetree_update(); 282 rc = pseries_devicetree_update(MIGRATION_SCOPE);
280 if (rc) { 283 if (rc) {
281 printk(KERN_ERR "Initial post-mobility device tree update " 284 printk(KERN_ERR "Initial post-mobility device tree update "
282 "failed: %d\n", rc); 285 "failed: %d\n", rc);
@@ -292,7 +295,7 @@ void post_mobility_fixup(void)
292 295
293 rc = rtas_call(activate_fw_token, 0, 1, NULL); 296 rc = rtas_call(activate_fw_token, 0, 1, NULL);
294 if (!rc) { 297 if (!rc) {
295 rc = pseries_devicetree_update(); 298 rc = pseries_devicetree_update(MIGRATION_SCOPE);
296 if (rc) 299 if (rc)
297 printk(KERN_ERR "Secondary post-mobility device tree " 300 printk(KERN_ERR "Secondary post-mobility device tree "
298 "update failed: %d\n", rc); 301 "update failed: %d\n", rc);