aboutsummaryrefslogtreecommitdiffstats
path: root/arch/powerpc/platforms/pseries
diff options
context:
space:
mode:
authorNathan Fontenot <nfont@austin.ibm.com>2009-11-24 16:13:32 -0500
committerBenjamin Herrenschmidt <benh@kernel.crashing.org>2009-12-09 01:09:34 -0500
commit1a8061c46c46c960f715c597b9d279ea2ba42bd9 (patch)
tree1703769dcccf9c367e73d5ccaf851ac4ec53a8b1 /arch/powerpc/platforms/pseries
parent12633e803a2a556f6469e0933d08233d0844a2d9 (diff)
powerpc/pseries: Add kernel based CPU DLPAR handling
This patch adds the specific routines to probe and release (add and remove) cpu resource for the powerpc pseries platform and registers these handlers with the ppc_md callout structure. Signed-off-by: Nathan Fontenot <nfont@austin.ibm.com> Acked-by: Paul Mackerras <paulus@samba.org> Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Diffstat (limited to 'arch/powerpc/platforms/pseries')
-rw-r--r--arch/powerpc/platforms/pseries/dlpar.c88
1 files changed, 88 insertions, 0 deletions
diff --git a/arch/powerpc/platforms/pseries/dlpar.c b/arch/powerpc/platforms/pseries/dlpar.c
index c80e8ef0eb58..fe8d4b3c50cd 100644
--- a/arch/powerpc/platforms/pseries/dlpar.c
+++ b/arch/powerpc/platforms/pseries/dlpar.c
@@ -341,4 +341,92 @@ int dlpar_release_drc(u32 drc_index)
341 return 0; 341 return 0;
342} 342}
343 343
344#ifdef CONFIG_ARCH_CPU_PROBE_RELEASE
344 345
346static ssize_t dlpar_cpu_probe(const char *buf, size_t count)
347{
348 struct device_node *dn;
349 unsigned long drc_index;
350 char *cpu_name;
351 int rc;
352
353 rc = strict_strtoul(buf, 0, &drc_index);
354 if (rc)
355 return -EINVAL;
356
357 dn = dlpar_configure_connector(drc_index);
358 if (!dn)
359 return -EINVAL;
360
361 /* configure-connector reports cpus as living in the base
362 * directory of the device tree. CPUs actually live in the
363 * cpus directory so we need to fixup the full_name.
364 */
365 cpu_name = kzalloc(strlen(dn->full_name) + strlen("/cpus") + 1,
366 GFP_KERNEL);
367 if (!cpu_name) {
368 dlpar_free_cc_nodes(dn);
369 return -ENOMEM;
370 }
371
372 sprintf(cpu_name, "/cpus%s", dn->full_name);
373 kfree(dn->full_name);
374 dn->full_name = cpu_name;
375
376 rc = dlpar_acquire_drc(drc_index);
377 if (rc) {
378 dlpar_free_cc_nodes(dn);
379 return -EINVAL;
380 }
381
382 rc = dlpar_attach_node(dn);
383 if (rc) {
384 dlpar_release_drc(drc_index);
385 dlpar_free_cc_nodes(dn);
386 }
387
388 return rc ? rc : count;
389}
390
391static ssize_t dlpar_cpu_release(const char *buf, size_t count)
392{
393 struct device_node *dn;
394 const u32 *drc_index;
395 int rc;
396
397 dn = of_find_node_by_path(buf);
398 if (!dn)
399 return -EINVAL;
400
401 drc_index = of_get_property(dn, "ibm,my-drc-index", NULL);
402 if (!drc_index) {
403 of_node_put(dn);
404 return -EINVAL;
405 }
406
407 rc = dlpar_release_drc(*drc_index);
408 if (rc) {
409 of_node_put(dn);
410 return -EINVAL;
411 }
412
413 rc = dlpar_detach_node(dn);
414 if (rc) {
415 dlpar_acquire_drc(*drc_index);
416 return rc;
417 }
418
419 of_node_put(dn);
420 return count;
421}
422
423static int __init pseries_dlpar_init(void)
424{
425 ppc_md.cpu_probe = dlpar_cpu_probe;
426 ppc_md.cpu_release = dlpar_cpu_release;
427
428 return 0;
429}
430machine_device_initcall(pseries, pseries_dlpar_init);
431
432#endif /* CONFIG_ARCH_CPU_PROBE_RELEASE */