|
@@ -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) {
|