aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/powerpc/platforms/pseries/dlpar.c188
1 files changed, 94 insertions, 94 deletions
diff --git a/arch/powerpc/platforms/pseries/dlpar.c b/arch/powerpc/platforms/pseries/dlpar.c
index fd2f0afeb4de..12df9e8812a9 100644
--- a/arch/powerpc/platforms/pseries/dlpar.c
+++ b/arch/powerpc/platforms/pseries/dlpar.c
@@ -288,98 +288,6 @@ int dlpar_detach_node(struct device_node *dn)
288 return 0; 288 return 0;
289} 289}
290 290
291int online_node_cpus(struct device_node *dn)
292{
293 int rc = 0;
294 unsigned int cpu;
295 int len, nthreads, i;
296 const u32 *intserv;
297
298 intserv = of_get_property(dn, "ibm,ppc-interrupt-server#s", &len);
299 if (!intserv)
300 return -EINVAL;
301
302 nthreads = len / sizeof(u32);
303
304 cpu_maps_update_begin();
305 for (i = 0; i < nthreads; i++) {
306 for_each_present_cpu(cpu) {
307 if (get_hard_smp_processor_id(cpu) != intserv[i])
308 continue;
309 BUG_ON(get_cpu_current_state(cpu)
310 != CPU_STATE_OFFLINE);
311 cpu_maps_update_done();
312 rc = cpu_up(cpu);
313 if (rc)
314 goto out;
315 cpu_maps_update_begin();
316
317 break;
318 }
319 if (cpu == num_possible_cpus())
320 printk(KERN_WARNING "Could not find cpu to online "
321 "with physical id 0x%x\n", intserv[i]);
322 }
323 cpu_maps_update_done();
324
325out:
326 return rc;
327
328}
329
330int offline_node_cpus(struct device_node *dn)
331{
332 int rc = 0;
333 unsigned int cpu;
334 int len, nthreads, i;
335 const u32 *intserv;
336
337 intserv = of_get_property(dn, "ibm,ppc-interrupt-server#s", &len);
338 if (!intserv)
339 return -EINVAL;
340
341 nthreads = len / sizeof(u32);
342
343 cpu_maps_update_begin();
344 for (i = 0; i < nthreads; i++) {
345 for_each_present_cpu(cpu) {
346 if (get_hard_smp_processor_id(cpu) != intserv[i])
347 continue;
348
349 if (get_cpu_current_state(cpu) == CPU_STATE_OFFLINE)
350 break;
351
352 if (get_cpu_current_state(cpu) == CPU_STATE_ONLINE) {
353 cpu_maps_update_done();
354 rc = cpu_down(cpu);
355 if (rc)
356 goto out;
357 cpu_maps_update_begin();
358 break;
359
360 }
361
362 /*
363 * The cpu is in CPU_STATE_INACTIVE.
364 * Upgrade it's state to CPU_STATE_OFFLINE.
365 */
366 set_preferred_offline_state(cpu, CPU_STATE_OFFLINE);
367 BUG_ON(plpar_hcall_norets(H_PROD, intserv[i])
368 != H_SUCCESS);
369 __cpu_die(cpu);
370 break;
371 }
372 if (cpu == num_possible_cpus())
373 printk(KERN_WARNING "Could not find cpu to offline "
374 "with physical id 0x%x\n", intserv[i]);
375 }
376 cpu_maps_update_done();
377
378out:
379 return rc;
380
381}
382
383#define DR_ENTITY_SENSE 9003 291#define DR_ENTITY_SENSE 9003
384#define DR_ENTITY_PRESENT 1 292#define DR_ENTITY_PRESENT 1
385#define DR_ENTITY_UNUSABLE 2 293#define DR_ENTITY_UNUSABLE 2
@@ -448,6 +356,45 @@ void cpu_hotplug_driver_unlock()
448 mutex_unlock(&pseries_cpu_hotplug_mutex); 356 mutex_unlock(&pseries_cpu_hotplug_mutex);
449} 357}
450 358
359static int dlpar_online_cpu(struct device_node *dn)
360{
361 int rc = 0;
362 unsigned int cpu;
363 int len, nthreads, i;
364 const u32 *intserv;
365
366 intserv = of_get_property(dn, "ibm,ppc-interrupt-server#s", &len);
367 if (!intserv)
368 return -EINVAL;
369
370 nthreads = len / sizeof(u32);
371
372 cpu_maps_update_begin();
373 for (i = 0; i < nthreads; i++) {
374 for_each_present_cpu(cpu) {
375 if (get_hard_smp_processor_id(cpu) != intserv[i])
376 continue;
377 BUG_ON(get_cpu_current_state(cpu)
378 != CPU_STATE_OFFLINE);
379 cpu_maps_update_done();
380 rc = cpu_up(cpu);
381 if (rc)
382 goto out;
383 cpu_maps_update_begin();
384
385 break;
386 }
387 if (cpu == num_possible_cpus())
388 printk(KERN_WARNING "Could not find cpu to online "
389 "with physical id 0x%x\n", intserv[i]);
390 }
391 cpu_maps_update_done();
392
393out:
394 return rc;
395
396}
397
451static ssize_t dlpar_cpu_probe(const char *buf, size_t count) 398static ssize_t dlpar_cpu_probe(const char *buf, size_t count)
452{ 399{
453 struct device_node *dn; 400 struct device_node *dn;
@@ -497,13 +444,66 @@ static ssize_t dlpar_cpu_probe(const char *buf, size_t count)
497 dlpar_free_cc_nodes(dn); 444 dlpar_free_cc_nodes(dn);
498 } 445 }
499 446
500 rc = online_node_cpus(dn); 447 rc = dlpar_online_cpu(dn);
501out: 448out:
502 cpu_hotplug_driver_unlock(); 449 cpu_hotplug_driver_unlock();
503 450
504 return rc ? rc : count; 451 return rc ? rc : count;
505} 452}
506 453
454static int dlpar_offline_cpu(struct device_node *dn)
455{
456 int rc = 0;
457 unsigned int cpu;
458 int len, nthreads, i;
459 const u32 *intserv;
460
461 intserv = of_get_property(dn, "ibm,ppc-interrupt-server#s", &len);
462 if (!intserv)
463 return -EINVAL;
464
465 nthreads = len / sizeof(u32);
466
467 cpu_maps_update_begin();
468 for (i = 0; i < nthreads; i++) {
469 for_each_present_cpu(cpu) {
470 if (get_hard_smp_processor_id(cpu) != intserv[i])
471 continue;
472
473 if (get_cpu_current_state(cpu) == CPU_STATE_OFFLINE)
474 break;
475
476 if (get_cpu_current_state(cpu) == CPU_STATE_ONLINE) {
477 cpu_maps_update_done();
478 rc = cpu_down(cpu);
479 if (rc)
480 goto out;
481 cpu_maps_update_begin();
482 break;
483
484 }
485
486 /*
487 * The cpu is in CPU_STATE_INACTIVE.
488 * Upgrade it's state to CPU_STATE_OFFLINE.
489 */
490 set_preferred_offline_state(cpu, CPU_STATE_OFFLINE);
491 BUG_ON(plpar_hcall_norets(H_PROD, intserv[i])
492 != H_SUCCESS);
493 __cpu_die(cpu);
494 break;
495 }
496 if (cpu == num_possible_cpus())
497 printk(KERN_WARNING "Could not find cpu to offline "
498 "with physical id 0x%x\n", intserv[i]);
499 }
500 cpu_maps_update_done();
501
502out:
503 return rc;
504
505}
506
507static ssize_t dlpar_cpu_release(const char *buf, size_t count) 507static ssize_t dlpar_cpu_release(const char *buf, size_t count)
508{ 508{
509 struct device_node *dn; 509 struct device_node *dn;
@@ -521,7 +521,7 @@ static ssize_t dlpar_cpu_release(const char *buf, size_t count)
521 } 521 }
522 522
523 cpu_hotplug_driver_lock(); 523 cpu_hotplug_driver_lock();
524 rc = offline_node_cpus(dn); 524 rc = dlpar_offline_cpu(dn);
525 if (rc) { 525 if (rc) {
526 of_node_put(dn); 526 of_node_put(dn);
527 rc = -EINVAL; 527 rc = -EINVAL;