diff options
| -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; |
