diff options
-rw-r--r-- | Documentation/ABI/testing/sysfs-firmware-ofw | 28 | ||||
-rw-r--r-- | arch/powerpc/platforms/pseries/dlpar.c | 2 | ||||
-rw-r--r-- | arch/powerpc/platforms/pseries/reconfig.c | 2 | ||||
-rw-r--r-- | arch/powerpc/sysdev/msi_bitmap.c | 2 | ||||
-rw-r--r-- | drivers/of/base.c | 174 | ||||
-rw-r--r-- | drivers/of/fdt.c | 3 | ||||
-rw-r--r-- | drivers/of/pdt.c | 4 | ||||
-rw-r--r-- | drivers/of/testcase-data/tests-phandle.dtsi | 3 | ||||
-rw-r--r-- | include/linux/of.h | 9 |
9 files changed, 209 insertions, 18 deletions
diff --git a/Documentation/ABI/testing/sysfs-firmware-ofw b/Documentation/ABI/testing/sysfs-firmware-ofw new file mode 100644 index 000000000000..f562b188e71d --- /dev/null +++ b/Documentation/ABI/testing/sysfs-firmware-ofw | |||
@@ -0,0 +1,28 @@ | |||
1 | What: /sys/firmware/devicetree/* | ||
2 | Date: November 2013 | ||
3 | Contact: Grant Likely <grant.likely@linaro.org> | ||
4 | Description: | ||
5 | When using OpenFirmware or a Flattened Device Tree to enumerate | ||
6 | hardware, the device tree structure will be exposed in this | ||
7 | directory. | ||
8 | |||
9 | It is possible for multiple device-tree directories to exist. | ||
10 | Some device drivers use a separate detached device tree which | ||
11 | have no attachment to the system tree and will appear in a | ||
12 | different subdirectory under /sys/firmware/devicetree. | ||
13 | |||
14 | Userspace must not use the /sys/firmware/devicetree/base | ||
15 | path directly, but instead should follow /proc/device-tree | ||
16 | symlink. It is possible that the absolute path will change | ||
17 | in the future, but the symlink is the stable ABI. | ||
18 | |||
19 | The /proc/device-tree symlink replaces the devicetree /proc | ||
20 | filesystem support, and has largely the same semantics and | ||
21 | should be compatible with existing userspace. | ||
22 | |||
23 | The contents of /sys/firmware/devicetree/ is a | ||
24 | hierarchy of directories, one per device tree node. The | ||
25 | directory name is the resolved path component name (node | ||
26 | name plus address). Properties are represented as files | ||
27 | in the directory. The contents of each file is the exact | ||
28 | binary data from the device tree. | ||
diff --git a/arch/powerpc/platforms/pseries/dlpar.c b/arch/powerpc/platforms/pseries/dlpar.c index a8fe5aa3d34f..022b38e6a80b 100644 --- a/arch/powerpc/platforms/pseries/dlpar.c +++ b/arch/powerpc/platforms/pseries/dlpar.c | |||
@@ -11,7 +11,6 @@ | |||
11 | */ | 11 | */ |
12 | 12 | ||
13 | #include <linux/kernel.h> | 13 | #include <linux/kernel.h> |
14 | #include <linux/kref.h> | ||
15 | #include <linux/notifier.h> | 14 | #include <linux/notifier.h> |
16 | #include <linux/spinlock.h> | 15 | #include <linux/spinlock.h> |
17 | #include <linux/cpu.h> | 16 | #include <linux/cpu.h> |
@@ -87,7 +86,6 @@ static struct device_node *dlpar_parse_cc_node(struct cc_workarea *ccwa, | |||
87 | } | 86 | } |
88 | 87 | ||
89 | of_node_set_flag(dn, OF_DYNAMIC); | 88 | of_node_set_flag(dn, OF_DYNAMIC); |
90 | kref_init(&dn->kref); | ||
91 | 89 | ||
92 | return dn; | 90 | return dn; |
93 | } | 91 | } |
diff --git a/arch/powerpc/platforms/pseries/reconfig.c b/arch/powerpc/platforms/pseries/reconfig.c index f93cdf55628c..0435bb65d0aa 100644 --- a/arch/powerpc/platforms/pseries/reconfig.c +++ b/arch/powerpc/platforms/pseries/reconfig.c | |||
@@ -12,7 +12,6 @@ | |||
12 | */ | 12 | */ |
13 | 13 | ||
14 | #include <linux/kernel.h> | 14 | #include <linux/kernel.h> |
15 | #include <linux/kref.h> | ||
16 | #include <linux/notifier.h> | 15 | #include <linux/notifier.h> |
17 | #include <linux/proc_fs.h> | 16 | #include <linux/proc_fs.h> |
18 | #include <linux/slab.h> | 17 | #include <linux/slab.h> |
@@ -70,7 +69,6 @@ static int pSeries_reconfig_add_node(const char *path, struct property *proplist | |||
70 | 69 | ||
71 | np->properties = proplist; | 70 | np->properties = proplist; |
72 | of_node_set_flag(np, OF_DYNAMIC); | 71 | of_node_set_flag(np, OF_DYNAMIC); |
73 | kref_init(&np->kref); | ||
74 | 72 | ||
75 | np->parent = derive_parent(path); | 73 | np->parent = derive_parent(path); |
76 | if (IS_ERR(np->parent)) { | 74 | if (IS_ERR(np->parent)) { |
diff --git a/arch/powerpc/sysdev/msi_bitmap.c b/arch/powerpc/sysdev/msi_bitmap.c index 0968b66b4cf9..8ba60424be95 100644 --- a/arch/powerpc/sysdev/msi_bitmap.c +++ b/arch/powerpc/sysdev/msi_bitmap.c | |||
@@ -202,7 +202,7 @@ void __init test_of_node(void) | |||
202 | 202 | ||
203 | /* There should really be a struct device_node allocator */ | 203 | /* There should really be a struct device_node allocator */ |
204 | memset(&of_node, 0, sizeof(of_node)); | 204 | memset(&of_node, 0, sizeof(of_node)); |
205 | kref_init(&of_node.kref); | 205 | kref_init(&of_node.kobj.kref); |
206 | of_node.full_name = node_name; | 206 | of_node.full_name = node_name; |
207 | 207 | ||
208 | check(0 == msi_bitmap_alloc(&bmp, size, &of_node)); | 208 | check(0 == msi_bitmap_alloc(&bmp, size, &of_node)); |
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; | |||
35 | struct device_node *of_aliases; | 36 | struct device_node *of_aliases; |
36 | static struct device_node *of_stdout; | 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 | DEFINE_MUTEX(of_aliases_mutex); | 45 | DEFINE_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) | |||
92 | struct device_node *of_node_get(struct device_node *node) | 99 | struct 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 | } |
98 | EXPORT_SYMBOL(of_node_get); | 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 | * 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 | */ |
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 | 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) | |||
151 | void of_node_put(struct device_node *node) | 157 | void 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 | } |
156 | EXPORT_SYMBOL(of_node_put); | 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 | #endif /* CONFIG_OF_DYNAMIC */ | 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 | static struct property *__of_find_property(const struct device_node *np, | 294 | static 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) */ |
diff --git a/drivers/of/fdt.c b/drivers/of/fdt.c index 758b4f8b30b7..96ad1ab7f9d6 100644 --- a/drivers/of/fdt.c +++ b/drivers/of/fdt.c | |||
@@ -232,7 +232,6 @@ static void * unflatten_dt_node(struct boot_param_header *blob, | |||
232 | dad->next->sibling = np; | 232 | dad->next->sibling = np; |
233 | dad->next = np; | 233 | dad->next = np; |
234 | } | 234 | } |
235 | kref_init(&np->kref); | ||
236 | } | 235 | } |
237 | /* process properties */ | 236 | /* process properties */ |
238 | while (1) { | 237 | while (1) { |
@@ -327,6 +326,8 @@ static void * unflatten_dt_node(struct boot_param_header *blob, | |||
327 | np->name = "<NULL>"; | 326 | np->name = "<NULL>"; |
328 | if (!np->type) | 327 | if (!np->type) |
329 | np->type = "<NULL>"; | 328 | np->type = "<NULL>"; |
329 | |||
330 | of_node_add(np); | ||
330 | } | 331 | } |
331 | while (tag == OF_DT_BEGIN_NODE || tag == OF_DT_NOP) { | 332 | while (tag == OF_DT_BEGIN_NODE || tag == OF_DT_NOP) { |
332 | if (tag == OF_DT_NOP) | 333 | if (tag == OF_DT_NOP) |
diff --git a/drivers/of/pdt.c b/drivers/of/pdt.c index 7b666736c168..e64fa3d3da5f 100644 --- a/drivers/of/pdt.c +++ b/drivers/of/pdt.c | |||
@@ -179,8 +179,6 @@ static struct device_node * __init of_pdt_create_node(phandle node, | |||
179 | of_pdt_incr_unique_id(dp); | 179 | of_pdt_incr_unique_id(dp); |
180 | dp->parent = parent; | 180 | dp->parent = parent; |
181 | 181 | ||
182 | kref_init(&dp->kref); | ||
183 | |||
184 | dp->name = of_pdt_get_one_property(node, "name"); | 182 | dp->name = of_pdt_get_one_property(node, "name"); |
185 | dp->type = of_pdt_get_one_property(node, "device_type"); | 183 | dp->type = of_pdt_get_one_property(node, "device_type"); |
186 | dp->phandle = node; | 184 | dp->phandle = node; |
@@ -215,6 +213,7 @@ static struct device_node * __init of_pdt_build_tree(struct device_node *parent, | |||
215 | *nextp = &dp->allnext; | 213 | *nextp = &dp->allnext; |
216 | 214 | ||
217 | dp->full_name = of_pdt_build_full_name(dp); | 215 | dp->full_name = of_pdt_build_full_name(dp); |
216 | of_node_add(dp); | ||
218 | 217 | ||
219 | dp->child = of_pdt_build_tree(dp, | 218 | dp->child = of_pdt_build_tree(dp, |
220 | of_pdt_prom_ops->getchild(node), nextp); | 219 | of_pdt_prom_ops->getchild(node), nextp); |
@@ -245,6 +244,7 @@ void __init of_pdt_build_devicetree(phandle root_node, struct of_pdt_ops *ops) | |||
245 | of_allnodes->path_component_name = ""; | 244 | of_allnodes->path_component_name = ""; |
246 | #endif | 245 | #endif |
247 | of_allnodes->full_name = "/"; | 246 | of_allnodes->full_name = "/"; |
247 | of_node_add(of_allnodes); | ||
248 | 248 | ||
249 | nextp = &of_allnodes->allnext; | 249 | nextp = &of_allnodes->allnext; |
250 | of_allnodes->child = of_pdt_build_tree(of_allnodes, | 250 | of_allnodes->child = of_pdt_build_tree(of_allnodes, |
diff --git a/drivers/of/testcase-data/tests-phandle.dtsi b/drivers/of/testcase-data/tests-phandle.dtsi index 0007d3cd7dc2..788a4c24b8f5 100644 --- a/drivers/of/testcase-data/tests-phandle.dtsi +++ b/drivers/of/testcase-data/tests-phandle.dtsi | |||
@@ -1,6 +1,9 @@ | |||
1 | 1 | ||
2 | / { | 2 | / { |
3 | testcase-data { | 3 | testcase-data { |
4 | security-password = "password"; | ||
5 | duplicate-name = "duplicate"; | ||
6 | duplicate-name { }; | ||
4 | phandle-tests { | 7 | phandle-tests { |
5 | provider0: provider0 { | 8 | provider0: provider0 { |
6 | #phandle-cells = <0>; | 9 | #phandle-cells = <0>; |
diff --git a/include/linux/of.h b/include/linux/of.h index b3d0f6d86e3b..bd45be5bd565 100644 --- a/include/linux/of.h +++ b/include/linux/of.h | |||
@@ -18,7 +18,7 @@ | |||
18 | #include <linux/types.h> | 18 | #include <linux/types.h> |
19 | #include <linux/bitops.h> | 19 | #include <linux/bitops.h> |
20 | #include <linux/errno.h> | 20 | #include <linux/errno.h> |
21 | #include <linux/kref.h> | 21 | #include <linux/kobject.h> |
22 | #include <linux/mod_devicetable.h> | 22 | #include <linux/mod_devicetable.h> |
23 | #include <linux/spinlock.h> | 23 | #include <linux/spinlock.h> |
24 | #include <linux/topology.h> | 24 | #include <linux/topology.h> |
@@ -37,6 +37,7 @@ struct property { | |||
37 | struct property *next; | 37 | struct property *next; |
38 | unsigned long _flags; | 38 | unsigned long _flags; |
39 | unsigned int unique_id; | 39 | unsigned int unique_id; |
40 | struct bin_attribute attr; | ||
40 | }; | 41 | }; |
41 | 42 | ||
42 | #if defined(CONFIG_SPARC) | 43 | #if defined(CONFIG_SPARC) |
@@ -57,7 +58,7 @@ struct device_node { | |||
57 | struct device_node *next; /* next device of same type */ | 58 | struct device_node *next; /* next device of same type */ |
58 | struct device_node *allnext; /* next in list of all nodes */ | 59 | struct device_node *allnext; /* next in list of all nodes */ |
59 | struct proc_dir_entry *pde; /* this node's proc directory */ | 60 | struct proc_dir_entry *pde; /* this node's proc directory */ |
60 | struct kref kref; | 61 | struct kobject kobj; |
61 | unsigned long _flags; | 62 | unsigned long _flags; |
62 | void *data; | 63 | void *data; |
63 | #if defined(CONFIG_SPARC) | 64 | #if defined(CONFIG_SPARC) |
@@ -74,6 +75,8 @@ struct of_phandle_args { | |||
74 | uint32_t args[MAX_PHANDLE_ARGS]; | 75 | uint32_t args[MAX_PHANDLE_ARGS]; |
75 | }; | 76 | }; |
76 | 77 | ||
78 | extern int of_node_add(struct device_node *node); | ||
79 | |||
77 | #ifdef CONFIG_OF_DYNAMIC | 80 | #ifdef CONFIG_OF_DYNAMIC |
78 | extern struct device_node *of_node_get(struct device_node *node); | 81 | extern struct device_node *of_node_get(struct device_node *node); |
79 | extern void of_node_put(struct device_node *node); | 82 | extern void of_node_put(struct device_node *node); |
@@ -187,6 +190,8 @@ static inline const char *of_node_full_name(const struct device_node *np) | |||
187 | return np ? np->full_name : "<no-node>"; | 190 | return np ? np->full_name : "<no-node>"; |
188 | } | 191 | } |
189 | 192 | ||
193 | #define for_each_of_allnodes(dn) \ | ||
194 | for (dn = of_allnodes; dn; dn = dn->allnext) | ||
190 | extern struct device_node *of_find_node_by_name(struct device_node *from, | 195 | extern struct device_node *of_find_node_by_name(struct device_node *from, |
191 | const char *name); | 196 | const char *name); |
192 | extern struct device_node *of_find_node_by_type(struct device_node *from, | 197 | extern struct device_node *of_find_node_by_type(struct device_node *from, |