|
@@ -112,6 +112,7 @@ static ssize_t of_node_property_read(struct file *filp, struct kobject *kobj,
|
|
|
return memory_read_from_buffer(buf, count, &offset, pp->value, pp->length);
|
|
|
}
|
|
|
|
|
|
+/* always return newly allocated name, caller must free after use */
|
|
|
static const char *safe_name(struct kobject *kobj, const char *orig_name)
|
|
|
{
|
|
|
const char *name = orig_name;
|
|
@@ -126,9 +127,12 @@ static const char *safe_name(struct kobject *kobj, const char *orig_name)
|
|
|
name = kasprintf(GFP_KERNEL, "%s#%i", orig_name, ++i);
|
|
|
}
|
|
|
|
|
|
- if (name != orig_name)
|
|
|
+ if (name == orig_name) {
|
|
|
+ name = kstrdup(orig_name, GFP_KERNEL);
|
|
|
+ } else {
|
|
|
pr_warn("device-tree: Duplicate name in %s, renamed to \"%s\"\n",
|
|
|
kobject_name(kobj), name);
|
|
|
+ }
|
|
|
return name;
|
|
|
}
|
|
|
|
|
@@ -159,6 +163,7 @@ int __of_add_property_sysfs(struct device_node *np, struct property *pp)
|
|
|
int __of_attach_node_sysfs(struct device_node *np)
|
|
|
{
|
|
|
const char *name;
|
|
|
+ struct kobject *parent;
|
|
|
struct property *pp;
|
|
|
int rc;
|
|
|
|
|
@@ -171,15 +176,16 @@ int __of_attach_node_sysfs(struct device_node *np)
|
|
|
np->kobj.kset = of_kset;
|
|
|
if (!np->parent) {
|
|
|
/* Nodes without parents are new top level trees */
|
|
|
- rc = kobject_add(&np->kobj, NULL, "%s",
|
|
|
- safe_name(&of_kset->kobj, "base"));
|
|
|
+ name = safe_name(&of_kset->kobj, "base");
|
|
|
+ parent = NULL;
|
|
|
} else {
|
|
|
name = safe_name(&np->parent->kobj, kbasename(np->full_name));
|
|
|
- if (!name || !name[0])
|
|
|
- return -EINVAL;
|
|
|
-
|
|
|
- rc = kobject_add(&np->kobj, &np->parent->kobj, "%s", name);
|
|
|
+ parent = &np->parent->kobj;
|
|
|
}
|
|
|
+ if (!name)
|
|
|
+ return -ENOMEM;
|
|
|
+ rc = kobject_add(&np->kobj, parent, "%s", name);
|
|
|
+ kfree(name);
|
|
|
if (rc)
|
|
|
return rc;
|
|
|
|
|
@@ -1815,6 +1821,12 @@ int __of_remove_property(struct device_node *np, struct property *prop)
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
|
+void __of_sysfs_remove_bin_file(struct device_node *np, struct property *prop)
|
|
|
+{
|
|
|
+ sysfs_remove_bin_file(&np->kobj, &prop->attr);
|
|
|
+ kfree(prop->attr.attr.name);
|
|
|
+}
|
|
|
+
|
|
|
void __of_remove_property_sysfs(struct device_node *np, struct property *prop)
|
|
|
{
|
|
|
if (!IS_ENABLED(CONFIG_SYSFS))
|
|
@@ -1822,7 +1834,7 @@ void __of_remove_property_sysfs(struct device_node *np, struct property *prop)
|
|
|
|
|
|
/* at early boot, bail here and defer setup to of_init() */
|
|
|
if (of_kset && of_node_is_attached(np))
|
|
|
- sysfs_remove_bin_file(&np->kobj, &prop->attr);
|
|
|
+ __of_sysfs_remove_bin_file(np, prop);
|
|
|
}
|
|
|
|
|
|
/**
|
|
@@ -1895,7 +1907,7 @@ void __of_update_property_sysfs(struct device_node *np, struct property *newprop
|
|
|
return;
|
|
|
|
|
|
if (oldprop)
|
|
|
- sysfs_remove_bin_file(&np->kobj, &oldprop->attr);
|
|
|
+ __of_sysfs_remove_bin_file(np, oldprop);
|
|
|
__of_add_property_sysfs(np, newprop);
|
|
|
}
|
|
|
|