From b1c8e5f69609fc99b60d89195032428bee60e94c Mon Sep 17 00:00:00 2001 From: Nathan Fontenot Date: Tue, 24 Nov 2009 21:13:32 +0000 Subject: [PATCH] --- yaml --- r: 175823 b: refs/heads/master c: 1a8061c46c46c960f715c597b9d279ea2ba42bd9 h: refs/heads/master i: 175821: 16cc76214deb564343e7647467f13ccbc724e975 175819: d0dff199e746be391aebdc4b8fe7887f36e107c5 175815: 3d9076881f3cfb9334a121f24bfceefe14452ff7 175807: 9a483bab38e6bdfbb4fc7e1183518b57bfa0b126 v: v3 --- [refs] | 2 +- trunk/arch/powerpc/platforms/pseries/dlpar.c | 88 ++++++++++++++++++++ 2 files changed, 89 insertions(+), 1 deletion(-) diff --git a/[refs] b/[refs] index 0d68e38b324a..29d094b4e5ad 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: 12633e803a2a556f6469e0933d08233d0844a2d9 +refs/heads/master: 1a8061c46c46c960f715c597b9d279ea2ba42bd9 diff --git a/trunk/arch/powerpc/platforms/pseries/dlpar.c b/trunk/arch/powerpc/platforms/pseries/dlpar.c index c80e8ef0eb58..fe8d4b3c50cd 100644 --- a/trunk/arch/powerpc/platforms/pseries/dlpar.c +++ b/trunk/arch/powerpc/platforms/pseries/dlpar.c @@ -341,4 +341,92 @@ int dlpar_release_drc(u32 drc_index) return 0; } +#ifdef CONFIG_ARCH_CPU_PROBE_RELEASE +static ssize_t dlpar_cpu_probe(const char *buf, size_t count) +{ + struct device_node *dn; + unsigned long drc_index; + char *cpu_name; + int rc; + + rc = strict_strtoul(buf, 0, &drc_index); + if (rc) + return -EINVAL; + + dn = dlpar_configure_connector(drc_index); + if (!dn) + return -EINVAL; + + /* configure-connector reports cpus as living in the base + * directory of the device tree. CPUs actually live in the + * cpus directory so we need to fixup the full_name. + */ + cpu_name = kzalloc(strlen(dn->full_name) + strlen("/cpus") + 1, + GFP_KERNEL); + if (!cpu_name) { + dlpar_free_cc_nodes(dn); + return -ENOMEM; + } + + sprintf(cpu_name, "/cpus%s", dn->full_name); + kfree(dn->full_name); + dn->full_name = cpu_name; + + rc = dlpar_acquire_drc(drc_index); + if (rc) { + dlpar_free_cc_nodes(dn); + return -EINVAL; + } + + rc = dlpar_attach_node(dn); + if (rc) { + dlpar_release_drc(drc_index); + dlpar_free_cc_nodes(dn); + } + + return rc ? rc : count; +} + +static ssize_t dlpar_cpu_release(const char *buf, size_t count) +{ + struct device_node *dn; + const u32 *drc_index; + int rc; + + dn = of_find_node_by_path(buf); + if (!dn) + return -EINVAL; + + drc_index = of_get_property(dn, "ibm,my-drc-index", NULL); + if (!drc_index) { + of_node_put(dn); + return -EINVAL; + } + + rc = dlpar_release_drc(*drc_index); + if (rc) { + of_node_put(dn); + return -EINVAL; + } + + rc = dlpar_detach_node(dn); + if (rc) { + dlpar_acquire_drc(*drc_index); + return rc; + } + + of_node_put(dn); + return count; +} + +static int __init pseries_dlpar_init(void) +{ + ppc_md.cpu_probe = dlpar_cpu_probe; + ppc_md.cpu_release = dlpar_cpu_release; + + return 0; +} +machine_device_initcall(pseries, pseries_dlpar_init); + +#endif /* CONFIG_ARCH_CPU_PROBE_RELEASE */