xref: /openbmc/linux/drivers/of/base.c (revision a3b85363)
197e873e5SStephen Rothwell /*
297e873e5SStephen Rothwell  * Procedures for creating, accessing and interpreting the device tree.
397e873e5SStephen Rothwell  *
497e873e5SStephen Rothwell  * Paul Mackerras	August 1996.
597e873e5SStephen Rothwell  * Copyright (C) 1996-2005 Paul Mackerras.
697e873e5SStephen Rothwell  *
797e873e5SStephen Rothwell  *  Adapted for 64bit PowerPC by Dave Engebretsen and Peter Bergner.
897e873e5SStephen Rothwell  *    {engebret|bergner}@us.ibm.com
997e873e5SStephen Rothwell  *
1097e873e5SStephen Rothwell  *  Adapted for sparc and sparc64 by David S. Miller davem@davemloft.net
1197e873e5SStephen Rothwell  *
12e91edcf5SGrant Likely  *  Reconsolidated from arch/x/kernel/prom.c by Stephen Rothwell and
13e91edcf5SGrant Likely  *  Grant Likely.
1497e873e5SStephen Rothwell  *
1597e873e5SStephen Rothwell  *      This program is free software; you can redistribute it and/or
1697e873e5SStephen Rothwell  *      modify it under the terms of the GNU General Public License
1797e873e5SStephen Rothwell  *      as published by the Free Software Foundation; either version
1897e873e5SStephen Rothwell  *      2 of the License, or (at your option) any later version.
1997e873e5SStephen Rothwell  */
2097e873e5SStephen Rothwell #include <linux/module.h>
2197e873e5SStephen Rothwell #include <linux/of.h>
22581b605aSStephen Rothwell #include <linux/spinlock.h>
235a0e3ad6STejun Heo #include <linux/slab.h>
24a9f2f63aSJeremy Kerr #include <linux/proc_fs.h>
25581b605aSStephen Rothwell 
261ef4d424SStephen Rothwell struct device_node *allnodes;
27fc0bdae4SGrant Likely struct device_node *of_chosen;
281ef4d424SStephen Rothwell 
29581b605aSStephen Rothwell /* use when traversing tree through the allnext, child, sibling,
30581b605aSStephen Rothwell  * or parent members of struct device_node.
31581b605aSStephen Rothwell  */
32581b605aSStephen Rothwell DEFINE_RWLOCK(devtree_lock);
3397e873e5SStephen Rothwell 
3497e873e5SStephen Rothwell int of_n_addr_cells(struct device_node *np)
3597e873e5SStephen Rothwell {
36a9fadeefSJeremy Kerr 	const __be32 *ip;
3797e873e5SStephen Rothwell 
3897e873e5SStephen Rothwell 	do {
3997e873e5SStephen Rothwell 		if (np->parent)
4097e873e5SStephen Rothwell 			np = np->parent;
4197e873e5SStephen Rothwell 		ip = of_get_property(np, "#address-cells", NULL);
4297e873e5SStephen Rothwell 		if (ip)
4333714881SJeremy Kerr 			return be32_to_cpup(ip);
4497e873e5SStephen Rothwell 	} while (np->parent);
4597e873e5SStephen Rothwell 	/* No #address-cells property for the root node */
4697e873e5SStephen Rothwell 	return OF_ROOT_NODE_ADDR_CELLS_DEFAULT;
4797e873e5SStephen Rothwell }
4897e873e5SStephen Rothwell EXPORT_SYMBOL(of_n_addr_cells);
4997e873e5SStephen Rothwell 
5097e873e5SStephen Rothwell int of_n_size_cells(struct device_node *np)
5197e873e5SStephen Rothwell {
52a9fadeefSJeremy Kerr 	const __be32 *ip;
5397e873e5SStephen Rothwell 
5497e873e5SStephen Rothwell 	do {
5597e873e5SStephen Rothwell 		if (np->parent)
5697e873e5SStephen Rothwell 			np = np->parent;
5797e873e5SStephen Rothwell 		ip = of_get_property(np, "#size-cells", NULL);
5897e873e5SStephen Rothwell 		if (ip)
5933714881SJeremy Kerr 			return be32_to_cpup(ip);
6097e873e5SStephen Rothwell 	} while (np->parent);
6197e873e5SStephen Rothwell 	/* No #size-cells property for the root node */
6297e873e5SStephen Rothwell 	return OF_ROOT_NODE_SIZE_CELLS_DEFAULT;
6397e873e5SStephen Rothwell }
6497e873e5SStephen Rothwell EXPORT_SYMBOL(of_n_size_cells);
6597e873e5SStephen Rothwell 
66923f7e30SGrant Likely #if !defined(CONFIG_SPARC)   /* SPARC doesn't do ref counting (yet) */
67923f7e30SGrant Likely /**
68923f7e30SGrant Likely  *	of_node_get - Increment refcount of a node
69923f7e30SGrant Likely  *	@node:	Node to inc refcount, NULL is supported to
70923f7e30SGrant Likely  *		simplify writing of callers
71923f7e30SGrant Likely  *
72923f7e30SGrant Likely  *	Returns node.
73923f7e30SGrant Likely  */
74923f7e30SGrant Likely struct device_node *of_node_get(struct device_node *node)
75923f7e30SGrant Likely {
76923f7e30SGrant Likely 	if (node)
77923f7e30SGrant Likely 		kref_get(&node->kref);
78923f7e30SGrant Likely 	return node;
79923f7e30SGrant Likely }
80923f7e30SGrant Likely EXPORT_SYMBOL(of_node_get);
81923f7e30SGrant Likely 
82923f7e30SGrant Likely static inline struct device_node *kref_to_device_node(struct kref *kref)
83923f7e30SGrant Likely {
84923f7e30SGrant Likely 	return container_of(kref, struct device_node, kref);
85923f7e30SGrant Likely }
86923f7e30SGrant Likely 
87923f7e30SGrant Likely /**
88923f7e30SGrant Likely  *	of_node_release - release a dynamically allocated node
89923f7e30SGrant Likely  *	@kref:  kref element of the node to be released
90923f7e30SGrant Likely  *
91923f7e30SGrant Likely  *	In of_node_put() this function is passed to kref_put()
92923f7e30SGrant Likely  *	as the destructor.
93923f7e30SGrant Likely  */
94923f7e30SGrant Likely static void of_node_release(struct kref *kref)
95923f7e30SGrant Likely {
96923f7e30SGrant Likely 	struct device_node *node = kref_to_device_node(kref);
97923f7e30SGrant Likely 	struct property *prop = node->properties;
98923f7e30SGrant Likely 
99923f7e30SGrant Likely 	/* We should never be releasing nodes that haven't been detached. */
100923f7e30SGrant Likely 	if (!of_node_check_flag(node, OF_DETACHED)) {
101923f7e30SGrant Likely 		pr_err("ERROR: Bad of_node_put() on %s\n", node->full_name);
102923f7e30SGrant Likely 		dump_stack();
103923f7e30SGrant Likely 		kref_init(&node->kref);
104923f7e30SGrant Likely 		return;
105923f7e30SGrant Likely 	}
106923f7e30SGrant Likely 
107923f7e30SGrant Likely 	if (!of_node_check_flag(node, OF_DYNAMIC))
108923f7e30SGrant Likely 		return;
109923f7e30SGrant Likely 
110923f7e30SGrant Likely 	while (prop) {
111923f7e30SGrant Likely 		struct property *next = prop->next;
112923f7e30SGrant Likely 		kfree(prop->name);
113923f7e30SGrant Likely 		kfree(prop->value);
114923f7e30SGrant Likely 		kfree(prop);
115923f7e30SGrant Likely 		prop = next;
116923f7e30SGrant Likely 
117923f7e30SGrant Likely 		if (!prop) {
118923f7e30SGrant Likely 			prop = node->deadprops;
119923f7e30SGrant Likely 			node->deadprops = NULL;
120923f7e30SGrant Likely 		}
121923f7e30SGrant Likely 	}
122923f7e30SGrant Likely 	kfree(node->full_name);
123923f7e30SGrant Likely 	kfree(node->data);
124923f7e30SGrant Likely 	kfree(node);
125923f7e30SGrant Likely }
126923f7e30SGrant Likely 
127923f7e30SGrant Likely /**
128923f7e30SGrant Likely  *	of_node_put - Decrement refcount of a node
129923f7e30SGrant Likely  *	@node:	Node to dec refcount, NULL is supported to
130923f7e30SGrant Likely  *		simplify writing of callers
131923f7e30SGrant Likely  *
132923f7e30SGrant Likely  */
133923f7e30SGrant Likely void of_node_put(struct device_node *node)
134923f7e30SGrant Likely {
135923f7e30SGrant Likely 	if (node)
136923f7e30SGrant Likely 		kref_put(&node->kref, of_node_release);
137923f7e30SGrant Likely }
138923f7e30SGrant Likely EXPORT_SYMBOL(of_node_put);
139923f7e30SGrant Likely #endif /* !CONFIG_SPARC */
140923f7e30SGrant Likely 
141581b605aSStephen Rothwell struct property *of_find_property(const struct device_node *np,
142581b605aSStephen Rothwell 				  const char *name,
143581b605aSStephen Rothwell 				  int *lenp)
144581b605aSStephen Rothwell {
145581b605aSStephen Rothwell 	struct property *pp;
146581b605aSStephen Rothwell 
14764e4566fSTimur Tabi 	if (!np)
14864e4566fSTimur Tabi 		return NULL;
14964e4566fSTimur Tabi 
150581b605aSStephen Rothwell 	read_lock(&devtree_lock);
151581b605aSStephen Rothwell 	for (pp = np->properties; pp != 0; pp = pp->next) {
152581b605aSStephen Rothwell 		if (of_prop_cmp(pp->name, name) == 0) {
153581b605aSStephen Rothwell 			if (lenp != 0)
154581b605aSStephen Rothwell 				*lenp = pp->length;
155581b605aSStephen Rothwell 			break;
156581b605aSStephen Rothwell 		}
157581b605aSStephen Rothwell 	}
158581b605aSStephen Rothwell 	read_unlock(&devtree_lock);
159581b605aSStephen Rothwell 
160581b605aSStephen Rothwell 	return pp;
161581b605aSStephen Rothwell }
162581b605aSStephen Rothwell EXPORT_SYMBOL(of_find_property);
163581b605aSStephen Rothwell 
164e91edcf5SGrant Likely /**
165e91edcf5SGrant Likely  * of_find_all_nodes - Get next node in global list
166e91edcf5SGrant Likely  * @prev:	Previous node or NULL to start iteration
167e91edcf5SGrant Likely  *		of_node_put() will be called on it
168e91edcf5SGrant Likely  *
169e91edcf5SGrant Likely  * Returns a node pointer with refcount incremented, use
170e91edcf5SGrant Likely  * of_node_put() on it when done.
171e91edcf5SGrant Likely  */
172e91edcf5SGrant Likely struct device_node *of_find_all_nodes(struct device_node *prev)
173e91edcf5SGrant Likely {
174e91edcf5SGrant Likely 	struct device_node *np;
175e91edcf5SGrant Likely 
176e91edcf5SGrant Likely 	read_lock(&devtree_lock);
177e91edcf5SGrant Likely 	np = prev ? prev->allnext : allnodes;
178e91edcf5SGrant Likely 	for (; np != NULL; np = np->allnext)
179e91edcf5SGrant Likely 		if (of_node_get(np))
180e91edcf5SGrant Likely 			break;
181e91edcf5SGrant Likely 	of_node_put(prev);
182e91edcf5SGrant Likely 	read_unlock(&devtree_lock);
183e91edcf5SGrant Likely 	return np;
184e91edcf5SGrant Likely }
185e91edcf5SGrant Likely EXPORT_SYMBOL(of_find_all_nodes);
186e91edcf5SGrant Likely 
18797e873e5SStephen Rothwell /*
18897e873e5SStephen Rothwell  * Find a property with a given name for a given node
18997e873e5SStephen Rothwell  * and return the value.
19097e873e5SStephen Rothwell  */
19197e873e5SStephen Rothwell const void *of_get_property(const struct device_node *np, const char *name,
19297e873e5SStephen Rothwell 			 int *lenp)
19397e873e5SStephen Rothwell {
19497e873e5SStephen Rothwell 	struct property *pp = of_find_property(np, name, lenp);
19597e873e5SStephen Rothwell 
19697e873e5SStephen Rothwell 	return pp ? pp->value : NULL;
19797e873e5SStephen Rothwell }
19897e873e5SStephen Rothwell EXPORT_SYMBOL(of_get_property);
1990081cbc3SStephen Rothwell 
2000081cbc3SStephen Rothwell /** Checks if the given "compat" string matches one of the strings in
2010081cbc3SStephen Rothwell  * the device's "compatible" property
2020081cbc3SStephen Rothwell  */
2030081cbc3SStephen Rothwell int of_device_is_compatible(const struct device_node *device,
2040081cbc3SStephen Rothwell 		const char *compat)
2050081cbc3SStephen Rothwell {
2060081cbc3SStephen Rothwell 	const char* cp;
2070081cbc3SStephen Rothwell 	int cplen, l;
2080081cbc3SStephen Rothwell 
2090081cbc3SStephen Rothwell 	cp = of_get_property(device, "compatible", &cplen);
2100081cbc3SStephen Rothwell 	if (cp == NULL)
2110081cbc3SStephen Rothwell 		return 0;
2120081cbc3SStephen Rothwell 	while (cplen > 0) {
2130081cbc3SStephen Rothwell 		if (of_compat_cmp(cp, compat, strlen(compat)) == 0)
2140081cbc3SStephen Rothwell 			return 1;
2150081cbc3SStephen Rothwell 		l = strlen(cp) + 1;
2160081cbc3SStephen Rothwell 		cp += l;
2170081cbc3SStephen Rothwell 		cplen -= l;
2180081cbc3SStephen Rothwell 	}
2190081cbc3SStephen Rothwell 
2200081cbc3SStephen Rothwell 	return 0;
2210081cbc3SStephen Rothwell }
2220081cbc3SStephen Rothwell EXPORT_SYMBOL(of_device_is_compatible);
223e679c5f4SStephen Rothwell 
224e679c5f4SStephen Rothwell /**
22571a157e8SGrant Likely  * of_machine_is_compatible - Test root of device tree for a given compatible value
2261f43cfb9SGrant Likely  * @compat: compatible string to look for in root node's compatible property.
2271f43cfb9SGrant Likely  *
2281f43cfb9SGrant Likely  * Returns true if the root node has the given value in its
2291f43cfb9SGrant Likely  * compatible property.
2301f43cfb9SGrant Likely  */
23171a157e8SGrant Likely int of_machine_is_compatible(const char *compat)
2321f43cfb9SGrant Likely {
2331f43cfb9SGrant Likely 	struct device_node *root;
2341f43cfb9SGrant Likely 	int rc = 0;
2351f43cfb9SGrant Likely 
2361f43cfb9SGrant Likely 	root = of_find_node_by_path("/");
2371f43cfb9SGrant Likely 	if (root) {
2381f43cfb9SGrant Likely 		rc = of_device_is_compatible(root, compat);
2391f43cfb9SGrant Likely 		of_node_put(root);
2401f43cfb9SGrant Likely 	}
2411f43cfb9SGrant Likely 	return rc;
2421f43cfb9SGrant Likely }
24371a157e8SGrant Likely EXPORT_SYMBOL(of_machine_is_compatible);
2441f43cfb9SGrant Likely 
2451f43cfb9SGrant Likely /**
246834d97d4SJosh Boyer  *  of_device_is_available - check if a device is available for use
247834d97d4SJosh Boyer  *
248834d97d4SJosh Boyer  *  @device: Node to check for availability
249834d97d4SJosh Boyer  *
250834d97d4SJosh Boyer  *  Returns 1 if the status property is absent or set to "okay" or "ok",
251834d97d4SJosh Boyer  *  0 otherwise
252834d97d4SJosh Boyer  */
253834d97d4SJosh Boyer int of_device_is_available(const struct device_node *device)
254834d97d4SJosh Boyer {
255834d97d4SJosh Boyer 	const char *status;
256834d97d4SJosh Boyer 	int statlen;
257834d97d4SJosh Boyer 
258834d97d4SJosh Boyer 	status = of_get_property(device, "status", &statlen);
259834d97d4SJosh Boyer 	if (status == NULL)
260834d97d4SJosh Boyer 		return 1;
261834d97d4SJosh Boyer 
262834d97d4SJosh Boyer 	if (statlen > 0) {
263834d97d4SJosh Boyer 		if (!strcmp(status, "okay") || !strcmp(status, "ok"))
264834d97d4SJosh Boyer 			return 1;
265834d97d4SJosh Boyer 	}
266834d97d4SJosh Boyer 
267834d97d4SJosh Boyer 	return 0;
268834d97d4SJosh Boyer }
269834d97d4SJosh Boyer EXPORT_SYMBOL(of_device_is_available);
270834d97d4SJosh Boyer 
271834d97d4SJosh Boyer /**
272e679c5f4SStephen Rothwell  *	of_get_parent - Get a node's parent if any
273e679c5f4SStephen Rothwell  *	@node:	Node to get parent
274e679c5f4SStephen Rothwell  *
275e679c5f4SStephen Rothwell  *	Returns a node pointer with refcount incremented, use
276e679c5f4SStephen Rothwell  *	of_node_put() on it when done.
277e679c5f4SStephen Rothwell  */
278e679c5f4SStephen Rothwell struct device_node *of_get_parent(const struct device_node *node)
279e679c5f4SStephen Rothwell {
280e679c5f4SStephen Rothwell 	struct device_node *np;
281e679c5f4SStephen Rothwell 
282e679c5f4SStephen Rothwell 	if (!node)
283e679c5f4SStephen Rothwell 		return NULL;
284e679c5f4SStephen Rothwell 
285e679c5f4SStephen Rothwell 	read_lock(&devtree_lock);
286e679c5f4SStephen Rothwell 	np = of_node_get(node->parent);
287e679c5f4SStephen Rothwell 	read_unlock(&devtree_lock);
288e679c5f4SStephen Rothwell 	return np;
289e679c5f4SStephen Rothwell }
290e679c5f4SStephen Rothwell EXPORT_SYMBOL(of_get_parent);
291d1cd355aSStephen Rothwell 
292d1cd355aSStephen Rothwell /**
293f4eb0107SMichael Ellerman  *	of_get_next_parent - Iterate to a node's parent
294f4eb0107SMichael Ellerman  *	@node:	Node to get parent of
295f4eb0107SMichael Ellerman  *
296f4eb0107SMichael Ellerman  * 	This is like of_get_parent() except that it drops the
297f4eb0107SMichael Ellerman  * 	refcount on the passed node, making it suitable for iterating
298f4eb0107SMichael Ellerman  * 	through a node's parents.
299f4eb0107SMichael Ellerman  *
300f4eb0107SMichael Ellerman  *	Returns a node pointer with refcount incremented, use
301f4eb0107SMichael Ellerman  *	of_node_put() on it when done.
302f4eb0107SMichael Ellerman  */
303f4eb0107SMichael Ellerman struct device_node *of_get_next_parent(struct device_node *node)
304f4eb0107SMichael Ellerman {
305f4eb0107SMichael Ellerman 	struct device_node *parent;
306f4eb0107SMichael Ellerman 
307f4eb0107SMichael Ellerman 	if (!node)
308f4eb0107SMichael Ellerman 		return NULL;
309f4eb0107SMichael Ellerman 
310f4eb0107SMichael Ellerman 	read_lock(&devtree_lock);
311f4eb0107SMichael Ellerman 	parent = of_node_get(node->parent);
312f4eb0107SMichael Ellerman 	of_node_put(node);
313f4eb0107SMichael Ellerman 	read_unlock(&devtree_lock);
314f4eb0107SMichael Ellerman 	return parent;
315f4eb0107SMichael Ellerman }
316f4eb0107SMichael Ellerman 
317f4eb0107SMichael Ellerman /**
318d1cd355aSStephen Rothwell  *	of_get_next_child - Iterate a node childs
319d1cd355aSStephen Rothwell  *	@node:	parent node
320d1cd355aSStephen Rothwell  *	@prev:	previous child of the parent node, or NULL to get first
321d1cd355aSStephen Rothwell  *
322d1cd355aSStephen Rothwell  *	Returns a node pointer with refcount incremented, use
323d1cd355aSStephen Rothwell  *	of_node_put() on it when done.
324d1cd355aSStephen Rothwell  */
325d1cd355aSStephen Rothwell struct device_node *of_get_next_child(const struct device_node *node,
326d1cd355aSStephen Rothwell 	struct device_node *prev)
327d1cd355aSStephen Rothwell {
328d1cd355aSStephen Rothwell 	struct device_node *next;
329d1cd355aSStephen Rothwell 
330d1cd355aSStephen Rothwell 	read_lock(&devtree_lock);
331d1cd355aSStephen Rothwell 	next = prev ? prev->sibling : node->child;
332d1cd355aSStephen Rothwell 	for (; next; next = next->sibling)
333d1cd355aSStephen Rothwell 		if (of_node_get(next))
334d1cd355aSStephen Rothwell 			break;
335d1cd355aSStephen Rothwell 	of_node_put(prev);
336d1cd355aSStephen Rothwell 	read_unlock(&devtree_lock);
337d1cd355aSStephen Rothwell 	return next;
338d1cd355aSStephen Rothwell }
339d1cd355aSStephen Rothwell EXPORT_SYMBOL(of_get_next_child);
3401ef4d424SStephen Rothwell 
3411ef4d424SStephen Rothwell /**
3421ef4d424SStephen Rothwell  *	of_find_node_by_path - Find a node matching a full OF path
3431ef4d424SStephen Rothwell  *	@path:	The full path to match
3441ef4d424SStephen Rothwell  *
3451ef4d424SStephen Rothwell  *	Returns a node pointer with refcount incremented, use
3461ef4d424SStephen Rothwell  *	of_node_put() on it when done.
3471ef4d424SStephen Rothwell  */
3481ef4d424SStephen Rothwell struct device_node *of_find_node_by_path(const char *path)
3491ef4d424SStephen Rothwell {
3501ef4d424SStephen Rothwell 	struct device_node *np = allnodes;
3511ef4d424SStephen Rothwell 
3521ef4d424SStephen Rothwell 	read_lock(&devtree_lock);
3531ef4d424SStephen Rothwell 	for (; np; np = np->allnext) {
3541ef4d424SStephen Rothwell 		if (np->full_name && (of_node_cmp(np->full_name, path) == 0)
3551ef4d424SStephen Rothwell 		    && of_node_get(np))
3561ef4d424SStephen Rothwell 			break;
3571ef4d424SStephen Rothwell 	}
3581ef4d424SStephen Rothwell 	read_unlock(&devtree_lock);
3591ef4d424SStephen Rothwell 	return np;
3601ef4d424SStephen Rothwell }
3611ef4d424SStephen Rothwell EXPORT_SYMBOL(of_find_node_by_path);
3621ef4d424SStephen Rothwell 
3631ef4d424SStephen Rothwell /**
3641ef4d424SStephen Rothwell  *	of_find_node_by_name - Find a node by its "name" property
3651ef4d424SStephen Rothwell  *	@from:	The node to start searching from or NULL, the node
3661ef4d424SStephen Rothwell  *		you pass will not be searched, only the next one
3671ef4d424SStephen Rothwell  *		will; typically, you pass what the previous call
3681ef4d424SStephen Rothwell  *		returned. of_node_put() will be called on it
3691ef4d424SStephen Rothwell  *	@name:	The name string to match against
3701ef4d424SStephen Rothwell  *
3711ef4d424SStephen Rothwell  *	Returns a node pointer with refcount incremented, use
3721ef4d424SStephen Rothwell  *	of_node_put() on it when done.
3731ef4d424SStephen Rothwell  */
3741ef4d424SStephen Rothwell struct device_node *of_find_node_by_name(struct device_node *from,
3751ef4d424SStephen Rothwell 	const char *name)
3761ef4d424SStephen Rothwell {
3771ef4d424SStephen Rothwell 	struct device_node *np;
3781ef4d424SStephen Rothwell 
3791ef4d424SStephen Rothwell 	read_lock(&devtree_lock);
3801ef4d424SStephen Rothwell 	np = from ? from->allnext : allnodes;
3811ef4d424SStephen Rothwell 	for (; np; np = np->allnext)
3821ef4d424SStephen Rothwell 		if (np->name && (of_node_cmp(np->name, name) == 0)
3831ef4d424SStephen Rothwell 		    && of_node_get(np))
3841ef4d424SStephen Rothwell 			break;
3851ef4d424SStephen Rothwell 	of_node_put(from);
3861ef4d424SStephen Rothwell 	read_unlock(&devtree_lock);
3871ef4d424SStephen Rothwell 	return np;
3881ef4d424SStephen Rothwell }
3891ef4d424SStephen Rothwell EXPORT_SYMBOL(of_find_node_by_name);
3901ef4d424SStephen Rothwell 
3911ef4d424SStephen Rothwell /**
3921ef4d424SStephen Rothwell  *	of_find_node_by_type - Find a node by its "device_type" property
3931ef4d424SStephen Rothwell  *	@from:	The node to start searching from, or NULL to start searching
3941ef4d424SStephen Rothwell  *		the entire device tree. The node you pass will not be
3951ef4d424SStephen Rothwell  *		searched, only the next one will; typically, you pass
3961ef4d424SStephen Rothwell  *		what the previous call returned. of_node_put() will be
3971ef4d424SStephen Rothwell  *		called on from for you.
3981ef4d424SStephen Rothwell  *	@type:	The type string to match against
3991ef4d424SStephen Rothwell  *
4001ef4d424SStephen Rothwell  *	Returns a node pointer with refcount incremented, use
4011ef4d424SStephen Rothwell  *	of_node_put() on it when done.
4021ef4d424SStephen Rothwell  */
4031ef4d424SStephen Rothwell struct device_node *of_find_node_by_type(struct device_node *from,
4041ef4d424SStephen Rothwell 	const char *type)
4051ef4d424SStephen Rothwell {
4061ef4d424SStephen Rothwell 	struct device_node *np;
4071ef4d424SStephen Rothwell 
4081ef4d424SStephen Rothwell 	read_lock(&devtree_lock);
4091ef4d424SStephen Rothwell 	np = from ? from->allnext : allnodes;
4101ef4d424SStephen Rothwell 	for (; np; np = np->allnext)
4111ef4d424SStephen Rothwell 		if (np->type && (of_node_cmp(np->type, type) == 0)
4121ef4d424SStephen Rothwell 		    && of_node_get(np))
4131ef4d424SStephen Rothwell 			break;
4141ef4d424SStephen Rothwell 	of_node_put(from);
4151ef4d424SStephen Rothwell 	read_unlock(&devtree_lock);
4161ef4d424SStephen Rothwell 	return np;
4171ef4d424SStephen Rothwell }
4181ef4d424SStephen Rothwell EXPORT_SYMBOL(of_find_node_by_type);
4191ef4d424SStephen Rothwell 
4201ef4d424SStephen Rothwell /**
4211ef4d424SStephen Rothwell  *	of_find_compatible_node - Find a node based on type and one of the
4221ef4d424SStephen Rothwell  *                                tokens in its "compatible" property
4231ef4d424SStephen Rothwell  *	@from:		The node to start searching from or NULL, the node
4241ef4d424SStephen Rothwell  *			you pass will not be searched, only the next one
4251ef4d424SStephen Rothwell  *			will; typically, you pass what the previous call
4261ef4d424SStephen Rothwell  *			returned. of_node_put() will be called on it
4271ef4d424SStephen Rothwell  *	@type:		The type string to match "device_type" or NULL to ignore
4281ef4d424SStephen Rothwell  *	@compatible:	The string to match to one of the tokens in the device
4291ef4d424SStephen Rothwell  *			"compatible" list.
4301ef4d424SStephen Rothwell  *
4311ef4d424SStephen Rothwell  *	Returns a node pointer with refcount incremented, use
4321ef4d424SStephen Rothwell  *	of_node_put() on it when done.
4331ef4d424SStephen Rothwell  */
4341ef4d424SStephen Rothwell struct device_node *of_find_compatible_node(struct device_node *from,
4351ef4d424SStephen Rothwell 	const char *type, const char *compatible)
4361ef4d424SStephen Rothwell {
4371ef4d424SStephen Rothwell 	struct device_node *np;
4381ef4d424SStephen Rothwell 
4391ef4d424SStephen Rothwell 	read_lock(&devtree_lock);
4401ef4d424SStephen Rothwell 	np = from ? from->allnext : allnodes;
4411ef4d424SStephen Rothwell 	for (; np; np = np->allnext) {
4421ef4d424SStephen Rothwell 		if (type
4431ef4d424SStephen Rothwell 		    && !(np->type && (of_node_cmp(np->type, type) == 0)))
4441ef4d424SStephen Rothwell 			continue;
4451ef4d424SStephen Rothwell 		if (of_device_is_compatible(np, compatible) && of_node_get(np))
4461ef4d424SStephen Rothwell 			break;
4471ef4d424SStephen Rothwell 	}
4481ef4d424SStephen Rothwell 	of_node_put(from);
4491ef4d424SStephen Rothwell 	read_unlock(&devtree_lock);
4501ef4d424SStephen Rothwell 	return np;
4511ef4d424SStephen Rothwell }
4521ef4d424SStephen Rothwell EXPORT_SYMBOL(of_find_compatible_node);
453283029d1SGrant Likely 
454283029d1SGrant Likely /**
4551e291b14SMichael Ellerman  *	of_find_node_with_property - Find a node which has a property with
4561e291b14SMichael Ellerman  *                                   the given name.
4571e291b14SMichael Ellerman  *	@from:		The node to start searching from or NULL, the node
4581e291b14SMichael Ellerman  *			you pass will not be searched, only the next one
4591e291b14SMichael Ellerman  *			will; typically, you pass what the previous call
4601e291b14SMichael Ellerman  *			returned. of_node_put() will be called on it
4611e291b14SMichael Ellerman  *	@prop_name:	The name of the property to look for.
4621e291b14SMichael Ellerman  *
4631e291b14SMichael Ellerman  *	Returns a node pointer with refcount incremented, use
4641e291b14SMichael Ellerman  *	of_node_put() on it when done.
4651e291b14SMichael Ellerman  */
4661e291b14SMichael Ellerman struct device_node *of_find_node_with_property(struct device_node *from,
4671e291b14SMichael Ellerman 	const char *prop_name)
4681e291b14SMichael Ellerman {
4691e291b14SMichael Ellerman 	struct device_node *np;
4701e291b14SMichael Ellerman 	struct property *pp;
4711e291b14SMichael Ellerman 
4721e291b14SMichael Ellerman 	read_lock(&devtree_lock);
4731e291b14SMichael Ellerman 	np = from ? from->allnext : allnodes;
4741e291b14SMichael Ellerman 	for (; np; np = np->allnext) {
4751e291b14SMichael Ellerman 		for (pp = np->properties; pp != 0; pp = pp->next) {
4761e291b14SMichael Ellerman 			if (of_prop_cmp(pp->name, prop_name) == 0) {
4771e291b14SMichael Ellerman 				of_node_get(np);
4781e291b14SMichael Ellerman 				goto out;
4791e291b14SMichael Ellerman 			}
4801e291b14SMichael Ellerman 		}
4811e291b14SMichael Ellerman 	}
4821e291b14SMichael Ellerman out:
4831e291b14SMichael Ellerman 	of_node_put(from);
4841e291b14SMichael Ellerman 	read_unlock(&devtree_lock);
4851e291b14SMichael Ellerman 	return np;
4861e291b14SMichael Ellerman }
4871e291b14SMichael Ellerman EXPORT_SYMBOL(of_find_node_with_property);
4881e291b14SMichael Ellerman 
4891e291b14SMichael Ellerman /**
490283029d1SGrant Likely  * of_match_node - Tell if an device_node has a matching of_match structure
491283029d1SGrant Likely  *	@matches:	array of of device match structures to search in
492283029d1SGrant Likely  *	@node:		the of device structure to match against
493283029d1SGrant Likely  *
494283029d1SGrant Likely  *	Low level utility function used by device matching.
495283029d1SGrant Likely  */
496283029d1SGrant Likely const struct of_device_id *of_match_node(const struct of_device_id *matches,
497283029d1SGrant Likely 					 const struct device_node *node)
498283029d1SGrant Likely {
499a52f07ecSGrant Likely 	if (!matches)
500a52f07ecSGrant Likely 		return NULL;
501a52f07ecSGrant Likely 
502283029d1SGrant Likely 	while (matches->name[0] || matches->type[0] || matches->compatible[0]) {
503283029d1SGrant Likely 		int match = 1;
504283029d1SGrant Likely 		if (matches->name[0])
505283029d1SGrant Likely 			match &= node->name
506283029d1SGrant Likely 				&& !strcmp(matches->name, node->name);
507283029d1SGrant Likely 		if (matches->type[0])
508283029d1SGrant Likely 			match &= node->type
509283029d1SGrant Likely 				&& !strcmp(matches->type, node->type);
510283029d1SGrant Likely 		if (matches->compatible[0])
511283029d1SGrant Likely 			match &= of_device_is_compatible(node,
512283029d1SGrant Likely 						matches->compatible);
513283029d1SGrant Likely 		if (match)
514283029d1SGrant Likely 			return matches;
515283029d1SGrant Likely 		matches++;
516283029d1SGrant Likely 	}
517283029d1SGrant Likely 	return NULL;
518283029d1SGrant Likely }
519283029d1SGrant Likely EXPORT_SYMBOL(of_match_node);
520283029d1SGrant Likely 
521283029d1SGrant Likely /**
522283029d1SGrant Likely  *	of_find_matching_node - Find a node based on an of_device_id match
523283029d1SGrant Likely  *				table.
524283029d1SGrant Likely  *	@from:		The node to start searching from or NULL, the node
525283029d1SGrant Likely  *			you pass will not be searched, only the next one
526283029d1SGrant Likely  *			will; typically, you pass what the previous call
527283029d1SGrant Likely  *			returned. of_node_put() will be called on it
528283029d1SGrant Likely  *	@matches:	array of of device match structures to search in
529283029d1SGrant Likely  *
530283029d1SGrant Likely  *	Returns a node pointer with refcount incremented, use
531283029d1SGrant Likely  *	of_node_put() on it when done.
532283029d1SGrant Likely  */
533283029d1SGrant Likely struct device_node *of_find_matching_node(struct device_node *from,
534283029d1SGrant Likely 					  const struct of_device_id *matches)
535283029d1SGrant Likely {
536283029d1SGrant Likely 	struct device_node *np;
537283029d1SGrant Likely 
538283029d1SGrant Likely 	read_lock(&devtree_lock);
539283029d1SGrant Likely 	np = from ? from->allnext : allnodes;
540283029d1SGrant Likely 	for (; np; np = np->allnext) {
541283029d1SGrant Likely 		if (of_match_node(matches, np) && of_node_get(np))
542283029d1SGrant Likely 			break;
543283029d1SGrant Likely 	}
544283029d1SGrant Likely 	of_node_put(from);
545283029d1SGrant Likely 	read_unlock(&devtree_lock);
546283029d1SGrant Likely 	return np;
547283029d1SGrant Likely }
548283029d1SGrant Likely EXPORT_SYMBOL(of_find_matching_node);
5493f07af49SGrant Likely 
5503f07af49SGrant Likely /**
5513f07af49SGrant Likely  * of_modalias_node - Lookup appropriate modalias for a device node
5523f07af49SGrant Likely  * @node:	pointer to a device tree node
5533f07af49SGrant Likely  * @modalias:	Pointer to buffer that modalias value will be copied into
5543f07af49SGrant Likely  * @len:	Length of modalias value
5553f07af49SGrant Likely  *
5562ffe8c5fSGrant Likely  * Based on the value of the compatible property, this routine will attempt
5572ffe8c5fSGrant Likely  * to choose an appropriate modalias value for a particular device tree node.
5582ffe8c5fSGrant Likely  * It does this by stripping the manufacturer prefix (as delimited by a ',')
5592ffe8c5fSGrant Likely  * from the first entry in the compatible list property.
5603f07af49SGrant Likely  *
5612ffe8c5fSGrant Likely  * This routine returns 0 on success, <0 on failure.
5623f07af49SGrant Likely  */
5633f07af49SGrant Likely int of_modalias_node(struct device_node *node, char *modalias, int len)
5643f07af49SGrant Likely {
5652ffe8c5fSGrant Likely 	const char *compatible, *p;
5662ffe8c5fSGrant Likely 	int cplen;
5673f07af49SGrant Likely 
5683f07af49SGrant Likely 	compatible = of_get_property(node, "compatible", &cplen);
5692ffe8c5fSGrant Likely 	if (!compatible || strlen(compatible) > cplen)
5703f07af49SGrant Likely 		return -ENODEV;
5713f07af49SGrant Likely 	p = strchr(compatible, ',');
5722ffe8c5fSGrant Likely 	strlcpy(modalias, p ? p + 1 : compatible, len);
5733f07af49SGrant Likely 	return 0;
5743f07af49SGrant Likely }
5753f07af49SGrant Likely EXPORT_SYMBOL_GPL(of_modalias_node);
5763f07af49SGrant Likely 
57764b60e09SAnton Vorontsov /**
57889751a7cSJeremy Kerr  * of_find_node_by_phandle - Find a node given a phandle
57989751a7cSJeremy Kerr  * @handle:	phandle of the node to find
58089751a7cSJeremy Kerr  *
58189751a7cSJeremy Kerr  * Returns a node pointer with refcount incremented, use
58289751a7cSJeremy Kerr  * of_node_put() on it when done.
58389751a7cSJeremy Kerr  */
58489751a7cSJeremy Kerr struct device_node *of_find_node_by_phandle(phandle handle)
58589751a7cSJeremy Kerr {
58689751a7cSJeremy Kerr 	struct device_node *np;
58789751a7cSJeremy Kerr 
58889751a7cSJeremy Kerr 	read_lock(&devtree_lock);
58989751a7cSJeremy Kerr 	for (np = allnodes; np; np = np->allnext)
59089751a7cSJeremy Kerr 		if (np->phandle == handle)
59189751a7cSJeremy Kerr 			break;
59289751a7cSJeremy Kerr 	of_node_get(np);
59389751a7cSJeremy Kerr 	read_unlock(&devtree_lock);
59489751a7cSJeremy Kerr 	return np;
59589751a7cSJeremy Kerr }
59689751a7cSJeremy Kerr EXPORT_SYMBOL(of_find_node_by_phandle);
59789751a7cSJeremy Kerr 
59889751a7cSJeremy Kerr /**
599a3b85363SThomas Abraham  * of_property_read_u32 - Find and read a 32 bit integer from a property
600a3b85363SThomas Abraham  * @np:		device node from which the property value is to be read.
601a3b85363SThomas Abraham  * @propname:	name of the property to be searched.
602a3b85363SThomas Abraham  * @out_value:	pointer to return value, modified only if return value is 0.
603a3b85363SThomas Abraham  *
604a3b85363SThomas Abraham  * Search for a property in a device node and read a 32-bit value from
605a3b85363SThomas Abraham  * it. Returns 0 on success, -EINVAL if the property does not exist,
606a3b85363SThomas Abraham  * -ENODATA if property does not have a value, and -EOVERFLOW if the
607a3b85363SThomas Abraham  * property data isn't large enough.
608a3b85363SThomas Abraham  *
609a3b85363SThomas Abraham  * The out_value is modified only if a valid u32 value can be decoded.
610a3b85363SThomas Abraham  */
611a3b85363SThomas Abraham int of_property_read_u32(struct device_node *np, char *propname, u32 *out_value)
612a3b85363SThomas Abraham {
613a3b85363SThomas Abraham 	struct property *prop = of_find_property(np, propname, NULL);
614a3b85363SThomas Abraham 
615a3b85363SThomas Abraham 	if (!prop)
616a3b85363SThomas Abraham 		return -EINVAL;
617a3b85363SThomas Abraham 	if (!prop->value)
618a3b85363SThomas Abraham 		return -ENODATA;
619a3b85363SThomas Abraham 	if (sizeof(*out_value) > prop->length)
620a3b85363SThomas Abraham 		return -EOVERFLOW;
621a3b85363SThomas Abraham 	*out_value = be32_to_cpup(prop->value);
622a3b85363SThomas Abraham 	return 0;
623a3b85363SThomas Abraham }
624a3b85363SThomas Abraham EXPORT_SYMBOL_GPL(of_property_read_u32);
625a3b85363SThomas Abraham 
626a3b85363SThomas Abraham /**
627a3b85363SThomas Abraham  * of_property_read_string - Find and read a string from a property
628a3b85363SThomas Abraham  * @np:		device node from which the property value is to be read.
629a3b85363SThomas Abraham  * @propname:	name of the property to be searched.
630a3b85363SThomas Abraham  * @out_string:	pointer to null terminated return string, modified only if
631a3b85363SThomas Abraham  *		return value is 0.
632a3b85363SThomas Abraham  *
633a3b85363SThomas Abraham  * Search for a property in a device tree node and retrieve a null
634a3b85363SThomas Abraham  * terminated string value (pointer to data, not a copy). Returns 0 on
635a3b85363SThomas Abraham  * success, -EINVAL if the property does not exist, -ENODATA if property
636a3b85363SThomas Abraham  * does not have a value, and -EILSEQ if the string is not null-terminated
637a3b85363SThomas Abraham  * within the length of the property data.
638a3b85363SThomas Abraham  *
639a3b85363SThomas Abraham  * The out_string pointer is modified only if a valid string can be decoded.
640a3b85363SThomas Abraham  */
641a3b85363SThomas Abraham int of_property_read_string(struct device_node *np, char *propname,
642a3b85363SThomas Abraham 				char **out_string)
643a3b85363SThomas Abraham {
644a3b85363SThomas Abraham 	struct property *prop = of_find_property(np, propname, NULL);
645a3b85363SThomas Abraham 	if (!prop)
646a3b85363SThomas Abraham 		return -EINVAL;
647a3b85363SThomas Abraham 	if (!prop->value)
648a3b85363SThomas Abraham 		return -ENODATA;
649a3b85363SThomas Abraham 	if (strnlen(prop->value, prop->length) >= prop->length)
650a3b85363SThomas Abraham 		return -EILSEQ;
651a3b85363SThomas Abraham 	*out_string = prop->value;
652a3b85363SThomas Abraham 	return 0;
653a3b85363SThomas Abraham }
654a3b85363SThomas Abraham EXPORT_SYMBOL_GPL(of_property_read_string);
655a3b85363SThomas Abraham 
656a3b85363SThomas Abraham /**
657739649c5SGrant Likely  * of_parse_phandle - Resolve a phandle property to a device_node pointer
658739649c5SGrant Likely  * @np: Pointer to device node holding phandle property
659739649c5SGrant Likely  * @phandle_name: Name of property holding a phandle value
660739649c5SGrant Likely  * @index: For properties holding a table of phandles, this is the index into
661739649c5SGrant Likely  *         the table
662739649c5SGrant Likely  *
663739649c5SGrant Likely  * Returns the device_node pointer with refcount incremented.  Use
664739649c5SGrant Likely  * of_node_put() on it when done.
665739649c5SGrant Likely  */
666739649c5SGrant Likely struct device_node *
667739649c5SGrant Likely of_parse_phandle(struct device_node *np, const char *phandle_name, int index)
668739649c5SGrant Likely {
6699a6b2e58SGrant Likely 	const __be32 *phandle;
670739649c5SGrant Likely 	int size;
671739649c5SGrant Likely 
672739649c5SGrant Likely 	phandle = of_get_property(np, phandle_name, &size);
673739649c5SGrant Likely 	if ((!phandle) || (size < sizeof(*phandle) * (index + 1)))
674739649c5SGrant Likely 		return NULL;
675739649c5SGrant Likely 
6769a6b2e58SGrant Likely 	return of_find_node_by_phandle(be32_to_cpup(phandle + index));
677739649c5SGrant Likely }
678739649c5SGrant Likely EXPORT_SYMBOL(of_parse_phandle);
679739649c5SGrant Likely 
680739649c5SGrant Likely /**
68164b60e09SAnton Vorontsov  * of_parse_phandles_with_args - Find a node pointed by phandle in a list
68264b60e09SAnton Vorontsov  * @np:		pointer to a device tree node containing a list
68364b60e09SAnton Vorontsov  * @list_name:	property name that contains a list
68464b60e09SAnton Vorontsov  * @cells_name:	property name that specifies phandles' arguments count
68564b60e09SAnton Vorontsov  * @index:	index of a phandle to parse out
6867736a3dbSAnton Vorontsov  * @out_node:	optional pointer to device_node struct pointer (will be filled)
6877736a3dbSAnton Vorontsov  * @out_args:	optional pointer to arguments pointer (will be filled)
68864b60e09SAnton Vorontsov  *
68964b60e09SAnton Vorontsov  * This function is useful to parse lists of phandles and their arguments.
69064b60e09SAnton Vorontsov  * Returns 0 on success and fills out_node and out_args, on error returns
69164b60e09SAnton Vorontsov  * appropriate errno value.
69264b60e09SAnton Vorontsov  *
69364b60e09SAnton Vorontsov  * Example:
69464b60e09SAnton Vorontsov  *
69564b60e09SAnton Vorontsov  * phandle1: node1 {
69664b60e09SAnton Vorontsov  * 	#list-cells = <2>;
69764b60e09SAnton Vorontsov  * }
69864b60e09SAnton Vorontsov  *
69964b60e09SAnton Vorontsov  * phandle2: node2 {
70064b60e09SAnton Vorontsov  * 	#list-cells = <1>;
70164b60e09SAnton Vorontsov  * }
70264b60e09SAnton Vorontsov  *
70364b60e09SAnton Vorontsov  * node3 {
70464b60e09SAnton Vorontsov  * 	list = <&phandle1 1 2 &phandle2 3>;
70564b60e09SAnton Vorontsov  * }
70664b60e09SAnton Vorontsov  *
70764b60e09SAnton Vorontsov  * To get a device_node of the `node2' node you may call this:
70864b60e09SAnton Vorontsov  * of_parse_phandles_with_args(node3, "list", "#list-cells", 2, &node2, &args);
70964b60e09SAnton Vorontsov  */
71064b60e09SAnton Vorontsov int of_parse_phandles_with_args(struct device_node *np, const char *list_name,
71164b60e09SAnton Vorontsov 				const char *cells_name, int index,
71264b60e09SAnton Vorontsov 				struct device_node **out_node,
71364b60e09SAnton Vorontsov 				const void **out_args)
71464b60e09SAnton Vorontsov {
71564b60e09SAnton Vorontsov 	int ret = -EINVAL;
71633714881SJeremy Kerr 	const __be32 *list;
71733714881SJeremy Kerr 	const __be32 *list_end;
71864b60e09SAnton Vorontsov 	int size;
71964b60e09SAnton Vorontsov 	int cur_index = 0;
72064b60e09SAnton Vorontsov 	struct device_node *node = NULL;
7217736a3dbSAnton Vorontsov 	const void *args = NULL;
72264b60e09SAnton Vorontsov 
72364b60e09SAnton Vorontsov 	list = of_get_property(np, list_name, &size);
72464b60e09SAnton Vorontsov 	if (!list) {
72564b60e09SAnton Vorontsov 		ret = -ENOENT;
72664b60e09SAnton Vorontsov 		goto err0;
72764b60e09SAnton Vorontsov 	}
72864b60e09SAnton Vorontsov 	list_end = list + size / sizeof(*list);
72964b60e09SAnton Vorontsov 
73064b60e09SAnton Vorontsov 	while (list < list_end) {
73133714881SJeremy Kerr 		const __be32 *cells;
7329a6b2e58SGrant Likely 		phandle phandle;
73364b60e09SAnton Vorontsov 
7349a6b2e58SGrant Likely 		phandle = be32_to_cpup(list++);
735c1bb7c6dSAnton Vorontsov 		args = list;
73664b60e09SAnton Vorontsov 
73764b60e09SAnton Vorontsov 		/* one cell hole in the list = <>; */
7389a6b2e58SGrant Likely 		if (!phandle)
73964b60e09SAnton Vorontsov 			goto next;
74064b60e09SAnton Vorontsov 
7419a6b2e58SGrant Likely 		node = of_find_node_by_phandle(phandle);
74264b60e09SAnton Vorontsov 		if (!node) {
74364b60e09SAnton Vorontsov 			pr_debug("%s: could not find phandle\n",
74464b60e09SAnton Vorontsov 				 np->full_name);
74564b60e09SAnton Vorontsov 			goto err0;
74664b60e09SAnton Vorontsov 		}
74764b60e09SAnton Vorontsov 
74864b60e09SAnton Vorontsov 		cells = of_get_property(node, cells_name, &size);
74964b60e09SAnton Vorontsov 		if (!cells || size != sizeof(*cells)) {
75064b60e09SAnton Vorontsov 			pr_debug("%s: could not get %s for %s\n",
75164b60e09SAnton Vorontsov 				 np->full_name, cells_name, node->full_name);
75264b60e09SAnton Vorontsov 			goto err1;
75364b60e09SAnton Vorontsov 		}
75464b60e09SAnton Vorontsov 
75533714881SJeremy Kerr 		list += be32_to_cpup(cells);
75664b60e09SAnton Vorontsov 		if (list > list_end) {
75764b60e09SAnton Vorontsov 			pr_debug("%s: insufficient arguments length\n",
75864b60e09SAnton Vorontsov 				 np->full_name);
75964b60e09SAnton Vorontsov 			goto err1;
76064b60e09SAnton Vorontsov 		}
76164b60e09SAnton Vorontsov next:
76264b60e09SAnton Vorontsov 		if (cur_index == index)
76364b60e09SAnton Vorontsov 			break;
76464b60e09SAnton Vorontsov 
76564b60e09SAnton Vorontsov 		of_node_put(node);
76664b60e09SAnton Vorontsov 		node = NULL;
7677736a3dbSAnton Vorontsov 		args = NULL;
76864b60e09SAnton Vorontsov 		cur_index++;
76964b60e09SAnton Vorontsov 	}
77064b60e09SAnton Vorontsov 
77164b60e09SAnton Vorontsov 	if (!node) {
7727736a3dbSAnton Vorontsov 		/*
7737736a3dbSAnton Vorontsov 		 * args w/o node indicates that the loop above has stopped at
7747736a3dbSAnton Vorontsov 		 * the 'hole' cell. Report this differently.
7757736a3dbSAnton Vorontsov 		 */
7767736a3dbSAnton Vorontsov 		if (args)
7777736a3dbSAnton Vorontsov 			ret = -EEXIST;
7787736a3dbSAnton Vorontsov 		else
77964b60e09SAnton Vorontsov 			ret = -ENOENT;
78064b60e09SAnton Vorontsov 		goto err0;
78164b60e09SAnton Vorontsov 	}
78264b60e09SAnton Vorontsov 
7837736a3dbSAnton Vorontsov 	if (out_node)
78464b60e09SAnton Vorontsov 		*out_node = node;
7857736a3dbSAnton Vorontsov 	if (out_args)
78664b60e09SAnton Vorontsov 		*out_args = args;
78764b60e09SAnton Vorontsov 
78864b60e09SAnton Vorontsov 	return 0;
78964b60e09SAnton Vorontsov err1:
79064b60e09SAnton Vorontsov 	of_node_put(node);
79164b60e09SAnton Vorontsov err0:
79264b60e09SAnton Vorontsov 	pr_debug("%s failed with status %d\n", __func__, ret);
79364b60e09SAnton Vorontsov 	return ret;
79464b60e09SAnton Vorontsov }
79564b60e09SAnton Vorontsov EXPORT_SYMBOL(of_parse_phandles_with_args);
79602af11b0SGrant Likely 
79702af11b0SGrant Likely /**
79802af11b0SGrant Likely  * prom_add_property - Add a property to a node
79902af11b0SGrant Likely  */
80002af11b0SGrant Likely int prom_add_property(struct device_node *np, struct property *prop)
80102af11b0SGrant Likely {
80202af11b0SGrant Likely 	struct property **next;
80302af11b0SGrant Likely 	unsigned long flags;
80402af11b0SGrant Likely 
80502af11b0SGrant Likely 	prop->next = NULL;
80602af11b0SGrant Likely 	write_lock_irqsave(&devtree_lock, flags);
80702af11b0SGrant Likely 	next = &np->properties;
80802af11b0SGrant Likely 	while (*next) {
80902af11b0SGrant Likely 		if (strcmp(prop->name, (*next)->name) == 0) {
81002af11b0SGrant Likely 			/* duplicate ! don't insert it */
81102af11b0SGrant Likely 			write_unlock_irqrestore(&devtree_lock, flags);
81202af11b0SGrant Likely 			return -1;
81302af11b0SGrant Likely 		}
81402af11b0SGrant Likely 		next = &(*next)->next;
81502af11b0SGrant Likely 	}
81602af11b0SGrant Likely 	*next = prop;
81702af11b0SGrant Likely 	write_unlock_irqrestore(&devtree_lock, flags);
81802af11b0SGrant Likely 
81902af11b0SGrant Likely #ifdef CONFIG_PROC_DEVICETREE
82002af11b0SGrant Likely 	/* try to add to proc as well if it was initialized */
82102af11b0SGrant Likely 	if (np->pde)
82202af11b0SGrant Likely 		proc_device_tree_add_prop(np->pde, prop);
82302af11b0SGrant Likely #endif /* CONFIG_PROC_DEVICETREE */
82402af11b0SGrant Likely 
82502af11b0SGrant Likely 	return 0;
82602af11b0SGrant Likely }
82702af11b0SGrant Likely 
82802af11b0SGrant Likely /**
82902af11b0SGrant Likely  * prom_remove_property - Remove a property from a node.
83002af11b0SGrant Likely  *
83102af11b0SGrant Likely  * Note that we don't actually remove it, since we have given out
83202af11b0SGrant Likely  * who-knows-how-many pointers to the data using get-property.
83302af11b0SGrant Likely  * Instead we just move the property to the "dead properties"
83402af11b0SGrant Likely  * list, so it won't be found any more.
83502af11b0SGrant Likely  */
83602af11b0SGrant Likely int prom_remove_property(struct device_node *np, struct property *prop)
83702af11b0SGrant Likely {
83802af11b0SGrant Likely 	struct property **next;
83902af11b0SGrant Likely 	unsigned long flags;
84002af11b0SGrant Likely 	int found = 0;
84102af11b0SGrant Likely 
84202af11b0SGrant Likely 	write_lock_irqsave(&devtree_lock, flags);
84302af11b0SGrant Likely 	next = &np->properties;
84402af11b0SGrant Likely 	while (*next) {
84502af11b0SGrant Likely 		if (*next == prop) {
84602af11b0SGrant Likely 			/* found the node */
84702af11b0SGrant Likely 			*next = prop->next;
84802af11b0SGrant Likely 			prop->next = np->deadprops;
84902af11b0SGrant Likely 			np->deadprops = prop;
85002af11b0SGrant Likely 			found = 1;
85102af11b0SGrant Likely 			break;
85202af11b0SGrant Likely 		}
85302af11b0SGrant Likely 		next = &(*next)->next;
85402af11b0SGrant Likely 	}
85502af11b0SGrant Likely 	write_unlock_irqrestore(&devtree_lock, flags);
85602af11b0SGrant Likely 
85702af11b0SGrant Likely 	if (!found)
85802af11b0SGrant Likely 		return -ENODEV;
85902af11b0SGrant Likely 
86002af11b0SGrant Likely #ifdef CONFIG_PROC_DEVICETREE
86102af11b0SGrant Likely 	/* try to remove the proc node as well */
86202af11b0SGrant Likely 	if (np->pde)
86302af11b0SGrant Likely 		proc_device_tree_remove_prop(np->pde, prop);
86402af11b0SGrant Likely #endif /* CONFIG_PROC_DEVICETREE */
86502af11b0SGrant Likely 
86602af11b0SGrant Likely 	return 0;
86702af11b0SGrant Likely }
86802af11b0SGrant Likely 
86902af11b0SGrant Likely /*
87002af11b0SGrant Likely  * prom_update_property - Update a property in a node.
87102af11b0SGrant Likely  *
87202af11b0SGrant Likely  * Note that we don't actually remove it, since we have given out
87302af11b0SGrant Likely  * who-knows-how-many pointers to the data using get-property.
87402af11b0SGrant Likely  * Instead we just move the property to the "dead properties" list,
87502af11b0SGrant Likely  * and add the new property to the property list
87602af11b0SGrant Likely  */
87702af11b0SGrant Likely int prom_update_property(struct device_node *np,
87802af11b0SGrant Likely 			 struct property *newprop,
87902af11b0SGrant Likely 			 struct property *oldprop)
88002af11b0SGrant Likely {
88102af11b0SGrant Likely 	struct property **next;
88202af11b0SGrant Likely 	unsigned long flags;
88302af11b0SGrant Likely 	int found = 0;
88402af11b0SGrant Likely 
88502af11b0SGrant Likely 	write_lock_irqsave(&devtree_lock, flags);
88602af11b0SGrant Likely 	next = &np->properties;
88702af11b0SGrant Likely 	while (*next) {
88802af11b0SGrant Likely 		if (*next == oldprop) {
88902af11b0SGrant Likely 			/* found the node */
89002af11b0SGrant Likely 			newprop->next = oldprop->next;
89102af11b0SGrant Likely 			*next = newprop;
89202af11b0SGrant Likely 			oldprop->next = np->deadprops;
89302af11b0SGrant Likely 			np->deadprops = oldprop;
89402af11b0SGrant Likely 			found = 1;
89502af11b0SGrant Likely 			break;
89602af11b0SGrant Likely 		}
89702af11b0SGrant Likely 		next = &(*next)->next;
89802af11b0SGrant Likely 	}
89902af11b0SGrant Likely 	write_unlock_irqrestore(&devtree_lock, flags);
90002af11b0SGrant Likely 
90102af11b0SGrant Likely 	if (!found)
90202af11b0SGrant Likely 		return -ENODEV;
90302af11b0SGrant Likely 
90402af11b0SGrant Likely #ifdef CONFIG_PROC_DEVICETREE
90502af11b0SGrant Likely 	/* try to add to proc as well if it was initialized */
90602af11b0SGrant Likely 	if (np->pde)
90702af11b0SGrant Likely 		proc_device_tree_update_prop(np->pde, newprop, oldprop);
90802af11b0SGrant Likely #endif /* CONFIG_PROC_DEVICETREE */
90902af11b0SGrant Likely 
91002af11b0SGrant Likely 	return 0;
91102af11b0SGrant Likely }
912fcdeb7feSGrant Likely 
913fcdeb7feSGrant Likely #if defined(CONFIG_OF_DYNAMIC)
914fcdeb7feSGrant Likely /*
915fcdeb7feSGrant Likely  * Support for dynamic device trees.
916fcdeb7feSGrant Likely  *
917fcdeb7feSGrant Likely  * On some platforms, the device tree can be manipulated at runtime.
918fcdeb7feSGrant Likely  * The routines in this section support adding, removing and changing
919fcdeb7feSGrant Likely  * device tree nodes.
920fcdeb7feSGrant Likely  */
921fcdeb7feSGrant Likely 
922fcdeb7feSGrant Likely /**
923fcdeb7feSGrant Likely  * of_attach_node - Plug a device node into the tree and global list.
924fcdeb7feSGrant Likely  */
925fcdeb7feSGrant Likely void of_attach_node(struct device_node *np)
926fcdeb7feSGrant Likely {
927fcdeb7feSGrant Likely 	unsigned long flags;
928fcdeb7feSGrant Likely 
929fcdeb7feSGrant Likely 	write_lock_irqsave(&devtree_lock, flags);
930fcdeb7feSGrant Likely 	np->sibling = np->parent->child;
931fcdeb7feSGrant Likely 	np->allnext = allnodes;
932fcdeb7feSGrant Likely 	np->parent->child = np;
933fcdeb7feSGrant Likely 	allnodes = np;
934fcdeb7feSGrant Likely 	write_unlock_irqrestore(&devtree_lock, flags);
935fcdeb7feSGrant Likely }
936fcdeb7feSGrant Likely 
937fcdeb7feSGrant Likely /**
938fcdeb7feSGrant Likely  * of_detach_node - "Unplug" a node from the device tree.
939fcdeb7feSGrant Likely  *
940fcdeb7feSGrant Likely  * The caller must hold a reference to the node.  The memory associated with
941fcdeb7feSGrant Likely  * the node is not freed until its refcount goes to zero.
942fcdeb7feSGrant Likely  */
943fcdeb7feSGrant Likely void of_detach_node(struct device_node *np)
944fcdeb7feSGrant Likely {
945fcdeb7feSGrant Likely 	struct device_node *parent;
946fcdeb7feSGrant Likely 	unsigned long flags;
947fcdeb7feSGrant Likely 
948fcdeb7feSGrant Likely 	write_lock_irqsave(&devtree_lock, flags);
949fcdeb7feSGrant Likely 
950fcdeb7feSGrant Likely 	parent = np->parent;
951fcdeb7feSGrant Likely 	if (!parent)
952fcdeb7feSGrant Likely 		goto out_unlock;
953fcdeb7feSGrant Likely 
954fcdeb7feSGrant Likely 	if (allnodes == np)
955fcdeb7feSGrant Likely 		allnodes = np->allnext;
956fcdeb7feSGrant Likely 	else {
957fcdeb7feSGrant Likely 		struct device_node *prev;
958fcdeb7feSGrant Likely 		for (prev = allnodes;
959fcdeb7feSGrant Likely 		     prev->allnext != np;
960fcdeb7feSGrant Likely 		     prev = prev->allnext)
961fcdeb7feSGrant Likely 			;
962fcdeb7feSGrant Likely 		prev->allnext = np->allnext;
963fcdeb7feSGrant Likely 	}
964fcdeb7feSGrant Likely 
965fcdeb7feSGrant Likely 	if (parent->child == np)
966fcdeb7feSGrant Likely 		parent->child = np->sibling;
967fcdeb7feSGrant Likely 	else {
968fcdeb7feSGrant Likely 		struct device_node *prevsib;
969fcdeb7feSGrant Likely 		for (prevsib = np->parent->child;
970fcdeb7feSGrant Likely 		     prevsib->sibling != np;
971fcdeb7feSGrant Likely 		     prevsib = prevsib->sibling)
972fcdeb7feSGrant Likely 			;
973fcdeb7feSGrant Likely 		prevsib->sibling = np->sibling;
974fcdeb7feSGrant Likely 	}
975fcdeb7feSGrant Likely 
976fcdeb7feSGrant Likely 	of_node_set_flag(np, OF_DETACHED);
977fcdeb7feSGrant Likely 
978fcdeb7feSGrant Likely out_unlock:
979fcdeb7feSGrant Likely 	write_unlock_irqrestore(&devtree_lock, flags);
980fcdeb7feSGrant Likely }
981fcdeb7feSGrant Likely #endif /* defined(CONFIG_OF_DYNAMIC) */
982fcdeb7feSGrant Likely 
983