xref: /openbmc/linux/drivers/of/base.c (revision f3cea45a)
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  */
20611cad72SShawn Guo #include <linux/ctype.h>
21183912d3SSudeep KarkadaNagesha #include <linux/cpu.h>
2297e873e5SStephen Rothwell #include <linux/module.h>
2397e873e5SStephen Rothwell #include <linux/of.h>
24581b605aSStephen Rothwell #include <linux/spinlock.h>
255a0e3ad6STejun Heo #include <linux/slab.h>
26a9f2f63aSJeremy Kerr #include <linux/proc_fs.h>
27581b605aSStephen Rothwell 
28ced4eec9SStepan Moskovchenko #include "of_private.h"
29611cad72SShawn Guo 
30ced4eec9SStepan Moskovchenko LIST_HEAD(aliases_lookup);
31611cad72SShawn Guo 
32465aac6dSRandy Dunlap struct device_node *of_allnodes;
33465aac6dSRandy Dunlap EXPORT_SYMBOL(of_allnodes);
34fc0bdae4SGrant Likely struct device_node *of_chosen;
35611cad72SShawn Guo struct device_node *of_aliases;
365c19e952SSascha Hauer static struct device_node *of_stdout;
37611cad72SShawn Guo 
38ced4eec9SStepan Moskovchenko DEFINE_MUTEX(of_aliases_mutex);
391ef4d424SStephen Rothwell 
40581b605aSStephen Rothwell /* use when traversing tree through the allnext, child, sibling,
41581b605aSStephen Rothwell  * or parent members of struct device_node.
42581b605aSStephen Rothwell  */
43d6d3c4e6SThomas Gleixner DEFINE_RAW_SPINLOCK(devtree_lock);
4497e873e5SStephen Rothwell 
4597e873e5SStephen Rothwell int of_n_addr_cells(struct device_node *np)
4697e873e5SStephen Rothwell {
47a9fadeefSJeremy Kerr 	const __be32 *ip;
4897e873e5SStephen Rothwell 
4997e873e5SStephen Rothwell 	do {
5097e873e5SStephen Rothwell 		if (np->parent)
5197e873e5SStephen Rothwell 			np = np->parent;
5297e873e5SStephen Rothwell 		ip = of_get_property(np, "#address-cells", NULL);
5397e873e5SStephen Rothwell 		if (ip)
5433714881SJeremy Kerr 			return be32_to_cpup(ip);
5597e873e5SStephen Rothwell 	} while (np->parent);
5697e873e5SStephen Rothwell 	/* No #address-cells property for the root node */
5797e873e5SStephen Rothwell 	return OF_ROOT_NODE_ADDR_CELLS_DEFAULT;
5897e873e5SStephen Rothwell }
5997e873e5SStephen Rothwell EXPORT_SYMBOL(of_n_addr_cells);
6097e873e5SStephen Rothwell 
6197e873e5SStephen Rothwell int of_n_size_cells(struct device_node *np)
6297e873e5SStephen Rothwell {
63a9fadeefSJeremy Kerr 	const __be32 *ip;
6497e873e5SStephen Rothwell 
6597e873e5SStephen Rothwell 	do {
6697e873e5SStephen Rothwell 		if (np->parent)
6797e873e5SStephen Rothwell 			np = np->parent;
6897e873e5SStephen Rothwell 		ip = of_get_property(np, "#size-cells", NULL);
6997e873e5SStephen Rothwell 		if (ip)
7033714881SJeremy Kerr 			return be32_to_cpup(ip);
7197e873e5SStephen Rothwell 	} while (np->parent);
7297e873e5SStephen Rothwell 	/* No #size-cells property for the root node */
7397e873e5SStephen Rothwell 	return OF_ROOT_NODE_SIZE_CELLS_DEFAULT;
7497e873e5SStephen Rothwell }
7597e873e5SStephen Rothwell EXPORT_SYMBOL(of_n_size_cells);
7697e873e5SStephen Rothwell 
770f22dd39SGrant Likely #if defined(CONFIG_OF_DYNAMIC)
78923f7e30SGrant Likely /**
79923f7e30SGrant Likely  *	of_node_get - Increment refcount of a node
80923f7e30SGrant Likely  *	@node:	Node to inc refcount, NULL is supported to
81923f7e30SGrant Likely  *		simplify writing of callers
82923f7e30SGrant Likely  *
83923f7e30SGrant Likely  *	Returns node.
84923f7e30SGrant Likely  */
85923f7e30SGrant Likely struct device_node *of_node_get(struct device_node *node)
86923f7e30SGrant Likely {
87923f7e30SGrant Likely 	if (node)
88923f7e30SGrant Likely 		kref_get(&node->kref);
89923f7e30SGrant Likely 	return node;
90923f7e30SGrant Likely }
91923f7e30SGrant Likely EXPORT_SYMBOL(of_node_get);
92923f7e30SGrant Likely 
93923f7e30SGrant Likely static inline struct device_node *kref_to_device_node(struct kref *kref)
94923f7e30SGrant Likely {
95923f7e30SGrant Likely 	return container_of(kref, struct device_node, kref);
96923f7e30SGrant Likely }
97923f7e30SGrant Likely 
98923f7e30SGrant Likely /**
99923f7e30SGrant Likely  *	of_node_release - release a dynamically allocated node
100923f7e30SGrant Likely  *	@kref:  kref element of the node to be released
101923f7e30SGrant Likely  *
102923f7e30SGrant Likely  *	In of_node_put() this function is passed to kref_put()
103923f7e30SGrant Likely  *	as the destructor.
104923f7e30SGrant Likely  */
105923f7e30SGrant Likely static void of_node_release(struct kref *kref)
106923f7e30SGrant Likely {
107923f7e30SGrant Likely 	struct device_node *node = kref_to_device_node(kref);
108923f7e30SGrant Likely 	struct property *prop = node->properties;
109923f7e30SGrant Likely 
110923f7e30SGrant Likely 	/* We should never be releasing nodes that haven't been detached. */
111923f7e30SGrant Likely 	if (!of_node_check_flag(node, OF_DETACHED)) {
112923f7e30SGrant Likely 		pr_err("ERROR: Bad of_node_put() on %s\n", node->full_name);
113923f7e30SGrant Likely 		dump_stack();
114923f7e30SGrant Likely 		kref_init(&node->kref);
115923f7e30SGrant Likely 		return;
116923f7e30SGrant Likely 	}
117923f7e30SGrant Likely 
118923f7e30SGrant Likely 	if (!of_node_check_flag(node, OF_DYNAMIC))
119923f7e30SGrant Likely 		return;
120923f7e30SGrant Likely 
121923f7e30SGrant Likely 	while (prop) {
122923f7e30SGrant Likely 		struct property *next = prop->next;
123923f7e30SGrant Likely 		kfree(prop->name);
124923f7e30SGrant Likely 		kfree(prop->value);
125923f7e30SGrant Likely 		kfree(prop);
126923f7e30SGrant Likely 		prop = next;
127923f7e30SGrant Likely 
128923f7e30SGrant Likely 		if (!prop) {
129923f7e30SGrant Likely 			prop = node->deadprops;
130923f7e30SGrant Likely 			node->deadprops = NULL;
131923f7e30SGrant Likely 		}
132923f7e30SGrant Likely 	}
133923f7e30SGrant Likely 	kfree(node->full_name);
134923f7e30SGrant Likely 	kfree(node->data);
135923f7e30SGrant Likely 	kfree(node);
136923f7e30SGrant Likely }
137923f7e30SGrant Likely 
138923f7e30SGrant Likely /**
139923f7e30SGrant Likely  *	of_node_put - Decrement refcount of a node
140923f7e30SGrant Likely  *	@node:	Node to dec refcount, NULL is supported to
141923f7e30SGrant Likely  *		simplify writing of callers
142923f7e30SGrant Likely  *
143923f7e30SGrant Likely  */
144923f7e30SGrant Likely void of_node_put(struct device_node *node)
145923f7e30SGrant Likely {
146923f7e30SGrant Likely 	if (node)
147923f7e30SGrant Likely 		kref_put(&node->kref, of_node_release);
148923f7e30SGrant Likely }
149923f7e30SGrant Likely EXPORT_SYMBOL(of_node_put);
1500f22dd39SGrant Likely #endif /* CONFIG_OF_DYNAMIC */
151923f7e30SGrant Likely 
15228d0e36bSThomas Gleixner static struct property *__of_find_property(const struct device_node *np,
15328d0e36bSThomas Gleixner 					   const char *name, int *lenp)
154581b605aSStephen Rothwell {
155581b605aSStephen Rothwell 	struct property *pp;
156581b605aSStephen Rothwell 
15764e4566fSTimur Tabi 	if (!np)
15864e4566fSTimur Tabi 		return NULL;
15964e4566fSTimur Tabi 
160a3a7cab1SSachin Kamat 	for (pp = np->properties; pp; pp = pp->next) {
161581b605aSStephen Rothwell 		if (of_prop_cmp(pp->name, name) == 0) {
162a3a7cab1SSachin Kamat 			if (lenp)
163581b605aSStephen Rothwell 				*lenp = pp->length;
164581b605aSStephen Rothwell 			break;
165581b605aSStephen Rothwell 		}
166581b605aSStephen Rothwell 	}
16728d0e36bSThomas Gleixner 
16828d0e36bSThomas Gleixner 	return pp;
16928d0e36bSThomas Gleixner }
17028d0e36bSThomas Gleixner 
17128d0e36bSThomas Gleixner struct property *of_find_property(const struct device_node *np,
17228d0e36bSThomas Gleixner 				  const char *name,
17328d0e36bSThomas Gleixner 				  int *lenp)
17428d0e36bSThomas Gleixner {
17528d0e36bSThomas Gleixner 	struct property *pp;
176d6d3c4e6SThomas Gleixner 	unsigned long flags;
17728d0e36bSThomas Gleixner 
178d6d3c4e6SThomas Gleixner 	raw_spin_lock_irqsave(&devtree_lock, flags);
17928d0e36bSThomas Gleixner 	pp = __of_find_property(np, name, lenp);
180d6d3c4e6SThomas Gleixner 	raw_spin_unlock_irqrestore(&devtree_lock, flags);
181581b605aSStephen Rothwell 
182581b605aSStephen Rothwell 	return pp;
183581b605aSStephen Rothwell }
184581b605aSStephen Rothwell EXPORT_SYMBOL(of_find_property);
185581b605aSStephen Rothwell 
186e91edcf5SGrant Likely /**
187e91edcf5SGrant Likely  * of_find_all_nodes - Get next node in global list
188e91edcf5SGrant Likely  * @prev:	Previous node or NULL to start iteration
189e91edcf5SGrant Likely  *		of_node_put() will be called on it
190e91edcf5SGrant Likely  *
191e91edcf5SGrant Likely  * Returns a node pointer with refcount incremented, use
192e91edcf5SGrant Likely  * of_node_put() on it when done.
193e91edcf5SGrant Likely  */
194e91edcf5SGrant Likely struct device_node *of_find_all_nodes(struct device_node *prev)
195e91edcf5SGrant Likely {
196e91edcf5SGrant Likely 	struct device_node *np;
197d25d8694SBenjamin Herrenschmidt 	unsigned long flags;
198e91edcf5SGrant Likely 
199d25d8694SBenjamin Herrenschmidt 	raw_spin_lock_irqsave(&devtree_lock, flags);
200465aac6dSRandy Dunlap 	np = prev ? prev->allnext : of_allnodes;
201e91edcf5SGrant Likely 	for (; np != NULL; np = np->allnext)
202e91edcf5SGrant Likely 		if (of_node_get(np))
203e91edcf5SGrant Likely 			break;
204e91edcf5SGrant Likely 	of_node_put(prev);
205d25d8694SBenjamin Herrenschmidt 	raw_spin_unlock_irqrestore(&devtree_lock, flags);
206e91edcf5SGrant Likely 	return np;
207e91edcf5SGrant Likely }
208e91edcf5SGrant Likely EXPORT_SYMBOL(of_find_all_nodes);
209e91edcf5SGrant Likely 
21097e873e5SStephen Rothwell /*
21197e873e5SStephen Rothwell  * Find a property with a given name for a given node
21297e873e5SStephen Rothwell  * and return the value.
21397e873e5SStephen Rothwell  */
21428d0e36bSThomas Gleixner static const void *__of_get_property(const struct device_node *np,
21528d0e36bSThomas Gleixner 				     const char *name, int *lenp)
21628d0e36bSThomas Gleixner {
21728d0e36bSThomas Gleixner 	struct property *pp = __of_find_property(np, name, lenp);
21828d0e36bSThomas Gleixner 
21928d0e36bSThomas Gleixner 	return pp ? pp->value : NULL;
22028d0e36bSThomas Gleixner }
22128d0e36bSThomas Gleixner 
22228d0e36bSThomas Gleixner /*
22328d0e36bSThomas Gleixner  * Find a property with a given name for a given node
22428d0e36bSThomas Gleixner  * and return the value.
22528d0e36bSThomas Gleixner  */
22697e873e5SStephen Rothwell const void *of_get_property(const struct device_node *np, const char *name,
22797e873e5SStephen Rothwell 			    int *lenp)
22897e873e5SStephen Rothwell {
22997e873e5SStephen Rothwell 	struct property *pp = of_find_property(np, name, lenp);
23097e873e5SStephen Rothwell 
23197e873e5SStephen Rothwell 	return pp ? pp->value : NULL;
23297e873e5SStephen Rothwell }
23397e873e5SStephen Rothwell EXPORT_SYMBOL(of_get_property);
2340081cbc3SStephen Rothwell 
235183912d3SSudeep KarkadaNagesha /*
236183912d3SSudeep KarkadaNagesha  * arch_match_cpu_phys_id - Match the given logical CPU and physical id
237183912d3SSudeep KarkadaNagesha  *
238183912d3SSudeep KarkadaNagesha  * @cpu: logical cpu index of a core/thread
239183912d3SSudeep KarkadaNagesha  * @phys_id: physical identifier of a core/thread
240183912d3SSudeep KarkadaNagesha  *
241183912d3SSudeep KarkadaNagesha  * CPU logical to physical index mapping is architecture specific.
242183912d3SSudeep KarkadaNagesha  * However this __weak function provides a default match of physical
243183912d3SSudeep KarkadaNagesha  * id to logical cpu index. phys_id provided here is usually values read
244183912d3SSudeep KarkadaNagesha  * from the device tree which must match the hardware internal registers.
245183912d3SSudeep KarkadaNagesha  *
246183912d3SSudeep KarkadaNagesha  * Returns true if the physical identifier and the logical cpu index
247183912d3SSudeep KarkadaNagesha  * correspond to the same core/thread, false otherwise.
248183912d3SSudeep KarkadaNagesha  */
249183912d3SSudeep KarkadaNagesha bool __weak arch_match_cpu_phys_id(int cpu, u64 phys_id)
250183912d3SSudeep KarkadaNagesha {
251183912d3SSudeep KarkadaNagesha 	return (u32)phys_id == cpu;
252183912d3SSudeep KarkadaNagesha }
253183912d3SSudeep KarkadaNagesha 
254183912d3SSudeep KarkadaNagesha /**
255183912d3SSudeep KarkadaNagesha  * Checks if the given "prop_name" property holds the physical id of the
256183912d3SSudeep KarkadaNagesha  * core/thread corresponding to the logical cpu 'cpu'. If 'thread' is not
257183912d3SSudeep KarkadaNagesha  * NULL, local thread number within the core is returned in it.
258183912d3SSudeep KarkadaNagesha  */
259183912d3SSudeep KarkadaNagesha static bool __of_find_n_match_cpu_property(struct device_node *cpun,
260183912d3SSudeep KarkadaNagesha 			const char *prop_name, int cpu, unsigned int *thread)
261183912d3SSudeep KarkadaNagesha {
262183912d3SSudeep KarkadaNagesha 	const __be32 *cell;
263183912d3SSudeep KarkadaNagesha 	int ac, prop_len, tid;
264183912d3SSudeep KarkadaNagesha 	u64 hwid;
265183912d3SSudeep KarkadaNagesha 
266183912d3SSudeep KarkadaNagesha 	ac = of_n_addr_cells(cpun);
267183912d3SSudeep KarkadaNagesha 	cell = of_get_property(cpun, prop_name, &prop_len);
268f3cea45aSGrant Likely 	if (!cell || !ac)
269183912d3SSudeep KarkadaNagesha 		return false;
270f3cea45aSGrant Likely 	prop_len /= sizeof(*cell) * ac;
271183912d3SSudeep KarkadaNagesha 	for (tid = 0; tid < prop_len; tid++) {
272183912d3SSudeep KarkadaNagesha 		hwid = of_read_number(cell, ac);
273183912d3SSudeep KarkadaNagesha 		if (arch_match_cpu_phys_id(cpu, hwid)) {
274183912d3SSudeep KarkadaNagesha 			if (thread)
275183912d3SSudeep KarkadaNagesha 				*thread = tid;
276183912d3SSudeep KarkadaNagesha 			return true;
277183912d3SSudeep KarkadaNagesha 		}
278183912d3SSudeep KarkadaNagesha 		cell += ac;
279183912d3SSudeep KarkadaNagesha 	}
280183912d3SSudeep KarkadaNagesha 	return false;
281183912d3SSudeep KarkadaNagesha }
282183912d3SSudeep KarkadaNagesha 
283d1cb9d1aSDavid Miller /*
284d1cb9d1aSDavid Miller  * arch_find_n_match_cpu_physical_id - See if the given device node is
285d1cb9d1aSDavid Miller  * for the cpu corresponding to logical cpu 'cpu'.  Return true if so,
286d1cb9d1aSDavid Miller  * else false.  If 'thread' is non-NULL, the local thread number within the
287d1cb9d1aSDavid Miller  * core is returned in it.
288d1cb9d1aSDavid Miller  */
289d1cb9d1aSDavid Miller bool __weak arch_find_n_match_cpu_physical_id(struct device_node *cpun,
290d1cb9d1aSDavid Miller 					      int cpu, unsigned int *thread)
291d1cb9d1aSDavid Miller {
292d1cb9d1aSDavid Miller 	/* Check for non-standard "ibm,ppc-interrupt-server#s" property
293d1cb9d1aSDavid Miller 	 * for thread ids on PowerPC. If it doesn't exist fallback to
294d1cb9d1aSDavid Miller 	 * standard "reg" property.
295d1cb9d1aSDavid Miller 	 */
296d1cb9d1aSDavid Miller 	if (IS_ENABLED(CONFIG_PPC) &&
297d1cb9d1aSDavid Miller 	    __of_find_n_match_cpu_property(cpun,
298d1cb9d1aSDavid Miller 					   "ibm,ppc-interrupt-server#s",
299d1cb9d1aSDavid Miller 					   cpu, thread))
300d1cb9d1aSDavid Miller 		return true;
301d1cb9d1aSDavid Miller 
302d1cb9d1aSDavid Miller 	if (__of_find_n_match_cpu_property(cpun, "reg", cpu, thread))
303d1cb9d1aSDavid Miller 		return true;
304d1cb9d1aSDavid Miller 
305d1cb9d1aSDavid Miller 	return false;
306d1cb9d1aSDavid Miller }
307d1cb9d1aSDavid Miller 
308183912d3SSudeep KarkadaNagesha /**
309183912d3SSudeep KarkadaNagesha  * of_get_cpu_node - Get device node associated with the given logical CPU
310183912d3SSudeep KarkadaNagesha  *
311183912d3SSudeep KarkadaNagesha  * @cpu: CPU number(logical index) for which device node is required
312183912d3SSudeep KarkadaNagesha  * @thread: if not NULL, local thread number within the physical core is
313183912d3SSudeep KarkadaNagesha  *          returned
314183912d3SSudeep KarkadaNagesha  *
315183912d3SSudeep KarkadaNagesha  * The main purpose of this function is to retrieve the device node for the
316183912d3SSudeep KarkadaNagesha  * given logical CPU index. It should be used to initialize the of_node in
317183912d3SSudeep KarkadaNagesha  * cpu device. Once of_node in cpu device is populated, all the further
318183912d3SSudeep KarkadaNagesha  * references can use that instead.
319183912d3SSudeep KarkadaNagesha  *
320183912d3SSudeep KarkadaNagesha  * CPU logical to physical index mapping is architecture specific and is built
321183912d3SSudeep KarkadaNagesha  * before booting secondary cores. This function uses arch_match_cpu_phys_id
322183912d3SSudeep KarkadaNagesha  * which can be overridden by architecture specific implementation.
323183912d3SSudeep KarkadaNagesha  *
324183912d3SSudeep KarkadaNagesha  * Returns a node pointer for the logical cpu if found, else NULL.
325183912d3SSudeep KarkadaNagesha  */
326183912d3SSudeep KarkadaNagesha struct device_node *of_get_cpu_node(int cpu, unsigned int *thread)
327183912d3SSudeep KarkadaNagesha {
328d1cb9d1aSDavid Miller 	struct device_node *cpun;
329183912d3SSudeep KarkadaNagesha 
330d1cb9d1aSDavid Miller 	for_each_node_by_type(cpun, "cpu") {
331d1cb9d1aSDavid Miller 		if (arch_find_n_match_cpu_physical_id(cpun, cpu, thread))
332183912d3SSudeep KarkadaNagesha 			return cpun;
333183912d3SSudeep KarkadaNagesha 	}
334183912d3SSudeep KarkadaNagesha 	return NULL;
335183912d3SSudeep KarkadaNagesha }
336183912d3SSudeep KarkadaNagesha EXPORT_SYMBOL(of_get_cpu_node);
337183912d3SSudeep KarkadaNagesha 
3380081cbc3SStephen Rothwell /** Checks if the given "compat" string matches one of the strings in
3390081cbc3SStephen Rothwell  * the device's "compatible" property
3400081cbc3SStephen Rothwell  */
34128d0e36bSThomas Gleixner static int __of_device_is_compatible(const struct device_node *device,
3420081cbc3SStephen Rothwell 				     const char *compat)
3430081cbc3SStephen Rothwell {
3440081cbc3SStephen Rothwell 	const char* cp;
3450081cbc3SStephen Rothwell 	int cplen, l;
3460081cbc3SStephen Rothwell 
34728d0e36bSThomas Gleixner 	cp = __of_get_property(device, "compatible", &cplen);
3480081cbc3SStephen Rothwell 	if (cp == NULL)
3490081cbc3SStephen Rothwell 		return 0;
3500081cbc3SStephen Rothwell 	while (cplen > 0) {
3510081cbc3SStephen Rothwell 		if (of_compat_cmp(cp, compat, strlen(compat)) == 0)
3520081cbc3SStephen Rothwell 			return 1;
3530081cbc3SStephen Rothwell 		l = strlen(cp) + 1;
3540081cbc3SStephen Rothwell 		cp += l;
3550081cbc3SStephen Rothwell 		cplen -= l;
3560081cbc3SStephen Rothwell 	}
3570081cbc3SStephen Rothwell 
3580081cbc3SStephen Rothwell 	return 0;
3590081cbc3SStephen Rothwell }
36028d0e36bSThomas Gleixner 
36128d0e36bSThomas Gleixner /** Checks if the given "compat" string matches one of the strings in
36228d0e36bSThomas Gleixner  * the device's "compatible" property
36328d0e36bSThomas Gleixner  */
36428d0e36bSThomas Gleixner int of_device_is_compatible(const struct device_node *device,
36528d0e36bSThomas Gleixner 		const char *compat)
36628d0e36bSThomas Gleixner {
367d6d3c4e6SThomas Gleixner 	unsigned long flags;
36828d0e36bSThomas Gleixner 	int res;
36928d0e36bSThomas Gleixner 
370d6d3c4e6SThomas Gleixner 	raw_spin_lock_irqsave(&devtree_lock, flags);
37128d0e36bSThomas Gleixner 	res = __of_device_is_compatible(device, compat);
372d6d3c4e6SThomas Gleixner 	raw_spin_unlock_irqrestore(&devtree_lock, flags);
37328d0e36bSThomas Gleixner 	return res;
37428d0e36bSThomas Gleixner }
3750081cbc3SStephen Rothwell EXPORT_SYMBOL(of_device_is_compatible);
376e679c5f4SStephen Rothwell 
377e679c5f4SStephen Rothwell /**
37871a157e8SGrant Likely  * of_machine_is_compatible - Test root of device tree for a given compatible value
3791f43cfb9SGrant Likely  * @compat: compatible string to look for in root node's compatible property.
3801f43cfb9SGrant Likely  *
3811f43cfb9SGrant Likely  * Returns true if the root node has the given value in its
3821f43cfb9SGrant Likely  * compatible property.
3831f43cfb9SGrant Likely  */
38471a157e8SGrant Likely int of_machine_is_compatible(const char *compat)
3851f43cfb9SGrant Likely {
3861f43cfb9SGrant Likely 	struct device_node *root;
3871f43cfb9SGrant Likely 	int rc = 0;
3881f43cfb9SGrant Likely 
3891f43cfb9SGrant Likely 	root = of_find_node_by_path("/");
3901f43cfb9SGrant Likely 	if (root) {
3911f43cfb9SGrant Likely 		rc = of_device_is_compatible(root, compat);
3921f43cfb9SGrant Likely 		of_node_put(root);
3931f43cfb9SGrant Likely 	}
3941f43cfb9SGrant Likely 	return rc;
3951f43cfb9SGrant Likely }
39671a157e8SGrant Likely EXPORT_SYMBOL(of_machine_is_compatible);
3971f43cfb9SGrant Likely 
3981f43cfb9SGrant Likely /**
399c31a0c05SStephen Warren  *  __of_device_is_available - check if a device is available for use
400834d97d4SJosh Boyer  *
401c31a0c05SStephen Warren  *  @device: Node to check for availability, with locks already held
402834d97d4SJosh Boyer  *
403834d97d4SJosh Boyer  *  Returns 1 if the status property is absent or set to "okay" or "ok",
404834d97d4SJosh Boyer  *  0 otherwise
405834d97d4SJosh Boyer  */
406c31a0c05SStephen Warren static int __of_device_is_available(const struct device_node *device)
407834d97d4SJosh Boyer {
408834d97d4SJosh Boyer 	const char *status;
409834d97d4SJosh Boyer 	int statlen;
410834d97d4SJosh Boyer 
411c31a0c05SStephen Warren 	status = __of_get_property(device, "status", &statlen);
412834d97d4SJosh Boyer 	if (status == NULL)
413834d97d4SJosh Boyer 		return 1;
414834d97d4SJosh Boyer 
415834d97d4SJosh Boyer 	if (statlen > 0) {
416834d97d4SJosh Boyer 		if (!strcmp(status, "okay") || !strcmp(status, "ok"))
417834d97d4SJosh Boyer 			return 1;
418834d97d4SJosh Boyer 	}
419834d97d4SJosh Boyer 
420834d97d4SJosh Boyer 	return 0;
421834d97d4SJosh Boyer }
422c31a0c05SStephen Warren 
423c31a0c05SStephen Warren /**
424c31a0c05SStephen Warren  *  of_device_is_available - check if a device is available for use
425c31a0c05SStephen Warren  *
426c31a0c05SStephen Warren  *  @device: Node to check for availability
427c31a0c05SStephen Warren  *
428c31a0c05SStephen Warren  *  Returns 1 if the status property is absent or set to "okay" or "ok",
429c31a0c05SStephen Warren  *  0 otherwise
430c31a0c05SStephen Warren  */
431c31a0c05SStephen Warren int of_device_is_available(const struct device_node *device)
432c31a0c05SStephen Warren {
433c31a0c05SStephen Warren 	unsigned long flags;
434c31a0c05SStephen Warren 	int res;
435c31a0c05SStephen Warren 
436c31a0c05SStephen Warren 	raw_spin_lock_irqsave(&devtree_lock, flags);
437c31a0c05SStephen Warren 	res = __of_device_is_available(device);
438c31a0c05SStephen Warren 	raw_spin_unlock_irqrestore(&devtree_lock, flags);
439c31a0c05SStephen Warren 	return res;
440c31a0c05SStephen Warren 
441c31a0c05SStephen Warren }
442834d97d4SJosh Boyer EXPORT_SYMBOL(of_device_is_available);
443834d97d4SJosh Boyer 
444834d97d4SJosh Boyer /**
445e679c5f4SStephen Rothwell  *	of_get_parent - Get a node's parent if any
446e679c5f4SStephen Rothwell  *	@node:	Node to get parent
447e679c5f4SStephen Rothwell  *
448e679c5f4SStephen Rothwell  *	Returns a node pointer with refcount incremented, use
449e679c5f4SStephen Rothwell  *	of_node_put() on it when done.
450e679c5f4SStephen Rothwell  */
451e679c5f4SStephen Rothwell struct device_node *of_get_parent(const struct device_node *node)
452e679c5f4SStephen Rothwell {
453e679c5f4SStephen Rothwell 	struct device_node *np;
454d6d3c4e6SThomas Gleixner 	unsigned long flags;
455e679c5f4SStephen Rothwell 
456e679c5f4SStephen Rothwell 	if (!node)
457e679c5f4SStephen Rothwell 		return NULL;
458e679c5f4SStephen Rothwell 
459d6d3c4e6SThomas Gleixner 	raw_spin_lock_irqsave(&devtree_lock, flags);
460e679c5f4SStephen Rothwell 	np = of_node_get(node->parent);
461d6d3c4e6SThomas Gleixner 	raw_spin_unlock_irqrestore(&devtree_lock, flags);
462e679c5f4SStephen Rothwell 	return np;
463e679c5f4SStephen Rothwell }
464e679c5f4SStephen Rothwell EXPORT_SYMBOL(of_get_parent);
465d1cd355aSStephen Rothwell 
466d1cd355aSStephen Rothwell /**
467f4eb0107SMichael Ellerman  *	of_get_next_parent - Iterate to a node's parent
468f4eb0107SMichael Ellerman  *	@node:	Node to get parent of
469f4eb0107SMichael Ellerman  *
470f4eb0107SMichael Ellerman  * 	This is like of_get_parent() except that it drops the
471f4eb0107SMichael Ellerman  * 	refcount on the passed node, making it suitable for iterating
472f4eb0107SMichael Ellerman  * 	through a node's parents.
473f4eb0107SMichael Ellerman  *
474f4eb0107SMichael Ellerman  *	Returns a node pointer with refcount incremented, use
475f4eb0107SMichael Ellerman  *	of_node_put() on it when done.
476f4eb0107SMichael Ellerman  */
477f4eb0107SMichael Ellerman struct device_node *of_get_next_parent(struct device_node *node)
478f4eb0107SMichael Ellerman {
479f4eb0107SMichael Ellerman 	struct device_node *parent;
480d6d3c4e6SThomas Gleixner 	unsigned long flags;
481f4eb0107SMichael Ellerman 
482f4eb0107SMichael Ellerman 	if (!node)
483f4eb0107SMichael Ellerman 		return NULL;
484f4eb0107SMichael Ellerman 
485d6d3c4e6SThomas Gleixner 	raw_spin_lock_irqsave(&devtree_lock, flags);
486f4eb0107SMichael Ellerman 	parent = of_node_get(node->parent);
487f4eb0107SMichael Ellerman 	of_node_put(node);
488d6d3c4e6SThomas Gleixner 	raw_spin_unlock_irqrestore(&devtree_lock, flags);
489f4eb0107SMichael Ellerman 	return parent;
490f4eb0107SMichael Ellerman }
4916695be68SGuennadi Liakhovetski EXPORT_SYMBOL(of_get_next_parent);
492f4eb0107SMichael Ellerman 
493f4eb0107SMichael Ellerman /**
494d1cd355aSStephen Rothwell  *	of_get_next_child - Iterate a node childs
495d1cd355aSStephen Rothwell  *	@node:	parent node
496d1cd355aSStephen Rothwell  *	@prev:	previous child of the parent node, or NULL to get first
497d1cd355aSStephen Rothwell  *
498d1cd355aSStephen Rothwell  *	Returns a node pointer with refcount incremented, use
499d1cd355aSStephen Rothwell  *	of_node_put() on it when done.
500d1cd355aSStephen Rothwell  */
501d1cd355aSStephen Rothwell struct device_node *of_get_next_child(const struct device_node *node,
502d1cd355aSStephen Rothwell 	struct device_node *prev)
503d1cd355aSStephen Rothwell {
504d1cd355aSStephen Rothwell 	struct device_node *next;
505d6d3c4e6SThomas Gleixner 	unsigned long flags;
506d1cd355aSStephen Rothwell 
507d6d3c4e6SThomas Gleixner 	raw_spin_lock_irqsave(&devtree_lock, flags);
508d1cd355aSStephen Rothwell 	next = prev ? prev->sibling : node->child;
509d1cd355aSStephen Rothwell 	for (; next; next = next->sibling)
510d1cd355aSStephen Rothwell 		if (of_node_get(next))
511d1cd355aSStephen Rothwell 			break;
512d1cd355aSStephen Rothwell 	of_node_put(prev);
513d6d3c4e6SThomas Gleixner 	raw_spin_unlock_irqrestore(&devtree_lock, flags);
514d1cd355aSStephen Rothwell 	return next;
515d1cd355aSStephen Rothwell }
516d1cd355aSStephen Rothwell EXPORT_SYMBOL(of_get_next_child);
5171ef4d424SStephen Rothwell 
5181ef4d424SStephen Rothwell /**
5193296193dSTimur Tabi  *	of_get_next_available_child - Find the next available child node
5203296193dSTimur Tabi  *	@node:	parent node
5213296193dSTimur Tabi  *	@prev:	previous child of the parent node, or NULL to get first
5223296193dSTimur Tabi  *
5233296193dSTimur Tabi  *      This function is like of_get_next_child(), except that it
5243296193dSTimur Tabi  *      automatically skips any disabled nodes (i.e. status = "disabled").
5253296193dSTimur Tabi  */
5263296193dSTimur Tabi struct device_node *of_get_next_available_child(const struct device_node *node,
5273296193dSTimur Tabi 	struct device_node *prev)
5283296193dSTimur Tabi {
5293296193dSTimur Tabi 	struct device_node *next;
530d25d8694SBenjamin Herrenschmidt 	unsigned long flags;
5313296193dSTimur Tabi 
532d25d8694SBenjamin Herrenschmidt 	raw_spin_lock_irqsave(&devtree_lock, flags);
5333296193dSTimur Tabi 	next = prev ? prev->sibling : node->child;
5343296193dSTimur Tabi 	for (; next; next = next->sibling) {
535c31a0c05SStephen Warren 		if (!__of_device_is_available(next))
5363296193dSTimur Tabi 			continue;
5373296193dSTimur Tabi 		if (of_node_get(next))
5383296193dSTimur Tabi 			break;
5393296193dSTimur Tabi 	}
5403296193dSTimur Tabi 	of_node_put(prev);
541d25d8694SBenjamin Herrenschmidt 	raw_spin_unlock_irqrestore(&devtree_lock, flags);
5423296193dSTimur Tabi 	return next;
5433296193dSTimur Tabi }
5443296193dSTimur Tabi EXPORT_SYMBOL(of_get_next_available_child);
5453296193dSTimur Tabi 
5463296193dSTimur Tabi /**
5479c19761aSSrinivas Kandagatla  *	of_get_child_by_name - Find the child node by name for a given parent
5489c19761aSSrinivas Kandagatla  *	@node:	parent node
5499c19761aSSrinivas Kandagatla  *	@name:	child name to look for.
5509c19761aSSrinivas Kandagatla  *
5519c19761aSSrinivas Kandagatla  *      This function looks for child node for given matching name
5529c19761aSSrinivas Kandagatla  *
5539c19761aSSrinivas Kandagatla  *	Returns a node pointer if found, with refcount incremented, use
5549c19761aSSrinivas Kandagatla  *	of_node_put() on it when done.
5559c19761aSSrinivas Kandagatla  *	Returns NULL if node is not found.
5569c19761aSSrinivas Kandagatla  */
5579c19761aSSrinivas Kandagatla struct device_node *of_get_child_by_name(const struct device_node *node,
5589c19761aSSrinivas Kandagatla 				const char *name)
5599c19761aSSrinivas Kandagatla {
5609c19761aSSrinivas Kandagatla 	struct device_node *child;
5619c19761aSSrinivas Kandagatla 
5629c19761aSSrinivas Kandagatla 	for_each_child_of_node(node, child)
5639c19761aSSrinivas Kandagatla 		if (child->name && (of_node_cmp(child->name, name) == 0))
5649c19761aSSrinivas Kandagatla 			break;
5659c19761aSSrinivas Kandagatla 	return child;
5669c19761aSSrinivas Kandagatla }
5679c19761aSSrinivas Kandagatla EXPORT_SYMBOL(of_get_child_by_name);
5689c19761aSSrinivas Kandagatla 
5699c19761aSSrinivas Kandagatla /**
5701ef4d424SStephen Rothwell  *	of_find_node_by_path - Find a node matching a full OF path
5711ef4d424SStephen Rothwell  *	@path:	The full path to match
5721ef4d424SStephen Rothwell  *
5731ef4d424SStephen Rothwell  *	Returns a node pointer with refcount incremented, use
5741ef4d424SStephen Rothwell  *	of_node_put() on it when done.
5751ef4d424SStephen Rothwell  */
5761ef4d424SStephen Rothwell struct device_node *of_find_node_by_path(const char *path)
5771ef4d424SStephen Rothwell {
578465aac6dSRandy Dunlap 	struct device_node *np = of_allnodes;
579d6d3c4e6SThomas Gleixner 	unsigned long flags;
5801ef4d424SStephen Rothwell 
581d6d3c4e6SThomas Gleixner 	raw_spin_lock_irqsave(&devtree_lock, flags);
5821ef4d424SStephen Rothwell 	for (; np; np = np->allnext) {
5831ef4d424SStephen Rothwell 		if (np->full_name && (of_node_cmp(np->full_name, path) == 0)
5841ef4d424SStephen Rothwell 		    && of_node_get(np))
5851ef4d424SStephen Rothwell 			break;
5861ef4d424SStephen Rothwell 	}
587d6d3c4e6SThomas Gleixner 	raw_spin_unlock_irqrestore(&devtree_lock, flags);
5881ef4d424SStephen Rothwell 	return np;
5891ef4d424SStephen Rothwell }
5901ef4d424SStephen Rothwell EXPORT_SYMBOL(of_find_node_by_path);
5911ef4d424SStephen Rothwell 
5921ef4d424SStephen Rothwell /**
5931ef4d424SStephen Rothwell  *	of_find_node_by_name - Find a node by its "name" property
5941ef4d424SStephen Rothwell  *	@from:	The node to start searching from or NULL, the node
5951ef4d424SStephen Rothwell  *		you pass will not be searched, only the next one
5961ef4d424SStephen Rothwell  *		will; typically, you pass what the previous call
5971ef4d424SStephen Rothwell  *		returned. of_node_put() will be called on it
5981ef4d424SStephen Rothwell  *	@name:	The name string to match against
5991ef4d424SStephen Rothwell  *
6001ef4d424SStephen Rothwell  *	Returns a node pointer with refcount incremented, use
6011ef4d424SStephen Rothwell  *	of_node_put() on it when done.
6021ef4d424SStephen Rothwell  */
6031ef4d424SStephen Rothwell struct device_node *of_find_node_by_name(struct device_node *from,
6041ef4d424SStephen Rothwell 	const char *name)
6051ef4d424SStephen Rothwell {
6061ef4d424SStephen Rothwell 	struct device_node *np;
607d6d3c4e6SThomas Gleixner 	unsigned long flags;
6081ef4d424SStephen Rothwell 
609d6d3c4e6SThomas Gleixner 	raw_spin_lock_irqsave(&devtree_lock, flags);
610465aac6dSRandy Dunlap 	np = from ? from->allnext : of_allnodes;
6111ef4d424SStephen Rothwell 	for (; np; np = np->allnext)
6121ef4d424SStephen Rothwell 		if (np->name && (of_node_cmp(np->name, name) == 0)
6131ef4d424SStephen Rothwell 		    && of_node_get(np))
6141ef4d424SStephen Rothwell 			break;
6151ef4d424SStephen Rothwell 	of_node_put(from);
616d6d3c4e6SThomas Gleixner 	raw_spin_unlock_irqrestore(&devtree_lock, flags);
6171ef4d424SStephen Rothwell 	return np;
6181ef4d424SStephen Rothwell }
6191ef4d424SStephen Rothwell EXPORT_SYMBOL(of_find_node_by_name);
6201ef4d424SStephen Rothwell 
6211ef4d424SStephen Rothwell /**
6221ef4d424SStephen Rothwell  *	of_find_node_by_type - Find a node by its "device_type" property
6231ef4d424SStephen Rothwell  *	@from:	The node to start searching from, or NULL to start searching
6241ef4d424SStephen Rothwell  *		the entire device tree. The node you pass will not be
6251ef4d424SStephen Rothwell  *		searched, only the next one will; typically, you pass
6261ef4d424SStephen Rothwell  *		what the previous call returned. of_node_put() will be
6271ef4d424SStephen Rothwell  *		called on from for you.
6281ef4d424SStephen Rothwell  *	@type:	The type string to match against
6291ef4d424SStephen Rothwell  *
6301ef4d424SStephen Rothwell  *	Returns a node pointer with refcount incremented, use
6311ef4d424SStephen Rothwell  *	of_node_put() on it when done.
6321ef4d424SStephen Rothwell  */
6331ef4d424SStephen Rothwell struct device_node *of_find_node_by_type(struct device_node *from,
6341ef4d424SStephen Rothwell 	const char *type)
6351ef4d424SStephen Rothwell {
6361ef4d424SStephen Rothwell 	struct device_node *np;
637d6d3c4e6SThomas Gleixner 	unsigned long flags;
6381ef4d424SStephen Rothwell 
639d6d3c4e6SThomas Gleixner 	raw_spin_lock_irqsave(&devtree_lock, flags);
640465aac6dSRandy Dunlap 	np = from ? from->allnext : of_allnodes;
6411ef4d424SStephen Rothwell 	for (; np; np = np->allnext)
6421ef4d424SStephen Rothwell 		if (np->type && (of_node_cmp(np->type, type) == 0)
6431ef4d424SStephen Rothwell 		    && of_node_get(np))
6441ef4d424SStephen Rothwell 			break;
6451ef4d424SStephen Rothwell 	of_node_put(from);
646d6d3c4e6SThomas Gleixner 	raw_spin_unlock_irqrestore(&devtree_lock, flags);
6471ef4d424SStephen Rothwell 	return np;
6481ef4d424SStephen Rothwell }
6491ef4d424SStephen Rothwell EXPORT_SYMBOL(of_find_node_by_type);
6501ef4d424SStephen Rothwell 
6511ef4d424SStephen Rothwell /**
6521ef4d424SStephen Rothwell  *	of_find_compatible_node - Find a node based on type and one of the
6531ef4d424SStephen Rothwell  *                                tokens in its "compatible" property
6541ef4d424SStephen Rothwell  *	@from:		The node to start searching from or NULL, the node
6551ef4d424SStephen Rothwell  *			you pass will not be searched, only the next one
6561ef4d424SStephen Rothwell  *			will; typically, you pass what the previous call
6571ef4d424SStephen Rothwell  *			returned. of_node_put() will be called on it
6581ef4d424SStephen Rothwell  *	@type:		The type string to match "device_type" or NULL to ignore
6591ef4d424SStephen Rothwell  *	@compatible:	The string to match to one of the tokens in the device
6601ef4d424SStephen Rothwell  *			"compatible" list.
6611ef4d424SStephen Rothwell  *
6621ef4d424SStephen Rothwell  *	Returns a node pointer with refcount incremented, use
6631ef4d424SStephen Rothwell  *	of_node_put() on it when done.
6641ef4d424SStephen Rothwell  */
6651ef4d424SStephen Rothwell struct device_node *of_find_compatible_node(struct device_node *from,
6661ef4d424SStephen Rothwell 	const char *type, const char *compatible)
6671ef4d424SStephen Rothwell {
6681ef4d424SStephen Rothwell 	struct device_node *np;
669d6d3c4e6SThomas Gleixner 	unsigned long flags;
6701ef4d424SStephen Rothwell 
671d6d3c4e6SThomas Gleixner 	raw_spin_lock_irqsave(&devtree_lock, flags);
672465aac6dSRandy Dunlap 	np = from ? from->allnext : of_allnodes;
6731ef4d424SStephen Rothwell 	for (; np; np = np->allnext) {
6741ef4d424SStephen Rothwell 		if (type
6751ef4d424SStephen Rothwell 		    && !(np->type && (of_node_cmp(np->type, type) == 0)))
6761ef4d424SStephen Rothwell 			continue;
67728d0e36bSThomas Gleixner 		if (__of_device_is_compatible(np, compatible) &&
67828d0e36bSThomas Gleixner 		    of_node_get(np))
6791ef4d424SStephen Rothwell 			break;
6801ef4d424SStephen Rothwell 	}
6811ef4d424SStephen Rothwell 	of_node_put(from);
682d6d3c4e6SThomas Gleixner 	raw_spin_unlock_irqrestore(&devtree_lock, flags);
6831ef4d424SStephen Rothwell 	return np;
6841ef4d424SStephen Rothwell }
6851ef4d424SStephen Rothwell EXPORT_SYMBOL(of_find_compatible_node);
686283029d1SGrant Likely 
687283029d1SGrant Likely /**
6881e291b14SMichael Ellerman  *	of_find_node_with_property - Find a node which has a property with
6891e291b14SMichael Ellerman  *                                   the given name.
6901e291b14SMichael Ellerman  *	@from:		The node to start searching from or NULL, the node
6911e291b14SMichael Ellerman  *			you pass will not be searched, only the next one
6921e291b14SMichael Ellerman  *			will; typically, you pass what the previous call
6931e291b14SMichael Ellerman  *			returned. of_node_put() will be called on it
6941e291b14SMichael Ellerman  *	@prop_name:	The name of the property to look for.
6951e291b14SMichael Ellerman  *
6961e291b14SMichael Ellerman  *	Returns a node pointer with refcount incremented, use
6971e291b14SMichael Ellerman  *	of_node_put() on it when done.
6981e291b14SMichael Ellerman  */
6991e291b14SMichael Ellerman struct device_node *of_find_node_with_property(struct device_node *from,
7001e291b14SMichael Ellerman 	const char *prop_name)
7011e291b14SMichael Ellerman {
7021e291b14SMichael Ellerman 	struct device_node *np;
7031e291b14SMichael Ellerman 	struct property *pp;
704d6d3c4e6SThomas Gleixner 	unsigned long flags;
7051e291b14SMichael Ellerman 
706d6d3c4e6SThomas Gleixner 	raw_spin_lock_irqsave(&devtree_lock, flags);
707465aac6dSRandy Dunlap 	np = from ? from->allnext : of_allnodes;
7081e291b14SMichael Ellerman 	for (; np; np = np->allnext) {
709a3a7cab1SSachin Kamat 		for (pp = np->properties; pp; pp = pp->next) {
7101e291b14SMichael Ellerman 			if (of_prop_cmp(pp->name, prop_name) == 0) {
7111e291b14SMichael Ellerman 				of_node_get(np);
7121e291b14SMichael Ellerman 				goto out;
7131e291b14SMichael Ellerman 			}
7141e291b14SMichael Ellerman 		}
7151e291b14SMichael Ellerman 	}
7161e291b14SMichael Ellerman out:
7171e291b14SMichael Ellerman 	of_node_put(from);
718d6d3c4e6SThomas Gleixner 	raw_spin_unlock_irqrestore(&devtree_lock, flags);
7191e291b14SMichael Ellerman 	return np;
7201e291b14SMichael Ellerman }
7211e291b14SMichael Ellerman EXPORT_SYMBOL(of_find_node_with_property);
7221e291b14SMichael Ellerman 
72328d0e36bSThomas Gleixner static
72428d0e36bSThomas Gleixner const struct of_device_id *__of_match_node(const struct of_device_id *matches,
725283029d1SGrant Likely 					   const struct device_node *node)
726283029d1SGrant Likely {
727a52f07ecSGrant Likely 	if (!matches)
728a52f07ecSGrant Likely 		return NULL;
729a52f07ecSGrant Likely 
730283029d1SGrant Likely 	while (matches->name[0] || matches->type[0] || matches->compatible[0]) {
731283029d1SGrant Likely 		int match = 1;
732283029d1SGrant Likely 		if (matches->name[0])
733283029d1SGrant Likely 			match &= node->name
734283029d1SGrant Likely 				&& !strcmp(matches->name, node->name);
735283029d1SGrant Likely 		if (matches->type[0])
736283029d1SGrant Likely 			match &= node->type
737283029d1SGrant Likely 				&& !strcmp(matches->type, node->type);
738bc51b0c2SLinus Torvalds 		if (matches->compatible[0])
73928d0e36bSThomas Gleixner 			match &= __of_device_is_compatible(node,
740bc51b0c2SLinus Torvalds 							   matches->compatible);
741bc51b0c2SLinus Torvalds 		if (match)
742283029d1SGrant Likely 			return matches;
743283029d1SGrant Likely 		matches++;
744283029d1SGrant Likely 	}
745283029d1SGrant Likely 	return NULL;
746283029d1SGrant Likely }
74728d0e36bSThomas Gleixner 
74828d0e36bSThomas Gleixner /**
74928d0e36bSThomas Gleixner  * of_match_node - Tell if an device_node has a matching of_match structure
75028d0e36bSThomas Gleixner  *	@matches:	array of of device match structures to search in
75128d0e36bSThomas Gleixner  *	@node:		the of device structure to match against
75228d0e36bSThomas Gleixner  *
75328d0e36bSThomas Gleixner  *	Low level utility function used by device matching.
75428d0e36bSThomas Gleixner  */
75528d0e36bSThomas Gleixner const struct of_device_id *of_match_node(const struct of_device_id *matches,
75628d0e36bSThomas Gleixner 					 const struct device_node *node)
75728d0e36bSThomas Gleixner {
75828d0e36bSThomas Gleixner 	const struct of_device_id *match;
759d6d3c4e6SThomas Gleixner 	unsigned long flags;
76028d0e36bSThomas Gleixner 
761d6d3c4e6SThomas Gleixner 	raw_spin_lock_irqsave(&devtree_lock, flags);
76228d0e36bSThomas Gleixner 	match = __of_match_node(matches, node);
763d6d3c4e6SThomas Gleixner 	raw_spin_unlock_irqrestore(&devtree_lock, flags);
76428d0e36bSThomas Gleixner 	return match;
76528d0e36bSThomas Gleixner }
766283029d1SGrant Likely EXPORT_SYMBOL(of_match_node);
767283029d1SGrant Likely 
768283029d1SGrant Likely /**
76950c8af4cSStephen Warren  *	of_find_matching_node_and_match - Find a node based on an of_device_id
77050c8af4cSStephen Warren  *					  match table.
771283029d1SGrant Likely  *	@from:		The node to start searching from or NULL, the node
772283029d1SGrant Likely  *			you pass will not be searched, only the next one
773283029d1SGrant Likely  *			will; typically, you pass what the previous call
774283029d1SGrant Likely  *			returned. of_node_put() will be called on it
775283029d1SGrant Likely  *	@matches:	array of of device match structures to search in
77650c8af4cSStephen Warren  *	@match		Updated to point at the matches entry which matched
777283029d1SGrant Likely  *
778283029d1SGrant Likely  *	Returns a node pointer with refcount incremented, use
779283029d1SGrant Likely  *	of_node_put() on it when done.
780283029d1SGrant Likely  */
78150c8af4cSStephen Warren struct device_node *of_find_matching_node_and_match(struct device_node *from,
78250c8af4cSStephen Warren 					const struct of_device_id *matches,
78350c8af4cSStephen Warren 					const struct of_device_id **match)
784283029d1SGrant Likely {
785283029d1SGrant Likely 	struct device_node *np;
786dc71bcf1SThomas Abraham 	const struct of_device_id *m;
787d6d3c4e6SThomas Gleixner 	unsigned long flags;
788283029d1SGrant Likely 
78950c8af4cSStephen Warren 	if (match)
79050c8af4cSStephen Warren 		*match = NULL;
79150c8af4cSStephen Warren 
792d6d3c4e6SThomas Gleixner 	raw_spin_lock_irqsave(&devtree_lock, flags);
793465aac6dSRandy Dunlap 	np = from ? from->allnext : of_allnodes;
794283029d1SGrant Likely 	for (; np; np = np->allnext) {
79528d0e36bSThomas Gleixner 		m = __of_match_node(matches, np);
796dc71bcf1SThomas Abraham 		if (m && of_node_get(np)) {
79750c8af4cSStephen Warren 			if (match)
798dc71bcf1SThomas Abraham 				*match = m;
799283029d1SGrant Likely 			break;
800283029d1SGrant Likely 		}
80150c8af4cSStephen Warren 	}
802283029d1SGrant Likely 	of_node_put(from);
803d6d3c4e6SThomas Gleixner 	raw_spin_unlock_irqrestore(&devtree_lock, flags);
804283029d1SGrant Likely 	return np;
805283029d1SGrant Likely }
80680c2022eSGrant Likely EXPORT_SYMBOL(of_find_matching_node_and_match);
8073f07af49SGrant Likely 
8083f07af49SGrant Likely /**
8093f07af49SGrant Likely  * of_modalias_node - Lookup appropriate modalias for a device node
8103f07af49SGrant Likely  * @node:	pointer to a device tree node
8113f07af49SGrant Likely  * @modalias:	Pointer to buffer that modalias value will be copied into
8123f07af49SGrant Likely  * @len:	Length of modalias value
8133f07af49SGrant Likely  *
8142ffe8c5fSGrant Likely  * Based on the value of the compatible property, this routine will attempt
8152ffe8c5fSGrant Likely  * to choose an appropriate modalias value for a particular device tree node.
8162ffe8c5fSGrant Likely  * It does this by stripping the manufacturer prefix (as delimited by a ',')
8172ffe8c5fSGrant Likely  * from the first entry in the compatible list property.
8183f07af49SGrant Likely  *
8192ffe8c5fSGrant Likely  * This routine returns 0 on success, <0 on failure.
8203f07af49SGrant Likely  */
8213f07af49SGrant Likely int of_modalias_node(struct device_node *node, char *modalias, int len)
8223f07af49SGrant Likely {
8232ffe8c5fSGrant Likely 	const char *compatible, *p;
8242ffe8c5fSGrant Likely 	int cplen;
8253f07af49SGrant Likely 
8263f07af49SGrant Likely 	compatible = of_get_property(node, "compatible", &cplen);
8272ffe8c5fSGrant Likely 	if (!compatible || strlen(compatible) > cplen)
8283f07af49SGrant Likely 		return -ENODEV;
8293f07af49SGrant Likely 	p = strchr(compatible, ',');
8302ffe8c5fSGrant Likely 	strlcpy(modalias, p ? p + 1 : compatible, len);
8313f07af49SGrant Likely 	return 0;
8323f07af49SGrant Likely }
8333f07af49SGrant Likely EXPORT_SYMBOL_GPL(of_modalias_node);
8343f07af49SGrant Likely 
83564b60e09SAnton Vorontsov /**
83689751a7cSJeremy Kerr  * of_find_node_by_phandle - Find a node given a phandle
83789751a7cSJeremy Kerr  * @handle:	phandle of the node to find
83889751a7cSJeremy Kerr  *
83989751a7cSJeremy Kerr  * Returns a node pointer with refcount incremented, use
84089751a7cSJeremy Kerr  * of_node_put() on it when done.
84189751a7cSJeremy Kerr  */
84289751a7cSJeremy Kerr struct device_node *of_find_node_by_phandle(phandle handle)
84389751a7cSJeremy Kerr {
84489751a7cSJeremy Kerr 	struct device_node *np;
845d25d8694SBenjamin Herrenschmidt 	unsigned long flags;
84689751a7cSJeremy Kerr 
847d25d8694SBenjamin Herrenschmidt 	raw_spin_lock_irqsave(&devtree_lock, flags);
848465aac6dSRandy Dunlap 	for (np = of_allnodes; np; np = np->allnext)
84989751a7cSJeremy Kerr 		if (np->phandle == handle)
85089751a7cSJeremy Kerr 			break;
85189751a7cSJeremy Kerr 	of_node_get(np);
852d25d8694SBenjamin Herrenschmidt 	raw_spin_unlock_irqrestore(&devtree_lock, flags);
85389751a7cSJeremy Kerr 	return np;
85489751a7cSJeremy Kerr }
85589751a7cSJeremy Kerr EXPORT_SYMBOL(of_find_node_by_phandle);
85689751a7cSJeremy Kerr 
85789751a7cSJeremy Kerr /**
858daeec1f0STony Prisk  * of_find_property_value_of_size
859daeec1f0STony Prisk  *
860daeec1f0STony Prisk  * @np:		device node from which the property value is to be read.
861daeec1f0STony Prisk  * @propname:	name of the property to be searched.
862daeec1f0STony Prisk  * @len:	requested length of property value
863daeec1f0STony Prisk  *
864daeec1f0STony Prisk  * Search for a property in a device node and valid the requested size.
865daeec1f0STony Prisk  * Returns the property value on success, -EINVAL if the property does not
866daeec1f0STony Prisk  *  exist, -ENODATA if property does not have a value, and -EOVERFLOW if the
867daeec1f0STony Prisk  * property data isn't large enough.
868daeec1f0STony Prisk  *
869daeec1f0STony Prisk  */
870daeec1f0STony Prisk static void *of_find_property_value_of_size(const struct device_node *np,
871daeec1f0STony Prisk 			const char *propname, u32 len)
872daeec1f0STony Prisk {
873daeec1f0STony Prisk 	struct property *prop = of_find_property(np, propname, NULL);
874daeec1f0STony Prisk 
875daeec1f0STony Prisk 	if (!prop)
876daeec1f0STony Prisk 		return ERR_PTR(-EINVAL);
877daeec1f0STony Prisk 	if (!prop->value)
878daeec1f0STony Prisk 		return ERR_PTR(-ENODATA);
879daeec1f0STony Prisk 	if (len > prop->length)
880daeec1f0STony Prisk 		return ERR_PTR(-EOVERFLOW);
881daeec1f0STony Prisk 
882daeec1f0STony Prisk 	return prop->value;
883daeec1f0STony Prisk }
884daeec1f0STony Prisk 
885daeec1f0STony Prisk /**
8863daf3726STony Prisk  * of_property_read_u32_index - Find and read a u32 from a multi-value property.
8873daf3726STony Prisk  *
8883daf3726STony Prisk  * @np:		device node from which the property value is to be read.
8893daf3726STony Prisk  * @propname:	name of the property to be searched.
8903daf3726STony Prisk  * @index:	index of the u32 in the list of values
8913daf3726STony Prisk  * @out_value:	pointer to return value, modified only if no error.
8923daf3726STony Prisk  *
8933daf3726STony Prisk  * Search for a property in a device node and read nth 32-bit value from
8943daf3726STony Prisk  * it. Returns 0 on success, -EINVAL if the property does not exist,
8953daf3726STony Prisk  * -ENODATA if property does not have a value, and -EOVERFLOW if the
8963daf3726STony Prisk  * property data isn't large enough.
8973daf3726STony Prisk  *
8983daf3726STony Prisk  * The out_value is modified only if a valid u32 value can be decoded.
8993daf3726STony Prisk  */
9003daf3726STony Prisk int of_property_read_u32_index(const struct device_node *np,
9013daf3726STony Prisk 				       const char *propname,
9023daf3726STony Prisk 				       u32 index, u32 *out_value)
9033daf3726STony Prisk {
904daeec1f0STony Prisk 	const u32 *val = of_find_property_value_of_size(np, propname,
905daeec1f0STony Prisk 					((index + 1) * sizeof(*out_value)));
9063daf3726STony Prisk 
907daeec1f0STony Prisk 	if (IS_ERR(val))
908daeec1f0STony Prisk 		return PTR_ERR(val);
9093daf3726STony Prisk 
910daeec1f0STony Prisk 	*out_value = be32_to_cpup(((__be32 *)val) + index);
9113daf3726STony Prisk 	return 0;
9123daf3726STony Prisk }
9133daf3726STony Prisk EXPORT_SYMBOL_GPL(of_property_read_u32_index);
9143daf3726STony Prisk 
9153daf3726STony Prisk /**
916be193249SViresh Kumar  * of_property_read_u8_array - Find and read an array of u8 from a property.
917be193249SViresh Kumar  *
918be193249SViresh Kumar  * @np:		device node from which the property value is to be read.
919be193249SViresh Kumar  * @propname:	name of the property to be searched.
920792efb84SLad, Prabhakar  * @out_values:	pointer to return value, modified only if return value is 0.
921be193249SViresh Kumar  * @sz:		number of array elements to read
922be193249SViresh Kumar  *
923be193249SViresh Kumar  * Search for a property in a device node and read 8-bit value(s) from
924be193249SViresh Kumar  * it. Returns 0 on success, -EINVAL if the property does not exist,
925be193249SViresh Kumar  * -ENODATA if property does not have a value, and -EOVERFLOW if the
926be193249SViresh Kumar  * property data isn't large enough.
927be193249SViresh Kumar  *
928be193249SViresh Kumar  * dts entry of array should be like:
929be193249SViresh Kumar  *	property = /bits/ 8 <0x50 0x60 0x70>;
930be193249SViresh Kumar  *
931792efb84SLad, Prabhakar  * The out_values is modified only if a valid u8 value can be decoded.
932be193249SViresh Kumar  */
933be193249SViresh Kumar int of_property_read_u8_array(const struct device_node *np,
934be193249SViresh Kumar 			const char *propname, u8 *out_values, size_t sz)
935be193249SViresh Kumar {
936daeec1f0STony Prisk 	const u8 *val = of_find_property_value_of_size(np, propname,
937daeec1f0STony Prisk 						(sz * sizeof(*out_values)));
938be193249SViresh Kumar 
939daeec1f0STony Prisk 	if (IS_ERR(val))
940daeec1f0STony Prisk 		return PTR_ERR(val);
941be193249SViresh Kumar 
942be193249SViresh Kumar 	while (sz--)
943be193249SViresh Kumar 		*out_values++ = *val++;
944be193249SViresh Kumar 	return 0;
945be193249SViresh Kumar }
946be193249SViresh Kumar EXPORT_SYMBOL_GPL(of_property_read_u8_array);
947be193249SViresh Kumar 
948be193249SViresh Kumar /**
949be193249SViresh Kumar  * of_property_read_u16_array - Find and read an array of u16 from a property.
950be193249SViresh Kumar  *
951be193249SViresh Kumar  * @np:		device node from which the property value is to be read.
952be193249SViresh Kumar  * @propname:	name of the property to be searched.
953792efb84SLad, Prabhakar  * @out_values:	pointer to return value, modified only if return value is 0.
954be193249SViresh Kumar  * @sz:		number of array elements to read
955be193249SViresh Kumar  *
956be193249SViresh Kumar  * Search for a property in a device node and read 16-bit value(s) from
957be193249SViresh Kumar  * it. Returns 0 on success, -EINVAL if the property does not exist,
958be193249SViresh Kumar  * -ENODATA if property does not have a value, and -EOVERFLOW if the
959be193249SViresh Kumar  * property data isn't large enough.
960be193249SViresh Kumar  *
961be193249SViresh Kumar  * dts entry of array should be like:
962be193249SViresh Kumar  *	property = /bits/ 16 <0x5000 0x6000 0x7000>;
963be193249SViresh Kumar  *
964792efb84SLad, Prabhakar  * The out_values is modified only if a valid u16 value can be decoded.
965be193249SViresh Kumar  */
966be193249SViresh Kumar int of_property_read_u16_array(const struct device_node *np,
967be193249SViresh Kumar 			const char *propname, u16 *out_values, size_t sz)
968be193249SViresh Kumar {
969daeec1f0STony Prisk 	const __be16 *val = of_find_property_value_of_size(np, propname,
970daeec1f0STony Prisk 						(sz * sizeof(*out_values)));
971be193249SViresh Kumar 
972daeec1f0STony Prisk 	if (IS_ERR(val))
973daeec1f0STony Prisk 		return PTR_ERR(val);
974be193249SViresh Kumar 
975be193249SViresh Kumar 	while (sz--)
976be193249SViresh Kumar 		*out_values++ = be16_to_cpup(val++);
977be193249SViresh Kumar 	return 0;
978be193249SViresh Kumar }
979be193249SViresh Kumar EXPORT_SYMBOL_GPL(of_property_read_u16_array);
980be193249SViresh Kumar 
981be193249SViresh Kumar /**
9820e373639SRob Herring  * of_property_read_u32_array - Find and read an array of 32 bit integers
9830e373639SRob Herring  * from a property.
9840e373639SRob Herring  *
985a3b85363SThomas Abraham  * @np:		device node from which the property value is to be read.
986a3b85363SThomas Abraham  * @propname:	name of the property to be searched.
987792efb84SLad, Prabhakar  * @out_values:	pointer to return value, modified only if return value is 0.
988be193249SViresh Kumar  * @sz:		number of array elements to read
989a3b85363SThomas Abraham  *
9900e373639SRob Herring  * Search for a property in a device node and read 32-bit value(s) from
991a3b85363SThomas Abraham  * it. Returns 0 on success, -EINVAL if the property does not exist,
992a3b85363SThomas Abraham  * -ENODATA if property does not have a value, and -EOVERFLOW if the
993a3b85363SThomas Abraham  * property data isn't large enough.
994a3b85363SThomas Abraham  *
995792efb84SLad, Prabhakar  * The out_values is modified only if a valid u32 value can be decoded.
996a3b85363SThomas Abraham  */
997aac285c6SJamie Iles int of_property_read_u32_array(const struct device_node *np,
998aac285c6SJamie Iles 			       const char *propname, u32 *out_values,
999aac285c6SJamie Iles 			       size_t sz)
1000a3b85363SThomas Abraham {
1001daeec1f0STony Prisk 	const __be32 *val = of_find_property_value_of_size(np, propname,
1002daeec1f0STony Prisk 						(sz * sizeof(*out_values)));
1003a3b85363SThomas Abraham 
1004daeec1f0STony Prisk 	if (IS_ERR(val))
1005daeec1f0STony Prisk 		return PTR_ERR(val);
10060e373639SRob Herring 
10070e373639SRob Herring 	while (sz--)
10080e373639SRob Herring 		*out_values++ = be32_to_cpup(val++);
1009a3b85363SThomas Abraham 	return 0;
1010a3b85363SThomas Abraham }
10110e373639SRob Herring EXPORT_SYMBOL_GPL(of_property_read_u32_array);
1012a3b85363SThomas Abraham 
1013a3b85363SThomas Abraham /**
10144cd7f7a3SJamie Iles  * of_property_read_u64 - Find and read a 64 bit integer from a property
10154cd7f7a3SJamie Iles  * @np:		device node from which the property value is to be read.
10164cd7f7a3SJamie Iles  * @propname:	name of the property to be searched.
10174cd7f7a3SJamie Iles  * @out_value:	pointer to return value, modified only if return value is 0.
10184cd7f7a3SJamie Iles  *
10194cd7f7a3SJamie Iles  * Search for a property in a device node and read a 64-bit value from
10204cd7f7a3SJamie Iles  * it. Returns 0 on success, -EINVAL if the property does not exist,
10214cd7f7a3SJamie Iles  * -ENODATA if property does not have a value, and -EOVERFLOW if the
10224cd7f7a3SJamie Iles  * property data isn't large enough.
10234cd7f7a3SJamie Iles  *
10244cd7f7a3SJamie Iles  * The out_value is modified only if a valid u64 value can be decoded.
10254cd7f7a3SJamie Iles  */
10264cd7f7a3SJamie Iles int of_property_read_u64(const struct device_node *np, const char *propname,
10274cd7f7a3SJamie Iles 			 u64 *out_value)
10284cd7f7a3SJamie Iles {
1029daeec1f0STony Prisk 	const __be32 *val = of_find_property_value_of_size(np, propname,
1030daeec1f0STony Prisk 						sizeof(*out_value));
10314cd7f7a3SJamie Iles 
1032daeec1f0STony Prisk 	if (IS_ERR(val))
1033daeec1f0STony Prisk 		return PTR_ERR(val);
1034daeec1f0STony Prisk 
1035daeec1f0STony Prisk 	*out_value = of_read_number(val, 2);
10364cd7f7a3SJamie Iles 	return 0;
10374cd7f7a3SJamie Iles }
10384cd7f7a3SJamie Iles EXPORT_SYMBOL_GPL(of_property_read_u64);
10394cd7f7a3SJamie Iles 
10404cd7f7a3SJamie Iles /**
1041a3b85363SThomas Abraham  * of_property_read_string - Find and read a string from a property
1042a3b85363SThomas Abraham  * @np:		device node from which the property value is to be read.
1043a3b85363SThomas Abraham  * @propname:	name of the property to be searched.
1044a3b85363SThomas Abraham  * @out_string:	pointer to null terminated return string, modified only if
1045a3b85363SThomas Abraham  *		return value is 0.
1046a3b85363SThomas Abraham  *
1047a3b85363SThomas Abraham  * Search for a property in a device tree node and retrieve a null
1048a3b85363SThomas Abraham  * terminated string value (pointer to data, not a copy). Returns 0 on
1049a3b85363SThomas Abraham  * success, -EINVAL if the property does not exist, -ENODATA if property
1050a3b85363SThomas Abraham  * does not have a value, and -EILSEQ if the string is not null-terminated
1051a3b85363SThomas Abraham  * within the length of the property data.
1052a3b85363SThomas Abraham  *
1053a3b85363SThomas Abraham  * The out_string pointer is modified only if a valid string can be decoded.
1054a3b85363SThomas Abraham  */
1055aac285c6SJamie Iles int of_property_read_string(struct device_node *np, const char *propname,
1056f09bc831SShawn Guo 				const char **out_string)
1057a3b85363SThomas Abraham {
1058a3b85363SThomas Abraham 	struct property *prop = of_find_property(np, propname, NULL);
1059a3b85363SThomas Abraham 	if (!prop)
1060a3b85363SThomas Abraham 		return -EINVAL;
1061a3b85363SThomas Abraham 	if (!prop->value)
1062a3b85363SThomas Abraham 		return -ENODATA;
1063a3b85363SThomas Abraham 	if (strnlen(prop->value, prop->length) >= prop->length)
1064a3b85363SThomas Abraham 		return -EILSEQ;
1065a3b85363SThomas Abraham 	*out_string = prop->value;
1066a3b85363SThomas Abraham 	return 0;
1067a3b85363SThomas Abraham }
1068a3b85363SThomas Abraham EXPORT_SYMBOL_GPL(of_property_read_string);
1069a3b85363SThomas Abraham 
1070a3b85363SThomas Abraham /**
10714fcd15a0SBenoit Cousson  * of_property_read_string_index - Find and read a string from a multiple
10724fcd15a0SBenoit Cousson  * strings property.
10734fcd15a0SBenoit Cousson  * @np:		device node from which the property value is to be read.
10744fcd15a0SBenoit Cousson  * @propname:	name of the property to be searched.
10754fcd15a0SBenoit Cousson  * @index:	index of the string in the list of strings
10764fcd15a0SBenoit Cousson  * @out_string:	pointer to null terminated return string, modified only if
10774fcd15a0SBenoit Cousson  *		return value is 0.
10784fcd15a0SBenoit Cousson  *
10794fcd15a0SBenoit Cousson  * Search for a property in a device tree node and retrieve a null
10804fcd15a0SBenoit Cousson  * terminated string value (pointer to data, not a copy) in the list of strings
10814fcd15a0SBenoit Cousson  * contained in that property.
10824fcd15a0SBenoit Cousson  * Returns 0 on success, -EINVAL if the property does not exist, -ENODATA if
10834fcd15a0SBenoit Cousson  * property does not have a value, and -EILSEQ if the string is not
10844fcd15a0SBenoit Cousson  * null-terminated within the length of the property data.
10854fcd15a0SBenoit Cousson  *
10864fcd15a0SBenoit Cousson  * The out_string pointer is modified only if a valid string can be decoded.
10874fcd15a0SBenoit Cousson  */
10884fcd15a0SBenoit Cousson int of_property_read_string_index(struct device_node *np, const char *propname,
10894fcd15a0SBenoit Cousson 				  int index, const char **output)
10904fcd15a0SBenoit Cousson {
10914fcd15a0SBenoit Cousson 	struct property *prop = of_find_property(np, propname, NULL);
10924fcd15a0SBenoit Cousson 	int i = 0;
10934fcd15a0SBenoit Cousson 	size_t l = 0, total = 0;
10944fcd15a0SBenoit Cousson 	const char *p;
10954fcd15a0SBenoit Cousson 
10964fcd15a0SBenoit Cousson 	if (!prop)
10974fcd15a0SBenoit Cousson 		return -EINVAL;
10984fcd15a0SBenoit Cousson 	if (!prop->value)
10994fcd15a0SBenoit Cousson 		return -ENODATA;
11004fcd15a0SBenoit Cousson 	if (strnlen(prop->value, prop->length) >= prop->length)
11014fcd15a0SBenoit Cousson 		return -EILSEQ;
11024fcd15a0SBenoit Cousson 
11034fcd15a0SBenoit Cousson 	p = prop->value;
11044fcd15a0SBenoit Cousson 
11054fcd15a0SBenoit Cousson 	for (i = 0; total < prop->length; total += l, p += l) {
11064fcd15a0SBenoit Cousson 		l = strlen(p) + 1;
110788af7f58SBenoit Cousson 		if (i++ == index) {
11084fcd15a0SBenoit Cousson 			*output = p;
11094fcd15a0SBenoit Cousson 			return 0;
11104fcd15a0SBenoit Cousson 		}
11114fcd15a0SBenoit Cousson 	}
11124fcd15a0SBenoit Cousson 	return -ENODATA;
11134fcd15a0SBenoit Cousson }
11144fcd15a0SBenoit Cousson EXPORT_SYMBOL_GPL(of_property_read_string_index);
11154fcd15a0SBenoit Cousson 
11167aff0fe3SGrant Likely /**
11177aff0fe3SGrant Likely  * of_property_match_string() - Find string in a list and return index
11187aff0fe3SGrant Likely  * @np: pointer to node containing string list property
11197aff0fe3SGrant Likely  * @propname: string list property name
11207aff0fe3SGrant Likely  * @string: pointer to string to search for in string list
11217aff0fe3SGrant Likely  *
11227aff0fe3SGrant Likely  * This function searches a string list property and returns the index
11237aff0fe3SGrant Likely  * of a specific string value.
11247aff0fe3SGrant Likely  */
11257aff0fe3SGrant Likely int of_property_match_string(struct device_node *np, const char *propname,
11267aff0fe3SGrant Likely 			     const char *string)
11277aff0fe3SGrant Likely {
11287aff0fe3SGrant Likely 	struct property *prop = of_find_property(np, propname, NULL);
11297aff0fe3SGrant Likely 	size_t l;
11307aff0fe3SGrant Likely 	int i;
11317aff0fe3SGrant Likely 	const char *p, *end;
11327aff0fe3SGrant Likely 
11337aff0fe3SGrant Likely 	if (!prop)
11347aff0fe3SGrant Likely 		return -EINVAL;
11357aff0fe3SGrant Likely 	if (!prop->value)
11367aff0fe3SGrant Likely 		return -ENODATA;
11377aff0fe3SGrant Likely 
11387aff0fe3SGrant Likely 	p = prop->value;
11397aff0fe3SGrant Likely 	end = p + prop->length;
11407aff0fe3SGrant Likely 
11417aff0fe3SGrant Likely 	for (i = 0; p < end; i++, p += l) {
11427aff0fe3SGrant Likely 		l = strlen(p) + 1;
11437aff0fe3SGrant Likely 		if (p + l > end)
11447aff0fe3SGrant Likely 			return -EILSEQ;
11457aff0fe3SGrant Likely 		pr_debug("comparing %s with %s\n", string, p);
11467aff0fe3SGrant Likely 		if (strcmp(string, p) == 0)
11477aff0fe3SGrant Likely 			return i; /* Found it; return index */
11487aff0fe3SGrant Likely 	}
11497aff0fe3SGrant Likely 	return -ENODATA;
11507aff0fe3SGrant Likely }
11517aff0fe3SGrant Likely EXPORT_SYMBOL_GPL(of_property_match_string);
11524fcd15a0SBenoit Cousson 
11534fcd15a0SBenoit Cousson /**
11544fcd15a0SBenoit Cousson  * of_property_count_strings - Find and return the number of strings from a
11554fcd15a0SBenoit Cousson  * multiple strings property.
11564fcd15a0SBenoit Cousson  * @np:		device node from which the property value is to be read.
11574fcd15a0SBenoit Cousson  * @propname:	name of the property to be searched.
11584fcd15a0SBenoit Cousson  *
11594fcd15a0SBenoit Cousson  * Search for a property in a device tree node and retrieve the number of null
11604fcd15a0SBenoit Cousson  * terminated string contain in it. Returns the number of strings on
11614fcd15a0SBenoit Cousson  * success, -EINVAL if the property does not exist, -ENODATA if property
11624fcd15a0SBenoit Cousson  * does not have a value, and -EILSEQ if the string is not null-terminated
11634fcd15a0SBenoit Cousson  * within the length of the property data.
11644fcd15a0SBenoit Cousson  */
11654fcd15a0SBenoit Cousson int of_property_count_strings(struct device_node *np, const char *propname)
11664fcd15a0SBenoit Cousson {
11674fcd15a0SBenoit Cousson 	struct property *prop = of_find_property(np, propname, NULL);
11684fcd15a0SBenoit Cousson 	int i = 0;
11694fcd15a0SBenoit Cousson 	size_t l = 0, total = 0;
11704fcd15a0SBenoit Cousson 	const char *p;
11714fcd15a0SBenoit Cousson 
11724fcd15a0SBenoit Cousson 	if (!prop)
11734fcd15a0SBenoit Cousson 		return -EINVAL;
11744fcd15a0SBenoit Cousson 	if (!prop->value)
11754fcd15a0SBenoit Cousson 		return -ENODATA;
11764fcd15a0SBenoit Cousson 	if (strnlen(prop->value, prop->length) >= prop->length)
11774fcd15a0SBenoit Cousson 		return -EILSEQ;
11784fcd15a0SBenoit Cousson 
11794fcd15a0SBenoit Cousson 	p = prop->value;
11804fcd15a0SBenoit Cousson 
118188af7f58SBenoit Cousson 	for (i = 0; total < prop->length; total += l, p += l, i++)
11824fcd15a0SBenoit Cousson 		l = strlen(p) + 1;
118388af7f58SBenoit Cousson 
11844fcd15a0SBenoit Cousson 	return i;
11854fcd15a0SBenoit Cousson }
11864fcd15a0SBenoit Cousson EXPORT_SYMBOL_GPL(of_property_count_strings);
11874fcd15a0SBenoit Cousson 
1188bd69f73fSGrant Likely static int __of_parse_phandle_with_args(const struct device_node *np,
1189bd69f73fSGrant Likely 					const char *list_name,
1190035fd948SStephen Warren 					const char *cells_name,
1191035fd948SStephen Warren 					int cell_count, int index,
119215c9a0acSGrant Likely 					struct of_phandle_args *out_args)
119364b60e09SAnton Vorontsov {
119415c9a0acSGrant Likely 	const __be32 *list, *list_end;
119523ce04c0SGrant Likely 	int rc = 0, size, cur_index = 0;
119615c9a0acSGrant Likely 	uint32_t count = 0;
119764b60e09SAnton Vorontsov 	struct device_node *node = NULL;
11989a6b2e58SGrant Likely 	phandle phandle;
119964b60e09SAnton Vorontsov 
120015c9a0acSGrant Likely 	/* Retrieve the phandle list property */
120115c9a0acSGrant Likely 	list = of_get_property(np, list_name, &size);
120215c9a0acSGrant Likely 	if (!list)
12031af4c7f1SAlexandre Courbot 		return -ENOENT;
120415c9a0acSGrant Likely 	list_end = list + size / sizeof(*list);
120515c9a0acSGrant Likely 
120615c9a0acSGrant Likely 	/* Loop over the phandles until all the requested entry is found */
120715c9a0acSGrant Likely 	while (list < list_end) {
120823ce04c0SGrant Likely 		rc = -EINVAL;
120915c9a0acSGrant Likely 		count = 0;
121015c9a0acSGrant Likely 
121115c9a0acSGrant Likely 		/*
121215c9a0acSGrant Likely 		 * If phandle is 0, then it is an empty entry with no
121315c9a0acSGrant Likely 		 * arguments.  Skip forward to the next entry.
121415c9a0acSGrant Likely 		 */
12159a6b2e58SGrant Likely 		phandle = be32_to_cpup(list++);
121615c9a0acSGrant Likely 		if (phandle) {
121715c9a0acSGrant Likely 			/*
121815c9a0acSGrant Likely 			 * Find the provider node and parse the #*-cells
121991d9942cSStephen Warren 			 * property to determine the argument length.
122091d9942cSStephen Warren 			 *
122191d9942cSStephen Warren 			 * This is not needed if the cell count is hard-coded
122291d9942cSStephen Warren 			 * (i.e. cells_name not set, but cell_count is set),
122391d9942cSStephen Warren 			 * except when we're going to return the found node
122491d9942cSStephen Warren 			 * below.
122515c9a0acSGrant Likely 			 */
122691d9942cSStephen Warren 			if (cells_name || cur_index == index) {
12279a6b2e58SGrant Likely 				node = of_find_node_by_phandle(phandle);
122864b60e09SAnton Vorontsov 				if (!node) {
122915c9a0acSGrant Likely 					pr_err("%s: could not find phandle\n",
123064b60e09SAnton Vorontsov 						np->full_name);
123123ce04c0SGrant Likely 					goto err;
123215c9a0acSGrant Likely 				}
123391d9942cSStephen Warren 			}
1234035fd948SStephen Warren 
1235035fd948SStephen Warren 			if (cells_name) {
1236035fd948SStephen Warren 				if (of_property_read_u32(node, cells_name,
1237035fd948SStephen Warren 							 &count)) {
123815c9a0acSGrant Likely 					pr_err("%s: could not get %s for %s\n",
123915c9a0acSGrant Likely 						np->full_name, cells_name,
124015c9a0acSGrant Likely 						node->full_name);
124123ce04c0SGrant Likely 					goto err;
124215c9a0acSGrant Likely 				}
1243035fd948SStephen Warren 			} else {
1244035fd948SStephen Warren 				count = cell_count;
1245035fd948SStephen Warren 			}
124615c9a0acSGrant Likely 
124715c9a0acSGrant Likely 			/*
124815c9a0acSGrant Likely 			 * Make sure that the arguments actually fit in the
124915c9a0acSGrant Likely 			 * remaining property data length
125015c9a0acSGrant Likely 			 */
125115c9a0acSGrant Likely 			if (list + count > list_end) {
125215c9a0acSGrant Likely 				pr_err("%s: arguments longer than property\n",
125315c9a0acSGrant Likely 					 np->full_name);
125423ce04c0SGrant Likely 				goto err;
125515c9a0acSGrant Likely 			}
125615c9a0acSGrant Likely 		}
125715c9a0acSGrant Likely 
125815c9a0acSGrant Likely 		/*
125915c9a0acSGrant Likely 		 * All of the error cases above bail out of the loop, so at
126015c9a0acSGrant Likely 		 * this point, the parsing is successful. If the requested
126115c9a0acSGrant Likely 		 * index matches, then fill the out_args structure and return,
126215c9a0acSGrant Likely 		 * or return -ENOENT for an empty entry.
126315c9a0acSGrant Likely 		 */
126423ce04c0SGrant Likely 		rc = -ENOENT;
126515c9a0acSGrant Likely 		if (cur_index == index) {
126615c9a0acSGrant Likely 			if (!phandle)
126723ce04c0SGrant Likely 				goto err;
126815c9a0acSGrant Likely 
126915c9a0acSGrant Likely 			if (out_args) {
127015c9a0acSGrant Likely 				int i;
127115c9a0acSGrant Likely 				if (WARN_ON(count > MAX_PHANDLE_ARGS))
127215c9a0acSGrant Likely 					count = MAX_PHANDLE_ARGS;
127315c9a0acSGrant Likely 				out_args->np = node;
127415c9a0acSGrant Likely 				out_args->args_count = count;
127515c9a0acSGrant Likely 				for (i = 0; i < count; i++)
127615c9a0acSGrant Likely 					out_args->args[i] = be32_to_cpup(list++);
1277b855f16bSTang Yuantian 			} else {
1278b855f16bSTang Yuantian 				of_node_put(node);
127915c9a0acSGrant Likely 			}
128023ce04c0SGrant Likely 
128123ce04c0SGrant Likely 			/* Found it! return success */
128215c9a0acSGrant Likely 			return 0;
128315c9a0acSGrant Likely 		}
128464b60e09SAnton Vorontsov 
128564b60e09SAnton Vorontsov 		of_node_put(node);
128664b60e09SAnton Vorontsov 		node = NULL;
128715c9a0acSGrant Likely 		list += count;
128864b60e09SAnton Vorontsov 		cur_index++;
128964b60e09SAnton Vorontsov 	}
129064b60e09SAnton Vorontsov 
129123ce04c0SGrant Likely 	/*
129223ce04c0SGrant Likely 	 * Unlock node before returning result; will be one of:
129323ce04c0SGrant Likely 	 * -ENOENT : index is for empty phandle
129423ce04c0SGrant Likely 	 * -EINVAL : parsing error on data
1295bd69f73fSGrant Likely 	 * [1..n]  : Number of phandle (count mode; when index = -1)
129623ce04c0SGrant Likely 	 */
1297bd69f73fSGrant Likely 	rc = index < 0 ? cur_index : -ENOENT;
129823ce04c0SGrant Likely  err:
129915c9a0acSGrant Likely 	if (node)
130064b60e09SAnton Vorontsov 		of_node_put(node);
130123ce04c0SGrant Likely 	return rc;
130264b60e09SAnton Vorontsov }
1303bd69f73fSGrant Likely 
1304eded9dd4SStephen Warren /**
13055fba49e3SStephen Warren  * of_parse_phandle - Resolve a phandle property to a device_node pointer
13065fba49e3SStephen Warren  * @np: Pointer to device node holding phandle property
13075fba49e3SStephen Warren  * @phandle_name: Name of property holding a phandle value
13085fba49e3SStephen Warren  * @index: For properties holding a table of phandles, this is the index into
13095fba49e3SStephen Warren  *         the table
13105fba49e3SStephen Warren  *
13115fba49e3SStephen Warren  * Returns the device_node pointer with refcount incremented.  Use
13125fba49e3SStephen Warren  * of_node_put() on it when done.
13135fba49e3SStephen Warren  */
13145fba49e3SStephen Warren struct device_node *of_parse_phandle(const struct device_node *np,
13155fba49e3SStephen Warren 				     const char *phandle_name, int index)
13165fba49e3SStephen Warren {
131791d9942cSStephen Warren 	struct of_phandle_args args;
13185fba49e3SStephen Warren 
131991d9942cSStephen Warren 	if (index < 0)
13205fba49e3SStephen Warren 		return NULL;
13215fba49e3SStephen Warren 
132291d9942cSStephen Warren 	if (__of_parse_phandle_with_args(np, phandle_name, NULL, 0,
132391d9942cSStephen Warren 					 index, &args))
132491d9942cSStephen Warren 		return NULL;
132591d9942cSStephen Warren 
132691d9942cSStephen Warren 	return args.np;
13275fba49e3SStephen Warren }
13285fba49e3SStephen Warren EXPORT_SYMBOL(of_parse_phandle);
13295fba49e3SStephen Warren 
13305fba49e3SStephen Warren /**
1331eded9dd4SStephen Warren  * of_parse_phandle_with_args() - Find a node pointed by phandle in a list
1332eded9dd4SStephen Warren  * @np:		pointer to a device tree node containing a list
1333eded9dd4SStephen Warren  * @list_name:	property name that contains a list
1334eded9dd4SStephen Warren  * @cells_name:	property name that specifies phandles' arguments count
1335eded9dd4SStephen Warren  * @index:	index of a phandle to parse out
1336eded9dd4SStephen Warren  * @out_args:	optional pointer to output arguments structure (will be filled)
1337eded9dd4SStephen Warren  *
1338eded9dd4SStephen Warren  * This function is useful to parse lists of phandles and their arguments.
1339eded9dd4SStephen Warren  * Returns 0 on success and fills out_args, on error returns appropriate
1340eded9dd4SStephen Warren  * errno value.
1341eded9dd4SStephen Warren  *
1342eded9dd4SStephen Warren  * Caller is responsible to call of_node_put() on the returned out_args->node
1343eded9dd4SStephen Warren  * pointer.
1344eded9dd4SStephen Warren  *
1345eded9dd4SStephen Warren  * Example:
1346eded9dd4SStephen Warren  *
1347eded9dd4SStephen Warren  * phandle1: node1 {
1348eded9dd4SStephen Warren  * 	#list-cells = <2>;
1349eded9dd4SStephen Warren  * }
1350eded9dd4SStephen Warren  *
1351eded9dd4SStephen Warren  * phandle2: node2 {
1352eded9dd4SStephen Warren  * 	#list-cells = <1>;
1353eded9dd4SStephen Warren  * }
1354eded9dd4SStephen Warren  *
1355eded9dd4SStephen Warren  * node3 {
1356eded9dd4SStephen Warren  * 	list = <&phandle1 1 2 &phandle2 3>;
1357eded9dd4SStephen Warren  * }
1358eded9dd4SStephen Warren  *
1359eded9dd4SStephen Warren  * To get a device_node of the `node2' node you may call this:
1360eded9dd4SStephen Warren  * of_parse_phandle_with_args(node3, "list", "#list-cells", 1, &args);
1361eded9dd4SStephen Warren  */
1362bd69f73fSGrant Likely int of_parse_phandle_with_args(const struct device_node *np, const char *list_name,
1363bd69f73fSGrant Likely 				const char *cells_name, int index,
1364bd69f73fSGrant Likely 				struct of_phandle_args *out_args)
1365bd69f73fSGrant Likely {
1366bd69f73fSGrant Likely 	if (index < 0)
1367bd69f73fSGrant Likely 		return -EINVAL;
1368035fd948SStephen Warren 	return __of_parse_phandle_with_args(np, list_name, cells_name, 0,
1369035fd948SStephen Warren 					    index, out_args);
1370bd69f73fSGrant Likely }
137115c9a0acSGrant Likely EXPORT_SYMBOL(of_parse_phandle_with_args);
137202af11b0SGrant Likely 
1373bd69f73fSGrant Likely /**
1374035fd948SStephen Warren  * of_parse_phandle_with_fixed_args() - Find a node pointed by phandle in a list
1375035fd948SStephen Warren  * @np:		pointer to a device tree node containing a list
1376035fd948SStephen Warren  * @list_name:	property name that contains a list
1377035fd948SStephen Warren  * @cell_count: number of argument cells following the phandle
1378035fd948SStephen Warren  * @index:	index of a phandle to parse out
1379035fd948SStephen Warren  * @out_args:	optional pointer to output arguments structure (will be filled)
1380035fd948SStephen Warren  *
1381035fd948SStephen Warren  * This function is useful to parse lists of phandles and their arguments.
1382035fd948SStephen Warren  * Returns 0 on success and fills out_args, on error returns appropriate
1383035fd948SStephen Warren  * errno value.
1384035fd948SStephen Warren  *
1385035fd948SStephen Warren  * Caller is responsible to call of_node_put() on the returned out_args->node
1386035fd948SStephen Warren  * pointer.
1387035fd948SStephen Warren  *
1388035fd948SStephen Warren  * Example:
1389035fd948SStephen Warren  *
1390035fd948SStephen Warren  * phandle1: node1 {
1391035fd948SStephen Warren  * }
1392035fd948SStephen Warren  *
1393035fd948SStephen Warren  * phandle2: node2 {
1394035fd948SStephen Warren  * }
1395035fd948SStephen Warren  *
1396035fd948SStephen Warren  * node3 {
1397035fd948SStephen Warren  * 	list = <&phandle1 0 2 &phandle2 2 3>;
1398035fd948SStephen Warren  * }
1399035fd948SStephen Warren  *
1400035fd948SStephen Warren  * To get a device_node of the `node2' node you may call this:
1401035fd948SStephen Warren  * of_parse_phandle_with_fixed_args(node3, "list", 2, 1, &args);
1402035fd948SStephen Warren  */
1403035fd948SStephen Warren int of_parse_phandle_with_fixed_args(const struct device_node *np,
1404035fd948SStephen Warren 				const char *list_name, int cell_count,
1405035fd948SStephen Warren 				int index, struct of_phandle_args *out_args)
1406035fd948SStephen Warren {
1407035fd948SStephen Warren 	if (index < 0)
1408035fd948SStephen Warren 		return -EINVAL;
1409035fd948SStephen Warren 	return __of_parse_phandle_with_args(np, list_name, NULL, cell_count,
1410035fd948SStephen Warren 					   index, out_args);
1411035fd948SStephen Warren }
1412035fd948SStephen Warren EXPORT_SYMBOL(of_parse_phandle_with_fixed_args);
1413035fd948SStephen Warren 
1414035fd948SStephen Warren /**
1415bd69f73fSGrant Likely  * of_count_phandle_with_args() - Find the number of phandles references in a property
1416bd69f73fSGrant Likely  * @np:		pointer to a device tree node containing a list
1417bd69f73fSGrant Likely  * @list_name:	property name that contains a list
1418bd69f73fSGrant Likely  * @cells_name:	property name that specifies phandles' arguments count
1419bd69f73fSGrant Likely  *
1420bd69f73fSGrant Likely  * Returns the number of phandle + argument tuples within a property. It
1421bd69f73fSGrant Likely  * is a typical pattern to encode a list of phandle and variable
1422bd69f73fSGrant Likely  * arguments into a single property. The number of arguments is encoded
1423bd69f73fSGrant Likely  * by a property in the phandle-target node. For example, a gpios
1424bd69f73fSGrant Likely  * property would contain a list of GPIO specifies consisting of a
1425bd69f73fSGrant Likely  * phandle and 1 or more arguments. The number of arguments are
1426bd69f73fSGrant Likely  * determined by the #gpio-cells property in the node pointed to by the
1427bd69f73fSGrant Likely  * phandle.
1428bd69f73fSGrant Likely  */
1429bd69f73fSGrant Likely int of_count_phandle_with_args(const struct device_node *np, const char *list_name,
1430bd69f73fSGrant Likely 				const char *cells_name)
1431bd69f73fSGrant Likely {
1432035fd948SStephen Warren 	return __of_parse_phandle_with_args(np, list_name, cells_name, 0, -1,
1433035fd948SStephen Warren 					    NULL);
1434bd69f73fSGrant Likely }
1435bd69f73fSGrant Likely EXPORT_SYMBOL(of_count_phandle_with_args);
1436bd69f73fSGrant Likely 
14371cf3d8b3SNathan Fontenot #if defined(CONFIG_OF_DYNAMIC)
14381cf3d8b3SNathan Fontenot static int of_property_notify(int action, struct device_node *np,
14391cf3d8b3SNathan Fontenot 			      struct property *prop)
14401cf3d8b3SNathan Fontenot {
14411cf3d8b3SNathan Fontenot 	struct of_prop_reconfig pr;
14421cf3d8b3SNathan Fontenot 
14431cf3d8b3SNathan Fontenot 	pr.dn = np;
14441cf3d8b3SNathan Fontenot 	pr.prop = prop;
14451cf3d8b3SNathan Fontenot 	return of_reconfig_notify(action, &pr);
14461cf3d8b3SNathan Fontenot }
14471cf3d8b3SNathan Fontenot #else
14481cf3d8b3SNathan Fontenot static int of_property_notify(int action, struct device_node *np,
14491cf3d8b3SNathan Fontenot 			      struct property *prop)
14501cf3d8b3SNathan Fontenot {
14511cf3d8b3SNathan Fontenot 	return 0;
14521cf3d8b3SNathan Fontenot }
14531cf3d8b3SNathan Fontenot #endif
14541cf3d8b3SNathan Fontenot 
145502af11b0SGrant Likely /**
145679d1c712SNathan Fontenot  * of_add_property - Add a property to a node
145702af11b0SGrant Likely  */
145879d1c712SNathan Fontenot int of_add_property(struct device_node *np, struct property *prop)
145902af11b0SGrant Likely {
146002af11b0SGrant Likely 	struct property **next;
146102af11b0SGrant Likely 	unsigned long flags;
14621cf3d8b3SNathan Fontenot 	int rc;
14631cf3d8b3SNathan Fontenot 
14641cf3d8b3SNathan Fontenot 	rc = of_property_notify(OF_RECONFIG_ADD_PROPERTY, np, prop);
14651cf3d8b3SNathan Fontenot 	if (rc)
14661cf3d8b3SNathan Fontenot 		return rc;
146702af11b0SGrant Likely 
146802af11b0SGrant Likely 	prop->next = NULL;
1469d6d3c4e6SThomas Gleixner 	raw_spin_lock_irqsave(&devtree_lock, flags);
147002af11b0SGrant Likely 	next = &np->properties;
147102af11b0SGrant Likely 	while (*next) {
147202af11b0SGrant Likely 		if (strcmp(prop->name, (*next)->name) == 0) {
147302af11b0SGrant Likely 			/* duplicate ! don't insert it */
1474d6d3c4e6SThomas Gleixner 			raw_spin_unlock_irqrestore(&devtree_lock, flags);
147502af11b0SGrant Likely 			return -1;
147602af11b0SGrant Likely 		}
147702af11b0SGrant Likely 		next = &(*next)->next;
147802af11b0SGrant Likely 	}
147902af11b0SGrant Likely 	*next = prop;
1480d6d3c4e6SThomas Gleixner 	raw_spin_unlock_irqrestore(&devtree_lock, flags);
148102af11b0SGrant Likely 
148202af11b0SGrant Likely #ifdef CONFIG_PROC_DEVICETREE
148302af11b0SGrant Likely 	/* try to add to proc as well if it was initialized */
148402af11b0SGrant Likely 	if (np->pde)
148502af11b0SGrant Likely 		proc_device_tree_add_prop(np->pde, prop);
148602af11b0SGrant Likely #endif /* CONFIG_PROC_DEVICETREE */
148702af11b0SGrant Likely 
148802af11b0SGrant Likely 	return 0;
148902af11b0SGrant Likely }
149002af11b0SGrant Likely 
149102af11b0SGrant Likely /**
149279d1c712SNathan Fontenot  * of_remove_property - Remove a property from a node.
149302af11b0SGrant Likely  *
149402af11b0SGrant Likely  * Note that we don't actually remove it, since we have given out
149502af11b0SGrant Likely  * who-knows-how-many pointers to the data using get-property.
149602af11b0SGrant Likely  * Instead we just move the property to the "dead properties"
149702af11b0SGrant Likely  * list, so it won't be found any more.
149802af11b0SGrant Likely  */
149979d1c712SNathan Fontenot int of_remove_property(struct device_node *np, struct property *prop)
150002af11b0SGrant Likely {
150102af11b0SGrant Likely 	struct property **next;
150202af11b0SGrant Likely 	unsigned long flags;
150302af11b0SGrant Likely 	int found = 0;
15041cf3d8b3SNathan Fontenot 	int rc;
15051cf3d8b3SNathan Fontenot 
15061cf3d8b3SNathan Fontenot 	rc = of_property_notify(OF_RECONFIG_REMOVE_PROPERTY, np, prop);
15071cf3d8b3SNathan Fontenot 	if (rc)
15081cf3d8b3SNathan Fontenot 		return rc;
150902af11b0SGrant Likely 
1510d6d3c4e6SThomas Gleixner 	raw_spin_lock_irqsave(&devtree_lock, flags);
151102af11b0SGrant Likely 	next = &np->properties;
151202af11b0SGrant Likely 	while (*next) {
151302af11b0SGrant Likely 		if (*next == prop) {
151402af11b0SGrant Likely 			/* found the node */
151502af11b0SGrant Likely 			*next = prop->next;
151602af11b0SGrant Likely 			prop->next = np->deadprops;
151702af11b0SGrant Likely 			np->deadprops = prop;
151802af11b0SGrant Likely 			found = 1;
151902af11b0SGrant Likely 			break;
152002af11b0SGrant Likely 		}
152102af11b0SGrant Likely 		next = &(*next)->next;
152202af11b0SGrant Likely 	}
1523d6d3c4e6SThomas Gleixner 	raw_spin_unlock_irqrestore(&devtree_lock, flags);
152402af11b0SGrant Likely 
152502af11b0SGrant Likely 	if (!found)
152602af11b0SGrant Likely 		return -ENODEV;
152702af11b0SGrant Likely 
152802af11b0SGrant Likely #ifdef CONFIG_PROC_DEVICETREE
152902af11b0SGrant Likely 	/* try to remove the proc node as well */
153002af11b0SGrant Likely 	if (np->pde)
153102af11b0SGrant Likely 		proc_device_tree_remove_prop(np->pde, prop);
153202af11b0SGrant Likely #endif /* CONFIG_PROC_DEVICETREE */
153302af11b0SGrant Likely 
153402af11b0SGrant Likely 	return 0;
153502af11b0SGrant Likely }
153602af11b0SGrant Likely 
153702af11b0SGrant Likely /*
153879d1c712SNathan Fontenot  * of_update_property - Update a property in a node, if the property does
1539475d0094SDong Aisheng  * not exist, add it.
154002af11b0SGrant Likely  *
154102af11b0SGrant Likely  * Note that we don't actually remove it, since we have given out
154202af11b0SGrant Likely  * who-knows-how-many pointers to the data using get-property.
154302af11b0SGrant Likely  * Instead we just move the property to the "dead properties" list,
154402af11b0SGrant Likely  * and add the new property to the property list
154502af11b0SGrant Likely  */
154679d1c712SNathan Fontenot int of_update_property(struct device_node *np, struct property *newprop)
154702af11b0SGrant Likely {
1548475d0094SDong Aisheng 	struct property **next, *oldprop;
154902af11b0SGrant Likely 	unsigned long flags;
15501cf3d8b3SNathan Fontenot 	int rc, found = 0;
15511cf3d8b3SNathan Fontenot 
15521cf3d8b3SNathan Fontenot 	rc = of_property_notify(OF_RECONFIG_UPDATE_PROPERTY, np, newprop);
15531cf3d8b3SNathan Fontenot 	if (rc)
15541cf3d8b3SNathan Fontenot 		return rc;
155502af11b0SGrant Likely 
1556475d0094SDong Aisheng 	if (!newprop->name)
1557475d0094SDong Aisheng 		return -EINVAL;
1558475d0094SDong Aisheng 
1559475d0094SDong Aisheng 	oldprop = of_find_property(np, newprop->name, NULL);
1560475d0094SDong Aisheng 	if (!oldprop)
156179d1c712SNathan Fontenot 		return of_add_property(np, newprop);
1562475d0094SDong Aisheng 
1563d6d3c4e6SThomas Gleixner 	raw_spin_lock_irqsave(&devtree_lock, flags);
156402af11b0SGrant Likely 	next = &np->properties;
156502af11b0SGrant Likely 	while (*next) {
156602af11b0SGrant Likely 		if (*next == oldprop) {
156702af11b0SGrant Likely 			/* found the node */
156802af11b0SGrant Likely 			newprop->next = oldprop->next;
156902af11b0SGrant Likely 			*next = newprop;
157002af11b0SGrant Likely 			oldprop->next = np->deadprops;
157102af11b0SGrant Likely 			np->deadprops = oldprop;
157202af11b0SGrant Likely 			found = 1;
157302af11b0SGrant Likely 			break;
157402af11b0SGrant Likely 		}
157502af11b0SGrant Likely 		next = &(*next)->next;
157602af11b0SGrant Likely 	}
1577d6d3c4e6SThomas Gleixner 	raw_spin_unlock_irqrestore(&devtree_lock, flags);
157802af11b0SGrant Likely 
157902af11b0SGrant Likely 	if (!found)
158002af11b0SGrant Likely 		return -ENODEV;
158102af11b0SGrant Likely 
158202af11b0SGrant Likely #ifdef CONFIG_PROC_DEVICETREE
158302af11b0SGrant Likely 	/* try to add to proc as well if it was initialized */
158402af11b0SGrant Likely 	if (np->pde)
158502af11b0SGrant Likely 		proc_device_tree_update_prop(np->pde, newprop, oldprop);
158602af11b0SGrant Likely #endif /* CONFIG_PROC_DEVICETREE */
158702af11b0SGrant Likely 
158802af11b0SGrant Likely 	return 0;
158902af11b0SGrant Likely }
1590fcdeb7feSGrant Likely 
1591fcdeb7feSGrant Likely #if defined(CONFIG_OF_DYNAMIC)
1592fcdeb7feSGrant Likely /*
1593fcdeb7feSGrant Likely  * Support for dynamic device trees.
1594fcdeb7feSGrant Likely  *
1595fcdeb7feSGrant Likely  * On some platforms, the device tree can be manipulated at runtime.
1596fcdeb7feSGrant Likely  * The routines in this section support adding, removing and changing
1597fcdeb7feSGrant Likely  * device tree nodes.
1598fcdeb7feSGrant Likely  */
1599fcdeb7feSGrant Likely 
16001cf3d8b3SNathan Fontenot static BLOCKING_NOTIFIER_HEAD(of_reconfig_chain);
16011cf3d8b3SNathan Fontenot 
16021cf3d8b3SNathan Fontenot int of_reconfig_notifier_register(struct notifier_block *nb)
16031cf3d8b3SNathan Fontenot {
16041cf3d8b3SNathan Fontenot 	return blocking_notifier_chain_register(&of_reconfig_chain, nb);
16051cf3d8b3SNathan Fontenot }
16061a9bd454SNathan Fontenot EXPORT_SYMBOL_GPL(of_reconfig_notifier_register);
16071cf3d8b3SNathan Fontenot 
16081cf3d8b3SNathan Fontenot int of_reconfig_notifier_unregister(struct notifier_block *nb)
16091cf3d8b3SNathan Fontenot {
16101cf3d8b3SNathan Fontenot 	return blocking_notifier_chain_unregister(&of_reconfig_chain, nb);
16111cf3d8b3SNathan Fontenot }
16121a9bd454SNathan Fontenot EXPORT_SYMBOL_GPL(of_reconfig_notifier_unregister);
16131cf3d8b3SNathan Fontenot 
16141cf3d8b3SNathan Fontenot int of_reconfig_notify(unsigned long action, void *p)
16151cf3d8b3SNathan Fontenot {
16161cf3d8b3SNathan Fontenot 	int rc;
16171cf3d8b3SNathan Fontenot 
16181cf3d8b3SNathan Fontenot 	rc = blocking_notifier_call_chain(&of_reconfig_chain, action, p);
16191cf3d8b3SNathan Fontenot 	return notifier_to_errno(rc);
16201cf3d8b3SNathan Fontenot }
16211cf3d8b3SNathan Fontenot 
1622e81b3295SNathan Fontenot #ifdef CONFIG_PROC_DEVICETREE
1623e81b3295SNathan Fontenot static void of_add_proc_dt_entry(struct device_node *dn)
1624e81b3295SNathan Fontenot {
1625e81b3295SNathan Fontenot 	struct proc_dir_entry *ent;
1626e81b3295SNathan Fontenot 
1627e81b3295SNathan Fontenot 	ent = proc_mkdir(strrchr(dn->full_name, '/') + 1, dn->parent->pde);
1628e81b3295SNathan Fontenot 	if (ent)
1629e81b3295SNathan Fontenot 		proc_device_tree_add_node(dn, ent);
1630e81b3295SNathan Fontenot }
1631e81b3295SNathan Fontenot #else
1632e81b3295SNathan Fontenot static void of_add_proc_dt_entry(struct device_node *dn)
1633e81b3295SNathan Fontenot {
1634e81b3295SNathan Fontenot 	return;
1635e81b3295SNathan Fontenot }
1636e81b3295SNathan Fontenot #endif
1637e81b3295SNathan Fontenot 
1638fcdeb7feSGrant Likely /**
1639fcdeb7feSGrant Likely  * of_attach_node - Plug a device node into the tree and global list.
1640fcdeb7feSGrant Likely  */
16411cf3d8b3SNathan Fontenot int of_attach_node(struct device_node *np)
1642fcdeb7feSGrant Likely {
1643fcdeb7feSGrant Likely 	unsigned long flags;
16441cf3d8b3SNathan Fontenot 	int rc;
16451cf3d8b3SNathan Fontenot 
16461cf3d8b3SNathan Fontenot 	rc = of_reconfig_notify(OF_RECONFIG_ATTACH_NODE, np);
16471cf3d8b3SNathan Fontenot 	if (rc)
16481cf3d8b3SNathan Fontenot 		return rc;
1649fcdeb7feSGrant Likely 
1650d6d3c4e6SThomas Gleixner 	raw_spin_lock_irqsave(&devtree_lock, flags);
1651fcdeb7feSGrant Likely 	np->sibling = np->parent->child;
1652465aac6dSRandy Dunlap 	np->allnext = of_allnodes;
1653fcdeb7feSGrant Likely 	np->parent->child = np;
1654465aac6dSRandy Dunlap 	of_allnodes = np;
1655d6d3c4e6SThomas Gleixner 	raw_spin_unlock_irqrestore(&devtree_lock, flags);
1656e81b3295SNathan Fontenot 
1657e81b3295SNathan Fontenot 	of_add_proc_dt_entry(np);
16581cf3d8b3SNathan Fontenot 	return 0;
1659fcdeb7feSGrant Likely }
1660fcdeb7feSGrant Likely 
1661e81b3295SNathan Fontenot #ifdef CONFIG_PROC_DEVICETREE
1662e81b3295SNathan Fontenot static void of_remove_proc_dt_entry(struct device_node *dn)
1663e81b3295SNathan Fontenot {
1664a8ca16eaSDavid Howells 	proc_remove(dn->pde);
1665e81b3295SNathan Fontenot }
1666e81b3295SNathan Fontenot #else
1667e81b3295SNathan Fontenot static void of_remove_proc_dt_entry(struct device_node *dn)
1668e81b3295SNathan Fontenot {
1669e81b3295SNathan Fontenot 	return;
1670e81b3295SNathan Fontenot }
1671e81b3295SNathan Fontenot #endif
1672e81b3295SNathan Fontenot 
1673fcdeb7feSGrant Likely /**
1674fcdeb7feSGrant Likely  * of_detach_node - "Unplug" a node from the device tree.
1675fcdeb7feSGrant Likely  *
1676fcdeb7feSGrant Likely  * The caller must hold a reference to the node.  The memory associated with
1677fcdeb7feSGrant Likely  * the node is not freed until its refcount goes to zero.
1678fcdeb7feSGrant Likely  */
16791cf3d8b3SNathan Fontenot int of_detach_node(struct device_node *np)
1680fcdeb7feSGrant Likely {
1681fcdeb7feSGrant Likely 	struct device_node *parent;
1682fcdeb7feSGrant Likely 	unsigned long flags;
16831cf3d8b3SNathan Fontenot 	int rc = 0;
16841cf3d8b3SNathan Fontenot 
16851cf3d8b3SNathan Fontenot 	rc = of_reconfig_notify(OF_RECONFIG_DETACH_NODE, np);
16861cf3d8b3SNathan Fontenot 	if (rc)
16871cf3d8b3SNathan Fontenot 		return rc;
1688fcdeb7feSGrant Likely 
1689d6d3c4e6SThomas Gleixner 	raw_spin_lock_irqsave(&devtree_lock, flags);
1690fcdeb7feSGrant Likely 
1691e81b3295SNathan Fontenot 	if (of_node_check_flag(np, OF_DETACHED)) {
1692e81b3295SNathan Fontenot 		/* someone already detached it */
1693d6d3c4e6SThomas Gleixner 		raw_spin_unlock_irqrestore(&devtree_lock, flags);
16941cf3d8b3SNathan Fontenot 		return rc;
1695e81b3295SNathan Fontenot 	}
1696e81b3295SNathan Fontenot 
1697fcdeb7feSGrant Likely 	parent = np->parent;
1698e81b3295SNathan Fontenot 	if (!parent) {
1699d6d3c4e6SThomas Gleixner 		raw_spin_unlock_irqrestore(&devtree_lock, flags);
17001cf3d8b3SNathan Fontenot 		return rc;
1701e81b3295SNathan Fontenot 	}
1702fcdeb7feSGrant Likely 
1703465aac6dSRandy Dunlap 	if (of_allnodes == np)
1704465aac6dSRandy Dunlap 		of_allnodes = np->allnext;
1705fcdeb7feSGrant Likely 	else {
1706fcdeb7feSGrant Likely 		struct device_node *prev;
1707465aac6dSRandy Dunlap 		for (prev = of_allnodes;
1708fcdeb7feSGrant Likely 		     prev->allnext != np;
1709fcdeb7feSGrant Likely 		     prev = prev->allnext)
1710fcdeb7feSGrant Likely 			;
1711fcdeb7feSGrant Likely 		prev->allnext = np->allnext;
1712fcdeb7feSGrant Likely 	}
1713fcdeb7feSGrant Likely 
1714fcdeb7feSGrant Likely 	if (parent->child == np)
1715fcdeb7feSGrant Likely 		parent->child = np->sibling;
1716fcdeb7feSGrant Likely 	else {
1717fcdeb7feSGrant Likely 		struct device_node *prevsib;
1718fcdeb7feSGrant Likely 		for (prevsib = np->parent->child;
1719fcdeb7feSGrant Likely 		     prevsib->sibling != np;
1720fcdeb7feSGrant Likely 		     prevsib = prevsib->sibling)
1721fcdeb7feSGrant Likely 			;
1722fcdeb7feSGrant Likely 		prevsib->sibling = np->sibling;
1723fcdeb7feSGrant Likely 	}
1724fcdeb7feSGrant Likely 
1725fcdeb7feSGrant Likely 	of_node_set_flag(np, OF_DETACHED);
1726d6d3c4e6SThomas Gleixner 	raw_spin_unlock_irqrestore(&devtree_lock, flags);
1727e81b3295SNathan Fontenot 
1728e81b3295SNathan Fontenot 	of_remove_proc_dt_entry(np);
17291cf3d8b3SNathan Fontenot 	return rc;
1730fcdeb7feSGrant Likely }
1731fcdeb7feSGrant Likely #endif /* defined(CONFIG_OF_DYNAMIC) */
1732fcdeb7feSGrant Likely 
1733611cad72SShawn Guo static void of_alias_add(struct alias_prop *ap, struct device_node *np,
1734611cad72SShawn Guo 			 int id, const char *stem, int stem_len)
1735611cad72SShawn Guo {
1736611cad72SShawn Guo 	ap->np = np;
1737611cad72SShawn Guo 	ap->id = id;
1738611cad72SShawn Guo 	strncpy(ap->stem, stem, stem_len);
1739611cad72SShawn Guo 	ap->stem[stem_len] = 0;
1740611cad72SShawn Guo 	list_add_tail(&ap->link, &aliases_lookup);
1741611cad72SShawn Guo 	pr_debug("adding DT alias:%s: stem=%s id=%i node=%s\n",
174274a7f084SGrant Likely 		 ap->alias, ap->stem, ap->id, of_node_full_name(np));
1743611cad72SShawn Guo }
1744611cad72SShawn Guo 
1745611cad72SShawn Guo /**
1746611cad72SShawn Guo  * of_alias_scan - Scan all properties of 'aliases' node
1747611cad72SShawn Guo  *
1748611cad72SShawn Guo  * The function scans all the properties of 'aliases' node and populate
1749611cad72SShawn Guo  * the the global lookup table with the properties.  It returns the
1750611cad72SShawn Guo  * number of alias_prop found, or error code in error case.
1751611cad72SShawn Guo  *
1752611cad72SShawn Guo  * @dt_alloc:	An allocator that provides a virtual address to memory
1753611cad72SShawn Guo  *		for the resulting tree
1754611cad72SShawn Guo  */
1755611cad72SShawn Guo void of_alias_scan(void * (*dt_alloc)(u64 size, u64 align))
1756611cad72SShawn Guo {
1757611cad72SShawn Guo 	struct property *pp;
1758611cad72SShawn Guo 
1759611cad72SShawn Guo 	of_chosen = of_find_node_by_path("/chosen");
1760611cad72SShawn Guo 	if (of_chosen == NULL)
1761611cad72SShawn Guo 		of_chosen = of_find_node_by_path("/chosen@0");
17625c19e952SSascha Hauer 
17635c19e952SSascha Hauer 	if (of_chosen) {
17645c19e952SSascha Hauer 		const char *name;
17655c19e952SSascha Hauer 
17665c19e952SSascha Hauer 		name = of_get_property(of_chosen, "linux,stdout-path", NULL);
17675c19e952SSascha Hauer 		if (name)
17685c19e952SSascha Hauer 			of_stdout = of_find_node_by_path(name);
17695c19e952SSascha Hauer 	}
17705c19e952SSascha Hauer 
1771611cad72SShawn Guo 	of_aliases = of_find_node_by_path("/aliases");
1772611cad72SShawn Guo 	if (!of_aliases)
1773611cad72SShawn Guo 		return;
1774611cad72SShawn Guo 
17758af0da93SDong Aisheng 	for_each_property_of_node(of_aliases, pp) {
1776611cad72SShawn Guo 		const char *start = pp->name;
1777611cad72SShawn Guo 		const char *end = start + strlen(start);
1778611cad72SShawn Guo 		struct device_node *np;
1779611cad72SShawn Guo 		struct alias_prop *ap;
1780611cad72SShawn Guo 		int id, len;
1781611cad72SShawn Guo 
1782611cad72SShawn Guo 		/* Skip those we do not want to proceed */
1783611cad72SShawn Guo 		if (!strcmp(pp->name, "name") ||
1784611cad72SShawn Guo 		    !strcmp(pp->name, "phandle") ||
1785611cad72SShawn Guo 		    !strcmp(pp->name, "linux,phandle"))
1786611cad72SShawn Guo 			continue;
1787611cad72SShawn Guo 
1788611cad72SShawn Guo 		np = of_find_node_by_path(pp->value);
1789611cad72SShawn Guo 		if (!np)
1790611cad72SShawn Guo 			continue;
1791611cad72SShawn Guo 
1792611cad72SShawn Guo 		/* walk the alias backwards to extract the id and work out
1793611cad72SShawn Guo 		 * the 'stem' string */
1794611cad72SShawn Guo 		while (isdigit(*(end-1)) && end > start)
1795611cad72SShawn Guo 			end--;
1796611cad72SShawn Guo 		len = end - start;
1797611cad72SShawn Guo 
1798611cad72SShawn Guo 		if (kstrtoint(end, 10, &id) < 0)
1799611cad72SShawn Guo 			continue;
1800611cad72SShawn Guo 
1801611cad72SShawn Guo 		/* Allocate an alias_prop with enough space for the stem */
1802611cad72SShawn Guo 		ap = dt_alloc(sizeof(*ap) + len + 1, 4);
1803611cad72SShawn Guo 		if (!ap)
1804611cad72SShawn Guo 			continue;
18050640332eSGrant Likely 		memset(ap, 0, sizeof(*ap) + len + 1);
1806611cad72SShawn Guo 		ap->alias = start;
1807611cad72SShawn Guo 		of_alias_add(ap, np, id, start, len);
1808611cad72SShawn Guo 	}
1809611cad72SShawn Guo }
1810611cad72SShawn Guo 
1811611cad72SShawn Guo /**
1812611cad72SShawn Guo  * of_alias_get_id - Get alias id for the given device_node
1813611cad72SShawn Guo  * @np:		Pointer to the given device_node
1814611cad72SShawn Guo  * @stem:	Alias stem of the given device_node
1815611cad72SShawn Guo  *
1816611cad72SShawn Guo  * The function travels the lookup table to get alias id for the given
1817611cad72SShawn Guo  * device_node and alias stem.  It returns the alias id if find it.
1818611cad72SShawn Guo  */
1819611cad72SShawn Guo int of_alias_get_id(struct device_node *np, const char *stem)
1820611cad72SShawn Guo {
1821611cad72SShawn Guo 	struct alias_prop *app;
1822611cad72SShawn Guo 	int id = -ENODEV;
1823611cad72SShawn Guo 
1824611cad72SShawn Guo 	mutex_lock(&of_aliases_mutex);
1825611cad72SShawn Guo 	list_for_each_entry(app, &aliases_lookup, link) {
1826611cad72SShawn Guo 		if (strcmp(app->stem, stem) != 0)
1827611cad72SShawn Guo 			continue;
1828611cad72SShawn Guo 
1829611cad72SShawn Guo 		if (np == app->np) {
1830611cad72SShawn Guo 			id = app->id;
1831611cad72SShawn Guo 			break;
1832611cad72SShawn Guo 		}
1833611cad72SShawn Guo 	}
1834611cad72SShawn Guo 	mutex_unlock(&of_aliases_mutex);
1835611cad72SShawn Guo 
1836611cad72SShawn Guo 	return id;
1837611cad72SShawn Guo }
1838611cad72SShawn Guo EXPORT_SYMBOL_GPL(of_alias_get_id);
1839c541adc6SStephen Warren 
1840c541adc6SStephen Warren const __be32 *of_prop_next_u32(struct property *prop, const __be32 *cur,
1841c541adc6SStephen Warren 			       u32 *pu)
1842c541adc6SStephen Warren {
1843c541adc6SStephen Warren 	const void *curv = cur;
1844c541adc6SStephen Warren 
1845c541adc6SStephen Warren 	if (!prop)
1846c541adc6SStephen Warren 		return NULL;
1847c541adc6SStephen Warren 
1848c541adc6SStephen Warren 	if (!cur) {
1849c541adc6SStephen Warren 		curv = prop->value;
1850c541adc6SStephen Warren 		goto out_val;
1851c541adc6SStephen Warren 	}
1852c541adc6SStephen Warren 
1853c541adc6SStephen Warren 	curv += sizeof(*cur);
1854c541adc6SStephen Warren 	if (curv >= prop->value + prop->length)
1855c541adc6SStephen Warren 		return NULL;
1856c541adc6SStephen Warren 
1857c541adc6SStephen Warren out_val:
1858c541adc6SStephen Warren 	*pu = be32_to_cpup(curv);
1859c541adc6SStephen Warren 	return curv;
1860c541adc6SStephen Warren }
1861c541adc6SStephen Warren EXPORT_SYMBOL_GPL(of_prop_next_u32);
1862c541adc6SStephen Warren 
1863c541adc6SStephen Warren const char *of_prop_next_string(struct property *prop, const char *cur)
1864c541adc6SStephen Warren {
1865c541adc6SStephen Warren 	const void *curv = cur;
1866c541adc6SStephen Warren 
1867c541adc6SStephen Warren 	if (!prop)
1868c541adc6SStephen Warren 		return NULL;
1869c541adc6SStephen Warren 
1870c541adc6SStephen Warren 	if (!cur)
1871c541adc6SStephen Warren 		return prop->value;
1872c541adc6SStephen Warren 
1873c541adc6SStephen Warren 	curv += strlen(cur) + 1;
1874c541adc6SStephen Warren 	if (curv >= prop->value + prop->length)
1875c541adc6SStephen Warren 		return NULL;
1876c541adc6SStephen Warren 
1877c541adc6SStephen Warren 	return curv;
1878c541adc6SStephen Warren }
1879c541adc6SStephen Warren EXPORT_SYMBOL_GPL(of_prop_next_string);
18805c19e952SSascha Hauer 
18815c19e952SSascha Hauer /**
18825c19e952SSascha Hauer  * of_device_is_stdout_path - check if a device node matches the
18835c19e952SSascha Hauer  *                            linux,stdout-path property
18845c19e952SSascha Hauer  *
18855c19e952SSascha Hauer  * Check if this device node matches the linux,stdout-path property
18865c19e952SSascha Hauer  * in the chosen node. return true if yes, false otherwise.
18875c19e952SSascha Hauer  */
18885c19e952SSascha Hauer int of_device_is_stdout_path(struct device_node *dn)
18895c19e952SSascha Hauer {
18905c19e952SSascha Hauer 	if (!of_stdout)
18915c19e952SSascha Hauer 		return false;
18925c19e952SSascha Hauer 
18935c19e952SSascha Hauer 	return of_stdout == dn;
18945c19e952SSascha Hauer }
18955c19e952SSascha Hauer EXPORT_SYMBOL_GPL(of_device_is_stdout_path);
1896