diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2014-04-02 17:27:15 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2014-04-02 17:27:15 -0400 |
commit | b9f2b21a32906a47c220b5167b88869f2c90f1c4 (patch) | |
tree | 96416cec877f9c1f2ee0f0ccdee64e38cc8e0683 /fs/proc | |
parent | 70f6c087573eeb406252ff8d98f511eb5f71496e (diff) | |
parent | a0e7398357f297dd22d043fb2d5aa1c44d61ca10 (diff) |
Merge tag 'dt-for-linus' of git://git.secretlab.ca/git/linux
Pull devicetree changes from Grant Likely:
"Updates to devicetree core code. This branch contains the following
notable changes:
- add reserved memory binding
- make struct device_node a kobject and remove legacy
/proc/device-tree
- ePAPR conformance fixes
- update in-kernel DTC copy to version v1.4.0
- preparatory changes for dynamic device tree overlays
- minor bug fixes and documentation changes
The most significant change in this branch is the conversion of struct
device_node to be a kobject that is exposed via sysfs and removal of
the old /proc/device-tree code. This simplifies the device tree
handling code and tightens up the lifecycle on device tree nodes.
[updated: added fix for dangling select PROC_DEVICETREE]"
* tag 'dt-for-linus' of git://git.secretlab.ca/git/linux: (29 commits)
dt: Remove dangling "select PROC_DEVICETREE"
of: Add support for ePAPR "stdout-path" property
of: device_node kobject lifecycle fixes
of: only scan for reserved mem when fdt present
powerpc: add support for reserved memory defined by device tree
arm64: add support for reserved memory defined by device tree
of: add missing major vendors
of: add vendor prefix for SMSC
of: remove /proc/device-tree
of/selftest: Add self tests for manipulation of properties
of: Make device nodes kobjects so they show up in sysfs
arm: add support for reserved memory defined by device tree
drivers: of: add support for custom reserved memory drivers
drivers: of: add initialization code for dynamic reserved memory
drivers: of: add initialization code for static reserved memory
of: document bindings for reserved-memory nodes
Revert "of: fix of_update_property()"
kbuild: dtbs_install: new make target
ARM: mvebu: Allows to get the SoC ID even without PCI enabled
of: Allows to use the PCI translator without the PCI core
...
Diffstat (limited to 'fs/proc')
-rw-r--r-- | fs/proc/Makefile | 1 | ||||
-rw-r--r-- | fs/proc/internal.h | 7 | ||||
-rw-r--r-- | fs/proc/proc_devtree.c | 241 | ||||
-rw-r--r-- | fs/proc/root.c | 3 |
4 files changed, 0 insertions, 252 deletions
diff --git a/fs/proc/Makefile b/fs/proc/Makefile index ab30716584f5..239493ec718e 100644 --- a/fs/proc/Makefile +++ b/fs/proc/Makefile | |||
@@ -27,6 +27,5 @@ proc-$(CONFIG_PROC_SYSCTL) += proc_sysctl.o | |||
27 | proc-$(CONFIG_NET) += proc_net.o | 27 | proc-$(CONFIG_NET) += proc_net.o |
28 | proc-$(CONFIG_PROC_KCORE) += kcore.o | 28 | proc-$(CONFIG_PROC_KCORE) += kcore.o |
29 | proc-$(CONFIG_PROC_VMCORE) += vmcore.o | 29 | proc-$(CONFIG_PROC_VMCORE) += vmcore.o |
30 | proc-$(CONFIG_PROC_DEVICETREE) += proc_devtree.o | ||
31 | proc-$(CONFIG_PRINTK) += kmsg.o | 30 | proc-$(CONFIG_PRINTK) += kmsg.o |
32 | proc-$(CONFIG_PROC_PAGE_MONITOR) += page.o | 31 | proc-$(CONFIG_PROC_PAGE_MONITOR) += page.o |
diff --git a/fs/proc/internal.h b/fs/proc/internal.h index 651d09a11dde..3ab6d14e71c5 100644 --- a/fs/proc/internal.h +++ b/fs/proc/internal.h | |||
@@ -211,13 +211,6 @@ extern int proc_fill_super(struct super_block *); | |||
211 | extern void proc_entry_rundown(struct proc_dir_entry *); | 211 | extern void proc_entry_rundown(struct proc_dir_entry *); |
212 | 212 | ||
213 | /* | 213 | /* |
214 | * proc_devtree.c | ||
215 | */ | ||
216 | #ifdef CONFIG_PROC_DEVICETREE | ||
217 | extern void proc_device_tree_init(void); | ||
218 | #endif | ||
219 | |||
220 | /* | ||
221 | * proc_namespaces.c | 214 | * proc_namespaces.c |
222 | */ | 215 | */ |
223 | extern const struct inode_operations proc_ns_dir_inode_operations; | 216 | extern const struct inode_operations proc_ns_dir_inode_operations; |
diff --git a/fs/proc/proc_devtree.c b/fs/proc/proc_devtree.c deleted file mode 100644 index c82dd5147845..000000000000 --- a/fs/proc/proc_devtree.c +++ /dev/null | |||
@@ -1,241 +0,0 @@ | |||
1 | /* | ||
2 | * proc_devtree.c - handles /proc/device-tree | ||
3 | * | ||
4 | * Copyright 1997 Paul Mackerras | ||
5 | */ | ||
6 | #include <linux/errno.h> | ||
7 | #include <linux/init.h> | ||
8 | #include <linux/time.h> | ||
9 | #include <linux/proc_fs.h> | ||
10 | #include <linux/seq_file.h> | ||
11 | #include <linux/printk.h> | ||
12 | #include <linux/stat.h> | ||
13 | #include <linux/string.h> | ||
14 | #include <linux/of.h> | ||
15 | #include <linux/export.h> | ||
16 | #include <linux/slab.h> | ||
17 | #include <asm/uaccess.h> | ||
18 | #include "internal.h" | ||
19 | |||
20 | static inline void set_node_proc_entry(struct device_node *np, | ||
21 | struct proc_dir_entry *de) | ||
22 | { | ||
23 | np->pde = de; | ||
24 | } | ||
25 | |||
26 | static struct proc_dir_entry *proc_device_tree; | ||
27 | |||
28 | /* | ||
29 | * Supply data on a read from /proc/device-tree/node/property. | ||
30 | */ | ||
31 | static int property_proc_show(struct seq_file *m, void *v) | ||
32 | { | ||
33 | struct property *pp = m->private; | ||
34 | |||
35 | seq_write(m, pp->value, pp->length); | ||
36 | return 0; | ||
37 | } | ||
38 | |||
39 | static int property_proc_open(struct inode *inode, struct file *file) | ||
40 | { | ||
41 | return single_open(file, property_proc_show, __PDE_DATA(inode)); | ||
42 | } | ||
43 | |||
44 | static const struct file_operations property_proc_fops = { | ||
45 | .owner = THIS_MODULE, | ||
46 | .open = property_proc_open, | ||
47 | .read = seq_read, | ||
48 | .llseek = seq_lseek, | ||
49 | .release = single_release, | ||
50 | }; | ||
51 | |||
52 | /* | ||
53 | * For a node with a name like "gc@10", we make symlinks called "gc" | ||
54 | * and "@10" to it. | ||
55 | */ | ||
56 | |||
57 | /* | ||
58 | * Add a property to a node | ||
59 | */ | ||
60 | static struct proc_dir_entry * | ||
61 | __proc_device_tree_add_prop(struct proc_dir_entry *de, struct property *pp, | ||
62 | const char *name) | ||
63 | { | ||
64 | struct proc_dir_entry *ent; | ||
65 | |||
66 | /* | ||
67 | * Unfortunately proc_register puts each new entry | ||
68 | * at the beginning of the list. So we rearrange them. | ||
69 | */ | ||
70 | ent = proc_create_data(name, | ||
71 | strncmp(name, "security-", 9) ? S_IRUGO : S_IRUSR, | ||
72 | de, &property_proc_fops, pp); | ||
73 | if (ent == NULL) | ||
74 | return NULL; | ||
75 | |||
76 | if (!strncmp(name, "security-", 9)) | ||
77 | proc_set_size(ent, 0); /* don't leak number of password chars */ | ||
78 | else | ||
79 | proc_set_size(ent, pp->length); | ||
80 | |||
81 | return ent; | ||
82 | } | ||
83 | |||
84 | |||
85 | void proc_device_tree_add_prop(struct proc_dir_entry *pde, struct property *prop) | ||
86 | { | ||
87 | __proc_device_tree_add_prop(pde, prop, prop->name); | ||
88 | } | ||
89 | |||
90 | void proc_device_tree_remove_prop(struct proc_dir_entry *pde, | ||
91 | struct property *prop) | ||
92 | { | ||
93 | remove_proc_entry(prop->name, pde); | ||
94 | } | ||
95 | |||
96 | void proc_device_tree_update_prop(struct proc_dir_entry *pde, | ||
97 | struct property *newprop, | ||
98 | struct property *oldprop) | ||
99 | { | ||
100 | struct proc_dir_entry *ent; | ||
101 | |||
102 | if (!oldprop) { | ||
103 | proc_device_tree_add_prop(pde, newprop); | ||
104 | return; | ||
105 | } | ||
106 | |||
107 | for (ent = pde->subdir; ent != NULL; ent = ent->next) | ||
108 | if (ent->data == oldprop) | ||
109 | break; | ||
110 | if (ent == NULL) { | ||
111 | pr_warn("device-tree: property \"%s\" does not exist\n", | ||
112 | oldprop->name); | ||
113 | } else { | ||
114 | ent->data = newprop; | ||
115 | ent->size = newprop->length; | ||
116 | } | ||
117 | } | ||
118 | |||
119 | /* | ||
120 | * Various dodgy firmware might give us nodes and/or properties with | ||
121 | * conflicting names. That's generally ok, except for exporting via /proc, | ||
122 | * so munge names here to ensure they're unique. | ||
123 | */ | ||
124 | |||
125 | static int duplicate_name(struct proc_dir_entry *de, const char *name) | ||
126 | { | ||
127 | struct proc_dir_entry *ent; | ||
128 | int found = 0; | ||
129 | |||
130 | spin_lock(&proc_subdir_lock); | ||
131 | |||
132 | for (ent = de->subdir; ent != NULL; ent = ent->next) { | ||
133 | if (strcmp(ent->name, name) == 0) { | ||
134 | found = 1; | ||
135 | break; | ||
136 | } | ||
137 | } | ||
138 | |||
139 | spin_unlock(&proc_subdir_lock); | ||
140 | |||
141 | return found; | ||
142 | } | ||
143 | |||
144 | static const char *fixup_name(struct device_node *np, struct proc_dir_entry *de, | ||
145 | const char *name) | ||
146 | { | ||
147 | char *fixed_name; | ||
148 | int fixup_len = strlen(name) + 2 + 1; /* name + #x + \0 */ | ||
149 | int i = 1, size; | ||
150 | |||
151 | realloc: | ||
152 | fixed_name = kmalloc(fixup_len, GFP_KERNEL); | ||
153 | if (fixed_name == NULL) { | ||
154 | pr_err("device-tree: Out of memory trying to fixup " | ||
155 | "name \"%s\"\n", name); | ||
156 | return name; | ||
157 | } | ||
158 | |||
159 | retry: | ||
160 | size = snprintf(fixed_name, fixup_len, "%s#%d", name, i); | ||
161 | size++; /* account for NULL */ | ||
162 | |||
163 | if (size > fixup_len) { | ||
164 | /* We ran out of space, free and reallocate. */ | ||
165 | kfree(fixed_name); | ||
166 | fixup_len = size; | ||
167 | goto realloc; | ||
168 | } | ||
169 | |||
170 | if (duplicate_name(de, fixed_name)) { | ||
171 | /* Multiple duplicates. Retry with a different offset. */ | ||
172 | i++; | ||
173 | goto retry; | ||
174 | } | ||
175 | |||
176 | pr_warn("device-tree: Duplicate name in %s, renamed to \"%s\"\n", | ||
177 | np->full_name, fixed_name); | ||
178 | |||
179 | return fixed_name; | ||
180 | } | ||
181 | |||
182 | /* | ||
183 | * Process a node, adding entries for its children and its properties. | ||
184 | */ | ||
185 | void proc_device_tree_add_node(struct device_node *np, | ||
186 | struct proc_dir_entry *de) | ||
187 | { | ||
188 | struct property *pp; | ||
189 | struct proc_dir_entry *ent; | ||
190 | struct device_node *child; | ||
191 | const char *p; | ||
192 | |||
193 | set_node_proc_entry(np, de); | ||
194 | for (child = NULL; (child = of_get_next_child(np, child));) { | ||
195 | /* Use everything after the last slash, or the full name */ | ||
196 | p = kbasename(child->full_name); | ||
197 | |||
198 | if (duplicate_name(de, p)) | ||
199 | p = fixup_name(np, de, p); | ||
200 | |||
201 | ent = proc_mkdir(p, de); | ||
202 | if (ent == NULL) | ||
203 | break; | ||
204 | proc_device_tree_add_node(child, ent); | ||
205 | } | ||
206 | of_node_put(child); | ||
207 | |||
208 | for (pp = np->properties; pp != NULL; pp = pp->next) { | ||
209 | p = pp->name; | ||
210 | |||
211 | if (strchr(p, '/')) | ||
212 | continue; | ||
213 | |||
214 | if (duplicate_name(de, p)) | ||
215 | p = fixup_name(np, de, p); | ||
216 | |||
217 | ent = __proc_device_tree_add_prop(de, pp, p); | ||
218 | if (ent == NULL) | ||
219 | break; | ||
220 | } | ||
221 | } | ||
222 | |||
223 | /* | ||
224 | * Called on initialization to set up the /proc/device-tree subtree | ||
225 | */ | ||
226 | void __init proc_device_tree_init(void) | ||
227 | { | ||
228 | struct device_node *root; | ||
229 | |||
230 | proc_device_tree = proc_mkdir("device-tree", NULL); | ||
231 | if (proc_device_tree == NULL) | ||
232 | return; | ||
233 | root = of_find_node_by_path("/"); | ||
234 | if (root == NULL) { | ||
235 | remove_proc_entry("device-tree", NULL); | ||
236 | pr_debug("/proc/device-tree: can't find root\n"); | ||
237 | return; | ||
238 | } | ||
239 | proc_device_tree_add_node(root, proc_device_tree); | ||
240 | of_node_put(root); | ||
241 | } | ||
diff --git a/fs/proc/root.c b/fs/proc/root.c index 87dbcbef7fe4..7bbeb5257af1 100644 --- a/fs/proc/root.c +++ b/fs/proc/root.c | |||
@@ -183,9 +183,6 @@ void __init proc_root_init(void) | |||
183 | proc_mkdir("openprom", NULL); | 183 | proc_mkdir("openprom", NULL); |
184 | #endif | 184 | #endif |
185 | proc_tty_init(); | 185 | proc_tty_init(); |
186 | #ifdef CONFIG_PROC_DEVICETREE | ||
187 | proc_device_tree_init(); | ||
188 | #endif | ||
189 | proc_mkdir("bus", NULL); | 186 | proc_mkdir("bus", NULL); |
190 | proc_sys_init(); | 187 | proc_sys_init(); |
191 | } | 188 | } |