|
@@ -246,10 +246,19 @@ static int __of_node_add(struct device_node *np)
|
|
|
int of_node_add(struct device_node *np)
|
|
|
{
|
|
|
int rc = 0;
|
|
|
- kobject_init(&np->kobj, &of_node_ktype);
|
|
|
+
|
|
|
+ BUG_ON(!of_node_is_initialized(np));
|
|
|
+
|
|
|
+ /*
|
|
|
+ * Grab the mutex here so that in a race condition between of_init() and
|
|
|
+ * of_node_add(), node addition will still be consistent.
|
|
|
+ */
|
|
|
mutex_lock(&of_aliases_mutex);
|
|
|
if (of_kset)
|
|
|
rc = __of_node_add(np);
|
|
|
+ else
|
|
|
+ /* This scenario may be perfectly valid, but report it anyway */
|
|
|
+ pr_info("of_node_add(%s) before of_init()\n", np->full_name);
|
|
|
mutex_unlock(&of_aliases_mutex);
|
|
|
return rc;
|
|
|
}
|
|
@@ -259,10 +268,17 @@ static void of_node_remove(struct device_node *np)
|
|
|
{
|
|
|
struct property *pp;
|
|
|
|
|
|
- for_each_property_of_node(np, pp)
|
|
|
- sysfs_remove_bin_file(&np->kobj, &pp->attr);
|
|
|
+ BUG_ON(!of_node_is_initialized(np));
|
|
|
+
|
|
|
+ /* only remove properties if on sysfs */
|
|
|
+ if (of_node_is_attached(np)) {
|
|
|
+ for_each_property_of_node(np, pp)
|
|
|
+ sysfs_remove_bin_file(&np->kobj, &pp->attr);
|
|
|
+ kobject_del(&np->kobj);
|
|
|
+ }
|
|
|
|
|
|
- kobject_del(&np->kobj);
|
|
|
+ /* finally remove the kobj_init ref */
|
|
|
+ of_node_put(np);
|
|
|
}
|
|
|
#endif
|
|
|
|
|
@@ -1631,6 +1647,10 @@ static int of_property_notify(int action, struct device_node *np,
|
|
|
{
|
|
|
struct of_prop_reconfig pr;
|
|
|
|
|
|
+ /* only call notifiers if the node is attached */
|
|
|
+ if (!of_node_is_attached(np))
|
|
|
+ return 0;
|
|
|
+
|
|
|
pr.dn = np;
|
|
|
pr.prop = prop;
|
|
|
return of_reconfig_notify(action, &pr);
|
|
@@ -1682,11 +1702,8 @@ int of_add_property(struct device_node *np, struct property *prop)
|
|
|
if (rc)
|
|
|
return rc;
|
|
|
|
|
|
- /* at early boot, bail hear and defer setup to of_init() */
|
|
|
- if (!of_kset)
|
|
|
- return 0;
|
|
|
-
|
|
|
- __of_add_property_sysfs(np, prop);
|
|
|
+ if (of_node_is_attached(np))
|
|
|
+ __of_add_property_sysfs(np, prop);
|
|
|
|
|
|
return rc;
|
|
|
}
|