Skip to content

Commit

Permalink
powerpc/pseries: Add kernel based CPU DLPAR handling
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Nathan Fontenot authored and ozbenh committed Dec 9, 2009
1 parent 12633e8 commit 1a8061c
Showing 1 changed file with 88 additions and 0 deletions.
88 changes: 88 additions & 0 deletions arch/powerpc/platforms/pseries/dlpar.c
Original file line number Diff line number Diff line change
Expand Up @@ -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 */

0 comments on commit 1a8061c

Please sign in to comment.