aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorStephen Rothwell <sfr@canb.auug.org.au>2007-04-24 03:57:33 -0400
committerStephen Rothwell <sfr@canb.auug.org.au>2007-07-19 23:39:06 -0400
commit1ef4d4242d9c494c49ae1ae66dc938fce0272816 (patch)
tree74c64ec940b306b5d1e7bb93a980041ad670468d /drivers
parentd1cd355a5e44dfe993efc0c0458ca9f99a28a9a3 (diff)
Consolidate of_find_node_by routines
This consolidates the routines of_find_node_by_path, of_find_node_by_name, of_find_node_by_type and of_find_compatible_device. Again, the comparison of strings are done differently by Sparc and PowerPC and also these add read_locks around the iterations. Signed-off-by: Stephen Rothwell <sfr@canb.auug.org.au> Acked-by: Paul Mackerras <paulus@samba.org> Acked-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/of/base.c115
1 files changed, 115 insertions, 0 deletions
diff --git a/drivers/of/base.c b/drivers/of/base.c
index 6b6dfcc56522..9377f3bc410a 100644
--- a/drivers/of/base.c
+++ b/drivers/of/base.c
@@ -20,6 +20,8 @@
20#include <linux/of.h> 20#include <linux/of.h>
21#include <linux/spinlock.h> 21#include <linux/spinlock.h>
22 22
23struct device_node *allnodes;
24
23/* use when traversing tree through the allnext, child, sibling, 25/* use when traversing tree through the allnext, child, sibling,
24 * or parent members of struct device_node. 26 * or parent members of struct device_node.
25 */ 27 */
@@ -158,3 +160,116 @@ struct device_node *of_get_next_child(const struct device_node *node,
158 return next; 160 return next;
159} 161}
160EXPORT_SYMBOL(of_get_next_child); 162EXPORT_SYMBOL(of_get_next_child);
163
164/**
165 * of_find_node_by_path - Find a node matching a full OF path
166 * @path: The full path to match
167 *
168 * Returns a node pointer with refcount incremented, use
169 * of_node_put() on it when done.
170 */
171struct device_node *of_find_node_by_path(const char *path)
172{
173 struct device_node *np = allnodes;
174
175 read_lock(&devtree_lock);
176 for (; np; np = np->allnext) {
177 if (np->full_name && (of_node_cmp(np->full_name, path) == 0)
178 && of_node_get(np))
179 break;
180 }
181 read_unlock(&devtree_lock);
182 return np;
183}
184EXPORT_SYMBOL(of_find_node_by_path);
185
186/**
187 * of_find_node_by_name - Find a node by its "name" property
188 * @from: The node to start searching from or NULL, the node
189 * you pass will not be searched, only the next one
190 * will; typically, you pass what the previous call
191 * returned. of_node_put() will be called on it
192 * @name: The name string to match against
193 *
194 * Returns a node pointer with refcount incremented, use
195 * of_node_put() on it when done.
196 */
197struct device_node *of_find_node_by_name(struct device_node *from,
198 const char *name)
199{
200 struct device_node *np;
201
202 read_lock(&devtree_lock);
203 np = from ? from->allnext : allnodes;
204 for (; np; np = np->allnext)
205 if (np->name && (of_node_cmp(np->name, name) == 0)
206 && of_node_get(np))
207 break;
208 of_node_put(from);
209 read_unlock(&devtree_lock);
210 return np;
211}
212EXPORT_SYMBOL(of_find_node_by_name);
213
214/**
215 * of_find_node_by_type - Find a node by its "device_type" property
216 * @from: The node to start searching from, or NULL to start searching
217 * the entire device tree. The node you pass will not be
218 * searched, only the next one will; typically, you pass
219 * what the previous call returned. of_node_put() will be
220 * called on from for you.
221 * @type: The type string to match against
222 *
223 * Returns a node pointer with refcount incremented, use
224 * of_node_put() on it when done.
225 */
226struct device_node *of_find_node_by_type(struct device_node *from,
227 const char *type)
228{
229 struct device_node *np;
230
231 read_lock(&devtree_lock);
232 np = from ? from->allnext : allnodes;
233 for (; np; np = np->allnext)
234 if (np->type && (of_node_cmp(np->type, type) == 0)
235 && of_node_get(np))
236 break;
237 of_node_put(from);
238 read_unlock(&devtree_lock);
239 return np;
240}
241EXPORT_SYMBOL(of_find_node_by_type);
242
243/**
244 * of_find_compatible_node - Find a node based on type and one of the
245 * tokens in its "compatible" property
246 * @from: The node to start searching from or NULL, the node
247 * you pass will not be searched, only the next one
248 * will; typically, you pass what the previous call
249 * returned. of_node_put() will be called on it
250 * @type: The type string to match "device_type" or NULL to ignore
251 * @compatible: The string to match to one of the tokens in the device
252 * "compatible" list.
253 *
254 * Returns a node pointer with refcount incremented, use
255 * of_node_put() on it when done.
256 */
257struct device_node *of_find_compatible_node(struct device_node *from,
258 const char *type, const char *compatible)
259{
260 struct device_node *np;
261
262 read_lock(&devtree_lock);
263 np = from ? from->allnext : allnodes;
264 for (; np; np = np->allnext) {
265 if (type
266 && !(np->type && (of_node_cmp(np->type, type) == 0)))
267 continue;
268 if (of_device_is_compatible(np, compatible) && of_node_get(np))
269 break;
270 }
271 of_node_put(from);
272 read_unlock(&devtree_lock);
273 return np;
274}
275EXPORT_SYMBOL(of_find_compatible_node);