diff options
Diffstat (limited to 'arch/powerpc/platforms/pseries/dlpar.c')
-rw-r--r-- | arch/powerpc/platforms/pseries/dlpar.c | 43 |
1 files changed, 39 insertions, 4 deletions
diff --git a/arch/powerpc/platforms/pseries/dlpar.c b/arch/powerpc/platforms/pseries/dlpar.c index f244dcb4f2cf..fe6320db9255 100644 --- a/arch/powerpc/platforms/pseries/dlpar.c +++ b/arch/powerpc/platforms/pseries/dlpar.c @@ -381,6 +381,32 @@ out: } +static bool dlpar_cpu_exists(struct device_node *parent, u32 drc_index) +{ + struct device_node *child = NULL; + u32 my_drc_index; + bool found; + int rc; + + /* Assume cpu doesn't exist */ + found = false; + + for_each_child_of_node(parent, child) { + rc = of_property_read_u32(child, "ibm,my-drc-index", + &my_drc_index); + if (rc) + continue; + + if (my_drc_index == drc_index) { + of_node_put(child); + found = true; + break; + } + } + + return found; +} + static ssize_t dlpar_cpu_probe(const char *buf, size_t count) { struct device_node *dn, *parent; @@ -391,14 +417,23 @@ static ssize_t dlpar_cpu_probe(const char *buf, size_t count) if (rc) return -EINVAL; - rc = dlpar_acquire_drc(drc_index); - if (rc) - return -EINVAL; - parent = of_find_node_by_path("/cpus"); if (!parent) return -ENODEV; + if (dlpar_cpu_exists(parent, drc_index)) { + of_node_put(parent); + printk(KERN_WARNING "CPU with drc index %x already exists\n", + drc_index); + return -EINVAL; + } + + rc = dlpar_acquire_drc(drc_index); + if (rc) { + of_node_put(parent); + return -EINVAL; + } + dn = dlpar_configure_connector(cpu_to_be32(drc_index), parent); of_node_put(parent); if (!dn) { |