summaryrefslogtreecommitdiff
path: root/drivers/of/dynamic.c
diff options
context:
space:
mode:
authorGrant Likely <grant.likely@linaro.org>2014-07-24 03:05:06 +0400
committerGrant Likely <grant.likely@linaro.org>2014-07-24 03:05:06 +0400
commit8a2b22a2595bf89d4396530edf8388159fad9d83 (patch)
treec07a9d0afabc92e922f0894e2cc13245a8c58ab4 /drivers/of/dynamic.c
parentd8c50088417ebf61ad8b132caad20d10f7736034 (diff)
downloadlinux-8a2b22a2595bf89d4396530edf8388159fad9d83.tar.xz
of: Make devicetree sysfs update functions consistent.
All of the DT modification functions are split into two parts, the first part manipulates the DT data structure, and the second part updates sysfs, but the code isn't very consistent about how the second half is called. They don't all enforce the same rules about when it is valid to update sysfs, and there isn't any clarity on locking. The transactional DT modification feature that is coming also needs access to these functions so that it can perform all the structure changes together, and then all the sysfs updates as a second stage instead of doing each one at a time. Fix up the second have by creating a separate __of_*_sysfs() function for each of the helpers. The new functions have consistent naming (ie. of_node_add() becomes __of_attach_node_sysfs()) and all of them now defer if of_init hasn't been called yet. Callers of the new functions must hold the of_mutex to ensure there are no race conditions with of_init(). The mutex ensures that there will only ever be one writer to the tree at any given time. There can still be any number of readers and the raw_spin_lock is still used to make sure access to the data structure is still consistent. Finally, put the function prototypes into of_private.h so they are accessible to the transaction code. Signed-off-by: Pantelis Antoniou <pantelis.antoniou@konsulko.com> [grant.likely: Changed suffix from _post to _sysfs to match existing code] [grant.likely: Reorganized to eliminate trivial wrappers] Signed-off-by: Grant Likely <grant.likely@linaro.org>
Diffstat (limited to 'drivers/of/dynamic.c')
-rw-r--r--drivers/of/dynamic.c12
1 files changed, 9 insertions, 3 deletions
diff --git a/drivers/of/dynamic.c b/drivers/of/dynamic.c
index 75fcc66fcefd..c875787fa394 100644
--- a/drivers/of/dynamic.c
+++ b/drivers/of/dynamic.c
@@ -41,11 +41,13 @@ void of_node_put(struct device_node *node)
}
EXPORT_SYMBOL(of_node_put);
-static void of_node_remove(struct device_node *np)
+void __of_detach_node_sysfs(struct device_node *np)
{
struct property *pp;
BUG_ON(!of_node_is_initialized(np));
+ if (!of_kset)
+ return;
/* only remove properties if on sysfs */
if (of_node_is_attached(np)) {
@@ -115,11 +117,13 @@ int of_attach_node(struct device_node *np)
if (rc)
return rc;
+ mutex_lock(&of_mutex);
raw_spin_lock_irqsave(&devtree_lock, flags);
__of_attach_node(np);
raw_spin_unlock_irqrestore(&devtree_lock, flags);
- of_node_add(np);
+ __of_attach_node_sysfs(np);
+ mutex_unlock(&of_mutex);
return 0;
}
@@ -174,11 +178,13 @@ int of_detach_node(struct device_node *np)
if (rc)
return rc;
+ mutex_lock(&of_mutex);
raw_spin_lock_irqsave(&devtree_lock, flags);
__of_detach_node(np);
raw_spin_unlock_irqrestore(&devtree_lock, flags);
- of_node_remove(np);
+ __of_detach_node_sysfs(np);
+ mutex_unlock(&of_mutex);
return rc;
}