23
23
#include <linux/of.h>
24
24
#include <linux/spinlock.h>
25
25
#include <linux/slab.h>
26
+ #include <linux/string.h>
26
27
#include <linux/proc_fs.h>
27
28
28
29
#include "of_private.h"
@@ -35,6 +36,12 @@ struct device_node *of_chosen;
35
36
struct device_node * of_aliases ;
36
37
static struct device_node * of_stdout ;
37
38
39
+ static 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
+ */
38
45
DEFINE_MUTEX (of_aliases_mutex );
39
46
40
47
/* use when traversing tree through the allnext, child, sibling,
@@ -92,14 +99,14 @@ int __weak of_node_to_nid(struct device_node *np)
92
99
struct device_node * of_node_get (struct device_node * node )
93
100
{
94
101
if (node )
95
- kref_get (& node -> kref );
102
+ kobject_get (& node -> kobj );
96
103
return node ;
97
104
}
98
105
EXPORT_SYMBOL (of_node_get );
99
106
100
- static inline struct device_node * kref_to_device_node (struct kref * kref )
107
+ static 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
116
* In of_node_put() this function is passed to kref_put()
110
117
* as the destructor.
111
118
*/
112
- static void of_node_release (struct kref * kref )
119
+ static 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
122
struct property * prop = node -> properties ;
116
123
117
124
/* We should never be releasing nodes that haven't been detached. */
118
125
if (!of_node_check_flag (node , OF_DETACHED )) {
119
126
pr_err ("ERROR: Bad of_node_put() on %s\n" , node -> full_name );
120
127
dump_stack ();
121
- kref_init (& node -> kref );
122
128
return ;
123
129
}
124
130
@@ -151,11 +157,140 @@ static void of_node_release(struct kref *kref)
151
157
void of_node_put (struct device_node * node )
152
158
{
153
159
if (node )
154
- kref_put (& node -> kref , of_node_release );
160
+ kobject_put (& node -> kobj );
155
161
}
156
162
EXPORT_SYMBOL (of_node_put );
163
+ #else
164
+ static void of_node_release (struct kobject * kobj )
165
+ {
166
+ /* Without CONFIG_OF_DYNAMIC, no nodes gets freed */
167
+ }
157
168
#endif /* CONFIG_OF_DYNAMIC */
158
169
170
+ struct kobj_type of_node_ktype = {
171
+ .release = of_node_release ,
172
+ };
173
+
174
+ static 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
+
182
+ static 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
+
202
+ static 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
+
220
+ static 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
+
246
+ int 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 )
258
+ static 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
+
269
+ static 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
+ }
292
+ core_initcall (of_init );
293
+
159
294
static struct property * __of_find_property (const struct device_node * np ,
160
295
const char * name , int * lenp )
161
296
{
@@ -1546,6 +1681,14 @@ int of_add_property(struct device_node *np, struct property *prop)
1546
1681
raw_spin_lock_irqsave (& devtree_lock , flags );
1547
1682
rc = __of_add_property (np , prop );
1548
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
1693
#ifdef CONFIG_PROC_DEVICETREE
1551
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
1736
if (!found )
1594
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
1745
#ifdef CONFIG_PROC_DEVICETREE
1597
1746
/* try to remove the proc node as well */
1598
1747
if (np -> pde )
@@ -1643,13 +1792,20 @@ int of_update_property(struct device_node *np, struct property *newprop)
1643
1792
next = & (* next )-> next ;
1644
1793
}
1645
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
1803
if (!found )
1648
1804
return - ENODEV ;
1649
1805
1650
1806
#ifdef CONFIG_PROC_DEVICETREE
1651
1807
/* try to add to proc as well if it was initialized */
1652
- if (! rc && np -> pde )
1808
+ if (np -> pde )
1653
1809
proc_device_tree_update_prop (np -> pde , newprop , oldprop );
1654
1810
#endif /* CONFIG_PROC_DEVICETREE */
1655
1811
@@ -1723,6 +1879,7 @@ int of_attach_node(struct device_node *np)
1723
1879
of_node_clear_flag (np , OF_DETACHED );
1724
1880
raw_spin_unlock_irqrestore (& devtree_lock , flags );
1725
1881
1882
+ of_node_add (np );
1726
1883
of_add_proc_dt_entry (np );
1727
1884
return 0 ;
1728
1885
}
@@ -1795,6 +1952,7 @@ int of_detach_node(struct device_node *np)
1795
1952
raw_spin_unlock_irqrestore (& devtree_lock , flags );
1796
1953
1797
1954
of_remove_proc_dt_entry (np );
1955
+ of_node_remove (np );
1798
1956
return rc ;
1799
1957
}
1800
1958
#endif /* defined(CONFIG_OF_DYNAMIC) */
0 commit comments