summaryrefslogtreecommitdiffstats
path: root/drivers/of/base.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/of/base.c')
-rw-r--r--drivers/of/base.c174
1 files changed, 166 insertions, 8 deletions
diff --git a/drivers/of/base.c b/drivers/of/base.c
index 48594f334151..3b70a468c8ab 100644
--- a/drivers/of/base.c
+++ b/drivers/of/base.c
@@ -23,6 +23,7 @@
23#include <linux/of.h> 23#include <linux/of.h>
24#include <linux/spinlock.h> 24#include <linux/spinlock.h>
25#include <linux/slab.h> 25#include <linux/slab.h>
26#include <linux/string.h>
26#include <linux/proc_fs.h> 27#include <linux/proc_fs.h>
27 28
28#include "of_private.h" 29#include "of_private.h"
@@ -35,6 +36,12 @@ struct device_node *of_chosen;
35struct device_node *of_aliases; 36struct device_node *of_aliases;
36static struct device_node *of_stdout; 37static struct device_node *of_stdout;
37 38
39static struct kset *of_kset;
40
41/*
42 * Used to protect the of_aliases; but also overloaded to hold off addition of
43 * nodes to sysfs
44 */
38DEFINE_MUTEX(of_aliases_mutex); 45DEFINE_MUTEX(of_aliases_mutex);
39 46
40/* use when traversing tree through the allnext, child, sibling, 47/* use when traversing tree through the allnext, child, sibling,
@@ -92,14 +99,14 @@ int __weak of_node_to_nid(struct device_node *np)
92struct device_node *of_node_get(struct device_node *node) 99struct device_node *of_node_get(struct device_node *node)
93{ 100{
94 if (node) 101 if (node)
95 kref_get(&node->kref); 102 kobject_get(&node->kobj);
96 return node; 103 return node;
97} 104}
98EXPORT_SYMBOL(of_node_get); 105EXPORT_SYMBOL(of_node_get);
99 106
100static inline struct device_node *kref_to_device_node(struct kref *kref) 107static inline struct device_node *kobj_to_device_node(struct kobject *kobj)
101{ 108{
102 return container_of(kref, struct device_node, kref); 109 return container_of(kobj, struct device_node, kobj);
103} 110}
104 111
105/** 112/**
@@ -109,16 +116,15 @@ static inline struct device_node *kref_to_device_node(struct kref *kref)
109 * In of_node_put() this function is passed to kref_put() 116 * In of_node_put() this function is passed to kref_put()
110 * as the destructor. 117 * as the destructor.
111 */ 118 */
112static void of_node_release(struct kref *kref) 119static void of_node_release(struct kobject *kobj)
113{ 120{
114 struct device_node *node = kref_to_device_node(kref); 121 struct device_node *node = kobj_to_device_node(kobj);
115 struct property *prop = node->properties; 122 struct property *prop = node->properties;
116 123
117 /* We should never be releasing nodes that haven't been detached. */ 124 /* We should never be releasing nodes that haven't been detached. */
118 if (!of_node_check_flag(node, OF_DETACHED)) { 125 if (!of_node_check_flag(node, OF_DETACHED)) {
119 pr_err("ERROR: Bad of_node_put() on %s\n", node->full_name); 126 pr_err("ERROR: Bad of_node_put() on %s\n", node->full_name);
120 dump_stack(); 127 dump_stack();
121 kref_init(&node->kref);
122 return; 128 return;
123 } 129 }
124 130
@@ -151,11 +157,140 @@ static void of_node_release(struct kref *kref)
151void of_node_put(struct device_node *node) 157void of_node_put(struct device_node *node)
152{ 158{
153 if (node) 159 if (node)
154 kref_put(&node->kref, of_node_release); 160 kobject_put(&node->kobj);
155} 161}
156EXPORT_SYMBOL(of_node_put); 162EXPORT_SYMBOL(of_node_put);
163#else
164static void of_node_release(struct kobject *kobj)
165{
166 /* Without CONFIG_OF_DYNAMIC, no nodes gets freed */
167}
157#endif /* CONFIG_OF_DYNAMIC */ 168#endif /* CONFIG_OF_DYNAMIC */
158 169
170struct kobj_type of_node_ktype = {
171 .release = of_node_release,
172};
173
174static ssize_t of_node_property_read(struct file *filp, struct kobject *kobj,
175 struct bin_attribute *bin_attr, char *buf,
176 loff_t offset, size_t count)
177{
178 struct property *pp = container_of(bin_attr, struct property, attr);
179 return memory_read_from_buffer(buf, count, &offset, pp->value, pp->length);
180}
181
182static const char *safe_name(struct kobject *kobj, const char *orig_name)
183{
184 const char *name = orig_name;
185 struct kernfs_node *kn;
186 int i = 0;
187
188 /* don't be a hero. After 16 tries give up */
189 while (i < 16 && (kn = sysfs_get_dirent(kobj->sd, name))) {
190 sysfs_put(kn);
191 if (name != orig_name)
192 kfree(name);
193 name = kasprintf(GFP_KERNEL, "%s#%i", orig_name, ++i);
194 }
195
196 if (name != orig_name)
197 pr_warn("device-tree: Duplicate name in %s, renamed to \"%s\"\n",
198 kobject_name(kobj), name);
199 return name;
200}
201
202static int __of_add_property_sysfs(struct device_node *np, struct property *pp)
203{
204 int rc;
205
206 /* Important: Don't leak passwords */
207 bool secure = strncmp(pp->name, "security-", 9) == 0;
208
209 sysfs_bin_attr_init(&pp->attr);
210 pp->attr.attr.name = safe_name(&np->kobj, pp->name);
211 pp->attr.attr.mode = secure ? S_IRUSR : S_IRUGO;
212 pp->attr.size = secure ? 0 : pp->length;
213 pp->attr.read = of_node_property_read;
214
215 rc = sysfs_create_bin_file(&np->kobj, &pp->attr);
216 WARN(rc, "error adding attribute %s to node %s\n", pp->name, np->full_name);
217 return rc;
218}
219
220static int __of_node_add(struct device_node *np)
221{
222 const char *name;
223 struct property *pp;
224 int rc;
225
226 np->kobj.kset = of_kset;
227 if (!np->parent) {
228 /* Nodes without parents are new top level trees */
229 rc = kobject_add(&np->kobj, NULL, safe_name(&of_kset->kobj, "base"));
230 } else {
231 name = safe_name(&np->parent->kobj, kbasename(np->full_name));
232 if (!name || !name[0])
233 return -EINVAL;
234
235 rc = kobject_add(&np->kobj, &np->parent->kobj, "%s", name);
236 }
237 if (rc)
238 return rc;
239
240 for_each_property_of_node(np, pp)
241 __of_add_property_sysfs(np, pp);
242
243 return 0;
244}
245
246int of_node_add(struct device_node *np)
247{
248 int rc = 0;
249 kobject_init(&np->kobj, &of_node_ktype);
250 mutex_lock(&of_aliases_mutex);
251 if (of_kset)
252 rc = __of_node_add(np);
253 mutex_unlock(&of_aliases_mutex);
254 return rc;
255}
256
257#if defined(CONFIG_OF_DYNAMIC)
258static void of_node_remove(struct device_node *np)
259{
260 struct property *pp;
261
262 for_each_property_of_node(np, pp)
263 sysfs_remove_bin_file(&np->kobj, &pp->attr);
264
265 kobject_del(&np->kobj);
266}
267#endif
268
269static int __init of_init(void)
270{
271 struct device_node *np;
272
273 /* Create the kset, and register existing nodes */
274 mutex_lock(&of_aliases_mutex);
275 of_kset = kset_create_and_add("devicetree", NULL, firmware_kobj);
276 if (!of_kset) {
277 mutex_unlock(&of_aliases_mutex);
278 return -ENOMEM;
279 }
280 for_each_of_allnodes(np)
281 __of_node_add(np);
282 mutex_unlock(&of_aliases_mutex);
283
284#if !defined(CONFIG_PROC_DEVICETREE)
285 /* Symlink to the new tree when PROC_DEVICETREE is disabled */
286 if (of_allnodes)
287 proc_symlink("device-tree", NULL, "/sys/firmware/devicetree/base");
288#endif /* CONFIG_PROC_DEVICETREE */
289
290 return 0;
291}
292core_initcall(of_init);
293
159static struct property *__of_find_property(const struct device_node *np, 294static struct property *__of_find_property(const struct device_node *np,
160 const char *name, int *lenp) 295 const char *name, int *lenp)
161{ 296{
@@ -1546,6 +1681,14 @@ int of_add_property(struct device_node *np, struct property *prop)
1546 raw_spin_lock_irqsave(&devtree_lock, flags); 1681 raw_spin_lock_irqsave(&devtree_lock, flags);
1547 rc = __of_add_property(np, prop); 1682 rc = __of_add_property(np, prop);
1548 raw_spin_unlock_irqrestore(&devtree_lock, flags); 1683 raw_spin_unlock_irqrestore(&devtree_lock, flags);
1684 if (rc)
1685 return rc;
1686
1687 /* at early boot, bail hear and defer setup to of_init() */
1688 if (!of_kset)
1689 return 0;
1690
1691 __of_add_property_sysfs(np, prop);
1549 1692
1550#ifdef CONFIG_PROC_DEVICETREE 1693#ifdef CONFIG_PROC_DEVICETREE
1551 /* try to add to proc as well if it was initialized */ 1694 /* try to add to proc as well if it was initialized */
@@ -1593,6 +1736,12 @@ int of_remove_property(struct device_node *np, struct property *prop)
1593 if (!found) 1736 if (!found)
1594 return -ENODEV; 1737 return -ENODEV;
1595 1738
1739 /* at early boot, bail hear and defer setup to of_init() */
1740 if (!of_kset)
1741 return 0;
1742
1743 sysfs_remove_bin_file(&np->kobj, &prop->attr);
1744
1596#ifdef CONFIG_PROC_DEVICETREE 1745#ifdef CONFIG_PROC_DEVICETREE
1597 /* try to remove the proc node as well */ 1746 /* try to remove the proc node as well */
1598 if (np->pde) 1747 if (np->pde)
@@ -1643,13 +1792,20 @@ int of_update_property(struct device_node *np, struct property *newprop)
1643 next = &(*next)->next; 1792 next = &(*next)->next;
1644 } 1793 }
1645 raw_spin_unlock_irqrestore(&devtree_lock, flags); 1794 raw_spin_unlock_irqrestore(&devtree_lock, flags);
1795 if (rc)
1796 return rc;
1797
1798 /* Update the sysfs attribute */
1799 if (oldprop)
1800 sysfs_remove_bin_file(&np->kobj, &oldprop->attr);
1801 __of_add_property_sysfs(np, newprop);
1646 1802
1647 if (!found) 1803 if (!found)
1648 return -ENODEV; 1804 return -ENODEV;
1649 1805
1650#ifdef CONFIG_PROC_DEVICETREE 1806#ifdef CONFIG_PROC_DEVICETREE
1651 /* try to add to proc as well if it was initialized */ 1807 /* try to add to proc as well if it was initialized */
1652 if (!rc && np->pde) 1808 if (np->pde)
1653 proc_device_tree_update_prop(np->pde, newprop, oldprop); 1809 proc_device_tree_update_prop(np->pde, newprop, oldprop);
1654#endif /* CONFIG_PROC_DEVICETREE */ 1810#endif /* CONFIG_PROC_DEVICETREE */
1655 1811
@@ -1723,6 +1879,7 @@ int of_attach_node(struct device_node *np)
1723 of_node_clear_flag(np, OF_DETACHED); 1879 of_node_clear_flag(np, OF_DETACHED);
1724 raw_spin_unlock_irqrestore(&devtree_lock, flags); 1880 raw_spin_unlock_irqrestore(&devtree_lock, flags);
1725 1881
1882 of_node_add(np);
1726 of_add_proc_dt_entry(np); 1883 of_add_proc_dt_entry(np);
1727 return 0; 1884 return 0;
1728} 1885}
@@ -1795,6 +1952,7 @@ int of_detach_node(struct device_node *np)
1795 raw_spin_unlock_irqrestore(&devtree_lock, flags); 1952 raw_spin_unlock_irqrestore(&devtree_lock, flags);
1796 1953
1797 of_remove_proc_dt_entry(np); 1954 of_remove_proc_dt_entry(np);
1955 of_node_remove(np);
1798 return rc; 1956 return rc;
1799} 1957}
1800#endif /* defined(CONFIG_OF_DYNAMIC) */ 1958#endif /* defined(CONFIG_OF_DYNAMIC) */