Skip to content

Commit 1a8061c

Browse files
Nathan Fontenotozbenh
authored andcommitted
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 <[email protected]> Acked-by: Paul Mackerras <[email protected]> Signed-off-by: Benjamin Herrenschmidt <[email protected]>
1 parent 12633e8 commit 1a8061c

File tree

1 file changed

+88
-0
lines changed
  • arch/powerpc/platforms/pseries

1 file changed

+88
-0
lines changed

arch/powerpc/platforms/pseries/dlpar.c

Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -341,4 +341,92 @@ int dlpar_release_drc(u32 drc_index)
341341
return 0;
342342
}
343343

344+
#ifdef CONFIG_ARCH_CPU_PROBE_RELEASE
344345

346+
static 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+
391+
static 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+
423+
static 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+
}
430+
machine_device_initcall(pseries, pseries_dlpar_init);
431+
432+
#endif /* CONFIG_ARCH_CPU_PROBE_RELEASE */

0 commit comments

Comments
 (0)