xref: /openbmc/linux/drivers/of/base.c (revision 62664f67)
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 
770c3f061cSRob Herring #ifdef CONFIG_NUMA
780c3f061cSRob Herring int __weak of_node_to_nid(struct device_node *np)
790c3f061cSRob Herring {
800c3f061cSRob Herring 	return numa_node_id();
810c3f061cSRob Herring }
820c3f061cSRob Herring #endif
830c3f061cSRob Herring 
840f22dd39SGrant Likely #if defined(CONFIG_OF_DYNAMIC)
85923f7e30SGrant Likely /**
86923f7e30SGrant Likely  *	of_node_get - Increment refcount of a node
87923f7e30SGrant Likely  *	@node:	Node to inc refcount, NULL is supported to
88923f7e30SGrant Likely  *		simplify writing of callers
89923f7e30SGrant Likely  *
90923f7e30SGrant Likely  *	Returns node.
91923f7e30SGrant Likely  */
92923f7e30SGrant Likely struct device_node *of_node_get(struct device_node *node)
93923f7e30SGrant Likely {
94923f7e30SGrant Likely 	if (node)
95923f7e30SGrant Likely 		kref_get(&node->kref);
96923f7e30SGrant Likely 	return node;
97923f7e30SGrant Likely }
98923f7e30SGrant Likely EXPORT_SYMBOL(of_node_get);
99923f7e30SGrant Likely 
100923f7e30SGrant Likely static inline struct device_node *kref_to_device_node(struct kref *kref)
101923f7e30SGrant Likely {
102923f7e30SGrant Likely 	return container_of(kref, struct device_node, kref);
103923f7e30SGrant Likely }
104923f7e30SGrant Likely 
105923f7e30SGrant Likely /**
106923f7e30SGrant Likely  *	of_node_release - release a dynamically allocated node
107923f7e30SGrant Likely  *	@kref:  kref element of the node to be released
108923f7e30SGrant Likely  *
109923f7e30SGrant Likely  *	In of_node_put() this function is passed to kref_put()
110923f7e30SGrant Likely  *	as the destructor.
111923f7e30SGrant Likely  */
112923f7e30SGrant Likely static void of_node_release(struct kref *kref)
113923f7e30SGrant Likely {
114923f7e30SGrant Likely 	struct device_node *node = kref_to_device_node(kref);
115923f7e30SGrant Likely 	struct property *prop = node->properties;
116923f7e30SGrant Likely 
117923f7e30SGrant Likely 	/* We should never be releasing nodes that haven't been detached. */
118923f7e30SGrant Likely 	if (!of_node_check_flag(node, OF_DETACHED)) {
119923f7e30SGrant Likely 		pr_err("ERROR: Bad of_node_put() on %s\n", node->full_name);
120923f7e30SGrant Likely 		dump_stack();
121923f7e30SGrant Likely 		kref_init(&node->kref);
122923f7e30SGrant Likely 		return;
123923f7e30SGrant Likely 	}
124923f7e30SGrant Likely 
125923f7e30SGrant Likely 	if (!of_node_check_flag(node, OF_DYNAMIC))
126923f7e30SGrant Likely 		return;
127923f7e30SGrant Likely 
128923f7e30SGrant Likely 	while (prop) {
129923f7e30SGrant Likely 		struct property *next = prop->next;
130923f7e30SGrant Likely 		kfree(prop->name);
131923f7e30SGrant Likely 		kfree(prop->value);
132923f7e30SGrant Likely 		kfree(prop);
133923f7e30SGrant Likely 		prop = next;
134923f7e30SGrant Likely 
135923f7e30SGrant Likely 		if (!prop) {
136923f7e30SGrant Likely 			prop = node->deadprops;
137923f7e30SGrant Likely 			node->deadprops = NULL;
138923f7e30SGrant Likely 		}
139923f7e30SGrant Likely 	}
140923f7e30SGrant Likely 	kfree(node->full_name);
141923f7e30SGrant Likely 	kfree(node->data);
142923f7e30SGrant Likely 	kfree(node);
143923f7e30SGrant Likely }
144923f7e30SGrant Likely 
145923f7e30SGrant Likely /**
146923f7e30SGrant Likely  *	of_node_put - Decrement refcount of a node
147923f7e30SGrant Likely  *	@node:	Node to dec refcount, NULL is supported to
148923f7e30SGrant Likely  *		simplify writing of callers
149923f7e30SGrant Likely  *
150923f7e30SGrant Likely  */
151923f7e30SGrant Likely void of_node_put(struct device_node *node)
152923f7e30SGrant Likely {
153923f7e30SGrant Likely 	if (node)
154923f7e30SGrant Likely 		kref_put(&node->kref, of_node_release);
155923f7e30SGrant Likely }
156923f7e30SGrant Likely EXPORT_SYMBOL(of_node_put);
1570f22dd39SGrant Likely #endif /* CONFIG_OF_DYNAMIC */
158923f7e30SGrant Likely 
15928d0e36bSThomas Gleixner static struct property *__of_find_property(const struct device_node *np,
16028d0e36bSThomas Gleixner 					   const char *name, int *lenp)
161581b605aSStephen Rothwell {
162581b605aSStephen Rothwell 	struct property *pp;
163581b605aSStephen Rothwell 
16464e4566fSTimur Tabi 	if (!np)
16564e4566fSTimur Tabi 		return NULL;
16664e4566fSTimur Tabi 
167a3a7cab1SSachin Kamat 	for (pp = np->properties; pp; pp = pp->next) {
168581b605aSStephen Rothwell 		if (of_prop_cmp(pp->name, name) == 0) {
169a3a7cab1SSachin Kamat 			if (lenp)
170581b605aSStephen Rothwell 				*lenp = pp->length;
171581b605aSStephen Rothwell 			break;
172581b605aSStephen Rothwell 		}
173581b605aSStephen Rothwell 	}
17428d0e36bSThomas Gleixner 
17528d0e36bSThomas Gleixner 	return pp;
17628d0e36bSThomas Gleixner }
17728d0e36bSThomas Gleixner 
17828d0e36bSThomas Gleixner struct property *of_find_property(const struct device_node *np,
17928d0e36bSThomas Gleixner 				  const char *name,
18028d0e36bSThomas Gleixner 				  int *lenp)
18128d0e36bSThomas Gleixner {
18228d0e36bSThomas Gleixner 	struct property *pp;
183d6d3c4e6SThomas Gleixner 	unsigned long flags;
18428d0e36bSThomas Gleixner 
185d6d3c4e6SThomas Gleixner 	raw_spin_lock_irqsave(&devtree_lock, flags);
18628d0e36bSThomas Gleixner 	pp = __of_find_property(np, name, lenp);
187d6d3c4e6SThomas Gleixner 	raw_spin_unlock_irqrestore(&devtree_lock, flags);
188581b605aSStephen Rothwell 
189581b605aSStephen Rothwell 	return pp;
190581b605aSStephen Rothwell }
191581b605aSStephen Rothwell EXPORT_SYMBOL(of_find_property);
192581b605aSStephen Rothwell 
193e91edcf5SGrant Likely /**
194e91edcf5SGrant Likely  * of_find_all_nodes - Get next node in global list
195e91edcf5SGrant Likely  * @prev:	Previous node or NULL to start iteration
196e91edcf5SGrant Likely  *		of_node_put() will be called on it
197e91edcf5SGrant Likely  *
198e91edcf5SGrant Likely  * Returns a node pointer with refcount incremented, use
199e91edcf5SGrant Likely  * of_node_put() on it when done.
200e91edcf5SGrant Likely  */
201e91edcf5SGrant Likely struct device_node *of_find_all_nodes(struct device_node *prev)
202e91edcf5SGrant Likely {
203e91edcf5SGrant Likely 	struct device_node *np;
204d25d8694SBenjamin Herrenschmidt 	unsigned long flags;
205e91edcf5SGrant Likely 
206d25d8694SBenjamin Herrenschmidt 	raw_spin_lock_irqsave(&devtree_lock, flags);
207465aac6dSRandy Dunlap 	np = prev ? prev->allnext : of_allnodes;
208e91edcf5SGrant Likely 	for (; np != NULL; np = np->allnext)
209e91edcf5SGrant Likely 		if (of_node_get(np))
210e91edcf5SGrant Likely 			break;
211e91edcf5SGrant Likely 	of_node_put(prev);
212d25d8694SBenjamin Herrenschmidt 	raw_spin_unlock_irqrestore(&devtree_lock, flags);
213e91edcf5SGrant Likely 	return np;
214e91edcf5SGrant Likely }
215e91edcf5SGrant Likely EXPORT_SYMBOL(of_find_all_nodes);
216e91edcf5SGrant Likely 
21797e873e5SStephen Rothwell /*
21897e873e5SStephen Rothwell  * Find a property with a given name for a given node
21997e873e5SStephen Rothwell  * and return the value.
22097e873e5SStephen Rothwell  */
22128d0e36bSThomas Gleixner static const void *__of_get_property(const struct device_node *np,
22228d0e36bSThomas Gleixner 				     const char *name, int *lenp)
22328d0e36bSThomas Gleixner {
22428d0e36bSThomas Gleixner 	struct property *pp = __of_find_property(np, name, lenp);
22528d0e36bSThomas Gleixner 
22628d0e36bSThomas Gleixner 	return pp ? pp->value : NULL;
22728d0e36bSThomas Gleixner }
22828d0e36bSThomas Gleixner 
22928d0e36bSThomas Gleixner /*
23028d0e36bSThomas Gleixner  * Find a property with a given name for a given node
23128d0e36bSThomas Gleixner  * and return the value.
23228d0e36bSThomas Gleixner  */
23397e873e5SStephen Rothwell const void *of_get_property(const struct device_node *np, const char *name,
23497e873e5SStephen Rothwell 			    int *lenp)
23597e873e5SStephen Rothwell {
23697e873e5SStephen Rothwell 	struct property *pp = of_find_property(np, name, lenp);
23797e873e5SStephen Rothwell 
23897e873e5SStephen Rothwell 	return pp ? pp->value : NULL;
23997e873e5SStephen Rothwell }
24097e873e5SStephen Rothwell EXPORT_SYMBOL(of_get_property);
2410081cbc3SStephen Rothwell 
242183912d3SSudeep KarkadaNagesha /*
243183912d3SSudeep KarkadaNagesha  * arch_match_cpu_phys_id - Match the given logical CPU and physical id
244183912d3SSudeep KarkadaNagesha  *
245183912d3SSudeep KarkadaNagesha  * @cpu: logical cpu index of a core/thread
246183912d3SSudeep KarkadaNagesha  * @phys_id: physical identifier of a core/thread
247183912d3SSudeep KarkadaNagesha  *
248183912d3SSudeep KarkadaNagesha  * CPU logical to physical index mapping is architecture specific.
249183912d3SSudeep KarkadaNagesha  * However this __weak function provides a default match of physical
250183912d3SSudeep KarkadaNagesha  * id to logical cpu index. phys_id provided here is usually values read
251183912d3SSudeep KarkadaNagesha  * from the device tree which must match the hardware internal registers.
252183912d3SSudeep KarkadaNagesha  *
253183912d3SSudeep KarkadaNagesha  * Returns true if the physical identifier and the logical cpu index
254183912d3SSudeep KarkadaNagesha  * correspond to the same core/thread, false otherwise.
255183912d3SSudeep KarkadaNagesha  */
256183912d3SSudeep KarkadaNagesha bool __weak arch_match_cpu_phys_id(int cpu, u64 phys_id)
257183912d3SSudeep KarkadaNagesha {
258183912d3SSudeep KarkadaNagesha 	return (u32)phys_id == cpu;
259183912d3SSudeep KarkadaNagesha }
260183912d3SSudeep KarkadaNagesha 
261183912d3SSudeep KarkadaNagesha /**
262183912d3SSudeep KarkadaNagesha  * Checks if the given "prop_name" property holds the physical id of the
263183912d3SSudeep KarkadaNagesha  * core/thread corresponding to the logical cpu 'cpu'. If 'thread' is not
264183912d3SSudeep KarkadaNagesha  * NULL, local thread number within the core is returned in it.
265183912d3SSudeep KarkadaNagesha  */
266183912d3SSudeep KarkadaNagesha static bool __of_find_n_match_cpu_property(struct device_node *cpun,
267183912d3SSudeep KarkadaNagesha 			const char *prop_name, int cpu, unsigned int *thread)
268183912d3SSudeep KarkadaNagesha {
269183912d3SSudeep KarkadaNagesha 	const __be32 *cell;
270183912d3SSudeep KarkadaNagesha 	int ac, prop_len, tid;
271183912d3SSudeep KarkadaNagesha 	u64 hwid;
272183912d3SSudeep KarkadaNagesha 
273183912d3SSudeep KarkadaNagesha 	ac = of_n_addr_cells(cpun);
274183912d3SSudeep KarkadaNagesha 	cell = of_get_property(cpun, prop_name, &prop_len);
275f3cea45aSGrant Likely 	if (!cell || !ac)
276183912d3SSudeep KarkadaNagesha 		return false;
277f3cea45aSGrant Likely 	prop_len /= sizeof(*cell) * ac;
278183912d3SSudeep KarkadaNagesha 	for (tid = 0; tid < prop_len; tid++) {
279183912d3SSudeep KarkadaNagesha 		hwid = of_read_number(cell, ac);
280183912d3SSudeep KarkadaNagesha 		if (arch_match_cpu_phys_id(cpu, hwid)) {
281183912d3SSudeep KarkadaNagesha 			if (thread)
282183912d3SSudeep KarkadaNagesha 				*thread = tid;
283183912d3SSudeep KarkadaNagesha 			return true;
284183912d3SSudeep KarkadaNagesha 		}
285183912d3SSudeep KarkadaNagesha 		cell += ac;
286183912d3SSudeep KarkadaNagesha 	}
287183912d3SSudeep KarkadaNagesha 	return false;
288183912d3SSudeep KarkadaNagesha }
289183912d3SSudeep KarkadaNagesha 
290d1cb9d1aSDavid Miller /*
291d1cb9d1aSDavid Miller  * arch_find_n_match_cpu_physical_id - See if the given device node is
292d1cb9d1aSDavid Miller  * for the cpu corresponding to logical cpu 'cpu'.  Return true if so,
293d1cb9d1aSDavid Miller  * else false.  If 'thread' is non-NULL, the local thread number within the
294d1cb9d1aSDavid Miller  * core is returned in it.
295d1cb9d1aSDavid Miller  */
296d1cb9d1aSDavid Miller bool __weak arch_find_n_match_cpu_physical_id(struct device_node *cpun,
297d1cb9d1aSDavid Miller 					      int cpu, unsigned int *thread)
298d1cb9d1aSDavid Miller {
299d1cb9d1aSDavid Miller 	/* Check for non-standard "ibm,ppc-interrupt-server#s" property
300d1cb9d1aSDavid Miller 	 * for thread ids on PowerPC. If it doesn't exist fallback to
301d1cb9d1aSDavid Miller 	 * standard "reg" property.
302d1cb9d1aSDavid Miller 	 */
303d1cb9d1aSDavid Miller 	if (IS_ENABLED(CONFIG_PPC) &&
304d1cb9d1aSDavid Miller 	    __of_find_n_match_cpu_property(cpun,
305d1cb9d1aSDavid Miller 					   "ibm,ppc-interrupt-server#s",
306d1cb9d1aSDavid Miller 					   cpu, thread))
307d1cb9d1aSDavid Miller 		return true;
308d1cb9d1aSDavid Miller 
309d1cb9d1aSDavid Miller 	if (__of_find_n_match_cpu_property(cpun, "reg", cpu, thread))
310d1cb9d1aSDavid Miller 		return true;
311d1cb9d1aSDavid Miller 
312d1cb9d1aSDavid Miller 	return false;
313d1cb9d1aSDavid Miller }
314d1cb9d1aSDavid Miller 
315183912d3SSudeep KarkadaNagesha /**
316183912d3SSudeep KarkadaNagesha  * of_get_cpu_node - Get device node associated with the given logical CPU
317183912d3SSudeep KarkadaNagesha  *
318183912d3SSudeep KarkadaNagesha  * @cpu: CPU number(logical index) for which device node is required
319183912d3SSudeep KarkadaNagesha  * @thread: if not NULL, local thread number within the physical core is
320183912d3SSudeep KarkadaNagesha  *          returned
321183912d3SSudeep KarkadaNagesha  *
322183912d3SSudeep KarkadaNagesha  * The main purpose of this function is to retrieve the device node for the
323183912d3SSudeep KarkadaNagesha  * given logical CPU index. It should be used to initialize the of_node in
324183912d3SSudeep KarkadaNagesha  * cpu device. Once of_node in cpu device is populated, all the further
325183912d3SSudeep KarkadaNagesha  * references can use that instead.
326183912d3SSudeep KarkadaNagesha  *
327183912d3SSudeep KarkadaNagesha  * CPU logical to physical index mapping is architecture specific and is built
328183912d3SSudeep KarkadaNagesha  * before booting secondary cores. This function uses arch_match_cpu_phys_id
329183912d3SSudeep KarkadaNagesha  * which can be overridden by architecture specific implementation.
330183912d3SSudeep KarkadaNagesha  *
331183912d3SSudeep KarkadaNagesha  * Returns a node pointer for the logical cpu if found, else NULL.
332183912d3SSudeep KarkadaNagesha  */
333183912d3SSudeep KarkadaNagesha struct device_node *of_get_cpu_node(int cpu, unsigned int *thread)
334183912d3SSudeep KarkadaNagesha {
335d1cb9d1aSDavid Miller 	struct device_node *cpun;
336183912d3SSudeep KarkadaNagesha 
337d1cb9d1aSDavid Miller 	for_each_node_by_type(cpun, "cpu") {
338d1cb9d1aSDavid Miller 		if (arch_find_n_match_cpu_physical_id(cpun, cpu, thread))
339183912d3SSudeep KarkadaNagesha 			return cpun;
340183912d3SSudeep KarkadaNagesha 	}
341183912d3SSudeep KarkadaNagesha 	return NULL;
342183912d3SSudeep KarkadaNagesha }
343183912d3SSudeep KarkadaNagesha EXPORT_SYMBOL(of_get_cpu_node);
344183912d3SSudeep KarkadaNagesha 
3450081cbc3SStephen Rothwell /** Checks if the given "compat" string matches one of the strings in
3460081cbc3SStephen Rothwell  * the device's "compatible" property
3470081cbc3SStephen Rothwell  */
34828d0e36bSThomas Gleixner static int __of_device_is_compatible(const struct device_node *device,
3490081cbc3SStephen Rothwell 				     const char *compat)
3500081cbc3SStephen Rothwell {
3510081cbc3SStephen Rothwell 	const char* cp;
3520081cbc3SStephen Rothwell 	int cplen, l;
3530081cbc3SStephen Rothwell 
35428d0e36bSThomas Gleixner 	cp = __of_get_property(device, "compatible", &cplen);
3550081cbc3SStephen Rothwell 	if (cp == NULL)
3560081cbc3SStephen Rothwell 		return 0;
3570081cbc3SStephen Rothwell 	while (cplen > 0) {
3580081cbc3SStephen Rothwell 		if (of_compat_cmp(cp, compat, strlen(compat)) == 0)
3590081cbc3SStephen Rothwell 			return 1;
3600081cbc3SStephen Rothwell 		l = strlen(cp) + 1;
3610081cbc3SStephen Rothwell 		cp += l;
3620081cbc3SStephen Rothwell 		cplen -= l;
3630081cbc3SStephen Rothwell 	}
3640081cbc3SStephen Rothwell 
3650081cbc3SStephen Rothwell 	return 0;
3660081cbc3SStephen Rothwell }
36728d0e36bSThomas Gleixner 
36828d0e36bSThomas Gleixner /** Checks if the given "compat" string matches one of the strings in
36928d0e36bSThomas Gleixner  * the device's "compatible" property
37028d0e36bSThomas Gleixner  */
37128d0e36bSThomas Gleixner int of_device_is_compatible(const struct device_node *device,
37228d0e36bSThomas Gleixner 		const char *compat)
37328d0e36bSThomas Gleixner {
374d6d3c4e6SThomas Gleixner 	unsigned long flags;
37528d0e36bSThomas Gleixner 	int res;
37628d0e36bSThomas Gleixner 
377d6d3c4e6SThomas Gleixner 	raw_spin_lock_irqsave(&devtree_lock, flags);
37828d0e36bSThomas Gleixner 	res = __of_device_is_compatible(device, compat);
379d6d3c4e6SThomas Gleixner 	raw_spin_unlock_irqrestore(&devtree_lock, flags);
38028d0e36bSThomas Gleixner 	return res;
38128d0e36bSThomas Gleixner }
3820081cbc3SStephen Rothwell EXPORT_SYMBOL(of_device_is_compatible);
383e679c5f4SStephen Rothwell 
384e679c5f4SStephen Rothwell /**
38571a157e8SGrant Likely  * of_machine_is_compatible - Test root of device tree for a given compatible value
3861f43cfb9SGrant Likely  * @compat: compatible string to look for in root node's compatible property.
3871f43cfb9SGrant Likely  *
3881f43cfb9SGrant Likely  * Returns true if the root node has the given value in its
3891f43cfb9SGrant Likely  * compatible property.
3901f43cfb9SGrant Likely  */
39171a157e8SGrant Likely int of_machine_is_compatible(const char *compat)
3921f43cfb9SGrant Likely {
3931f43cfb9SGrant Likely 	struct device_node *root;
3941f43cfb9SGrant Likely 	int rc = 0;
3951f43cfb9SGrant Likely 
3961f43cfb9SGrant Likely 	root = of_find_node_by_path("/");
3971f43cfb9SGrant Likely 	if (root) {
3981f43cfb9SGrant Likely 		rc = of_device_is_compatible(root, compat);
3991f43cfb9SGrant Likely 		of_node_put(root);
4001f43cfb9SGrant Likely 	}
4011f43cfb9SGrant Likely 	return rc;
4021f43cfb9SGrant Likely }
40371a157e8SGrant Likely EXPORT_SYMBOL(of_machine_is_compatible);
4041f43cfb9SGrant Likely 
4051f43cfb9SGrant Likely /**
406c31a0c05SStephen Warren  *  __of_device_is_available - check if a device is available for use
407834d97d4SJosh Boyer  *
408c31a0c05SStephen Warren  *  @device: Node to check for availability, with locks already held
409834d97d4SJosh Boyer  *
410834d97d4SJosh Boyer  *  Returns 1 if the status property is absent or set to "okay" or "ok",
411834d97d4SJosh Boyer  *  0 otherwise
412834d97d4SJosh Boyer  */
413c31a0c05SStephen Warren static int __of_device_is_available(const struct device_node *device)
414834d97d4SJosh Boyer {
415834d97d4SJosh Boyer 	const char *status;
416834d97d4SJosh Boyer 	int statlen;
417834d97d4SJosh Boyer 
41842ccd781SXiubo Li 	if (!device)
41942ccd781SXiubo Li 		return 0;
42042ccd781SXiubo Li 
421c31a0c05SStephen Warren 	status = __of_get_property(device, "status", &statlen);
422834d97d4SJosh Boyer 	if (status == NULL)
423834d97d4SJosh Boyer 		return 1;
424834d97d4SJosh Boyer 
425834d97d4SJosh Boyer 	if (statlen > 0) {
426834d97d4SJosh Boyer 		if (!strcmp(status, "okay") || !strcmp(status, "ok"))
427834d97d4SJosh Boyer 			return 1;
428834d97d4SJosh Boyer 	}
429834d97d4SJosh Boyer 
430834d97d4SJosh Boyer 	return 0;
431834d97d4SJosh Boyer }
432c31a0c05SStephen Warren 
433c31a0c05SStephen Warren /**
434c31a0c05SStephen Warren  *  of_device_is_available - check if a device is available for use
435c31a0c05SStephen Warren  *
436c31a0c05SStephen Warren  *  @device: Node to check for availability
437c31a0c05SStephen Warren  *
438c31a0c05SStephen Warren  *  Returns 1 if the status property is absent or set to "okay" or "ok",
439c31a0c05SStephen Warren  *  0 otherwise
440c31a0c05SStephen Warren  */
441c31a0c05SStephen Warren int of_device_is_available(const struct device_node *device)
442c31a0c05SStephen Warren {
443c31a0c05SStephen Warren 	unsigned long flags;
444c31a0c05SStephen Warren 	int res;
445c31a0c05SStephen Warren 
446c31a0c05SStephen Warren 	raw_spin_lock_irqsave(&devtree_lock, flags);
447c31a0c05SStephen Warren 	res = __of_device_is_available(device);
448c31a0c05SStephen Warren 	raw_spin_unlock_irqrestore(&devtree_lock, flags);
449c31a0c05SStephen Warren 	return res;
450c31a0c05SStephen Warren 
451c31a0c05SStephen Warren }
452834d97d4SJosh Boyer EXPORT_SYMBOL(of_device_is_available);
453834d97d4SJosh Boyer 
454834d97d4SJosh Boyer /**
455e679c5f4SStephen Rothwell  *	of_get_parent - Get a node's parent if any
456e679c5f4SStephen Rothwell  *	@node:	Node to get parent
457e679c5f4SStephen Rothwell  *
458e679c5f4SStephen Rothwell  *	Returns a node pointer with refcount incremented, use
459e679c5f4SStephen Rothwell  *	of_node_put() on it when done.
460e679c5f4SStephen Rothwell  */
461e679c5f4SStephen Rothwell struct device_node *of_get_parent(const struct device_node *node)
462e679c5f4SStephen Rothwell {
463e679c5f4SStephen Rothwell 	struct device_node *np;
464d6d3c4e6SThomas Gleixner 	unsigned long flags;
465e679c5f4SStephen Rothwell 
466e679c5f4SStephen Rothwell 	if (!node)
467e679c5f4SStephen Rothwell 		return NULL;
468e679c5f4SStephen Rothwell 
469d6d3c4e6SThomas Gleixner 	raw_spin_lock_irqsave(&devtree_lock, flags);
470e679c5f4SStephen Rothwell 	np = of_node_get(node->parent);
471d6d3c4e6SThomas Gleixner 	raw_spin_unlock_irqrestore(&devtree_lock, flags);
472e679c5f4SStephen Rothwell 	return np;
473e679c5f4SStephen Rothwell }
474e679c5f4SStephen Rothwell EXPORT_SYMBOL(of_get_parent);
475d1cd355aSStephen Rothwell 
476d1cd355aSStephen Rothwell /**
477f4eb0107SMichael Ellerman  *	of_get_next_parent - Iterate to a node's parent
478f4eb0107SMichael Ellerman  *	@node:	Node to get parent of
479f4eb0107SMichael Ellerman  *
480f4eb0107SMichael Ellerman  * 	This is like of_get_parent() except that it drops the
481f4eb0107SMichael Ellerman  * 	refcount on the passed node, making it suitable for iterating
482f4eb0107SMichael Ellerman  * 	through a node's parents.
483f4eb0107SMichael Ellerman  *
484f4eb0107SMichael Ellerman  *	Returns a node pointer with refcount incremented, use
485f4eb0107SMichael Ellerman  *	of_node_put() on it when done.
486f4eb0107SMichael Ellerman  */
487f4eb0107SMichael Ellerman struct device_node *of_get_next_parent(struct device_node *node)
488f4eb0107SMichael Ellerman {
489f4eb0107SMichael Ellerman 	struct device_node *parent;
490d6d3c4e6SThomas Gleixner 	unsigned long flags;
491f4eb0107SMichael Ellerman 
492f4eb0107SMichael Ellerman 	if (!node)
493f4eb0107SMichael Ellerman 		return NULL;
494f4eb0107SMichael Ellerman 
495d6d3c4e6SThomas Gleixner 	raw_spin_lock_irqsave(&devtree_lock, flags);
496f4eb0107SMichael Ellerman 	parent = of_node_get(node->parent);
497f4eb0107SMichael Ellerman 	of_node_put(node);
498d6d3c4e6SThomas Gleixner 	raw_spin_unlock_irqrestore(&devtree_lock, flags);
499f4eb0107SMichael Ellerman 	return parent;
500f4eb0107SMichael Ellerman }
5016695be68SGuennadi Liakhovetski EXPORT_SYMBOL(of_get_next_parent);
502f4eb0107SMichael Ellerman 
503f4eb0107SMichael Ellerman /**
504d1cd355aSStephen Rothwell  *	of_get_next_child - Iterate a node childs
505d1cd355aSStephen Rothwell  *	@node:	parent node
506d1cd355aSStephen Rothwell  *	@prev:	previous child of the parent node, or NULL to get first
507d1cd355aSStephen Rothwell  *
508d1cd355aSStephen Rothwell  *	Returns a node pointer with refcount incremented, use
509d1cd355aSStephen Rothwell  *	of_node_put() on it when done.
510d1cd355aSStephen Rothwell  */
511d1cd355aSStephen Rothwell struct device_node *of_get_next_child(const struct device_node *node,
512d1cd355aSStephen Rothwell 	struct device_node *prev)
513d1cd355aSStephen Rothwell {
514d1cd355aSStephen Rothwell 	struct device_node *next;
515d6d3c4e6SThomas Gleixner 	unsigned long flags;
516d1cd355aSStephen Rothwell 
517d6d3c4e6SThomas Gleixner 	raw_spin_lock_irqsave(&devtree_lock, flags);
518d1cd355aSStephen Rothwell 	next = prev ? prev->sibling : node->child;
519d1cd355aSStephen Rothwell 	for (; next; next = next->sibling)
520d1cd355aSStephen Rothwell 		if (of_node_get(next))
521d1cd355aSStephen Rothwell 			break;
522d1cd355aSStephen Rothwell 	of_node_put(prev);
523d6d3c4e6SThomas Gleixner 	raw_spin_unlock_irqrestore(&devtree_lock, flags);
524d1cd355aSStephen Rothwell 	return next;
525d1cd355aSStephen Rothwell }
526d1cd355aSStephen Rothwell EXPORT_SYMBOL(of_get_next_child);
5271ef4d424SStephen Rothwell 
5281ef4d424SStephen Rothwell /**
5293296193dSTimur Tabi  *	of_get_next_available_child - Find the next available child node
5303296193dSTimur Tabi  *	@node:	parent node
5313296193dSTimur Tabi  *	@prev:	previous child of the parent node, or NULL to get first
5323296193dSTimur Tabi  *
5333296193dSTimur Tabi  *      This function is like of_get_next_child(), except that it
5343296193dSTimur Tabi  *      automatically skips any disabled nodes (i.e. status = "disabled").
5353296193dSTimur Tabi  */
5363296193dSTimur Tabi struct device_node *of_get_next_available_child(const struct device_node *node,
5373296193dSTimur Tabi 	struct device_node *prev)
5383296193dSTimur Tabi {
5393296193dSTimur Tabi 	struct device_node *next;
540d25d8694SBenjamin Herrenschmidt 	unsigned long flags;
5413296193dSTimur Tabi 
542d25d8694SBenjamin Herrenschmidt 	raw_spin_lock_irqsave(&devtree_lock, flags);
5433296193dSTimur Tabi 	next = prev ? prev->sibling : node->child;
5443296193dSTimur Tabi 	for (; next; next = next->sibling) {
545c31a0c05SStephen Warren 		if (!__of_device_is_available(next))
5463296193dSTimur Tabi 			continue;
5473296193dSTimur Tabi 		if (of_node_get(next))
5483296193dSTimur Tabi 			break;
5493296193dSTimur Tabi 	}
5503296193dSTimur Tabi 	of_node_put(prev);
551d25d8694SBenjamin Herrenschmidt 	raw_spin_unlock_irqrestore(&devtree_lock, flags);
5523296193dSTimur Tabi 	return next;
5533296193dSTimur Tabi }
5543296193dSTimur Tabi EXPORT_SYMBOL(of_get_next_available_child);
5553296193dSTimur Tabi 
5563296193dSTimur Tabi /**
5579c19761aSSrinivas Kandagatla  *	of_get_child_by_name - Find the child node by name for a given parent
5589c19761aSSrinivas Kandagatla  *	@node:	parent node
5599c19761aSSrinivas Kandagatla  *	@name:	child name to look for.
5609c19761aSSrinivas Kandagatla  *
5619c19761aSSrinivas Kandagatla  *      This function looks for child node for given matching name
5629c19761aSSrinivas Kandagatla  *
5639c19761aSSrinivas Kandagatla  *	Returns a node pointer if found, with refcount incremented, use
5649c19761aSSrinivas Kandagatla  *	of_node_put() on it when done.
5659c19761aSSrinivas Kandagatla  *	Returns NULL if node is not found.
5669c19761aSSrinivas Kandagatla  */
5679c19761aSSrinivas Kandagatla struct device_node *of_get_child_by_name(const struct device_node *node,
5689c19761aSSrinivas Kandagatla 				const char *name)
5699c19761aSSrinivas Kandagatla {
5709c19761aSSrinivas Kandagatla 	struct device_node *child;
5719c19761aSSrinivas Kandagatla 
5729c19761aSSrinivas Kandagatla 	for_each_child_of_node(node, child)
5739c19761aSSrinivas Kandagatla 		if (child->name && (of_node_cmp(child->name, name) == 0))
5749c19761aSSrinivas Kandagatla 			break;
5759c19761aSSrinivas Kandagatla 	return child;
5769c19761aSSrinivas Kandagatla }
5779c19761aSSrinivas Kandagatla EXPORT_SYMBOL(of_get_child_by_name);
5789c19761aSSrinivas Kandagatla 
5799c19761aSSrinivas Kandagatla /**
5801ef4d424SStephen Rothwell  *	of_find_node_by_path - Find a node matching a full OF path
5811ef4d424SStephen Rothwell  *	@path:	The full path to match
5821ef4d424SStephen Rothwell  *
5831ef4d424SStephen Rothwell  *	Returns a node pointer with refcount incremented, use
5841ef4d424SStephen Rothwell  *	of_node_put() on it when done.
5851ef4d424SStephen Rothwell  */
5861ef4d424SStephen Rothwell struct device_node *of_find_node_by_path(const char *path)
5871ef4d424SStephen Rothwell {
588465aac6dSRandy Dunlap 	struct device_node *np = of_allnodes;
589d6d3c4e6SThomas Gleixner 	unsigned long flags;
5901ef4d424SStephen Rothwell 
591d6d3c4e6SThomas Gleixner 	raw_spin_lock_irqsave(&devtree_lock, flags);
5921ef4d424SStephen Rothwell 	for (; np; np = np->allnext) {
5931ef4d424SStephen Rothwell 		if (np->full_name && (of_node_cmp(np->full_name, path) == 0)
5941ef4d424SStephen Rothwell 		    && of_node_get(np))
5951ef4d424SStephen Rothwell 			break;
5961ef4d424SStephen Rothwell 	}
597d6d3c4e6SThomas Gleixner 	raw_spin_unlock_irqrestore(&devtree_lock, flags);
5981ef4d424SStephen Rothwell 	return np;
5991ef4d424SStephen Rothwell }
6001ef4d424SStephen Rothwell EXPORT_SYMBOL(of_find_node_by_path);
6011ef4d424SStephen Rothwell 
6021ef4d424SStephen Rothwell /**
6031ef4d424SStephen Rothwell  *	of_find_node_by_name - Find a node by its "name" property
6041ef4d424SStephen Rothwell  *	@from:	The node to start searching from or NULL, the node
6051ef4d424SStephen Rothwell  *		you pass will not be searched, only the next one
6061ef4d424SStephen Rothwell  *		will; typically, you pass what the previous call
6071ef4d424SStephen Rothwell  *		returned. of_node_put() will be called on it
6081ef4d424SStephen Rothwell  *	@name:	The name string to match against
6091ef4d424SStephen Rothwell  *
6101ef4d424SStephen Rothwell  *	Returns a node pointer with refcount incremented, use
6111ef4d424SStephen Rothwell  *	of_node_put() on it when done.
6121ef4d424SStephen Rothwell  */
6131ef4d424SStephen Rothwell struct device_node *of_find_node_by_name(struct device_node *from,
6141ef4d424SStephen Rothwell 	const char *name)
6151ef4d424SStephen Rothwell {
6161ef4d424SStephen Rothwell 	struct device_node *np;
617d6d3c4e6SThomas Gleixner 	unsigned long flags;
6181ef4d424SStephen Rothwell 
619d6d3c4e6SThomas Gleixner 	raw_spin_lock_irqsave(&devtree_lock, flags);
620465aac6dSRandy Dunlap 	np = from ? from->allnext : of_allnodes;
6211ef4d424SStephen Rothwell 	for (; np; np = np->allnext)
6221ef4d424SStephen Rothwell 		if (np->name && (of_node_cmp(np->name, name) == 0)
6231ef4d424SStephen Rothwell 		    && of_node_get(np))
6241ef4d424SStephen Rothwell 			break;
6251ef4d424SStephen Rothwell 	of_node_put(from);
626d6d3c4e6SThomas Gleixner 	raw_spin_unlock_irqrestore(&devtree_lock, flags);
6271ef4d424SStephen Rothwell 	return np;
6281ef4d424SStephen Rothwell }
6291ef4d424SStephen Rothwell EXPORT_SYMBOL(of_find_node_by_name);
6301ef4d424SStephen Rothwell 
6311ef4d424SStephen Rothwell /**
6321ef4d424SStephen Rothwell  *	of_find_node_by_type - Find a node by its "device_type" property
6331ef4d424SStephen Rothwell  *	@from:	The node to start searching from, or NULL to start searching
6341ef4d424SStephen Rothwell  *		the entire device tree. The node you pass will not be
6351ef4d424SStephen Rothwell  *		searched, only the next one will; typically, you pass
6361ef4d424SStephen Rothwell  *		what the previous call returned. of_node_put() will be
6371ef4d424SStephen Rothwell  *		called on from for you.
6381ef4d424SStephen Rothwell  *	@type:	The type string to match against
6391ef4d424SStephen Rothwell  *
6401ef4d424SStephen Rothwell  *	Returns a node pointer with refcount incremented, use
6411ef4d424SStephen Rothwell  *	of_node_put() on it when done.
6421ef4d424SStephen Rothwell  */
6431ef4d424SStephen Rothwell struct device_node *of_find_node_by_type(struct device_node *from,
6441ef4d424SStephen Rothwell 	const char *type)
6451ef4d424SStephen Rothwell {
6461ef4d424SStephen Rothwell 	struct device_node *np;
647d6d3c4e6SThomas Gleixner 	unsigned long flags;
6481ef4d424SStephen Rothwell 
649d6d3c4e6SThomas Gleixner 	raw_spin_lock_irqsave(&devtree_lock, flags);
650465aac6dSRandy Dunlap 	np = from ? from->allnext : of_allnodes;
6511ef4d424SStephen Rothwell 	for (; np; np = np->allnext)
6521ef4d424SStephen Rothwell 		if (np->type && (of_node_cmp(np->type, type) == 0)
6531ef4d424SStephen Rothwell 		    && of_node_get(np))
6541ef4d424SStephen Rothwell 			break;
6551ef4d424SStephen Rothwell 	of_node_put(from);
656d6d3c4e6SThomas Gleixner 	raw_spin_unlock_irqrestore(&devtree_lock, flags);
6571ef4d424SStephen Rothwell 	return np;
6581ef4d424SStephen Rothwell }
6591ef4d424SStephen Rothwell EXPORT_SYMBOL(of_find_node_by_type);
6601ef4d424SStephen Rothwell 
6611ef4d424SStephen Rothwell /**
6621ef4d424SStephen Rothwell  *	of_find_compatible_node - Find a node based on type and one of the
6631ef4d424SStephen Rothwell  *                                tokens in its "compatible" property
6641ef4d424SStephen Rothwell  *	@from:		The node to start searching from or NULL, the node
6651ef4d424SStephen Rothwell  *			you pass will not be searched, only the next one
6661ef4d424SStephen Rothwell  *			will; typically, you pass what the previous call
6671ef4d424SStephen Rothwell  *			returned. of_node_put() will be called on it
6681ef4d424SStephen Rothwell  *	@type:		The type string to match "device_type" or NULL to ignore
6691ef4d424SStephen Rothwell  *	@compatible:	The string to match to one of the tokens in the device
6701ef4d424SStephen Rothwell  *			"compatible" list.
6711ef4d424SStephen Rothwell  *
6721ef4d424SStephen Rothwell  *	Returns a node pointer with refcount incremented, use
6731ef4d424SStephen Rothwell  *	of_node_put() on it when done.
6741ef4d424SStephen Rothwell  */
6751ef4d424SStephen Rothwell struct device_node *of_find_compatible_node(struct device_node *from,
6761ef4d424SStephen Rothwell 	const char *type, const char *compatible)
6771ef4d424SStephen Rothwell {
6781ef4d424SStephen Rothwell 	struct device_node *np;
679d6d3c4e6SThomas Gleixner 	unsigned long flags;
6801ef4d424SStephen Rothwell 
681d6d3c4e6SThomas Gleixner 	raw_spin_lock_irqsave(&devtree_lock, flags);
682465aac6dSRandy Dunlap 	np = from ? from->allnext : of_allnodes;
6831ef4d424SStephen Rothwell 	for (; np; np = np->allnext) {
6841ef4d424SStephen Rothwell 		if (type
6851ef4d424SStephen Rothwell 		    && !(np->type && (of_node_cmp(np->type, type) == 0)))
6861ef4d424SStephen Rothwell 			continue;
68728d0e36bSThomas Gleixner 		if (__of_device_is_compatible(np, compatible) &&
68828d0e36bSThomas Gleixner 		    of_node_get(np))
6891ef4d424SStephen Rothwell 			break;
6901ef4d424SStephen Rothwell 	}
6911ef4d424SStephen Rothwell 	of_node_put(from);
692d6d3c4e6SThomas Gleixner 	raw_spin_unlock_irqrestore(&devtree_lock, flags);
6931ef4d424SStephen Rothwell 	return np;
6941ef4d424SStephen Rothwell }
6951ef4d424SStephen Rothwell EXPORT_SYMBOL(of_find_compatible_node);
696283029d1SGrant Likely 
697283029d1SGrant Likely /**
6981e291b14SMichael Ellerman  *	of_find_node_with_property - Find a node which has a property with
6991e291b14SMichael Ellerman  *                                   the given name.
7001e291b14SMichael Ellerman  *	@from:		The node to start searching from or NULL, the node
7011e291b14SMichael Ellerman  *			you pass will not be searched, only the next one
7021e291b14SMichael Ellerman  *			will; typically, you pass what the previous call
7031e291b14SMichael Ellerman  *			returned. of_node_put() will be called on it
7041e291b14SMichael Ellerman  *	@prop_name:	The name of the property to look for.
7051e291b14SMichael Ellerman  *
7061e291b14SMichael Ellerman  *	Returns a node pointer with refcount incremented, use
7071e291b14SMichael Ellerman  *	of_node_put() on it when done.
7081e291b14SMichael Ellerman  */
7091e291b14SMichael Ellerman struct device_node *of_find_node_with_property(struct device_node *from,
7101e291b14SMichael Ellerman 	const char *prop_name)
7111e291b14SMichael Ellerman {
7121e291b14SMichael Ellerman 	struct device_node *np;
7131e291b14SMichael Ellerman 	struct property *pp;
714d6d3c4e6SThomas Gleixner 	unsigned long flags;
7151e291b14SMichael Ellerman 
716d6d3c4e6SThomas Gleixner 	raw_spin_lock_irqsave(&devtree_lock, flags);
717465aac6dSRandy Dunlap 	np = from ? from->allnext : of_allnodes;
7181e291b14SMichael Ellerman 	for (; np; np = np->allnext) {
719a3a7cab1SSachin Kamat 		for (pp = np->properties; pp; pp = pp->next) {
7201e291b14SMichael Ellerman 			if (of_prop_cmp(pp->name, prop_name) == 0) {
7211e291b14SMichael Ellerman 				of_node_get(np);
7221e291b14SMichael Ellerman 				goto out;
7231e291b14SMichael Ellerman 			}
7241e291b14SMichael Ellerman 		}
7251e291b14SMichael Ellerman 	}
7261e291b14SMichael Ellerman out:
7271e291b14SMichael Ellerman 	of_node_put(from);
728d6d3c4e6SThomas Gleixner 	raw_spin_unlock_irqrestore(&devtree_lock, flags);
7291e291b14SMichael Ellerman 	return np;
7301e291b14SMichael Ellerman }
7311e291b14SMichael Ellerman EXPORT_SYMBOL(of_find_node_with_property);
7321e291b14SMichael Ellerman 
73328d0e36bSThomas Gleixner static
73428d0e36bSThomas Gleixner const struct of_device_id *__of_match_node(const struct of_device_id *matches,
735283029d1SGrant Likely 					   const struct device_node *node)
736283029d1SGrant Likely {
73710535314SSebastian Hesselbarth 	const char *cp;
73810535314SSebastian Hesselbarth 	int cplen, l;
73910535314SSebastian Hesselbarth 
740a52f07ecSGrant Likely 	if (!matches)
741a52f07ecSGrant Likely 		return NULL;
742a52f07ecSGrant Likely 
74310535314SSebastian Hesselbarth 	cp = __of_get_property(node, "compatible", &cplen);
74410535314SSebastian Hesselbarth 	do {
74510535314SSebastian Hesselbarth 		const struct of_device_id *m = matches;
74610535314SSebastian Hesselbarth 
74710535314SSebastian Hesselbarth 		/* Check against matches with current compatible string */
74810535314SSebastian Hesselbarth 		while (m->name[0] || m->type[0] || m->compatible[0]) {
749283029d1SGrant Likely 			int match = 1;
75010535314SSebastian Hesselbarth 			if (m->name[0])
751283029d1SGrant Likely 				match &= node->name
75210535314SSebastian Hesselbarth 					&& !strcmp(m->name, node->name);
75310535314SSebastian Hesselbarth 			if (m->type[0])
754283029d1SGrant Likely 				match &= node->type
75510535314SSebastian Hesselbarth 					&& !strcmp(m->type, node->type);
75610535314SSebastian Hesselbarth 			if (m->compatible[0])
75710535314SSebastian Hesselbarth 				match &= cp
75810535314SSebastian Hesselbarth 					&& !of_compat_cmp(m->compatible, cp,
75910535314SSebastian Hesselbarth 							strlen(m->compatible));
760bc51b0c2SLinus Torvalds 			if (match)
76110535314SSebastian Hesselbarth 				return m;
76210535314SSebastian Hesselbarth 			m++;
763283029d1SGrant Likely 		}
76410535314SSebastian Hesselbarth 
76510535314SSebastian Hesselbarth 		/* Get node's next compatible string */
76610535314SSebastian Hesselbarth 		if (cp) {
76710535314SSebastian Hesselbarth 			l = strlen(cp) + 1;
76810535314SSebastian Hesselbarth 			cp += l;
76910535314SSebastian Hesselbarth 			cplen -= l;
77010535314SSebastian Hesselbarth 		}
77110535314SSebastian Hesselbarth 	} while (cp && (cplen > 0));
77210535314SSebastian Hesselbarth 
773283029d1SGrant Likely 	return NULL;
774283029d1SGrant Likely }
77528d0e36bSThomas Gleixner 
77628d0e36bSThomas Gleixner /**
77728d0e36bSThomas Gleixner  * of_match_node - Tell if an device_node has a matching of_match structure
77828d0e36bSThomas Gleixner  *	@matches:	array of of device match structures to search in
77928d0e36bSThomas Gleixner  *	@node:		the of device structure to match against
78028d0e36bSThomas Gleixner  *
78110535314SSebastian Hesselbarth  *	Low level utility function used by device matching. Matching order
78210535314SSebastian Hesselbarth  *	is to compare each of the node's compatibles with all given matches
78310535314SSebastian Hesselbarth  *	first. This implies node's compatible is sorted from specific to
78410535314SSebastian Hesselbarth  *	generic while matches can be in any order.
78528d0e36bSThomas Gleixner  */
78628d0e36bSThomas Gleixner const struct of_device_id *of_match_node(const struct of_device_id *matches,
78728d0e36bSThomas Gleixner 					 const struct device_node *node)
78828d0e36bSThomas Gleixner {
78928d0e36bSThomas Gleixner 	const struct of_device_id *match;
790d6d3c4e6SThomas Gleixner 	unsigned long flags;
79128d0e36bSThomas Gleixner 
792d6d3c4e6SThomas Gleixner 	raw_spin_lock_irqsave(&devtree_lock, flags);
79328d0e36bSThomas Gleixner 	match = __of_match_node(matches, node);
794d6d3c4e6SThomas Gleixner 	raw_spin_unlock_irqrestore(&devtree_lock, flags);
79528d0e36bSThomas Gleixner 	return match;
79628d0e36bSThomas Gleixner }
797283029d1SGrant Likely EXPORT_SYMBOL(of_match_node);
798283029d1SGrant Likely 
799283029d1SGrant Likely /**
80050c8af4cSStephen Warren  *	of_find_matching_node_and_match - Find a node based on an of_device_id
80150c8af4cSStephen Warren  *					  match table.
802283029d1SGrant Likely  *	@from:		The node to start searching from or NULL, the node
803283029d1SGrant Likely  *			you pass will not be searched, only the next one
804283029d1SGrant Likely  *			will; typically, you pass what the previous call
805283029d1SGrant Likely  *			returned. of_node_put() will be called on it
806283029d1SGrant Likely  *	@matches:	array of of device match structures to search in
80750c8af4cSStephen Warren  *	@match		Updated to point at the matches entry which matched
808283029d1SGrant Likely  *
809283029d1SGrant Likely  *	Returns a node pointer with refcount incremented, use
810283029d1SGrant Likely  *	of_node_put() on it when done.
811283029d1SGrant Likely  */
81250c8af4cSStephen Warren struct device_node *of_find_matching_node_and_match(struct device_node *from,
81350c8af4cSStephen Warren 					const struct of_device_id *matches,
81450c8af4cSStephen Warren 					const struct of_device_id **match)
815283029d1SGrant Likely {
816283029d1SGrant Likely 	struct device_node *np;
817dc71bcf1SThomas Abraham 	const struct of_device_id *m;
818d6d3c4e6SThomas Gleixner 	unsigned long flags;
819283029d1SGrant Likely 
82050c8af4cSStephen Warren 	if (match)
82150c8af4cSStephen Warren 		*match = NULL;
82250c8af4cSStephen Warren 
823d6d3c4e6SThomas Gleixner 	raw_spin_lock_irqsave(&devtree_lock, flags);
824465aac6dSRandy Dunlap 	np = from ? from->allnext : of_allnodes;
825283029d1SGrant Likely 	for (; np; np = np->allnext) {
82628d0e36bSThomas Gleixner 		m = __of_match_node(matches, np);
827dc71bcf1SThomas Abraham 		if (m && of_node_get(np)) {
82850c8af4cSStephen Warren 			if (match)
829dc71bcf1SThomas Abraham 				*match = m;
830283029d1SGrant Likely 			break;
831283029d1SGrant Likely 		}
83250c8af4cSStephen Warren 	}
833283029d1SGrant Likely 	of_node_put(from);
834d6d3c4e6SThomas Gleixner 	raw_spin_unlock_irqrestore(&devtree_lock, flags);
835283029d1SGrant Likely 	return np;
836283029d1SGrant Likely }
83780c2022eSGrant Likely EXPORT_SYMBOL(of_find_matching_node_and_match);
8383f07af49SGrant Likely 
8393f07af49SGrant Likely /**
8403f07af49SGrant Likely  * of_modalias_node - Lookup appropriate modalias for a device node
8413f07af49SGrant Likely  * @node:	pointer to a device tree node
8423f07af49SGrant Likely  * @modalias:	Pointer to buffer that modalias value will be copied into
8433f07af49SGrant Likely  * @len:	Length of modalias value
8443f07af49SGrant Likely  *
8452ffe8c5fSGrant Likely  * Based on the value of the compatible property, this routine will attempt
8462ffe8c5fSGrant Likely  * to choose an appropriate modalias value for a particular device tree node.
8472ffe8c5fSGrant Likely  * It does this by stripping the manufacturer prefix (as delimited by a ',')
8482ffe8c5fSGrant Likely  * from the first entry in the compatible list property.
8493f07af49SGrant Likely  *
8502ffe8c5fSGrant Likely  * This routine returns 0 on success, <0 on failure.
8513f07af49SGrant Likely  */
8523f07af49SGrant Likely int of_modalias_node(struct device_node *node, char *modalias, int len)
8533f07af49SGrant Likely {
8542ffe8c5fSGrant Likely 	const char *compatible, *p;
8552ffe8c5fSGrant Likely 	int cplen;
8563f07af49SGrant Likely 
8573f07af49SGrant Likely 	compatible = of_get_property(node, "compatible", &cplen);
8582ffe8c5fSGrant Likely 	if (!compatible || strlen(compatible) > cplen)
8593f07af49SGrant Likely 		return -ENODEV;
8603f07af49SGrant Likely 	p = strchr(compatible, ',');
8612ffe8c5fSGrant Likely 	strlcpy(modalias, p ? p + 1 : compatible, len);
8623f07af49SGrant Likely 	return 0;
8633f07af49SGrant Likely }
8643f07af49SGrant Likely EXPORT_SYMBOL_GPL(of_modalias_node);
8653f07af49SGrant Likely 
86664b60e09SAnton Vorontsov /**
86789751a7cSJeremy Kerr  * of_find_node_by_phandle - Find a node given a phandle
86889751a7cSJeremy Kerr  * @handle:	phandle of the node to find
86989751a7cSJeremy Kerr  *
87089751a7cSJeremy Kerr  * Returns a node pointer with refcount incremented, use
87189751a7cSJeremy Kerr  * of_node_put() on it when done.
87289751a7cSJeremy Kerr  */
87389751a7cSJeremy Kerr struct device_node *of_find_node_by_phandle(phandle handle)
87489751a7cSJeremy Kerr {
87589751a7cSJeremy Kerr 	struct device_node *np;
876d25d8694SBenjamin Herrenschmidt 	unsigned long flags;
87789751a7cSJeremy Kerr 
878d25d8694SBenjamin Herrenschmidt 	raw_spin_lock_irqsave(&devtree_lock, flags);
879465aac6dSRandy Dunlap 	for (np = of_allnodes; np; np = np->allnext)
88089751a7cSJeremy Kerr 		if (np->phandle == handle)
88189751a7cSJeremy Kerr 			break;
88289751a7cSJeremy Kerr 	of_node_get(np);
883d25d8694SBenjamin Herrenschmidt 	raw_spin_unlock_irqrestore(&devtree_lock, flags);
88489751a7cSJeremy Kerr 	return np;
88589751a7cSJeremy Kerr }
88689751a7cSJeremy Kerr EXPORT_SYMBOL(of_find_node_by_phandle);
88789751a7cSJeremy Kerr 
88889751a7cSJeremy Kerr /**
889daeec1f0STony Prisk  * of_find_property_value_of_size
890daeec1f0STony Prisk  *
891daeec1f0STony Prisk  * @np:		device node from which the property value is to be read.
892daeec1f0STony Prisk  * @propname:	name of the property to be searched.
893daeec1f0STony Prisk  * @len:	requested length of property value
894daeec1f0STony Prisk  *
895daeec1f0STony Prisk  * Search for a property in a device node and valid the requested size.
896daeec1f0STony Prisk  * Returns the property value on success, -EINVAL if the property does not
897daeec1f0STony Prisk  *  exist, -ENODATA if property does not have a value, and -EOVERFLOW if the
898daeec1f0STony Prisk  * property data isn't large enough.
899daeec1f0STony Prisk  *
900daeec1f0STony Prisk  */
901daeec1f0STony Prisk static void *of_find_property_value_of_size(const struct device_node *np,
902daeec1f0STony Prisk 			const char *propname, u32 len)
903daeec1f0STony Prisk {
904daeec1f0STony Prisk 	struct property *prop = of_find_property(np, propname, NULL);
905daeec1f0STony Prisk 
906daeec1f0STony Prisk 	if (!prop)
907daeec1f0STony Prisk 		return ERR_PTR(-EINVAL);
908daeec1f0STony Prisk 	if (!prop->value)
909daeec1f0STony Prisk 		return ERR_PTR(-ENODATA);
910daeec1f0STony Prisk 	if (len > prop->length)
911daeec1f0STony Prisk 		return ERR_PTR(-EOVERFLOW);
912daeec1f0STony Prisk 
913daeec1f0STony Prisk 	return prop->value;
914daeec1f0STony Prisk }
915daeec1f0STony Prisk 
916daeec1f0STony Prisk /**
9173daf3726STony Prisk  * of_property_read_u32_index - Find and read a u32 from a multi-value property.
9183daf3726STony Prisk  *
9193daf3726STony Prisk  * @np:		device node from which the property value is to be read.
9203daf3726STony Prisk  * @propname:	name of the property to be searched.
9213daf3726STony Prisk  * @index:	index of the u32 in the list of values
9223daf3726STony Prisk  * @out_value:	pointer to return value, modified only if no error.
9233daf3726STony Prisk  *
9243daf3726STony Prisk  * Search for a property in a device node and read nth 32-bit value from
9253daf3726STony Prisk  * it. Returns 0 on success, -EINVAL if the property does not exist,
9263daf3726STony Prisk  * -ENODATA if property does not have a value, and -EOVERFLOW if the
9273daf3726STony Prisk  * property data isn't large enough.
9283daf3726STony Prisk  *
9293daf3726STony Prisk  * The out_value is modified only if a valid u32 value can be decoded.
9303daf3726STony Prisk  */
9313daf3726STony Prisk int of_property_read_u32_index(const struct device_node *np,
9323daf3726STony Prisk 				       const char *propname,
9333daf3726STony Prisk 				       u32 index, u32 *out_value)
9343daf3726STony Prisk {
935daeec1f0STony Prisk 	const u32 *val = of_find_property_value_of_size(np, propname,
936daeec1f0STony Prisk 					((index + 1) * sizeof(*out_value)));
9373daf3726STony Prisk 
938daeec1f0STony Prisk 	if (IS_ERR(val))
939daeec1f0STony Prisk 		return PTR_ERR(val);
9403daf3726STony Prisk 
941daeec1f0STony Prisk 	*out_value = be32_to_cpup(((__be32 *)val) + index);
9423daf3726STony Prisk 	return 0;
9433daf3726STony Prisk }
9443daf3726STony Prisk EXPORT_SYMBOL_GPL(of_property_read_u32_index);
9453daf3726STony Prisk 
9463daf3726STony Prisk /**
947be193249SViresh Kumar  * of_property_read_u8_array - Find and read an array of u8 from a property.
948be193249SViresh Kumar  *
949be193249SViresh Kumar  * @np:		device node from which the property value is to be read.
950be193249SViresh Kumar  * @propname:	name of the property to be searched.
951792efb84SLad, Prabhakar  * @out_values:	pointer to return value, modified only if return value is 0.
952be193249SViresh Kumar  * @sz:		number of array elements to read
953be193249SViresh Kumar  *
954be193249SViresh Kumar  * Search for a property in a device node and read 8-bit value(s) from
955be193249SViresh Kumar  * it. Returns 0 on success, -EINVAL if the property does not exist,
956be193249SViresh Kumar  * -ENODATA if property does not have a value, and -EOVERFLOW if the
957be193249SViresh Kumar  * property data isn't large enough.
958be193249SViresh Kumar  *
959be193249SViresh Kumar  * dts entry of array should be like:
960be193249SViresh Kumar  *	property = /bits/ 8 <0x50 0x60 0x70>;
961be193249SViresh Kumar  *
962792efb84SLad, Prabhakar  * The out_values is modified only if a valid u8 value can be decoded.
963be193249SViresh Kumar  */
964be193249SViresh Kumar int of_property_read_u8_array(const struct device_node *np,
965be193249SViresh Kumar 			const char *propname, u8 *out_values, size_t sz)
966be193249SViresh Kumar {
967daeec1f0STony Prisk 	const u8 *val = of_find_property_value_of_size(np, propname,
968daeec1f0STony Prisk 						(sz * sizeof(*out_values)));
969be193249SViresh Kumar 
970daeec1f0STony Prisk 	if (IS_ERR(val))
971daeec1f0STony Prisk 		return PTR_ERR(val);
972be193249SViresh Kumar 
973be193249SViresh Kumar 	while (sz--)
974be193249SViresh Kumar 		*out_values++ = *val++;
975be193249SViresh Kumar 	return 0;
976be193249SViresh Kumar }
977be193249SViresh Kumar EXPORT_SYMBOL_GPL(of_property_read_u8_array);
978be193249SViresh Kumar 
979be193249SViresh Kumar /**
980be193249SViresh Kumar  * of_property_read_u16_array - Find and read an array of u16 from a property.
981be193249SViresh Kumar  *
982be193249SViresh Kumar  * @np:		device node from which the property value is to be read.
983be193249SViresh Kumar  * @propname:	name of the property to be searched.
984792efb84SLad, Prabhakar  * @out_values:	pointer to return value, modified only if return value is 0.
985be193249SViresh Kumar  * @sz:		number of array elements to read
986be193249SViresh Kumar  *
987be193249SViresh Kumar  * Search for a property in a device node and read 16-bit value(s) from
988be193249SViresh Kumar  * it. Returns 0 on success, -EINVAL if the property does not exist,
989be193249SViresh Kumar  * -ENODATA if property does not have a value, and -EOVERFLOW if the
990be193249SViresh Kumar  * property data isn't large enough.
991be193249SViresh Kumar  *
992be193249SViresh Kumar  * dts entry of array should be like:
993be193249SViresh Kumar  *	property = /bits/ 16 <0x5000 0x6000 0x7000>;
994be193249SViresh Kumar  *
995792efb84SLad, Prabhakar  * The out_values is modified only if a valid u16 value can be decoded.
996be193249SViresh Kumar  */
997be193249SViresh Kumar int of_property_read_u16_array(const struct device_node *np,
998be193249SViresh Kumar 			const char *propname, u16 *out_values, size_t sz)
999be193249SViresh Kumar {
1000daeec1f0STony Prisk 	const __be16 *val = of_find_property_value_of_size(np, propname,
1001daeec1f0STony Prisk 						(sz * sizeof(*out_values)));
1002be193249SViresh Kumar 
1003daeec1f0STony Prisk 	if (IS_ERR(val))
1004daeec1f0STony Prisk 		return PTR_ERR(val);
1005be193249SViresh Kumar 
1006be193249SViresh Kumar 	while (sz--)
1007be193249SViresh Kumar 		*out_values++ = be16_to_cpup(val++);
1008be193249SViresh Kumar 	return 0;
1009be193249SViresh Kumar }
1010be193249SViresh Kumar EXPORT_SYMBOL_GPL(of_property_read_u16_array);
1011be193249SViresh Kumar 
1012be193249SViresh Kumar /**
10130e373639SRob Herring  * of_property_read_u32_array - Find and read an array of 32 bit integers
10140e373639SRob Herring  * from a property.
10150e373639SRob Herring  *
1016a3b85363SThomas Abraham  * @np:		device node from which the property value is to be read.
1017a3b85363SThomas Abraham  * @propname:	name of the property to be searched.
1018792efb84SLad, Prabhakar  * @out_values:	pointer to return value, modified only if return value is 0.
1019be193249SViresh Kumar  * @sz:		number of array elements to read
1020a3b85363SThomas Abraham  *
10210e373639SRob Herring  * Search for a property in a device node and read 32-bit value(s) from
1022a3b85363SThomas Abraham  * it. Returns 0 on success, -EINVAL if the property does not exist,
1023a3b85363SThomas Abraham  * -ENODATA if property does not have a value, and -EOVERFLOW if the
1024a3b85363SThomas Abraham  * property data isn't large enough.
1025a3b85363SThomas Abraham  *
1026792efb84SLad, Prabhakar  * The out_values is modified only if a valid u32 value can be decoded.
1027a3b85363SThomas Abraham  */
1028aac285c6SJamie Iles int of_property_read_u32_array(const struct device_node *np,
1029aac285c6SJamie Iles 			       const char *propname, u32 *out_values,
1030aac285c6SJamie Iles 			       size_t sz)
1031a3b85363SThomas Abraham {
1032daeec1f0STony Prisk 	const __be32 *val = of_find_property_value_of_size(np, propname,
1033daeec1f0STony Prisk 						(sz * sizeof(*out_values)));
1034a3b85363SThomas Abraham 
1035daeec1f0STony Prisk 	if (IS_ERR(val))
1036daeec1f0STony Prisk 		return PTR_ERR(val);
10370e373639SRob Herring 
10380e373639SRob Herring 	while (sz--)
10390e373639SRob Herring 		*out_values++ = be32_to_cpup(val++);
1040a3b85363SThomas Abraham 	return 0;
1041a3b85363SThomas Abraham }
10420e373639SRob Herring EXPORT_SYMBOL_GPL(of_property_read_u32_array);
1043a3b85363SThomas Abraham 
1044a3b85363SThomas Abraham /**
10454cd7f7a3SJamie Iles  * of_property_read_u64 - Find and read a 64 bit integer from a property
10464cd7f7a3SJamie Iles  * @np:		device node from which the property value is to be read.
10474cd7f7a3SJamie Iles  * @propname:	name of the property to be searched.
10484cd7f7a3SJamie Iles  * @out_value:	pointer to return value, modified only if return value is 0.
10494cd7f7a3SJamie Iles  *
10504cd7f7a3SJamie Iles  * Search for a property in a device node and read a 64-bit value from
10514cd7f7a3SJamie Iles  * it. Returns 0 on success, -EINVAL if the property does not exist,
10524cd7f7a3SJamie Iles  * -ENODATA if property does not have a value, and -EOVERFLOW if the
10534cd7f7a3SJamie Iles  * property data isn't large enough.
10544cd7f7a3SJamie Iles  *
10554cd7f7a3SJamie Iles  * The out_value is modified only if a valid u64 value can be decoded.
10564cd7f7a3SJamie Iles  */
10574cd7f7a3SJamie Iles int of_property_read_u64(const struct device_node *np, const char *propname,
10584cd7f7a3SJamie Iles 			 u64 *out_value)
10594cd7f7a3SJamie Iles {
1060daeec1f0STony Prisk 	const __be32 *val = of_find_property_value_of_size(np, propname,
1061daeec1f0STony Prisk 						sizeof(*out_value));
10624cd7f7a3SJamie Iles 
1063daeec1f0STony Prisk 	if (IS_ERR(val))
1064daeec1f0STony Prisk 		return PTR_ERR(val);
1065daeec1f0STony Prisk 
1066daeec1f0STony Prisk 	*out_value = of_read_number(val, 2);
10674cd7f7a3SJamie Iles 	return 0;
10684cd7f7a3SJamie Iles }
10694cd7f7a3SJamie Iles EXPORT_SYMBOL_GPL(of_property_read_u64);
10704cd7f7a3SJamie Iles 
10714cd7f7a3SJamie Iles /**
1072a3b85363SThomas Abraham  * of_property_read_string - Find and read a string from a property
1073a3b85363SThomas Abraham  * @np:		device node from which the property value is to be read.
1074a3b85363SThomas Abraham  * @propname:	name of the property to be searched.
1075a3b85363SThomas Abraham  * @out_string:	pointer to null terminated return string, modified only if
1076a3b85363SThomas Abraham  *		return value is 0.
1077a3b85363SThomas Abraham  *
1078a3b85363SThomas Abraham  * Search for a property in a device tree node and retrieve a null
1079a3b85363SThomas Abraham  * terminated string value (pointer to data, not a copy). Returns 0 on
1080a3b85363SThomas Abraham  * success, -EINVAL if the property does not exist, -ENODATA if property
1081a3b85363SThomas Abraham  * does not have a value, and -EILSEQ if the string is not null-terminated
1082a3b85363SThomas Abraham  * within the length of the property data.
1083a3b85363SThomas Abraham  *
1084a3b85363SThomas Abraham  * The out_string pointer is modified only if a valid string can be decoded.
1085a3b85363SThomas Abraham  */
1086aac285c6SJamie Iles int of_property_read_string(struct device_node *np, const char *propname,
1087f09bc831SShawn Guo 				const char **out_string)
1088a3b85363SThomas Abraham {
1089a3b85363SThomas Abraham 	struct property *prop = of_find_property(np, propname, NULL);
1090a3b85363SThomas Abraham 	if (!prop)
1091a3b85363SThomas Abraham 		return -EINVAL;
1092a3b85363SThomas Abraham 	if (!prop->value)
1093a3b85363SThomas Abraham 		return -ENODATA;
1094a3b85363SThomas Abraham 	if (strnlen(prop->value, prop->length) >= prop->length)
1095a3b85363SThomas Abraham 		return -EILSEQ;
1096a3b85363SThomas Abraham 	*out_string = prop->value;
1097a3b85363SThomas Abraham 	return 0;
1098a3b85363SThomas Abraham }
1099a3b85363SThomas Abraham EXPORT_SYMBOL_GPL(of_property_read_string);
1100a3b85363SThomas Abraham 
1101a3b85363SThomas Abraham /**
11024fcd15a0SBenoit Cousson  * of_property_read_string_index - Find and read a string from a multiple
11034fcd15a0SBenoit Cousson  * strings property.
11044fcd15a0SBenoit Cousson  * @np:		device node from which the property value is to be read.
11054fcd15a0SBenoit Cousson  * @propname:	name of the property to be searched.
11064fcd15a0SBenoit Cousson  * @index:	index of the string in the list of strings
11074fcd15a0SBenoit Cousson  * @out_string:	pointer to null terminated return string, modified only if
11084fcd15a0SBenoit Cousson  *		return value is 0.
11094fcd15a0SBenoit Cousson  *
11104fcd15a0SBenoit Cousson  * Search for a property in a device tree node and retrieve a null
11114fcd15a0SBenoit Cousson  * terminated string value (pointer to data, not a copy) in the list of strings
11124fcd15a0SBenoit Cousson  * contained in that property.
11134fcd15a0SBenoit Cousson  * Returns 0 on success, -EINVAL if the property does not exist, -ENODATA if
11144fcd15a0SBenoit Cousson  * property does not have a value, and -EILSEQ if the string is not
11154fcd15a0SBenoit Cousson  * null-terminated within the length of the property data.
11164fcd15a0SBenoit Cousson  *
11174fcd15a0SBenoit Cousson  * The out_string pointer is modified only if a valid string can be decoded.
11184fcd15a0SBenoit Cousson  */
11194fcd15a0SBenoit Cousson int of_property_read_string_index(struct device_node *np, const char *propname,
11204fcd15a0SBenoit Cousson 				  int index, const char **output)
11214fcd15a0SBenoit Cousson {
11224fcd15a0SBenoit Cousson 	struct property *prop = of_find_property(np, propname, NULL);
11234fcd15a0SBenoit Cousson 	int i = 0;
11244fcd15a0SBenoit Cousson 	size_t l = 0, total = 0;
11254fcd15a0SBenoit Cousson 	const char *p;
11264fcd15a0SBenoit Cousson 
11274fcd15a0SBenoit Cousson 	if (!prop)
11284fcd15a0SBenoit Cousson 		return -EINVAL;
11294fcd15a0SBenoit Cousson 	if (!prop->value)
11304fcd15a0SBenoit Cousson 		return -ENODATA;
11314fcd15a0SBenoit Cousson 	if (strnlen(prop->value, prop->length) >= prop->length)
11324fcd15a0SBenoit Cousson 		return -EILSEQ;
11334fcd15a0SBenoit Cousson 
11344fcd15a0SBenoit Cousson 	p = prop->value;
11354fcd15a0SBenoit Cousson 
11364fcd15a0SBenoit Cousson 	for (i = 0; total < prop->length; total += l, p += l) {
11374fcd15a0SBenoit Cousson 		l = strlen(p) + 1;
113888af7f58SBenoit Cousson 		if (i++ == index) {
11394fcd15a0SBenoit Cousson 			*output = p;
11404fcd15a0SBenoit Cousson 			return 0;
11414fcd15a0SBenoit Cousson 		}
11424fcd15a0SBenoit Cousson 	}
11434fcd15a0SBenoit Cousson 	return -ENODATA;
11444fcd15a0SBenoit Cousson }
11454fcd15a0SBenoit Cousson EXPORT_SYMBOL_GPL(of_property_read_string_index);
11464fcd15a0SBenoit Cousson 
11477aff0fe3SGrant Likely /**
11487aff0fe3SGrant Likely  * of_property_match_string() - Find string in a list and return index
11497aff0fe3SGrant Likely  * @np: pointer to node containing string list property
11507aff0fe3SGrant Likely  * @propname: string list property name
11517aff0fe3SGrant Likely  * @string: pointer to string to search for in string list
11527aff0fe3SGrant Likely  *
11537aff0fe3SGrant Likely  * This function searches a string list property and returns the index
11547aff0fe3SGrant Likely  * of a specific string value.
11557aff0fe3SGrant Likely  */
11567aff0fe3SGrant Likely int of_property_match_string(struct device_node *np, const char *propname,
11577aff0fe3SGrant Likely 			     const char *string)
11587aff0fe3SGrant Likely {
11597aff0fe3SGrant Likely 	struct property *prop = of_find_property(np, propname, NULL);
11607aff0fe3SGrant Likely 	size_t l;
11617aff0fe3SGrant Likely 	int i;
11627aff0fe3SGrant Likely 	const char *p, *end;
11637aff0fe3SGrant Likely 
11647aff0fe3SGrant Likely 	if (!prop)
11657aff0fe3SGrant Likely 		return -EINVAL;
11667aff0fe3SGrant Likely 	if (!prop->value)
11677aff0fe3SGrant Likely 		return -ENODATA;
11687aff0fe3SGrant Likely 
11697aff0fe3SGrant Likely 	p = prop->value;
11707aff0fe3SGrant Likely 	end = p + prop->length;
11717aff0fe3SGrant Likely 
11727aff0fe3SGrant Likely 	for (i = 0; p < end; i++, p += l) {
11737aff0fe3SGrant Likely 		l = strlen(p) + 1;
11747aff0fe3SGrant Likely 		if (p + l > end)
11757aff0fe3SGrant Likely 			return -EILSEQ;
11767aff0fe3SGrant Likely 		pr_debug("comparing %s with %s\n", string, p);
11777aff0fe3SGrant Likely 		if (strcmp(string, p) == 0)
11787aff0fe3SGrant Likely 			return i; /* Found it; return index */
11797aff0fe3SGrant Likely 	}
11807aff0fe3SGrant Likely 	return -ENODATA;
11817aff0fe3SGrant Likely }
11827aff0fe3SGrant Likely EXPORT_SYMBOL_GPL(of_property_match_string);
11834fcd15a0SBenoit Cousson 
11844fcd15a0SBenoit Cousson /**
11854fcd15a0SBenoit Cousson  * of_property_count_strings - Find and return the number of strings from a
11864fcd15a0SBenoit Cousson  * multiple strings property.
11874fcd15a0SBenoit Cousson  * @np:		device node from which the property value is to be read.
11884fcd15a0SBenoit Cousson  * @propname:	name of the property to be searched.
11894fcd15a0SBenoit Cousson  *
11904fcd15a0SBenoit Cousson  * Search for a property in a device tree node and retrieve the number of null
11914fcd15a0SBenoit Cousson  * terminated string contain in it. Returns the number of strings on
11924fcd15a0SBenoit Cousson  * success, -EINVAL if the property does not exist, -ENODATA if property
11934fcd15a0SBenoit Cousson  * does not have a value, and -EILSEQ if the string is not null-terminated
11944fcd15a0SBenoit Cousson  * within the length of the property data.
11954fcd15a0SBenoit Cousson  */
11964fcd15a0SBenoit Cousson int of_property_count_strings(struct device_node *np, const char *propname)
11974fcd15a0SBenoit Cousson {
11984fcd15a0SBenoit Cousson 	struct property *prop = of_find_property(np, propname, NULL);
11994fcd15a0SBenoit Cousson 	int i = 0;
12004fcd15a0SBenoit Cousson 	size_t l = 0, total = 0;
12014fcd15a0SBenoit Cousson 	const char *p;
12024fcd15a0SBenoit Cousson 
12034fcd15a0SBenoit Cousson 	if (!prop)
12044fcd15a0SBenoit Cousson 		return -EINVAL;
12054fcd15a0SBenoit Cousson 	if (!prop->value)
12064fcd15a0SBenoit Cousson 		return -ENODATA;
12074fcd15a0SBenoit Cousson 	if (strnlen(prop->value, prop->length) >= prop->length)
12084fcd15a0SBenoit Cousson 		return -EILSEQ;
12094fcd15a0SBenoit Cousson 
12104fcd15a0SBenoit Cousson 	p = prop->value;
12114fcd15a0SBenoit Cousson 
121288af7f58SBenoit Cousson 	for (i = 0; total < prop->length; total += l, p += l, i++)
12134fcd15a0SBenoit Cousson 		l = strlen(p) + 1;
121488af7f58SBenoit Cousson 
12154fcd15a0SBenoit Cousson 	return i;
12164fcd15a0SBenoit Cousson }
12174fcd15a0SBenoit Cousson EXPORT_SYMBOL_GPL(of_property_count_strings);
12184fcd15a0SBenoit Cousson 
1219624cfca5SGrant Likely void of_print_phandle_args(const char *msg, const struct of_phandle_args *args)
1220624cfca5SGrant Likely {
1221624cfca5SGrant Likely 	int i;
1222624cfca5SGrant Likely 	printk("%s %s", msg, of_node_full_name(args->np));
1223624cfca5SGrant Likely 	for (i = 0; i < args->args_count; i++)
1224624cfca5SGrant Likely 		printk(i ? ",%08x" : ":%08x", args->args[i]);
1225624cfca5SGrant Likely 	printk("\n");
1226624cfca5SGrant Likely }
1227624cfca5SGrant Likely 
1228bd69f73fSGrant Likely static int __of_parse_phandle_with_args(const struct device_node *np,
1229bd69f73fSGrant Likely 					const char *list_name,
1230035fd948SStephen Warren 					const char *cells_name,
1231035fd948SStephen Warren 					int cell_count, int index,
123215c9a0acSGrant Likely 					struct of_phandle_args *out_args)
123364b60e09SAnton Vorontsov {
123415c9a0acSGrant Likely 	const __be32 *list, *list_end;
123523ce04c0SGrant Likely 	int rc = 0, size, cur_index = 0;
123615c9a0acSGrant Likely 	uint32_t count = 0;
123764b60e09SAnton Vorontsov 	struct device_node *node = NULL;
12389a6b2e58SGrant Likely 	phandle phandle;
123964b60e09SAnton Vorontsov 
124015c9a0acSGrant Likely 	/* Retrieve the phandle list property */
124115c9a0acSGrant Likely 	list = of_get_property(np, list_name, &size);
124215c9a0acSGrant Likely 	if (!list)
12431af4c7f1SAlexandre Courbot 		return -ENOENT;
124415c9a0acSGrant Likely 	list_end = list + size / sizeof(*list);
124515c9a0acSGrant Likely 
124615c9a0acSGrant Likely 	/* Loop over the phandles until all the requested entry is found */
124715c9a0acSGrant Likely 	while (list < list_end) {
124823ce04c0SGrant Likely 		rc = -EINVAL;
124915c9a0acSGrant Likely 		count = 0;
125015c9a0acSGrant Likely 
125115c9a0acSGrant Likely 		/*
125215c9a0acSGrant Likely 		 * If phandle is 0, then it is an empty entry with no
125315c9a0acSGrant Likely 		 * arguments.  Skip forward to the next entry.
125415c9a0acSGrant Likely 		 */
12559a6b2e58SGrant Likely 		phandle = be32_to_cpup(list++);
125615c9a0acSGrant Likely 		if (phandle) {
125715c9a0acSGrant Likely 			/*
125815c9a0acSGrant Likely 			 * Find the provider node and parse the #*-cells
125991d9942cSStephen Warren 			 * property to determine the argument length.
126091d9942cSStephen Warren 			 *
126191d9942cSStephen Warren 			 * This is not needed if the cell count is hard-coded
126291d9942cSStephen Warren 			 * (i.e. cells_name not set, but cell_count is set),
126391d9942cSStephen Warren 			 * except when we're going to return the found node
126491d9942cSStephen Warren 			 * below.
126515c9a0acSGrant Likely 			 */
126691d9942cSStephen Warren 			if (cells_name || cur_index == index) {
12679a6b2e58SGrant Likely 				node = of_find_node_by_phandle(phandle);
126864b60e09SAnton Vorontsov 				if (!node) {
126915c9a0acSGrant Likely 					pr_err("%s: could not find phandle\n",
127064b60e09SAnton Vorontsov 						np->full_name);
127123ce04c0SGrant Likely 					goto err;
127215c9a0acSGrant Likely 				}
127391d9942cSStephen Warren 			}
1274035fd948SStephen Warren 
1275035fd948SStephen Warren 			if (cells_name) {
1276035fd948SStephen Warren 				if (of_property_read_u32(node, cells_name,
1277035fd948SStephen Warren 							 &count)) {
127815c9a0acSGrant Likely 					pr_err("%s: could not get %s for %s\n",
127915c9a0acSGrant Likely 						np->full_name, cells_name,
128015c9a0acSGrant Likely 						node->full_name);
128123ce04c0SGrant Likely 					goto err;
128215c9a0acSGrant Likely 				}
1283035fd948SStephen Warren 			} else {
1284035fd948SStephen Warren 				count = cell_count;
1285035fd948SStephen Warren 			}
128615c9a0acSGrant Likely 
128715c9a0acSGrant Likely 			/*
128815c9a0acSGrant Likely 			 * Make sure that the arguments actually fit in the
128915c9a0acSGrant Likely 			 * remaining property data length
129015c9a0acSGrant Likely 			 */
129115c9a0acSGrant Likely 			if (list + count > list_end) {
129215c9a0acSGrant Likely 				pr_err("%s: arguments longer than property\n",
129315c9a0acSGrant Likely 					 np->full_name);
129423ce04c0SGrant Likely 				goto err;
129515c9a0acSGrant Likely 			}
129615c9a0acSGrant Likely 		}
129715c9a0acSGrant Likely 
129815c9a0acSGrant Likely 		/*
129915c9a0acSGrant Likely 		 * All of the error cases above bail out of the loop, so at
130015c9a0acSGrant Likely 		 * this point, the parsing is successful. If the requested
130115c9a0acSGrant Likely 		 * index matches, then fill the out_args structure and return,
130215c9a0acSGrant Likely 		 * or return -ENOENT for an empty entry.
130315c9a0acSGrant Likely 		 */
130423ce04c0SGrant Likely 		rc = -ENOENT;
130515c9a0acSGrant Likely 		if (cur_index == index) {
130615c9a0acSGrant Likely 			if (!phandle)
130723ce04c0SGrant Likely 				goto err;
130815c9a0acSGrant Likely 
130915c9a0acSGrant Likely 			if (out_args) {
131015c9a0acSGrant Likely 				int i;
131115c9a0acSGrant Likely 				if (WARN_ON(count > MAX_PHANDLE_ARGS))
131215c9a0acSGrant Likely 					count = MAX_PHANDLE_ARGS;
131315c9a0acSGrant Likely 				out_args->np = node;
131415c9a0acSGrant Likely 				out_args->args_count = count;
131515c9a0acSGrant Likely 				for (i = 0; i < count; i++)
131615c9a0acSGrant Likely 					out_args->args[i] = be32_to_cpup(list++);
1317b855f16bSTang Yuantian 			} else {
1318b855f16bSTang Yuantian 				of_node_put(node);
131915c9a0acSGrant Likely 			}
132023ce04c0SGrant Likely 
132123ce04c0SGrant Likely 			/* Found it! return success */
132215c9a0acSGrant Likely 			return 0;
132315c9a0acSGrant Likely 		}
132464b60e09SAnton Vorontsov 
132564b60e09SAnton Vorontsov 		of_node_put(node);
132664b60e09SAnton Vorontsov 		node = NULL;
132715c9a0acSGrant Likely 		list += count;
132864b60e09SAnton Vorontsov 		cur_index++;
132964b60e09SAnton Vorontsov 	}
133064b60e09SAnton Vorontsov 
133123ce04c0SGrant Likely 	/*
133223ce04c0SGrant Likely 	 * Unlock node before returning result; will be one of:
133323ce04c0SGrant Likely 	 * -ENOENT : index is for empty phandle
133423ce04c0SGrant Likely 	 * -EINVAL : parsing error on data
1335bd69f73fSGrant Likely 	 * [1..n]  : Number of phandle (count mode; when index = -1)
133623ce04c0SGrant Likely 	 */
1337bd69f73fSGrant Likely 	rc = index < 0 ? cur_index : -ENOENT;
133823ce04c0SGrant Likely  err:
133915c9a0acSGrant Likely 	if (node)
134064b60e09SAnton Vorontsov 		of_node_put(node);
134123ce04c0SGrant Likely 	return rc;
134264b60e09SAnton Vorontsov }
1343bd69f73fSGrant Likely 
1344eded9dd4SStephen Warren /**
13455fba49e3SStephen Warren  * of_parse_phandle - Resolve a phandle property to a device_node pointer
13465fba49e3SStephen Warren  * @np: Pointer to device node holding phandle property
13475fba49e3SStephen Warren  * @phandle_name: Name of property holding a phandle value
13485fba49e3SStephen Warren  * @index: For properties holding a table of phandles, this is the index into
13495fba49e3SStephen Warren  *         the table
13505fba49e3SStephen Warren  *
13515fba49e3SStephen Warren  * Returns the device_node pointer with refcount incremented.  Use
13525fba49e3SStephen Warren  * of_node_put() on it when done.
13535fba49e3SStephen Warren  */
13545fba49e3SStephen Warren struct device_node *of_parse_phandle(const struct device_node *np,
13555fba49e3SStephen Warren 				     const char *phandle_name, int index)
13565fba49e3SStephen Warren {
135791d9942cSStephen Warren 	struct of_phandle_args args;
13585fba49e3SStephen Warren 
135991d9942cSStephen Warren 	if (index < 0)
13605fba49e3SStephen Warren 		return NULL;
13615fba49e3SStephen Warren 
136291d9942cSStephen Warren 	if (__of_parse_phandle_with_args(np, phandle_name, NULL, 0,
136391d9942cSStephen Warren 					 index, &args))
136491d9942cSStephen Warren 		return NULL;
136591d9942cSStephen Warren 
136691d9942cSStephen Warren 	return args.np;
13675fba49e3SStephen Warren }
13685fba49e3SStephen Warren EXPORT_SYMBOL(of_parse_phandle);
13695fba49e3SStephen Warren 
13705fba49e3SStephen Warren /**
1371eded9dd4SStephen Warren  * of_parse_phandle_with_args() - Find a node pointed by phandle in a list
1372eded9dd4SStephen Warren  * @np:		pointer to a device tree node containing a list
1373eded9dd4SStephen Warren  * @list_name:	property name that contains a list
1374eded9dd4SStephen Warren  * @cells_name:	property name that specifies phandles' arguments count
1375eded9dd4SStephen Warren  * @index:	index of a phandle to parse out
1376eded9dd4SStephen Warren  * @out_args:	optional pointer to output arguments structure (will be filled)
1377eded9dd4SStephen Warren  *
1378eded9dd4SStephen Warren  * This function is useful to parse lists of phandles and their arguments.
1379eded9dd4SStephen Warren  * Returns 0 on success and fills out_args, on error returns appropriate
1380eded9dd4SStephen Warren  * errno value.
1381eded9dd4SStephen Warren  *
1382eded9dd4SStephen Warren  * Caller is responsible to call of_node_put() on the returned out_args->node
1383eded9dd4SStephen Warren  * pointer.
1384eded9dd4SStephen Warren  *
1385eded9dd4SStephen Warren  * Example:
1386eded9dd4SStephen Warren  *
1387eded9dd4SStephen Warren  * phandle1: node1 {
1388eded9dd4SStephen Warren  * 	#list-cells = <2>;
1389eded9dd4SStephen Warren  * }
1390eded9dd4SStephen Warren  *
1391eded9dd4SStephen Warren  * phandle2: node2 {
1392eded9dd4SStephen Warren  * 	#list-cells = <1>;
1393eded9dd4SStephen Warren  * }
1394eded9dd4SStephen Warren  *
1395eded9dd4SStephen Warren  * node3 {
1396eded9dd4SStephen Warren  * 	list = <&phandle1 1 2 &phandle2 3>;
1397eded9dd4SStephen Warren  * }
1398eded9dd4SStephen Warren  *
1399eded9dd4SStephen Warren  * To get a device_node of the `node2' node you may call this:
1400eded9dd4SStephen Warren  * of_parse_phandle_with_args(node3, "list", "#list-cells", 1, &args);
1401eded9dd4SStephen Warren  */
1402bd69f73fSGrant Likely int of_parse_phandle_with_args(const struct device_node *np, const char *list_name,
1403bd69f73fSGrant Likely 				const char *cells_name, int index,
1404bd69f73fSGrant Likely 				struct of_phandle_args *out_args)
1405bd69f73fSGrant Likely {
1406bd69f73fSGrant Likely 	if (index < 0)
1407bd69f73fSGrant Likely 		return -EINVAL;
1408035fd948SStephen Warren 	return __of_parse_phandle_with_args(np, list_name, cells_name, 0,
1409035fd948SStephen Warren 					    index, out_args);
1410bd69f73fSGrant Likely }
141115c9a0acSGrant Likely EXPORT_SYMBOL(of_parse_phandle_with_args);
141202af11b0SGrant Likely 
1413bd69f73fSGrant Likely /**
1414035fd948SStephen Warren  * of_parse_phandle_with_fixed_args() - Find a node pointed by phandle in a list
1415035fd948SStephen Warren  * @np:		pointer to a device tree node containing a list
1416035fd948SStephen Warren  * @list_name:	property name that contains a list
1417035fd948SStephen Warren  * @cell_count: number of argument cells following the phandle
1418035fd948SStephen Warren  * @index:	index of a phandle to parse out
1419035fd948SStephen Warren  * @out_args:	optional pointer to output arguments structure (will be filled)
1420035fd948SStephen Warren  *
1421035fd948SStephen Warren  * This function is useful to parse lists of phandles and their arguments.
1422035fd948SStephen Warren  * Returns 0 on success and fills out_args, on error returns appropriate
1423035fd948SStephen Warren  * errno value.
1424035fd948SStephen Warren  *
1425035fd948SStephen Warren  * Caller is responsible to call of_node_put() on the returned out_args->node
1426035fd948SStephen Warren  * pointer.
1427035fd948SStephen Warren  *
1428035fd948SStephen Warren  * Example:
1429035fd948SStephen Warren  *
1430035fd948SStephen Warren  * phandle1: node1 {
1431035fd948SStephen Warren  * }
1432035fd948SStephen Warren  *
1433035fd948SStephen Warren  * phandle2: node2 {
1434035fd948SStephen Warren  * }
1435035fd948SStephen Warren  *
1436035fd948SStephen Warren  * node3 {
1437035fd948SStephen Warren  * 	list = <&phandle1 0 2 &phandle2 2 3>;
1438035fd948SStephen Warren  * }
1439035fd948SStephen Warren  *
1440035fd948SStephen Warren  * To get a device_node of the `node2' node you may call this:
1441035fd948SStephen Warren  * of_parse_phandle_with_fixed_args(node3, "list", 2, 1, &args);
1442035fd948SStephen Warren  */
1443035fd948SStephen Warren int of_parse_phandle_with_fixed_args(const struct device_node *np,
1444035fd948SStephen Warren 				const char *list_name, int cell_count,
1445035fd948SStephen Warren 				int index, struct of_phandle_args *out_args)
1446035fd948SStephen Warren {
1447035fd948SStephen Warren 	if (index < 0)
1448035fd948SStephen Warren 		return -EINVAL;
1449035fd948SStephen Warren 	return __of_parse_phandle_with_args(np, list_name, NULL, cell_count,
1450035fd948SStephen Warren 					   index, out_args);
1451035fd948SStephen Warren }
1452035fd948SStephen Warren EXPORT_SYMBOL(of_parse_phandle_with_fixed_args);
1453035fd948SStephen Warren 
1454035fd948SStephen Warren /**
1455bd69f73fSGrant Likely  * of_count_phandle_with_args() - Find the number of phandles references in a property
1456bd69f73fSGrant Likely  * @np:		pointer to a device tree node containing a list
1457bd69f73fSGrant Likely  * @list_name:	property name that contains a list
1458bd69f73fSGrant Likely  * @cells_name:	property name that specifies phandles' arguments count
1459bd69f73fSGrant Likely  *
1460bd69f73fSGrant Likely  * Returns the number of phandle + argument tuples within a property. It
1461bd69f73fSGrant Likely  * is a typical pattern to encode a list of phandle and variable
1462bd69f73fSGrant Likely  * arguments into a single property. The number of arguments is encoded
1463bd69f73fSGrant Likely  * by a property in the phandle-target node. For example, a gpios
1464bd69f73fSGrant Likely  * property would contain a list of GPIO specifies consisting of a
1465bd69f73fSGrant Likely  * phandle and 1 or more arguments. The number of arguments are
1466bd69f73fSGrant Likely  * determined by the #gpio-cells property in the node pointed to by the
1467bd69f73fSGrant Likely  * phandle.
1468bd69f73fSGrant Likely  */
1469bd69f73fSGrant Likely int of_count_phandle_with_args(const struct device_node *np, const char *list_name,
1470bd69f73fSGrant Likely 				const char *cells_name)
1471bd69f73fSGrant Likely {
1472035fd948SStephen Warren 	return __of_parse_phandle_with_args(np, list_name, cells_name, 0, -1,
1473035fd948SStephen Warren 					    NULL);
1474bd69f73fSGrant Likely }
1475bd69f73fSGrant Likely EXPORT_SYMBOL(of_count_phandle_with_args);
1476bd69f73fSGrant Likely 
14771cf3d8b3SNathan Fontenot #if defined(CONFIG_OF_DYNAMIC)
14781cf3d8b3SNathan Fontenot static int of_property_notify(int action, struct device_node *np,
14791cf3d8b3SNathan Fontenot 			      struct property *prop)
14801cf3d8b3SNathan Fontenot {
14811cf3d8b3SNathan Fontenot 	struct of_prop_reconfig pr;
14821cf3d8b3SNathan Fontenot 
14831cf3d8b3SNathan Fontenot 	pr.dn = np;
14841cf3d8b3SNathan Fontenot 	pr.prop = prop;
14851cf3d8b3SNathan Fontenot 	return of_reconfig_notify(action, &pr);
14861cf3d8b3SNathan Fontenot }
14871cf3d8b3SNathan Fontenot #else
14881cf3d8b3SNathan Fontenot static int of_property_notify(int action, struct device_node *np,
14891cf3d8b3SNathan Fontenot 			      struct property *prop)
14901cf3d8b3SNathan Fontenot {
14911cf3d8b3SNathan Fontenot 	return 0;
14921cf3d8b3SNathan Fontenot }
14931cf3d8b3SNathan Fontenot #endif
14941cf3d8b3SNathan Fontenot 
149502af11b0SGrant Likely /**
149662664f67SXiubo Li  * __of_add_property - Add a property to a node without lock operations
149762664f67SXiubo Li  */
149862664f67SXiubo Li static int __of_add_property(struct device_node *np, struct property *prop)
149962664f67SXiubo Li {
150062664f67SXiubo Li 	struct property **next;
150162664f67SXiubo Li 
150262664f67SXiubo Li 	prop->next = NULL;
150362664f67SXiubo Li 	next = &np->properties;
150462664f67SXiubo Li 	while (*next) {
150562664f67SXiubo Li 		if (strcmp(prop->name, (*next)->name) == 0)
150662664f67SXiubo Li 			/* duplicate ! don't insert it */
150762664f67SXiubo Li 			return -EEXIST;
150862664f67SXiubo Li 
150962664f67SXiubo Li 		next = &(*next)->next;
151062664f67SXiubo Li 	}
151162664f67SXiubo Li 	*next = prop;
151262664f67SXiubo Li 
151362664f67SXiubo Li 	return 0;
151462664f67SXiubo Li }
151562664f67SXiubo Li 
151662664f67SXiubo Li /**
151779d1c712SNathan Fontenot  * of_add_property - Add a property to a node
151802af11b0SGrant Likely  */
151979d1c712SNathan Fontenot int of_add_property(struct device_node *np, struct property *prop)
152002af11b0SGrant Likely {
152102af11b0SGrant Likely 	unsigned long flags;
15221cf3d8b3SNathan Fontenot 	int rc;
15231cf3d8b3SNathan Fontenot 
15241cf3d8b3SNathan Fontenot 	rc = of_property_notify(OF_RECONFIG_ADD_PROPERTY, np, prop);
15251cf3d8b3SNathan Fontenot 	if (rc)
15261cf3d8b3SNathan Fontenot 		return rc;
152702af11b0SGrant Likely 
1528d6d3c4e6SThomas Gleixner 	raw_spin_lock_irqsave(&devtree_lock, flags);
152962664f67SXiubo Li 	rc = __of_add_property(np, prop);
1530d6d3c4e6SThomas Gleixner 	raw_spin_unlock_irqrestore(&devtree_lock, flags);
153102af11b0SGrant Likely 
153202af11b0SGrant Likely #ifdef CONFIG_PROC_DEVICETREE
153302af11b0SGrant Likely 	/* try to add to proc as well if it was initialized */
153462664f67SXiubo Li 	if (!rc && np->pde)
153502af11b0SGrant Likely 		proc_device_tree_add_prop(np->pde, prop);
153602af11b0SGrant Likely #endif /* CONFIG_PROC_DEVICETREE */
153702af11b0SGrant Likely 
153862664f67SXiubo Li 	return rc;
153902af11b0SGrant Likely }
154002af11b0SGrant Likely 
154102af11b0SGrant Likely /**
154279d1c712SNathan Fontenot  * of_remove_property - Remove a property from a node.
154302af11b0SGrant Likely  *
154402af11b0SGrant Likely  * Note that we don't actually remove it, since we have given out
154502af11b0SGrant Likely  * who-knows-how-many pointers to the data using get-property.
154602af11b0SGrant Likely  * Instead we just move the property to the "dead properties"
154702af11b0SGrant Likely  * list, so it won't be found any more.
154802af11b0SGrant Likely  */
154979d1c712SNathan Fontenot int of_remove_property(struct device_node *np, struct property *prop)
155002af11b0SGrant Likely {
155102af11b0SGrant Likely 	struct property **next;
155202af11b0SGrant Likely 	unsigned long flags;
155302af11b0SGrant Likely 	int found = 0;
15541cf3d8b3SNathan Fontenot 	int rc;
15551cf3d8b3SNathan Fontenot 
15561cf3d8b3SNathan Fontenot 	rc = of_property_notify(OF_RECONFIG_REMOVE_PROPERTY, np, prop);
15571cf3d8b3SNathan Fontenot 	if (rc)
15581cf3d8b3SNathan Fontenot 		return rc;
155902af11b0SGrant Likely 
1560d6d3c4e6SThomas Gleixner 	raw_spin_lock_irqsave(&devtree_lock, flags);
156102af11b0SGrant Likely 	next = &np->properties;
156202af11b0SGrant Likely 	while (*next) {
156302af11b0SGrant Likely 		if (*next == prop) {
156402af11b0SGrant Likely 			/* found the node */
156502af11b0SGrant Likely 			*next = prop->next;
156602af11b0SGrant Likely 			prop->next = np->deadprops;
156702af11b0SGrant Likely 			np->deadprops = prop;
156802af11b0SGrant Likely 			found = 1;
156902af11b0SGrant Likely 			break;
157002af11b0SGrant Likely 		}
157102af11b0SGrant Likely 		next = &(*next)->next;
157202af11b0SGrant Likely 	}
1573d6d3c4e6SThomas Gleixner 	raw_spin_unlock_irqrestore(&devtree_lock, flags);
157402af11b0SGrant Likely 
157502af11b0SGrant Likely 	if (!found)
157602af11b0SGrant Likely 		return -ENODEV;
157702af11b0SGrant Likely 
157802af11b0SGrant Likely #ifdef CONFIG_PROC_DEVICETREE
157902af11b0SGrant Likely 	/* try to remove the proc node as well */
158002af11b0SGrant Likely 	if (np->pde)
158102af11b0SGrant Likely 		proc_device_tree_remove_prop(np->pde, prop);
158202af11b0SGrant Likely #endif /* CONFIG_PROC_DEVICETREE */
158302af11b0SGrant Likely 
158402af11b0SGrant Likely 	return 0;
158502af11b0SGrant Likely }
158602af11b0SGrant Likely 
158702af11b0SGrant Likely /*
158879d1c712SNathan Fontenot  * of_update_property - Update a property in a node, if the property does
1589475d0094SDong Aisheng  * not exist, add it.
159002af11b0SGrant Likely  *
159102af11b0SGrant Likely  * Note that we don't actually remove it, since we have given out
159202af11b0SGrant Likely  * who-knows-how-many pointers to the data using get-property.
159302af11b0SGrant Likely  * Instead we just move the property to the "dead properties" list,
159402af11b0SGrant Likely  * and add the new property to the property list
159502af11b0SGrant Likely  */
159679d1c712SNathan Fontenot int of_update_property(struct device_node *np, struct property *newprop)
159702af11b0SGrant Likely {
1598475d0094SDong Aisheng 	struct property **next, *oldprop;
159902af11b0SGrant Likely 	unsigned long flags;
16001cf3d8b3SNathan Fontenot 	int rc, found = 0;
16011cf3d8b3SNathan Fontenot 
16021cf3d8b3SNathan Fontenot 	rc = of_property_notify(OF_RECONFIG_UPDATE_PROPERTY, np, newprop);
16031cf3d8b3SNathan Fontenot 	if (rc)
16041cf3d8b3SNathan Fontenot 		return rc;
160502af11b0SGrant Likely 
1606475d0094SDong Aisheng 	if (!newprop->name)
1607475d0094SDong Aisheng 		return -EINVAL;
1608475d0094SDong Aisheng 
1609475d0094SDong Aisheng 	oldprop = of_find_property(np, newprop->name, NULL);
1610475d0094SDong Aisheng 	if (!oldprop)
161179d1c712SNathan Fontenot 		return of_add_property(np, newprop);
1612475d0094SDong Aisheng 
1613d6d3c4e6SThomas Gleixner 	raw_spin_lock_irqsave(&devtree_lock, flags);
161402af11b0SGrant Likely 	next = &np->properties;
161502af11b0SGrant Likely 	while (*next) {
161602af11b0SGrant Likely 		if (*next == oldprop) {
161702af11b0SGrant Likely 			/* found the node */
161802af11b0SGrant Likely 			newprop->next = oldprop->next;
161902af11b0SGrant Likely 			*next = newprop;
162002af11b0SGrant Likely 			oldprop->next = np->deadprops;
162102af11b0SGrant Likely 			np->deadprops = oldprop;
162202af11b0SGrant Likely 			found = 1;
162302af11b0SGrant Likely 			break;
162402af11b0SGrant Likely 		}
162502af11b0SGrant Likely 		next = &(*next)->next;
162602af11b0SGrant Likely 	}
1627d6d3c4e6SThomas Gleixner 	raw_spin_unlock_irqrestore(&devtree_lock, flags);
162802af11b0SGrant Likely 
162902af11b0SGrant Likely 	if (!found)
163002af11b0SGrant Likely 		return -ENODEV;
163102af11b0SGrant Likely 
163202af11b0SGrant Likely #ifdef CONFIG_PROC_DEVICETREE
163302af11b0SGrant Likely 	/* try to add to proc as well if it was initialized */
163402af11b0SGrant Likely 	if (np->pde)
163502af11b0SGrant Likely 		proc_device_tree_update_prop(np->pde, newprop, oldprop);
163602af11b0SGrant Likely #endif /* CONFIG_PROC_DEVICETREE */
163702af11b0SGrant Likely 
163802af11b0SGrant Likely 	return 0;
163902af11b0SGrant Likely }
1640fcdeb7feSGrant Likely 
1641fcdeb7feSGrant Likely #if defined(CONFIG_OF_DYNAMIC)
1642fcdeb7feSGrant Likely /*
1643fcdeb7feSGrant Likely  * Support for dynamic device trees.
1644fcdeb7feSGrant Likely  *
1645fcdeb7feSGrant Likely  * On some platforms, the device tree can be manipulated at runtime.
1646fcdeb7feSGrant Likely  * The routines in this section support adding, removing and changing
1647fcdeb7feSGrant Likely  * device tree nodes.
1648fcdeb7feSGrant Likely  */
1649fcdeb7feSGrant Likely 
16501cf3d8b3SNathan Fontenot static BLOCKING_NOTIFIER_HEAD(of_reconfig_chain);
16511cf3d8b3SNathan Fontenot 
16521cf3d8b3SNathan Fontenot int of_reconfig_notifier_register(struct notifier_block *nb)
16531cf3d8b3SNathan Fontenot {
16541cf3d8b3SNathan Fontenot 	return blocking_notifier_chain_register(&of_reconfig_chain, nb);
16551cf3d8b3SNathan Fontenot }
16561a9bd454SNathan Fontenot EXPORT_SYMBOL_GPL(of_reconfig_notifier_register);
16571cf3d8b3SNathan Fontenot 
16581cf3d8b3SNathan Fontenot int of_reconfig_notifier_unregister(struct notifier_block *nb)
16591cf3d8b3SNathan Fontenot {
16601cf3d8b3SNathan Fontenot 	return blocking_notifier_chain_unregister(&of_reconfig_chain, nb);
16611cf3d8b3SNathan Fontenot }
16621a9bd454SNathan Fontenot EXPORT_SYMBOL_GPL(of_reconfig_notifier_unregister);
16631cf3d8b3SNathan Fontenot 
16641cf3d8b3SNathan Fontenot int of_reconfig_notify(unsigned long action, void *p)
16651cf3d8b3SNathan Fontenot {
16661cf3d8b3SNathan Fontenot 	int rc;
16671cf3d8b3SNathan Fontenot 
16681cf3d8b3SNathan Fontenot 	rc = blocking_notifier_call_chain(&of_reconfig_chain, action, p);
16691cf3d8b3SNathan Fontenot 	return notifier_to_errno(rc);
16701cf3d8b3SNathan Fontenot }
16711cf3d8b3SNathan Fontenot 
1672e81b3295SNathan Fontenot #ifdef CONFIG_PROC_DEVICETREE
1673e81b3295SNathan Fontenot static void of_add_proc_dt_entry(struct device_node *dn)
1674e81b3295SNathan Fontenot {
1675e81b3295SNathan Fontenot 	struct proc_dir_entry *ent;
1676e81b3295SNathan Fontenot 
1677e81b3295SNathan Fontenot 	ent = proc_mkdir(strrchr(dn->full_name, '/') + 1, dn->parent->pde);
1678e81b3295SNathan Fontenot 	if (ent)
1679e81b3295SNathan Fontenot 		proc_device_tree_add_node(dn, ent);
1680e81b3295SNathan Fontenot }
1681e81b3295SNathan Fontenot #else
1682e81b3295SNathan Fontenot static void of_add_proc_dt_entry(struct device_node *dn)
1683e81b3295SNathan Fontenot {
1684e81b3295SNathan Fontenot 	return;
1685e81b3295SNathan Fontenot }
1686e81b3295SNathan Fontenot #endif
1687e81b3295SNathan Fontenot 
1688fcdeb7feSGrant Likely /**
1689fcdeb7feSGrant Likely  * of_attach_node - Plug a device node into the tree and global list.
1690fcdeb7feSGrant Likely  */
16911cf3d8b3SNathan Fontenot int of_attach_node(struct device_node *np)
1692fcdeb7feSGrant Likely {
1693fcdeb7feSGrant Likely 	unsigned long flags;
16941cf3d8b3SNathan Fontenot 	int rc;
16951cf3d8b3SNathan Fontenot 
16961cf3d8b3SNathan Fontenot 	rc = of_reconfig_notify(OF_RECONFIG_ATTACH_NODE, np);
16971cf3d8b3SNathan Fontenot 	if (rc)
16981cf3d8b3SNathan Fontenot 		return rc;
1699fcdeb7feSGrant Likely 
1700d6d3c4e6SThomas Gleixner 	raw_spin_lock_irqsave(&devtree_lock, flags);
1701fcdeb7feSGrant Likely 	np->sibling = np->parent->child;
1702465aac6dSRandy Dunlap 	np->allnext = of_allnodes;
1703fcdeb7feSGrant Likely 	np->parent->child = np;
1704465aac6dSRandy Dunlap 	of_allnodes = np;
1705e3963fd6SPantelis Antoniou 	of_node_clear_flag(np, OF_DETACHED);
1706d6d3c4e6SThomas Gleixner 	raw_spin_unlock_irqrestore(&devtree_lock, flags);
1707e81b3295SNathan Fontenot 
1708e81b3295SNathan Fontenot 	of_add_proc_dt_entry(np);
17091cf3d8b3SNathan Fontenot 	return 0;
1710fcdeb7feSGrant Likely }
1711fcdeb7feSGrant Likely 
1712e81b3295SNathan Fontenot #ifdef CONFIG_PROC_DEVICETREE
1713e81b3295SNathan Fontenot static void of_remove_proc_dt_entry(struct device_node *dn)
1714e81b3295SNathan Fontenot {
1715a8ca16eaSDavid Howells 	proc_remove(dn->pde);
1716e81b3295SNathan Fontenot }
1717e81b3295SNathan Fontenot #else
1718e81b3295SNathan Fontenot static void of_remove_proc_dt_entry(struct device_node *dn)
1719e81b3295SNathan Fontenot {
1720e81b3295SNathan Fontenot 	return;
1721e81b3295SNathan Fontenot }
1722e81b3295SNathan Fontenot #endif
1723e81b3295SNathan Fontenot 
1724fcdeb7feSGrant Likely /**
1725fcdeb7feSGrant Likely  * of_detach_node - "Unplug" a node from the device tree.
1726fcdeb7feSGrant Likely  *
1727fcdeb7feSGrant Likely  * The caller must hold a reference to the node.  The memory associated with
1728fcdeb7feSGrant Likely  * the node is not freed until its refcount goes to zero.
1729fcdeb7feSGrant Likely  */
17301cf3d8b3SNathan Fontenot int of_detach_node(struct device_node *np)
1731fcdeb7feSGrant Likely {
1732fcdeb7feSGrant Likely 	struct device_node *parent;
1733fcdeb7feSGrant Likely 	unsigned long flags;
17341cf3d8b3SNathan Fontenot 	int rc = 0;
17351cf3d8b3SNathan Fontenot 
17361cf3d8b3SNathan Fontenot 	rc = of_reconfig_notify(OF_RECONFIG_DETACH_NODE, np);
17371cf3d8b3SNathan Fontenot 	if (rc)
17381cf3d8b3SNathan Fontenot 		return rc;
1739fcdeb7feSGrant Likely 
1740d6d3c4e6SThomas Gleixner 	raw_spin_lock_irqsave(&devtree_lock, flags);
1741fcdeb7feSGrant Likely 
1742e81b3295SNathan Fontenot 	if (of_node_check_flag(np, OF_DETACHED)) {
1743e81b3295SNathan Fontenot 		/* someone already detached it */
1744d6d3c4e6SThomas Gleixner 		raw_spin_unlock_irqrestore(&devtree_lock, flags);
17451cf3d8b3SNathan Fontenot 		return rc;
1746e81b3295SNathan Fontenot 	}
1747e81b3295SNathan Fontenot 
1748fcdeb7feSGrant Likely 	parent = np->parent;
1749e81b3295SNathan Fontenot 	if (!parent) {
1750d6d3c4e6SThomas Gleixner 		raw_spin_unlock_irqrestore(&devtree_lock, flags);
17511cf3d8b3SNathan Fontenot 		return rc;
1752e81b3295SNathan Fontenot 	}
1753fcdeb7feSGrant Likely 
1754465aac6dSRandy Dunlap 	if (of_allnodes == np)
1755465aac6dSRandy Dunlap 		of_allnodes = np->allnext;
1756fcdeb7feSGrant Likely 	else {
1757fcdeb7feSGrant Likely 		struct device_node *prev;
1758465aac6dSRandy Dunlap 		for (prev = of_allnodes;
1759fcdeb7feSGrant Likely 		     prev->allnext != np;
1760fcdeb7feSGrant Likely 		     prev = prev->allnext)
1761fcdeb7feSGrant Likely 			;
1762fcdeb7feSGrant Likely 		prev->allnext = np->allnext;
1763fcdeb7feSGrant Likely 	}
1764fcdeb7feSGrant Likely 
1765fcdeb7feSGrant Likely 	if (parent->child == np)
1766fcdeb7feSGrant Likely 		parent->child = np->sibling;
1767fcdeb7feSGrant Likely 	else {
1768fcdeb7feSGrant Likely 		struct device_node *prevsib;
1769fcdeb7feSGrant Likely 		for (prevsib = np->parent->child;
1770fcdeb7feSGrant Likely 		     prevsib->sibling != np;
1771fcdeb7feSGrant Likely 		     prevsib = prevsib->sibling)
1772fcdeb7feSGrant Likely 			;
1773fcdeb7feSGrant Likely 		prevsib->sibling = np->sibling;
1774fcdeb7feSGrant Likely 	}
1775fcdeb7feSGrant Likely 
1776fcdeb7feSGrant Likely 	of_node_set_flag(np, OF_DETACHED);
1777d6d3c4e6SThomas Gleixner 	raw_spin_unlock_irqrestore(&devtree_lock, flags);
1778e81b3295SNathan Fontenot 
1779e81b3295SNathan Fontenot 	of_remove_proc_dt_entry(np);
17801cf3d8b3SNathan Fontenot 	return rc;
1781fcdeb7feSGrant Likely }
1782fcdeb7feSGrant Likely #endif /* defined(CONFIG_OF_DYNAMIC) */
1783fcdeb7feSGrant Likely 
1784611cad72SShawn Guo static void of_alias_add(struct alias_prop *ap, struct device_node *np,
1785611cad72SShawn Guo 			 int id, const char *stem, int stem_len)
1786611cad72SShawn Guo {
1787611cad72SShawn Guo 	ap->np = np;
1788611cad72SShawn Guo 	ap->id = id;
1789611cad72SShawn Guo 	strncpy(ap->stem, stem, stem_len);
1790611cad72SShawn Guo 	ap->stem[stem_len] = 0;
1791611cad72SShawn Guo 	list_add_tail(&ap->link, &aliases_lookup);
1792611cad72SShawn Guo 	pr_debug("adding DT alias:%s: stem=%s id=%i node=%s\n",
179374a7f084SGrant Likely 		 ap->alias, ap->stem, ap->id, of_node_full_name(np));
1794611cad72SShawn Guo }
1795611cad72SShawn Guo 
1796611cad72SShawn Guo /**
1797611cad72SShawn Guo  * of_alias_scan - Scan all properties of 'aliases' node
1798611cad72SShawn Guo  *
1799611cad72SShawn Guo  * The function scans all the properties of 'aliases' node and populate
1800611cad72SShawn Guo  * the the global lookup table with the properties.  It returns the
1801611cad72SShawn Guo  * number of alias_prop found, or error code in error case.
1802611cad72SShawn Guo  *
1803611cad72SShawn Guo  * @dt_alloc:	An allocator that provides a virtual address to memory
1804611cad72SShawn Guo  *		for the resulting tree
1805611cad72SShawn Guo  */
1806611cad72SShawn Guo void of_alias_scan(void * (*dt_alloc)(u64 size, u64 align))
1807611cad72SShawn Guo {
1808611cad72SShawn Guo 	struct property *pp;
1809611cad72SShawn Guo 
1810611cad72SShawn Guo 	of_chosen = of_find_node_by_path("/chosen");
1811611cad72SShawn Guo 	if (of_chosen == NULL)
1812611cad72SShawn Guo 		of_chosen = of_find_node_by_path("/chosen@0");
18135c19e952SSascha Hauer 
18145c19e952SSascha Hauer 	if (of_chosen) {
18155c19e952SSascha Hauer 		const char *name;
18165c19e952SSascha Hauer 
18175c19e952SSascha Hauer 		name = of_get_property(of_chosen, "linux,stdout-path", NULL);
18185c19e952SSascha Hauer 		if (name)
18195c19e952SSascha Hauer 			of_stdout = of_find_node_by_path(name);
18205c19e952SSascha Hauer 	}
18215c19e952SSascha Hauer 
1822611cad72SShawn Guo 	of_aliases = of_find_node_by_path("/aliases");
1823611cad72SShawn Guo 	if (!of_aliases)
1824611cad72SShawn Guo 		return;
1825611cad72SShawn Guo 
18268af0da93SDong Aisheng 	for_each_property_of_node(of_aliases, pp) {
1827611cad72SShawn Guo 		const char *start = pp->name;
1828611cad72SShawn Guo 		const char *end = start + strlen(start);
1829611cad72SShawn Guo 		struct device_node *np;
1830611cad72SShawn Guo 		struct alias_prop *ap;
1831611cad72SShawn Guo 		int id, len;
1832611cad72SShawn Guo 
1833611cad72SShawn Guo 		/* Skip those we do not want to proceed */
1834611cad72SShawn Guo 		if (!strcmp(pp->name, "name") ||
1835611cad72SShawn Guo 		    !strcmp(pp->name, "phandle") ||
1836611cad72SShawn Guo 		    !strcmp(pp->name, "linux,phandle"))
1837611cad72SShawn Guo 			continue;
1838611cad72SShawn Guo 
1839611cad72SShawn Guo 		np = of_find_node_by_path(pp->value);
1840611cad72SShawn Guo 		if (!np)
1841611cad72SShawn Guo 			continue;
1842611cad72SShawn Guo 
1843611cad72SShawn Guo 		/* walk the alias backwards to extract the id and work out
1844611cad72SShawn Guo 		 * the 'stem' string */
1845611cad72SShawn Guo 		while (isdigit(*(end-1)) && end > start)
1846611cad72SShawn Guo 			end--;
1847611cad72SShawn Guo 		len = end - start;
1848611cad72SShawn Guo 
1849611cad72SShawn Guo 		if (kstrtoint(end, 10, &id) < 0)
1850611cad72SShawn Guo 			continue;
1851611cad72SShawn Guo 
1852611cad72SShawn Guo 		/* Allocate an alias_prop with enough space for the stem */
1853611cad72SShawn Guo 		ap = dt_alloc(sizeof(*ap) + len + 1, 4);
1854611cad72SShawn Guo 		if (!ap)
1855611cad72SShawn Guo 			continue;
18560640332eSGrant Likely 		memset(ap, 0, sizeof(*ap) + len + 1);
1857611cad72SShawn Guo 		ap->alias = start;
1858611cad72SShawn Guo 		of_alias_add(ap, np, id, start, len);
1859611cad72SShawn Guo 	}
1860611cad72SShawn Guo }
1861611cad72SShawn Guo 
1862611cad72SShawn Guo /**
1863611cad72SShawn Guo  * of_alias_get_id - Get alias id for the given device_node
1864611cad72SShawn Guo  * @np:		Pointer to the given device_node
1865611cad72SShawn Guo  * @stem:	Alias stem of the given device_node
1866611cad72SShawn Guo  *
1867611cad72SShawn Guo  * The function travels the lookup table to get alias id for the given
1868611cad72SShawn Guo  * device_node and alias stem.  It returns the alias id if find it.
1869611cad72SShawn Guo  */
1870611cad72SShawn Guo int of_alias_get_id(struct device_node *np, const char *stem)
1871611cad72SShawn Guo {
1872611cad72SShawn Guo 	struct alias_prop *app;
1873611cad72SShawn Guo 	int id = -ENODEV;
1874611cad72SShawn Guo 
1875611cad72SShawn Guo 	mutex_lock(&of_aliases_mutex);
1876611cad72SShawn Guo 	list_for_each_entry(app, &aliases_lookup, link) {
1877611cad72SShawn Guo 		if (strcmp(app->stem, stem) != 0)
1878611cad72SShawn Guo 			continue;
1879611cad72SShawn Guo 
1880611cad72SShawn Guo 		if (np == app->np) {
1881611cad72SShawn Guo 			id = app->id;
1882611cad72SShawn Guo 			break;
1883611cad72SShawn Guo 		}
1884611cad72SShawn Guo 	}
1885611cad72SShawn Guo 	mutex_unlock(&of_aliases_mutex);
1886611cad72SShawn Guo 
1887611cad72SShawn Guo 	return id;
1888611cad72SShawn Guo }
1889611cad72SShawn Guo EXPORT_SYMBOL_GPL(of_alias_get_id);
1890c541adc6SStephen Warren 
1891c541adc6SStephen Warren const __be32 *of_prop_next_u32(struct property *prop, const __be32 *cur,
1892c541adc6SStephen Warren 			       u32 *pu)
1893c541adc6SStephen Warren {
1894c541adc6SStephen Warren 	const void *curv = cur;
1895c541adc6SStephen Warren 
1896c541adc6SStephen Warren 	if (!prop)
1897c541adc6SStephen Warren 		return NULL;
1898c541adc6SStephen Warren 
1899c541adc6SStephen Warren 	if (!cur) {
1900c541adc6SStephen Warren 		curv = prop->value;
1901c541adc6SStephen Warren 		goto out_val;
1902c541adc6SStephen Warren 	}
1903c541adc6SStephen Warren 
1904c541adc6SStephen Warren 	curv += sizeof(*cur);
1905c541adc6SStephen Warren 	if (curv >= prop->value + prop->length)
1906c541adc6SStephen Warren 		return NULL;
1907c541adc6SStephen Warren 
1908c541adc6SStephen Warren out_val:
1909c541adc6SStephen Warren 	*pu = be32_to_cpup(curv);
1910c541adc6SStephen Warren 	return curv;
1911c541adc6SStephen Warren }
1912c541adc6SStephen Warren EXPORT_SYMBOL_GPL(of_prop_next_u32);
1913c541adc6SStephen Warren 
1914c541adc6SStephen Warren const char *of_prop_next_string(struct property *prop, const char *cur)
1915c541adc6SStephen Warren {
1916c541adc6SStephen Warren 	const void *curv = cur;
1917c541adc6SStephen Warren 
1918c541adc6SStephen Warren 	if (!prop)
1919c541adc6SStephen Warren 		return NULL;
1920c541adc6SStephen Warren 
1921c541adc6SStephen Warren 	if (!cur)
1922c541adc6SStephen Warren 		return prop->value;
1923c541adc6SStephen Warren 
1924c541adc6SStephen Warren 	curv += strlen(cur) + 1;
1925c541adc6SStephen Warren 	if (curv >= prop->value + prop->length)
1926c541adc6SStephen Warren 		return NULL;
1927c541adc6SStephen Warren 
1928c541adc6SStephen Warren 	return curv;
1929c541adc6SStephen Warren }
1930c541adc6SStephen Warren EXPORT_SYMBOL_GPL(of_prop_next_string);
19315c19e952SSascha Hauer 
19325c19e952SSascha Hauer /**
19335c19e952SSascha Hauer  * of_device_is_stdout_path - check if a device node matches the
19345c19e952SSascha Hauer  *                            linux,stdout-path property
19355c19e952SSascha Hauer  *
19365c19e952SSascha Hauer  * Check if this device node matches the linux,stdout-path property
19375c19e952SSascha Hauer  * in the chosen node. return true if yes, false otherwise.
19385c19e952SSascha Hauer  */
19395c19e952SSascha Hauer int of_device_is_stdout_path(struct device_node *dn)
19405c19e952SSascha Hauer {
19415c19e952SSascha Hauer 	if (!of_stdout)
19425c19e952SSascha Hauer 		return false;
19435c19e952SSascha Hauer 
19445c19e952SSascha Hauer 	return of_stdout == dn;
19455c19e952SSascha Hauer }
19465c19e952SSascha Hauer EXPORT_SYMBOL_GPL(of_device_is_stdout_path);
1947a3e31b45SSudeep KarkadaNagesha 
1948a3e31b45SSudeep KarkadaNagesha /**
1949a3e31b45SSudeep KarkadaNagesha  *	of_find_next_cache_node - Find a node's subsidiary cache
1950a3e31b45SSudeep KarkadaNagesha  *	@np:	node of type "cpu" or "cache"
1951a3e31b45SSudeep KarkadaNagesha  *
1952a3e31b45SSudeep KarkadaNagesha  *	Returns a node pointer with refcount incremented, use
1953a3e31b45SSudeep KarkadaNagesha  *	of_node_put() on it when done.  Caller should hold a reference
1954a3e31b45SSudeep KarkadaNagesha  *	to np.
1955a3e31b45SSudeep KarkadaNagesha  */
1956a3e31b45SSudeep KarkadaNagesha struct device_node *of_find_next_cache_node(const struct device_node *np)
1957a3e31b45SSudeep KarkadaNagesha {
1958a3e31b45SSudeep KarkadaNagesha 	struct device_node *child;
1959a3e31b45SSudeep KarkadaNagesha 	const phandle *handle;
1960a3e31b45SSudeep KarkadaNagesha 
1961a3e31b45SSudeep KarkadaNagesha 	handle = of_get_property(np, "l2-cache", NULL);
1962a3e31b45SSudeep KarkadaNagesha 	if (!handle)
1963a3e31b45SSudeep KarkadaNagesha 		handle = of_get_property(np, "next-level-cache", NULL);
1964a3e31b45SSudeep KarkadaNagesha 
1965a3e31b45SSudeep KarkadaNagesha 	if (handle)
1966a3e31b45SSudeep KarkadaNagesha 		return of_find_node_by_phandle(be32_to_cpup(handle));
1967a3e31b45SSudeep KarkadaNagesha 
1968a3e31b45SSudeep KarkadaNagesha 	/* OF on pmac has nodes instead of properties named "l2-cache"
1969a3e31b45SSudeep KarkadaNagesha 	 * beneath CPU nodes.
1970a3e31b45SSudeep KarkadaNagesha 	 */
1971a3e31b45SSudeep KarkadaNagesha 	if (!strcmp(np->type, "cpu"))
1972a3e31b45SSudeep KarkadaNagesha 		for_each_child_of_node(np, child)
1973a3e31b45SSudeep KarkadaNagesha 			if (!strcmp(child->type, "cache"))
1974a3e31b45SSudeep KarkadaNagesha 				return child;
1975a3e31b45SSudeep KarkadaNagesha 
1976a3e31b45SSudeep KarkadaNagesha 	return NULL;
1977a3e31b45SSudeep KarkadaNagesha }
1978