diff options
Diffstat (limited to 'arch')
-rw-r--r-- | arch/powerpc/platforms/pseries/dlpar.c | 188 |
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 | ||
291 | int 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 | |||
325 | out: | ||
326 | return rc; | ||
327 | |||
328 | } | ||
329 | |||
330 | int 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 | |||
378 | out: | ||
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 | ||
359 | static 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 | |||
393 | out: | ||
394 | return rc; | ||
395 | |||
396 | } | ||
397 | |||
451 | static ssize_t dlpar_cpu_probe(const char *buf, size_t count) | 398 | static 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); |
501 | out: | 448 | out: |
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 | ||
454 | static 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 | |||
502 | out: | ||
503 | return rc; | ||
504 | |||
505 | } | ||
506 | |||
507 | static ssize_t dlpar_cpu_release(const char *buf, size_t count) | 507 | static 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; |