xref: /openbmc/linux/drivers/of/base.c (revision 02a876b5)
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  */
20606ad42aSRob Herring 
21606ad42aSRob Herring #define pr_fmt(fmt)	"OF: " fmt
22606ad42aSRob Herring 
233482f2c5SGrant Likely #include <linux/console.h>
24611cad72SShawn Guo #include <linux/ctype.h>
25183912d3SSudeep KarkadaNagesha #include <linux/cpu.h>
2697e873e5SStephen Rothwell #include <linux/module.h>
2797e873e5SStephen Rothwell #include <linux/of.h>
285fa23530SSudeep Holla #include <linux/of_device.h>
29fd9fdb78SPhilipp Zabel #include <linux/of_graph.h>
30581b605aSStephen Rothwell #include <linux/spinlock.h>
315a0e3ad6STejun Heo #include <linux/slab.h>
3275b57ecfSGrant Likely #include <linux/string.h>
33a9f2f63aSJeremy Kerr #include <linux/proc_fs.h>
34581b605aSStephen Rothwell 
35ced4eec9SStepan Moskovchenko #include "of_private.h"
36611cad72SShawn Guo 
37ced4eec9SStepan Moskovchenko LIST_HEAD(aliases_lookup);
38611cad72SShawn Guo 
395063e25aSGrant Likely struct device_node *of_root;
405063e25aSGrant Likely EXPORT_SYMBOL(of_root);
41fc0bdae4SGrant Likely struct device_node *of_chosen;
42611cad72SShawn Guo struct device_node *of_aliases;
43a752ee56SGrant Likely struct device_node *of_stdout;
447914a7c5SLeif Lindholm static const char *of_stdout_options;
45611cad72SShawn Guo 
468a2b22a2SGrant Likely struct kset *of_kset;
4775b57ecfSGrant Likely 
4875b57ecfSGrant Likely /*
498a2b22a2SGrant Likely  * Used to protect the of_aliases, to hold off addition of nodes to sysfs.
508a2b22a2SGrant Likely  * This mutex must be held whenever modifications are being made to the
518a2b22a2SGrant Likely  * device tree. The of_{attach,detach}_node() and
528a2b22a2SGrant Likely  * of_{add,remove,update}_property() helpers make sure this happens.
5375b57ecfSGrant Likely  */
54c05aba2bSPantelis Antoniou DEFINE_MUTEX(of_mutex);
551ef4d424SStephen Rothwell 
565063e25aSGrant Likely /* use when traversing tree through the child, sibling,
57581b605aSStephen Rothwell  * or parent members of struct device_node.
58581b605aSStephen Rothwell  */
59d6d3c4e6SThomas Gleixner DEFINE_RAW_SPINLOCK(devtree_lock);
6097e873e5SStephen Rothwell 
6197e873e5SStephen Rothwell int of_n_addr_cells(struct device_node *np)
6297e873e5SStephen Rothwell {
638832963dSSergei Shtylyov 	u32 cells;
6497e873e5SStephen Rothwell 
6597e873e5SStephen Rothwell 	do {
6697e873e5SStephen Rothwell 		if (np->parent)
6797e873e5SStephen Rothwell 			np = np->parent;
688832963dSSergei Shtylyov 		if (!of_property_read_u32(np, "#address-cells", &cells))
698832963dSSergei Shtylyov 			return cells;
7097e873e5SStephen Rothwell 	} while (np->parent);
7197e873e5SStephen Rothwell 	/* No #address-cells property for the root node */
7297e873e5SStephen Rothwell 	return OF_ROOT_NODE_ADDR_CELLS_DEFAULT;
7397e873e5SStephen Rothwell }
7497e873e5SStephen Rothwell EXPORT_SYMBOL(of_n_addr_cells);
7597e873e5SStephen Rothwell 
7697e873e5SStephen Rothwell int of_n_size_cells(struct device_node *np)
7797e873e5SStephen Rothwell {
788832963dSSergei Shtylyov 	u32 cells;
7997e873e5SStephen Rothwell 
8097e873e5SStephen Rothwell 	do {
8197e873e5SStephen Rothwell 		if (np->parent)
8297e873e5SStephen Rothwell 			np = np->parent;
838832963dSSergei Shtylyov 		if (!of_property_read_u32(np, "#size-cells", &cells))
848832963dSSergei Shtylyov 			return cells;
8597e873e5SStephen Rothwell 	} while (np->parent);
8697e873e5SStephen Rothwell 	/* No #size-cells property for the root node */
8797e873e5SStephen Rothwell 	return OF_ROOT_NODE_SIZE_CELLS_DEFAULT;
8897e873e5SStephen Rothwell }
8997e873e5SStephen Rothwell EXPORT_SYMBOL(of_n_size_cells);
9097e873e5SStephen Rothwell 
910c3f061cSRob Herring #ifdef CONFIG_NUMA
920c3f061cSRob Herring int __weak of_node_to_nid(struct device_node *np)
930c3f061cSRob Herring {
94c8fff7bcSKonstantin Khlebnikov 	return NUMA_NO_NODE;
950c3f061cSRob Herring }
960c3f061cSRob Herring #endif
970c3f061cSRob Herring 
98194ec936SSudeep Holla void __init of_core_init(void)
9975b57ecfSGrant Likely {
10075b57ecfSGrant Likely 	struct device_node *np;
10175b57ecfSGrant Likely 
10275b57ecfSGrant Likely 	/* Create the kset, and register existing nodes */
103c05aba2bSPantelis Antoniou 	mutex_lock(&of_mutex);
10475b57ecfSGrant Likely 	of_kset = kset_create_and_add("devicetree", NULL, firmware_kobj);
10575b57ecfSGrant Likely 	if (!of_kset) {
106c05aba2bSPantelis Antoniou 		mutex_unlock(&of_mutex);
107606ad42aSRob Herring 		pr_err("failed to register existing nodes\n");
108194ec936SSudeep Holla 		return;
10975b57ecfSGrant Likely 	}
11075b57ecfSGrant Likely 	for_each_of_allnodes(np)
1118a2b22a2SGrant Likely 		__of_attach_node_sysfs(np);
112c05aba2bSPantelis Antoniou 	mutex_unlock(&of_mutex);
11375b57ecfSGrant Likely 
1148357041aSGrant Likely 	/* Symlink in /proc as required by userspace ABI */
1155063e25aSGrant Likely 	if (of_root)
11675b57ecfSGrant Likely 		proc_symlink("device-tree", NULL, "/sys/firmware/devicetree/base");
11775b57ecfSGrant Likely }
11875b57ecfSGrant Likely 
11928d0e36bSThomas Gleixner static struct property *__of_find_property(const struct device_node *np,
12028d0e36bSThomas Gleixner 					   const char *name, int *lenp)
121581b605aSStephen Rothwell {
122581b605aSStephen Rothwell 	struct property *pp;
123581b605aSStephen Rothwell 
12464e4566fSTimur Tabi 	if (!np)
12564e4566fSTimur Tabi 		return NULL;
12664e4566fSTimur Tabi 
127a3a7cab1SSachin Kamat 	for (pp = np->properties; pp; pp = pp->next) {
128581b605aSStephen Rothwell 		if (of_prop_cmp(pp->name, name) == 0) {
129a3a7cab1SSachin Kamat 			if (lenp)
130581b605aSStephen Rothwell 				*lenp = pp->length;
131581b605aSStephen Rothwell 			break;
132581b605aSStephen Rothwell 		}
133581b605aSStephen Rothwell 	}
13428d0e36bSThomas Gleixner 
13528d0e36bSThomas Gleixner 	return pp;
13628d0e36bSThomas Gleixner }
13728d0e36bSThomas Gleixner 
13828d0e36bSThomas Gleixner struct property *of_find_property(const struct device_node *np,
13928d0e36bSThomas Gleixner 				  const char *name,
14028d0e36bSThomas Gleixner 				  int *lenp)
14128d0e36bSThomas Gleixner {
14228d0e36bSThomas Gleixner 	struct property *pp;
143d6d3c4e6SThomas Gleixner 	unsigned long flags;
14428d0e36bSThomas Gleixner 
145d6d3c4e6SThomas Gleixner 	raw_spin_lock_irqsave(&devtree_lock, flags);
14628d0e36bSThomas Gleixner 	pp = __of_find_property(np, name, lenp);
147d6d3c4e6SThomas Gleixner 	raw_spin_unlock_irqrestore(&devtree_lock, flags);
148581b605aSStephen Rothwell 
149581b605aSStephen Rothwell 	return pp;
150581b605aSStephen Rothwell }
151581b605aSStephen Rothwell EXPORT_SYMBOL(of_find_property);
152581b605aSStephen Rothwell 
1535063e25aSGrant Likely struct device_node *__of_find_all_nodes(struct device_node *prev)
1545063e25aSGrant Likely {
1555063e25aSGrant Likely 	struct device_node *np;
1565063e25aSGrant Likely 	if (!prev) {
1575063e25aSGrant Likely 		np = of_root;
1585063e25aSGrant Likely 	} else if (prev->child) {
1595063e25aSGrant Likely 		np = prev->child;
1605063e25aSGrant Likely 	} else {
1615063e25aSGrant Likely 		/* Walk back up looking for a sibling, or the end of the structure */
1625063e25aSGrant Likely 		np = prev;
1635063e25aSGrant Likely 		while (np->parent && !np->sibling)
1645063e25aSGrant Likely 			np = np->parent;
1655063e25aSGrant Likely 		np = np->sibling; /* Might be null at the end of the tree */
1665063e25aSGrant Likely 	}
1675063e25aSGrant Likely 	return np;
1685063e25aSGrant Likely }
1695063e25aSGrant Likely 
170e91edcf5SGrant Likely /**
171e91edcf5SGrant Likely  * of_find_all_nodes - Get next node in global list
172e91edcf5SGrant Likely  * @prev:	Previous node or NULL to start iteration
173e91edcf5SGrant Likely  *		of_node_put() will be called on it
174e91edcf5SGrant Likely  *
175e91edcf5SGrant Likely  * Returns a node pointer with refcount incremented, use
176e91edcf5SGrant Likely  * of_node_put() on it when done.
177e91edcf5SGrant Likely  */
178e91edcf5SGrant Likely struct device_node *of_find_all_nodes(struct device_node *prev)
179e91edcf5SGrant Likely {
180e91edcf5SGrant Likely 	struct device_node *np;
181d25d8694SBenjamin Herrenschmidt 	unsigned long flags;
182e91edcf5SGrant Likely 
183d25d8694SBenjamin Herrenschmidt 	raw_spin_lock_irqsave(&devtree_lock, flags);
1845063e25aSGrant Likely 	np = __of_find_all_nodes(prev);
1855063e25aSGrant Likely 	of_node_get(np);
186e91edcf5SGrant Likely 	of_node_put(prev);
187d25d8694SBenjamin Herrenschmidt 	raw_spin_unlock_irqrestore(&devtree_lock, flags);
188e91edcf5SGrant Likely 	return np;
189e91edcf5SGrant Likely }
190e91edcf5SGrant Likely EXPORT_SYMBOL(of_find_all_nodes);
191e91edcf5SGrant Likely 
19297e873e5SStephen Rothwell /*
19397e873e5SStephen Rothwell  * Find a property with a given name for a given node
19497e873e5SStephen Rothwell  * and return the value.
19597e873e5SStephen Rothwell  */
196a25095d4SGrant Likely const void *__of_get_property(const struct device_node *np,
19728d0e36bSThomas Gleixner 			      const char *name, int *lenp)
19828d0e36bSThomas Gleixner {
19928d0e36bSThomas Gleixner 	struct property *pp = __of_find_property(np, name, lenp);
20028d0e36bSThomas Gleixner 
20128d0e36bSThomas Gleixner 	return pp ? pp->value : NULL;
20228d0e36bSThomas Gleixner }
20328d0e36bSThomas Gleixner 
20428d0e36bSThomas Gleixner /*
20528d0e36bSThomas Gleixner  * Find a property with a given name for a given node
20628d0e36bSThomas Gleixner  * and return the value.
20728d0e36bSThomas Gleixner  */
20897e873e5SStephen Rothwell const void *of_get_property(const struct device_node *np, const char *name,
20997e873e5SStephen Rothwell 			    int *lenp)
21097e873e5SStephen Rothwell {
21197e873e5SStephen Rothwell 	struct property *pp = of_find_property(np, name, lenp);
21297e873e5SStephen Rothwell 
21397e873e5SStephen Rothwell 	return pp ? pp->value : NULL;
21497e873e5SStephen Rothwell }
21597e873e5SStephen Rothwell EXPORT_SYMBOL(of_get_property);
2160081cbc3SStephen Rothwell 
217183912d3SSudeep KarkadaNagesha /*
218183912d3SSudeep KarkadaNagesha  * arch_match_cpu_phys_id - Match the given logical CPU and physical id
219183912d3SSudeep KarkadaNagesha  *
220183912d3SSudeep KarkadaNagesha  * @cpu: logical cpu index of a core/thread
221183912d3SSudeep KarkadaNagesha  * @phys_id: physical identifier of a core/thread
222183912d3SSudeep KarkadaNagesha  *
223183912d3SSudeep KarkadaNagesha  * CPU logical to physical index mapping is architecture specific.
224183912d3SSudeep KarkadaNagesha  * However this __weak function provides a default match of physical
225183912d3SSudeep KarkadaNagesha  * id to logical cpu index. phys_id provided here is usually values read
226183912d3SSudeep KarkadaNagesha  * from the device tree which must match the hardware internal registers.
227183912d3SSudeep KarkadaNagesha  *
228183912d3SSudeep KarkadaNagesha  * Returns true if the physical identifier and the logical cpu index
229183912d3SSudeep KarkadaNagesha  * correspond to the same core/thread, false otherwise.
230183912d3SSudeep KarkadaNagesha  */
231183912d3SSudeep KarkadaNagesha bool __weak arch_match_cpu_phys_id(int cpu, u64 phys_id)
232183912d3SSudeep KarkadaNagesha {
233183912d3SSudeep KarkadaNagesha 	return (u32)phys_id == cpu;
234183912d3SSudeep KarkadaNagesha }
235183912d3SSudeep KarkadaNagesha 
236183912d3SSudeep KarkadaNagesha /**
237183912d3SSudeep KarkadaNagesha  * Checks if the given "prop_name" property holds the physical id of the
238183912d3SSudeep KarkadaNagesha  * core/thread corresponding to the logical cpu 'cpu'. If 'thread' is not
239183912d3SSudeep KarkadaNagesha  * NULL, local thread number within the core is returned in it.
240183912d3SSudeep KarkadaNagesha  */
241183912d3SSudeep KarkadaNagesha static bool __of_find_n_match_cpu_property(struct device_node *cpun,
242183912d3SSudeep KarkadaNagesha 			const char *prop_name, int cpu, unsigned int *thread)
243183912d3SSudeep KarkadaNagesha {
244183912d3SSudeep KarkadaNagesha 	const __be32 *cell;
245183912d3SSudeep KarkadaNagesha 	int ac, prop_len, tid;
246183912d3SSudeep KarkadaNagesha 	u64 hwid;
247183912d3SSudeep KarkadaNagesha 
248183912d3SSudeep KarkadaNagesha 	ac = of_n_addr_cells(cpun);
249183912d3SSudeep KarkadaNagesha 	cell = of_get_property(cpun, prop_name, &prop_len);
250f3cea45aSGrant Likely 	if (!cell || !ac)
251183912d3SSudeep KarkadaNagesha 		return false;
252f3cea45aSGrant Likely 	prop_len /= sizeof(*cell) * ac;
253183912d3SSudeep KarkadaNagesha 	for (tid = 0; tid < prop_len; tid++) {
254183912d3SSudeep KarkadaNagesha 		hwid = of_read_number(cell, ac);
255183912d3SSudeep KarkadaNagesha 		if (arch_match_cpu_phys_id(cpu, hwid)) {
256183912d3SSudeep KarkadaNagesha 			if (thread)
257183912d3SSudeep KarkadaNagesha 				*thread = tid;
258183912d3SSudeep KarkadaNagesha 			return true;
259183912d3SSudeep KarkadaNagesha 		}
260183912d3SSudeep KarkadaNagesha 		cell += ac;
261183912d3SSudeep KarkadaNagesha 	}
262183912d3SSudeep KarkadaNagesha 	return false;
263183912d3SSudeep KarkadaNagesha }
264183912d3SSudeep KarkadaNagesha 
265d1cb9d1aSDavid Miller /*
266d1cb9d1aSDavid Miller  * arch_find_n_match_cpu_physical_id - See if the given device node is
267d1cb9d1aSDavid Miller  * for the cpu corresponding to logical cpu 'cpu'.  Return true if so,
268d1cb9d1aSDavid Miller  * else false.  If 'thread' is non-NULL, the local thread number within the
269d1cb9d1aSDavid Miller  * core is returned in it.
270d1cb9d1aSDavid Miller  */
271d1cb9d1aSDavid Miller bool __weak arch_find_n_match_cpu_physical_id(struct device_node *cpun,
272d1cb9d1aSDavid Miller 					      int cpu, unsigned int *thread)
273d1cb9d1aSDavid Miller {
274d1cb9d1aSDavid Miller 	/* Check for non-standard "ibm,ppc-interrupt-server#s" property
275d1cb9d1aSDavid Miller 	 * for thread ids on PowerPC. If it doesn't exist fallback to
276d1cb9d1aSDavid Miller 	 * standard "reg" property.
277d1cb9d1aSDavid Miller 	 */
278d1cb9d1aSDavid Miller 	if (IS_ENABLED(CONFIG_PPC) &&
279d1cb9d1aSDavid Miller 	    __of_find_n_match_cpu_property(cpun,
280d1cb9d1aSDavid Miller 					   "ibm,ppc-interrupt-server#s",
281d1cb9d1aSDavid Miller 					   cpu, thread))
282d1cb9d1aSDavid Miller 		return true;
283d1cb9d1aSDavid Miller 
284510bd068SMasahiro Yamada 	return __of_find_n_match_cpu_property(cpun, "reg", cpu, thread);
285d1cb9d1aSDavid Miller }
286d1cb9d1aSDavid Miller 
287183912d3SSudeep KarkadaNagesha /**
288183912d3SSudeep KarkadaNagesha  * of_get_cpu_node - Get device node associated with the given logical CPU
289183912d3SSudeep KarkadaNagesha  *
290183912d3SSudeep KarkadaNagesha  * @cpu: CPU number(logical index) for which device node is required
291183912d3SSudeep KarkadaNagesha  * @thread: if not NULL, local thread number within the physical core is
292183912d3SSudeep KarkadaNagesha  *          returned
293183912d3SSudeep KarkadaNagesha  *
294183912d3SSudeep KarkadaNagesha  * The main purpose of this function is to retrieve the device node for the
295183912d3SSudeep KarkadaNagesha  * given logical CPU index. It should be used to initialize the of_node in
296183912d3SSudeep KarkadaNagesha  * cpu device. Once of_node in cpu device is populated, all the further
297183912d3SSudeep KarkadaNagesha  * references can use that instead.
298183912d3SSudeep KarkadaNagesha  *
299183912d3SSudeep KarkadaNagesha  * CPU logical to physical index mapping is architecture specific and is built
300183912d3SSudeep KarkadaNagesha  * before booting secondary cores. This function uses arch_match_cpu_phys_id
301183912d3SSudeep KarkadaNagesha  * which can be overridden by architecture specific implementation.
302183912d3SSudeep KarkadaNagesha  *
3031c986e36SMasahiro Yamada  * Returns a node pointer for the logical cpu with refcount incremented, use
3041c986e36SMasahiro Yamada  * of_node_put() on it when done. Returns NULL if not found.
305183912d3SSudeep KarkadaNagesha  */
306183912d3SSudeep KarkadaNagesha struct device_node *of_get_cpu_node(int cpu, unsigned int *thread)
307183912d3SSudeep KarkadaNagesha {
308d1cb9d1aSDavid Miller 	struct device_node *cpun;
309183912d3SSudeep KarkadaNagesha 
310d1cb9d1aSDavid Miller 	for_each_node_by_type(cpun, "cpu") {
311d1cb9d1aSDavid Miller 		if (arch_find_n_match_cpu_physical_id(cpun, cpu, thread))
312183912d3SSudeep KarkadaNagesha 			return cpun;
313183912d3SSudeep KarkadaNagesha 	}
314183912d3SSudeep KarkadaNagesha 	return NULL;
315183912d3SSudeep KarkadaNagesha }
316183912d3SSudeep KarkadaNagesha EXPORT_SYMBOL(of_get_cpu_node);
317183912d3SSudeep KarkadaNagesha 
318215a14cfSKevin Hao /**
319215a14cfSKevin Hao  * __of_device_is_compatible() - Check if the node matches given constraints
320215a14cfSKevin Hao  * @device: pointer to node
321215a14cfSKevin Hao  * @compat: required compatible string, NULL or "" for any match
322215a14cfSKevin Hao  * @type: required device_type value, NULL or "" for any match
323215a14cfSKevin Hao  * @name: required node name, NULL or "" for any match
324215a14cfSKevin Hao  *
325215a14cfSKevin Hao  * Checks if the given @compat, @type and @name strings match the
326215a14cfSKevin Hao  * properties of the given @device. A constraints can be skipped by
327215a14cfSKevin Hao  * passing NULL or an empty string as the constraint.
328215a14cfSKevin Hao  *
329215a14cfSKevin Hao  * Returns 0 for no match, and a positive integer on match. The return
330215a14cfSKevin Hao  * value is a relative score with larger values indicating better
331215a14cfSKevin Hao  * matches. The score is weighted for the most specific compatible value
332215a14cfSKevin Hao  * to get the highest score. Matching type is next, followed by matching
333215a14cfSKevin Hao  * name. Practically speaking, this results in the following priority
334215a14cfSKevin Hao  * order for matches:
335215a14cfSKevin Hao  *
336215a14cfSKevin Hao  * 1. specific compatible && type && name
337215a14cfSKevin Hao  * 2. specific compatible && type
338215a14cfSKevin Hao  * 3. specific compatible && name
339215a14cfSKevin Hao  * 4. specific compatible
340215a14cfSKevin Hao  * 5. general compatible && type && name
341215a14cfSKevin Hao  * 6. general compatible && type
342215a14cfSKevin Hao  * 7. general compatible && name
343215a14cfSKevin Hao  * 8. general compatible
344215a14cfSKevin Hao  * 9. type && name
345215a14cfSKevin Hao  * 10. type
346215a14cfSKevin Hao  * 11. name
3470081cbc3SStephen Rothwell  */
34828d0e36bSThomas Gleixner static int __of_device_is_compatible(const struct device_node *device,
349215a14cfSKevin Hao 				     const char *compat, const char *type, const char *name)
3500081cbc3SStephen Rothwell {
351215a14cfSKevin Hao 	struct property *prop;
3520081cbc3SStephen Rothwell 	const char *cp;
353215a14cfSKevin Hao 	int index = 0, score = 0;
3540081cbc3SStephen Rothwell 
355215a14cfSKevin Hao 	/* Compatible match has highest priority */
356215a14cfSKevin Hao 	if (compat && compat[0]) {
357215a14cfSKevin Hao 		prop = __of_find_property(device, "compatible", NULL);
358215a14cfSKevin Hao 		for (cp = of_prop_next_string(prop, NULL); cp;
359215a14cfSKevin Hao 		     cp = of_prop_next_string(prop, cp), index++) {
360215a14cfSKevin Hao 			if (of_compat_cmp(cp, compat, strlen(compat)) == 0) {
361215a14cfSKevin Hao 				score = INT_MAX/2 - (index << 2);
362215a14cfSKevin Hao 				break;
363215a14cfSKevin Hao 			}
364215a14cfSKevin Hao 		}
365215a14cfSKevin Hao 		if (!score)
3660081cbc3SStephen Rothwell 			return 0;
3670081cbc3SStephen Rothwell 	}
3680081cbc3SStephen Rothwell 
369215a14cfSKevin Hao 	/* Matching type is better than matching name */
370215a14cfSKevin Hao 	if (type && type[0]) {
371215a14cfSKevin Hao 		if (!device->type || of_node_cmp(type, device->type))
3720081cbc3SStephen Rothwell 			return 0;
373215a14cfSKevin Hao 		score += 2;
374215a14cfSKevin Hao 	}
375215a14cfSKevin Hao 
376215a14cfSKevin Hao 	/* Matching name is a bit better than not */
377215a14cfSKevin Hao 	if (name && name[0]) {
378215a14cfSKevin Hao 		if (!device->name || of_node_cmp(name, device->name))
379215a14cfSKevin Hao 			return 0;
380215a14cfSKevin Hao 		score++;
381215a14cfSKevin Hao 	}
382215a14cfSKevin Hao 
383215a14cfSKevin Hao 	return score;
3840081cbc3SStephen Rothwell }
38528d0e36bSThomas Gleixner 
38628d0e36bSThomas Gleixner /** Checks if the given "compat" string matches one of the strings in
38728d0e36bSThomas Gleixner  * the device's "compatible" property
38828d0e36bSThomas Gleixner  */
38928d0e36bSThomas Gleixner int of_device_is_compatible(const struct device_node *device,
39028d0e36bSThomas Gleixner 		const char *compat)
39128d0e36bSThomas Gleixner {
392d6d3c4e6SThomas Gleixner 	unsigned long flags;
39328d0e36bSThomas Gleixner 	int res;
39428d0e36bSThomas Gleixner 
395d6d3c4e6SThomas Gleixner 	raw_spin_lock_irqsave(&devtree_lock, flags);
396215a14cfSKevin Hao 	res = __of_device_is_compatible(device, compat, NULL, NULL);
397d6d3c4e6SThomas Gleixner 	raw_spin_unlock_irqrestore(&devtree_lock, flags);
39828d0e36bSThomas Gleixner 	return res;
39928d0e36bSThomas Gleixner }
4000081cbc3SStephen Rothwell EXPORT_SYMBOL(of_device_is_compatible);
401e679c5f4SStephen Rothwell 
402b9c13fe3SBenjamin Herrenschmidt /** Checks if the device is compatible with any of the entries in
403b9c13fe3SBenjamin Herrenschmidt  *  a NULL terminated array of strings. Returns the best match
404b9c13fe3SBenjamin Herrenschmidt  *  score or 0.
405b9c13fe3SBenjamin Herrenschmidt  */
406b9c13fe3SBenjamin Herrenschmidt int of_device_compatible_match(struct device_node *device,
407b9c13fe3SBenjamin Herrenschmidt 			       const char *const *compat)
408b9c13fe3SBenjamin Herrenschmidt {
409b9c13fe3SBenjamin Herrenschmidt 	unsigned int tmp, score = 0;
410b9c13fe3SBenjamin Herrenschmidt 
411b9c13fe3SBenjamin Herrenschmidt 	if (!compat)
412b9c13fe3SBenjamin Herrenschmidt 		return 0;
413b9c13fe3SBenjamin Herrenschmidt 
414b9c13fe3SBenjamin Herrenschmidt 	while (*compat) {
415b9c13fe3SBenjamin Herrenschmidt 		tmp = of_device_is_compatible(device, *compat);
416b9c13fe3SBenjamin Herrenschmidt 		if (tmp > score)
417b9c13fe3SBenjamin Herrenschmidt 			score = tmp;
418b9c13fe3SBenjamin Herrenschmidt 		compat++;
419b9c13fe3SBenjamin Herrenschmidt 	}
420b9c13fe3SBenjamin Herrenschmidt 
421b9c13fe3SBenjamin Herrenschmidt 	return score;
422b9c13fe3SBenjamin Herrenschmidt }
423b9c13fe3SBenjamin Herrenschmidt 
424e679c5f4SStephen Rothwell /**
42571a157e8SGrant Likely  * of_machine_is_compatible - Test root of device tree for a given compatible value
4261f43cfb9SGrant Likely  * @compat: compatible string to look for in root node's compatible property.
4271f43cfb9SGrant Likely  *
42825c7a1deSKevin Cernekee  * Returns a positive integer if the root node has the given value in its
4291f43cfb9SGrant Likely  * compatible property.
4301f43cfb9SGrant Likely  */
43171a157e8SGrant Likely int of_machine_is_compatible(const char *compat)
4321f43cfb9SGrant Likely {
4331f43cfb9SGrant Likely 	struct device_node *root;
4341f43cfb9SGrant Likely 	int rc = 0;
4351f43cfb9SGrant Likely 
4361f43cfb9SGrant Likely 	root = of_find_node_by_path("/");
4371f43cfb9SGrant Likely 	if (root) {
4381f43cfb9SGrant Likely 		rc = of_device_is_compatible(root, compat);
4391f43cfb9SGrant Likely 		of_node_put(root);
4401f43cfb9SGrant Likely 	}
4411f43cfb9SGrant Likely 	return rc;
4421f43cfb9SGrant Likely }
44371a157e8SGrant Likely EXPORT_SYMBOL(of_machine_is_compatible);
4441f43cfb9SGrant Likely 
4451f43cfb9SGrant Likely /**
446c31a0c05SStephen Warren  *  __of_device_is_available - check if a device is available for use
447834d97d4SJosh Boyer  *
448c31a0c05SStephen Warren  *  @device: Node to check for availability, with locks already held
449834d97d4SJosh Boyer  *
45053a4ab96SKevin Cernekee  *  Returns true if the status property is absent or set to "okay" or "ok",
45153a4ab96SKevin Cernekee  *  false otherwise
452834d97d4SJosh Boyer  */
45353a4ab96SKevin Cernekee static bool __of_device_is_available(const struct device_node *device)
454834d97d4SJosh Boyer {
455834d97d4SJosh Boyer 	const char *status;
456834d97d4SJosh Boyer 	int statlen;
457834d97d4SJosh Boyer 
45842ccd781SXiubo Li 	if (!device)
45953a4ab96SKevin Cernekee 		return false;
46042ccd781SXiubo Li 
461c31a0c05SStephen Warren 	status = __of_get_property(device, "status", &statlen);
462834d97d4SJosh Boyer 	if (status == NULL)
46353a4ab96SKevin Cernekee 		return true;
464834d97d4SJosh Boyer 
465834d97d4SJosh Boyer 	if (statlen > 0) {
466834d97d4SJosh Boyer 		if (!strcmp(status, "okay") || !strcmp(status, "ok"))
46753a4ab96SKevin Cernekee 			return true;
468834d97d4SJosh Boyer 	}
469834d97d4SJosh Boyer 
47053a4ab96SKevin Cernekee 	return false;
471834d97d4SJosh Boyer }
472c31a0c05SStephen Warren 
473c31a0c05SStephen Warren /**
474c31a0c05SStephen Warren  *  of_device_is_available - check if a device is available for use
475c31a0c05SStephen Warren  *
476c31a0c05SStephen Warren  *  @device: Node to check for availability
477c31a0c05SStephen Warren  *
47853a4ab96SKevin Cernekee  *  Returns true if the status property is absent or set to "okay" or "ok",
47953a4ab96SKevin Cernekee  *  false otherwise
480c31a0c05SStephen Warren  */
48153a4ab96SKevin Cernekee bool of_device_is_available(const struct device_node *device)
482c31a0c05SStephen Warren {
483c31a0c05SStephen Warren 	unsigned long flags;
48453a4ab96SKevin Cernekee 	bool res;
485c31a0c05SStephen Warren 
486c31a0c05SStephen Warren 	raw_spin_lock_irqsave(&devtree_lock, flags);
487c31a0c05SStephen Warren 	res = __of_device_is_available(device);
488c31a0c05SStephen Warren 	raw_spin_unlock_irqrestore(&devtree_lock, flags);
489c31a0c05SStephen Warren 	return res;
490c31a0c05SStephen Warren 
491c31a0c05SStephen Warren }
492834d97d4SJosh Boyer EXPORT_SYMBOL(of_device_is_available);
493834d97d4SJosh Boyer 
494834d97d4SJosh Boyer /**
49537786c7fSKevin Cernekee  *  of_device_is_big_endian - check if a device has BE registers
49637786c7fSKevin Cernekee  *
49737786c7fSKevin Cernekee  *  @device: Node to check for endianness
49837786c7fSKevin Cernekee  *
49937786c7fSKevin Cernekee  *  Returns true if the device has a "big-endian" property, or if the kernel
50037786c7fSKevin Cernekee  *  was compiled for BE *and* the device has a "native-endian" property.
50137786c7fSKevin Cernekee  *  Returns false otherwise.
50237786c7fSKevin Cernekee  *
50337786c7fSKevin Cernekee  *  Callers would nominally use ioread32be/iowrite32be if
50437786c7fSKevin Cernekee  *  of_device_is_big_endian() == true, or readl/writel otherwise.
50537786c7fSKevin Cernekee  */
50637786c7fSKevin Cernekee bool of_device_is_big_endian(const struct device_node *device)
50737786c7fSKevin Cernekee {
50837786c7fSKevin Cernekee 	if (of_property_read_bool(device, "big-endian"))
50937786c7fSKevin Cernekee 		return true;
51037786c7fSKevin Cernekee 	if (IS_ENABLED(CONFIG_CPU_BIG_ENDIAN) &&
51137786c7fSKevin Cernekee 	    of_property_read_bool(device, "native-endian"))
51237786c7fSKevin Cernekee 		return true;
51337786c7fSKevin Cernekee 	return false;
51437786c7fSKevin Cernekee }
51537786c7fSKevin Cernekee EXPORT_SYMBOL(of_device_is_big_endian);
51637786c7fSKevin Cernekee 
51737786c7fSKevin Cernekee /**
518e679c5f4SStephen Rothwell  *	of_get_parent - Get a node's parent if any
519e679c5f4SStephen Rothwell  *	@node:	Node to get parent
520e679c5f4SStephen Rothwell  *
521e679c5f4SStephen Rothwell  *	Returns a node pointer with refcount incremented, use
522e679c5f4SStephen Rothwell  *	of_node_put() on it when done.
523e679c5f4SStephen Rothwell  */
524e679c5f4SStephen Rothwell struct device_node *of_get_parent(const struct device_node *node)
525e679c5f4SStephen Rothwell {
526e679c5f4SStephen Rothwell 	struct device_node *np;
527d6d3c4e6SThomas Gleixner 	unsigned long flags;
528e679c5f4SStephen Rothwell 
529e679c5f4SStephen Rothwell 	if (!node)
530e679c5f4SStephen Rothwell 		return NULL;
531e679c5f4SStephen Rothwell 
532d6d3c4e6SThomas Gleixner 	raw_spin_lock_irqsave(&devtree_lock, flags);
533e679c5f4SStephen Rothwell 	np = of_node_get(node->parent);
534d6d3c4e6SThomas Gleixner 	raw_spin_unlock_irqrestore(&devtree_lock, flags);
535e679c5f4SStephen Rothwell 	return np;
536e679c5f4SStephen Rothwell }
537e679c5f4SStephen Rothwell EXPORT_SYMBOL(of_get_parent);
538d1cd355aSStephen Rothwell 
539d1cd355aSStephen Rothwell /**
540f4eb0107SMichael Ellerman  *	of_get_next_parent - Iterate to a node's parent
541f4eb0107SMichael Ellerman  *	@node:	Node to get parent of
542f4eb0107SMichael Ellerman  *
543f4eb0107SMichael Ellerman  *	This is like of_get_parent() except that it drops the
544f4eb0107SMichael Ellerman  *	refcount on the passed node, making it suitable for iterating
545f4eb0107SMichael Ellerman  *	through a node's parents.
546f4eb0107SMichael Ellerman  *
547f4eb0107SMichael Ellerman  *	Returns a node pointer with refcount incremented, use
548f4eb0107SMichael Ellerman  *	of_node_put() on it when done.
549f4eb0107SMichael Ellerman  */
550f4eb0107SMichael Ellerman struct device_node *of_get_next_parent(struct device_node *node)
551f4eb0107SMichael Ellerman {
552f4eb0107SMichael Ellerman 	struct device_node *parent;
553d6d3c4e6SThomas Gleixner 	unsigned long flags;
554f4eb0107SMichael Ellerman 
555f4eb0107SMichael Ellerman 	if (!node)
556f4eb0107SMichael Ellerman 		return NULL;
557f4eb0107SMichael Ellerman 
558d6d3c4e6SThomas Gleixner 	raw_spin_lock_irqsave(&devtree_lock, flags);
559f4eb0107SMichael Ellerman 	parent = of_node_get(node->parent);
560f4eb0107SMichael Ellerman 	of_node_put(node);
561d6d3c4e6SThomas Gleixner 	raw_spin_unlock_irqrestore(&devtree_lock, flags);
562f4eb0107SMichael Ellerman 	return parent;
563f4eb0107SMichael Ellerman }
5646695be68SGuennadi Liakhovetski EXPORT_SYMBOL(of_get_next_parent);
565f4eb0107SMichael Ellerman 
5660d0e02d6SGrant Likely static struct device_node *__of_get_next_child(const struct device_node *node,
5670d0e02d6SGrant Likely 						struct device_node *prev)
5680d0e02d6SGrant Likely {
5690d0e02d6SGrant Likely 	struct device_node *next;
5700d0e02d6SGrant Likely 
57143cb4367SFlorian Fainelli 	if (!node)
57243cb4367SFlorian Fainelli 		return NULL;
57343cb4367SFlorian Fainelli 
5740d0e02d6SGrant Likely 	next = prev ? prev->sibling : node->child;
5750d0e02d6SGrant Likely 	for (; next; next = next->sibling)
5760d0e02d6SGrant Likely 		if (of_node_get(next))
5770d0e02d6SGrant Likely 			break;
5780d0e02d6SGrant Likely 	of_node_put(prev);
5790d0e02d6SGrant Likely 	return next;
5800d0e02d6SGrant Likely }
5810d0e02d6SGrant Likely #define __for_each_child_of_node(parent, child) \
5820d0e02d6SGrant Likely 	for (child = __of_get_next_child(parent, NULL); child != NULL; \
5830d0e02d6SGrant Likely 	     child = __of_get_next_child(parent, child))
5840d0e02d6SGrant Likely 
585f4eb0107SMichael Ellerman /**
586d1cd355aSStephen Rothwell  *	of_get_next_child - Iterate a node childs
587d1cd355aSStephen Rothwell  *	@node:	parent node
588d1cd355aSStephen Rothwell  *	@prev:	previous child of the parent node, or NULL to get first
589d1cd355aSStephen Rothwell  *
59064808273SBaruch Siach  *	Returns a node pointer with refcount incremented, use of_node_put() on
59164808273SBaruch Siach  *	it when done. Returns NULL when prev is the last child. Decrements the
59264808273SBaruch Siach  *	refcount of prev.
593d1cd355aSStephen Rothwell  */
594d1cd355aSStephen Rothwell struct device_node *of_get_next_child(const struct device_node *node,
595d1cd355aSStephen Rothwell 	struct device_node *prev)
596d1cd355aSStephen Rothwell {
597d1cd355aSStephen Rothwell 	struct device_node *next;
598d6d3c4e6SThomas Gleixner 	unsigned long flags;
599d1cd355aSStephen Rothwell 
600d6d3c4e6SThomas Gleixner 	raw_spin_lock_irqsave(&devtree_lock, flags);
6010d0e02d6SGrant Likely 	next = __of_get_next_child(node, prev);
602d6d3c4e6SThomas Gleixner 	raw_spin_unlock_irqrestore(&devtree_lock, flags);
603d1cd355aSStephen Rothwell 	return next;
604d1cd355aSStephen Rothwell }
605d1cd355aSStephen Rothwell EXPORT_SYMBOL(of_get_next_child);
6061ef4d424SStephen Rothwell 
6071ef4d424SStephen Rothwell /**
6083296193dSTimur Tabi  *	of_get_next_available_child - Find the next available child node
6093296193dSTimur Tabi  *	@node:	parent node
6103296193dSTimur Tabi  *	@prev:	previous child of the parent node, or NULL to get first
6113296193dSTimur Tabi  *
6123296193dSTimur Tabi  *      This function is like of_get_next_child(), except that it
6133296193dSTimur Tabi  *      automatically skips any disabled nodes (i.e. status = "disabled").
6143296193dSTimur Tabi  */
6153296193dSTimur Tabi struct device_node *of_get_next_available_child(const struct device_node *node,
6163296193dSTimur Tabi 	struct device_node *prev)
6173296193dSTimur Tabi {
6183296193dSTimur Tabi 	struct device_node *next;
619d25d8694SBenjamin Herrenschmidt 	unsigned long flags;
6203296193dSTimur Tabi 
62143cb4367SFlorian Fainelli 	if (!node)
62243cb4367SFlorian Fainelli 		return NULL;
62343cb4367SFlorian Fainelli 
624d25d8694SBenjamin Herrenschmidt 	raw_spin_lock_irqsave(&devtree_lock, flags);
6253296193dSTimur Tabi 	next = prev ? prev->sibling : node->child;
6263296193dSTimur Tabi 	for (; next; next = next->sibling) {
627c31a0c05SStephen Warren 		if (!__of_device_is_available(next))
6283296193dSTimur Tabi 			continue;
6293296193dSTimur Tabi 		if (of_node_get(next))
6303296193dSTimur Tabi 			break;
6313296193dSTimur Tabi 	}
6323296193dSTimur Tabi 	of_node_put(prev);
633d25d8694SBenjamin Herrenschmidt 	raw_spin_unlock_irqrestore(&devtree_lock, flags);
6343296193dSTimur Tabi 	return next;
6353296193dSTimur Tabi }
6363296193dSTimur Tabi EXPORT_SYMBOL(of_get_next_available_child);
6373296193dSTimur Tabi 
6383296193dSTimur Tabi /**
6399c19761aSSrinivas Kandagatla  *	of_get_child_by_name - Find the child node by name for a given parent
6409c19761aSSrinivas Kandagatla  *	@node:	parent node
6419c19761aSSrinivas Kandagatla  *	@name:	child name to look for.
6429c19761aSSrinivas Kandagatla  *
6439c19761aSSrinivas Kandagatla  *      This function looks for child node for given matching name
6449c19761aSSrinivas Kandagatla  *
6459c19761aSSrinivas Kandagatla  *	Returns a node pointer if found, with refcount incremented, use
6469c19761aSSrinivas Kandagatla  *	of_node_put() on it when done.
6479c19761aSSrinivas Kandagatla  *	Returns NULL if node is not found.
6489c19761aSSrinivas Kandagatla  */
6499c19761aSSrinivas Kandagatla struct device_node *of_get_child_by_name(const struct device_node *node,
6509c19761aSSrinivas Kandagatla 				const char *name)
6519c19761aSSrinivas Kandagatla {
6529c19761aSSrinivas Kandagatla 	struct device_node *child;
6539c19761aSSrinivas Kandagatla 
6549c19761aSSrinivas Kandagatla 	for_each_child_of_node(node, child)
6559c19761aSSrinivas Kandagatla 		if (child->name && (of_node_cmp(child->name, name) == 0))
6569c19761aSSrinivas Kandagatla 			break;
6579c19761aSSrinivas Kandagatla 	return child;
6589c19761aSSrinivas Kandagatla }
6599c19761aSSrinivas Kandagatla EXPORT_SYMBOL(of_get_child_by_name);
6609c19761aSSrinivas Kandagatla 
661e0a58f3eSFrank Rowand struct device_node *__of_find_node_by_path(struct device_node *parent,
662c22e650eSGrant Likely 						const char *path)
663c22e650eSGrant Likely {
664c22e650eSGrant Likely 	struct device_node *child;
665106937e8SLeif Lindholm 	int len;
666c22e650eSGrant Likely 
667721a09e9SBrian Norris 	len = strcspn(path, "/:");
668c22e650eSGrant Likely 	if (!len)
669c22e650eSGrant Likely 		return NULL;
670c22e650eSGrant Likely 
671c22e650eSGrant Likely 	__for_each_child_of_node(parent, child) {
67295e6b1faSRob Herring 		const char *name = kbasename(child->full_name);
673c22e650eSGrant Likely 		if (strncmp(path, name, len) == 0 && (strlen(name) == len))
674c22e650eSGrant Likely 			return child;
675c22e650eSGrant Likely 	}
676c22e650eSGrant Likely 	return NULL;
677c22e650eSGrant Likely }
678c22e650eSGrant Likely 
67927497e11SRob Herring struct device_node *__of_find_node_by_full_path(struct device_node *node,
68027497e11SRob Herring 						const char *path)
68127497e11SRob Herring {
68227497e11SRob Herring 	const char *separator = strchr(path, ':');
68327497e11SRob Herring 
68427497e11SRob Herring 	while (node && *path == '/') {
68527497e11SRob Herring 		struct device_node *tmp = node;
68627497e11SRob Herring 
68727497e11SRob Herring 		path++; /* Increment past '/' delimiter */
68827497e11SRob Herring 		node = __of_find_node_by_path(node, path);
68927497e11SRob Herring 		of_node_put(tmp);
69027497e11SRob Herring 		path = strchrnul(path, '/');
69127497e11SRob Herring 		if (separator && separator < path)
69227497e11SRob Herring 			break;
69327497e11SRob Herring 	}
69427497e11SRob Herring 	return node;
69527497e11SRob Herring }
69627497e11SRob Herring 
6979c19761aSSrinivas Kandagatla /**
69875c28c09SLeif Lindholm  *	of_find_node_opts_by_path - Find a node matching a full OF path
699c22e650eSGrant Likely  *	@path: Either the full path to match, or if the path does not
700c22e650eSGrant Likely  *	       start with '/', the name of a property of the /aliases
701c22e650eSGrant Likely  *	       node (an alias).  In the case of an alias, the node
702c22e650eSGrant Likely  *	       matching the alias' value will be returned.
70375c28c09SLeif Lindholm  *	@opts: Address of a pointer into which to store the start of
70475c28c09SLeif Lindholm  *	       an options string appended to the end of the path with
70575c28c09SLeif Lindholm  *	       a ':' separator.
706c22e650eSGrant Likely  *
707c22e650eSGrant Likely  *	Valid paths:
708c22e650eSGrant Likely  *		/foo/bar	Full path
709c22e650eSGrant Likely  *		foo		Valid alias
710c22e650eSGrant Likely  *		foo/bar		Valid alias + relative path
7111ef4d424SStephen Rothwell  *
7121ef4d424SStephen Rothwell  *	Returns a node pointer with refcount incremented, use
7131ef4d424SStephen Rothwell  *	of_node_put() on it when done.
7141ef4d424SStephen Rothwell  */
71575c28c09SLeif Lindholm struct device_node *of_find_node_opts_by_path(const char *path, const char **opts)
7161ef4d424SStephen Rothwell {
717c22e650eSGrant Likely 	struct device_node *np = NULL;
718c22e650eSGrant Likely 	struct property *pp;
719d6d3c4e6SThomas Gleixner 	unsigned long flags;
72075c28c09SLeif Lindholm 	const char *separator = strchr(path, ':');
72175c28c09SLeif Lindholm 
72275c28c09SLeif Lindholm 	if (opts)
72375c28c09SLeif Lindholm 		*opts = separator ? separator + 1 : NULL;
7241ef4d424SStephen Rothwell 
725c22e650eSGrant Likely 	if (strcmp(path, "/") == 0)
7265063e25aSGrant Likely 		return of_node_get(of_root);
727c22e650eSGrant Likely 
728c22e650eSGrant Likely 	/* The path could begin with an alias */
729c22e650eSGrant Likely 	if (*path != '/') {
730106937e8SLeif Lindholm 		int len;
731106937e8SLeif Lindholm 		const char *p = separator;
732106937e8SLeif Lindholm 
733106937e8SLeif Lindholm 		if (!p)
734106937e8SLeif Lindholm 			p = strchrnul(path, '/');
735106937e8SLeif Lindholm 		len = p - path;
736c22e650eSGrant Likely 
737c22e650eSGrant Likely 		/* of_aliases must not be NULL */
738c22e650eSGrant Likely 		if (!of_aliases)
739c22e650eSGrant Likely 			return NULL;
740c22e650eSGrant Likely 
741c22e650eSGrant Likely 		for_each_property_of_node(of_aliases, pp) {
742c22e650eSGrant Likely 			if (strlen(pp->name) == len && !strncmp(pp->name, path, len)) {
743c22e650eSGrant Likely 				np = of_find_node_by_path(pp->value);
7441ef4d424SStephen Rothwell 				break;
7451ef4d424SStephen Rothwell 			}
746c22e650eSGrant Likely 		}
747c22e650eSGrant Likely 		if (!np)
748c22e650eSGrant Likely 			return NULL;
749c22e650eSGrant Likely 		path = p;
750c22e650eSGrant Likely 	}
751c22e650eSGrant Likely 
752c22e650eSGrant Likely 	/* Step down the tree matching path components */
753c22e650eSGrant Likely 	raw_spin_lock_irqsave(&devtree_lock, flags);
754c22e650eSGrant Likely 	if (!np)
7555063e25aSGrant Likely 		np = of_node_get(of_root);
75627497e11SRob Herring 	np = __of_find_node_by_full_path(np, path);
757d6d3c4e6SThomas Gleixner 	raw_spin_unlock_irqrestore(&devtree_lock, flags);
7581ef4d424SStephen Rothwell 	return np;
7591ef4d424SStephen Rothwell }
76075c28c09SLeif Lindholm EXPORT_SYMBOL(of_find_node_opts_by_path);
7611ef4d424SStephen Rothwell 
7621ef4d424SStephen Rothwell /**
7631ef4d424SStephen Rothwell  *	of_find_node_by_name - Find a node by its "name" property
76402a876b5SStephen Boyd  *	@from:	The node to start searching from or NULL; the node
7651ef4d424SStephen Rothwell  *		you pass will not be searched, only the next one
76602a876b5SStephen Boyd  *		will. Typically, you pass what the previous call
76702a876b5SStephen Boyd  *		returned. of_node_put() will be called on @from.
7681ef4d424SStephen Rothwell  *	@name:	The name string to match against
7691ef4d424SStephen Rothwell  *
7701ef4d424SStephen Rothwell  *	Returns a node pointer with refcount incremented, use
7711ef4d424SStephen Rothwell  *	of_node_put() on it when done.
7721ef4d424SStephen Rothwell  */
7731ef4d424SStephen Rothwell struct device_node *of_find_node_by_name(struct device_node *from,
7741ef4d424SStephen Rothwell 	const char *name)
7751ef4d424SStephen Rothwell {
7761ef4d424SStephen Rothwell 	struct device_node *np;
777d6d3c4e6SThomas Gleixner 	unsigned long flags;
7781ef4d424SStephen Rothwell 
779d6d3c4e6SThomas Gleixner 	raw_spin_lock_irqsave(&devtree_lock, flags);
7805063e25aSGrant Likely 	for_each_of_allnodes_from(from, np)
7811ef4d424SStephen Rothwell 		if (np->name && (of_node_cmp(np->name, name) == 0)
7821ef4d424SStephen Rothwell 		    && of_node_get(np))
7831ef4d424SStephen Rothwell 			break;
7841ef4d424SStephen Rothwell 	of_node_put(from);
785d6d3c4e6SThomas Gleixner 	raw_spin_unlock_irqrestore(&devtree_lock, flags);
7861ef4d424SStephen Rothwell 	return np;
7871ef4d424SStephen Rothwell }
7881ef4d424SStephen Rothwell EXPORT_SYMBOL(of_find_node_by_name);
7891ef4d424SStephen Rothwell 
7901ef4d424SStephen Rothwell /**
7911ef4d424SStephen Rothwell  *	of_find_node_by_type - Find a node by its "device_type" property
7921ef4d424SStephen Rothwell  *	@from:	The node to start searching from, or NULL to start searching
7931ef4d424SStephen Rothwell  *		the entire device tree. The node you pass will not be
7941ef4d424SStephen Rothwell  *		searched, only the next one will; typically, you pass
7951ef4d424SStephen Rothwell  *		what the previous call returned. of_node_put() will be
7961ef4d424SStephen Rothwell  *		called on from for you.
7971ef4d424SStephen Rothwell  *	@type:	The type string to match against
7981ef4d424SStephen Rothwell  *
7991ef4d424SStephen Rothwell  *	Returns a node pointer with refcount incremented, use
8001ef4d424SStephen Rothwell  *	of_node_put() on it when done.
8011ef4d424SStephen Rothwell  */
8021ef4d424SStephen Rothwell struct device_node *of_find_node_by_type(struct device_node *from,
8031ef4d424SStephen Rothwell 	const char *type)
8041ef4d424SStephen Rothwell {
8051ef4d424SStephen Rothwell 	struct device_node *np;
806d6d3c4e6SThomas Gleixner 	unsigned long flags;
8071ef4d424SStephen Rothwell 
808d6d3c4e6SThomas Gleixner 	raw_spin_lock_irqsave(&devtree_lock, flags);
8095063e25aSGrant Likely 	for_each_of_allnodes_from(from, np)
8101ef4d424SStephen Rothwell 		if (np->type && (of_node_cmp(np->type, type) == 0)
8111ef4d424SStephen Rothwell 		    && of_node_get(np))
8121ef4d424SStephen Rothwell 			break;
8131ef4d424SStephen Rothwell 	of_node_put(from);
814d6d3c4e6SThomas Gleixner 	raw_spin_unlock_irqrestore(&devtree_lock, flags);
8151ef4d424SStephen Rothwell 	return np;
8161ef4d424SStephen Rothwell }
8171ef4d424SStephen Rothwell EXPORT_SYMBOL(of_find_node_by_type);
8181ef4d424SStephen Rothwell 
8191ef4d424SStephen Rothwell /**
8201ef4d424SStephen Rothwell  *	of_find_compatible_node - Find a node based on type and one of the
8211ef4d424SStephen Rothwell  *                                tokens in its "compatible" property
8221ef4d424SStephen Rothwell  *	@from:		The node to start searching from or NULL, the node
8231ef4d424SStephen Rothwell  *			you pass will not be searched, only the next one
8241ef4d424SStephen Rothwell  *			will; typically, you pass what the previous call
8251ef4d424SStephen Rothwell  *			returned. of_node_put() will be called on it
8261ef4d424SStephen Rothwell  *	@type:		The type string to match "device_type" or NULL to ignore
8271ef4d424SStephen Rothwell  *	@compatible:	The string to match to one of the tokens in the device
8281ef4d424SStephen Rothwell  *			"compatible" list.
8291ef4d424SStephen Rothwell  *
8301ef4d424SStephen Rothwell  *	Returns a node pointer with refcount incremented, use
8311ef4d424SStephen Rothwell  *	of_node_put() on it when done.
8321ef4d424SStephen Rothwell  */
8331ef4d424SStephen Rothwell struct device_node *of_find_compatible_node(struct device_node *from,
8341ef4d424SStephen Rothwell 	const char *type, const char *compatible)
8351ef4d424SStephen Rothwell {
8361ef4d424SStephen Rothwell 	struct device_node *np;
837d6d3c4e6SThomas Gleixner 	unsigned long flags;
8381ef4d424SStephen Rothwell 
839d6d3c4e6SThomas Gleixner 	raw_spin_lock_irqsave(&devtree_lock, flags);
8405063e25aSGrant Likely 	for_each_of_allnodes_from(from, np)
841215a14cfSKevin Hao 		if (__of_device_is_compatible(np, compatible, type, NULL) &&
84228d0e36bSThomas Gleixner 		    of_node_get(np))
8431ef4d424SStephen Rothwell 			break;
8441ef4d424SStephen Rothwell 	of_node_put(from);
845d6d3c4e6SThomas Gleixner 	raw_spin_unlock_irqrestore(&devtree_lock, flags);
8461ef4d424SStephen Rothwell 	return np;
8471ef4d424SStephen Rothwell }
8481ef4d424SStephen Rothwell EXPORT_SYMBOL(of_find_compatible_node);
849283029d1SGrant Likely 
850283029d1SGrant Likely /**
8511e291b14SMichael Ellerman  *	of_find_node_with_property - Find a node which has a property with
8521e291b14SMichael Ellerman  *                                   the given name.
8531e291b14SMichael Ellerman  *	@from:		The node to start searching from or NULL, the node
8541e291b14SMichael Ellerman  *			you pass will not be searched, only the next one
8551e291b14SMichael Ellerman  *			will; typically, you pass what the previous call
8561e291b14SMichael Ellerman  *			returned. of_node_put() will be called on it
8571e291b14SMichael Ellerman  *	@prop_name:	The name of the property to look for.
8581e291b14SMichael Ellerman  *
8591e291b14SMichael Ellerman  *	Returns a node pointer with refcount incremented, use
8601e291b14SMichael Ellerman  *	of_node_put() on it when done.
8611e291b14SMichael Ellerman  */
8621e291b14SMichael Ellerman struct device_node *of_find_node_with_property(struct device_node *from,
8631e291b14SMichael Ellerman 	const char *prop_name)
8641e291b14SMichael Ellerman {
8651e291b14SMichael Ellerman 	struct device_node *np;
8661e291b14SMichael Ellerman 	struct property *pp;
867d6d3c4e6SThomas Gleixner 	unsigned long flags;
8681e291b14SMichael Ellerman 
869d6d3c4e6SThomas Gleixner 	raw_spin_lock_irqsave(&devtree_lock, flags);
8705063e25aSGrant Likely 	for_each_of_allnodes_from(from, np) {
871a3a7cab1SSachin Kamat 		for (pp = np->properties; pp; pp = pp->next) {
8721e291b14SMichael Ellerman 			if (of_prop_cmp(pp->name, prop_name) == 0) {
8731e291b14SMichael Ellerman 				of_node_get(np);
8741e291b14SMichael Ellerman 				goto out;
8751e291b14SMichael Ellerman 			}
8761e291b14SMichael Ellerman 		}
8771e291b14SMichael Ellerman 	}
8781e291b14SMichael Ellerman out:
8791e291b14SMichael Ellerman 	of_node_put(from);
880d6d3c4e6SThomas Gleixner 	raw_spin_unlock_irqrestore(&devtree_lock, flags);
8811e291b14SMichael Ellerman 	return np;
8821e291b14SMichael Ellerman }
8831e291b14SMichael Ellerman EXPORT_SYMBOL(of_find_node_with_property);
8841e291b14SMichael Ellerman 
88528d0e36bSThomas Gleixner static
88628d0e36bSThomas Gleixner const struct of_device_id *__of_match_node(const struct of_device_id *matches,
887283029d1SGrant Likely 					   const struct device_node *node)
888283029d1SGrant Likely {
889215a14cfSKevin Hao 	const struct of_device_id *best_match = NULL;
890215a14cfSKevin Hao 	int score, best_score = 0;
891215a14cfSKevin Hao 
892a52f07ecSGrant Likely 	if (!matches)
893a52f07ecSGrant Likely 		return NULL;
894a52f07ecSGrant Likely 
895215a14cfSKevin Hao 	for (; matches->name[0] || matches->type[0] || matches->compatible[0]; matches++) {
896215a14cfSKevin Hao 		score = __of_device_is_compatible(node, matches->compatible,
897215a14cfSKevin Hao 						  matches->type, matches->name);
898215a14cfSKevin Hao 		if (score > best_score) {
899215a14cfSKevin Hao 			best_match = matches;
900215a14cfSKevin Hao 			best_score = score;
901283029d1SGrant Likely 		}
902215a14cfSKevin Hao 	}
903215a14cfSKevin Hao 
904215a14cfSKevin Hao 	return best_match;
905283029d1SGrant Likely }
90628d0e36bSThomas Gleixner 
90728d0e36bSThomas Gleixner /**
908c50949d3SGeert Uytterhoeven  * of_match_node - Tell if a device_node has a matching of_match structure
90928d0e36bSThomas Gleixner  *	@matches:	array of of device match structures to search in
91028d0e36bSThomas Gleixner  *	@node:		the of device structure to match against
91128d0e36bSThomas Gleixner  *
91271c5498eSKevin Hao  *	Low level utility function used by device matching.
91328d0e36bSThomas Gleixner  */
91428d0e36bSThomas Gleixner const struct of_device_id *of_match_node(const struct of_device_id *matches,
91528d0e36bSThomas Gleixner 					 const struct device_node *node)
91628d0e36bSThomas Gleixner {
91728d0e36bSThomas Gleixner 	const struct of_device_id *match;
918d6d3c4e6SThomas Gleixner 	unsigned long flags;
91928d0e36bSThomas Gleixner 
920d6d3c4e6SThomas Gleixner 	raw_spin_lock_irqsave(&devtree_lock, flags);
92128d0e36bSThomas Gleixner 	match = __of_match_node(matches, node);
922d6d3c4e6SThomas Gleixner 	raw_spin_unlock_irqrestore(&devtree_lock, flags);
92328d0e36bSThomas Gleixner 	return match;
92428d0e36bSThomas Gleixner }
925283029d1SGrant Likely EXPORT_SYMBOL(of_match_node);
926283029d1SGrant Likely 
927283029d1SGrant Likely /**
92850c8af4cSStephen Warren  *	of_find_matching_node_and_match - Find a node based on an of_device_id
92950c8af4cSStephen Warren  *					  match table.
930283029d1SGrant Likely  *	@from:		The node to start searching from or NULL, the node
931283029d1SGrant Likely  *			you pass will not be searched, only the next one
932283029d1SGrant Likely  *			will; typically, you pass what the previous call
933283029d1SGrant Likely  *			returned. of_node_put() will be called on it
934283029d1SGrant Likely  *	@matches:	array of of device match structures to search in
93550c8af4cSStephen Warren  *	@match		Updated to point at the matches entry which matched
936283029d1SGrant Likely  *
937283029d1SGrant Likely  *	Returns a node pointer with refcount incremented, use
938283029d1SGrant Likely  *	of_node_put() on it when done.
939283029d1SGrant Likely  */
94050c8af4cSStephen Warren struct device_node *of_find_matching_node_and_match(struct device_node *from,
94150c8af4cSStephen Warren 					const struct of_device_id *matches,
94250c8af4cSStephen Warren 					const struct of_device_id **match)
943283029d1SGrant Likely {
944283029d1SGrant Likely 	struct device_node *np;
945dc71bcf1SThomas Abraham 	const struct of_device_id *m;
946d6d3c4e6SThomas Gleixner 	unsigned long flags;
947283029d1SGrant Likely 
94850c8af4cSStephen Warren 	if (match)
94950c8af4cSStephen Warren 		*match = NULL;
95050c8af4cSStephen Warren 
951d6d3c4e6SThomas Gleixner 	raw_spin_lock_irqsave(&devtree_lock, flags);
9525063e25aSGrant Likely 	for_each_of_allnodes_from(from, np) {
95328d0e36bSThomas Gleixner 		m = __of_match_node(matches, np);
954dc71bcf1SThomas Abraham 		if (m && of_node_get(np)) {
95550c8af4cSStephen Warren 			if (match)
956dc71bcf1SThomas Abraham 				*match = m;
957283029d1SGrant Likely 			break;
958283029d1SGrant Likely 		}
95950c8af4cSStephen Warren 	}
960283029d1SGrant Likely 	of_node_put(from);
961d6d3c4e6SThomas Gleixner 	raw_spin_unlock_irqrestore(&devtree_lock, flags);
962283029d1SGrant Likely 	return np;
963283029d1SGrant Likely }
96480c2022eSGrant Likely EXPORT_SYMBOL(of_find_matching_node_and_match);
9653f07af49SGrant Likely 
9663f07af49SGrant Likely /**
9673f07af49SGrant Likely  * of_modalias_node - Lookup appropriate modalias for a device node
9683f07af49SGrant Likely  * @node:	pointer to a device tree node
9693f07af49SGrant Likely  * @modalias:	Pointer to buffer that modalias value will be copied into
9703f07af49SGrant Likely  * @len:	Length of modalias value
9713f07af49SGrant Likely  *
9722ffe8c5fSGrant Likely  * Based on the value of the compatible property, this routine will attempt
9732ffe8c5fSGrant Likely  * to choose an appropriate modalias value for a particular device tree node.
9742ffe8c5fSGrant Likely  * It does this by stripping the manufacturer prefix (as delimited by a ',')
9752ffe8c5fSGrant Likely  * from the first entry in the compatible list property.
9763f07af49SGrant Likely  *
9772ffe8c5fSGrant Likely  * This routine returns 0 on success, <0 on failure.
9783f07af49SGrant Likely  */
9793f07af49SGrant Likely int of_modalias_node(struct device_node *node, char *modalias, int len)
9803f07af49SGrant Likely {
9812ffe8c5fSGrant Likely 	const char *compatible, *p;
9822ffe8c5fSGrant Likely 	int cplen;
9833f07af49SGrant Likely 
9843f07af49SGrant Likely 	compatible = of_get_property(node, "compatible", &cplen);
9852ffe8c5fSGrant Likely 	if (!compatible || strlen(compatible) > cplen)
9863f07af49SGrant Likely 		return -ENODEV;
9873f07af49SGrant Likely 	p = strchr(compatible, ',');
9882ffe8c5fSGrant Likely 	strlcpy(modalias, p ? p + 1 : compatible, len);
9893f07af49SGrant Likely 	return 0;
9903f07af49SGrant Likely }
9913f07af49SGrant Likely EXPORT_SYMBOL_GPL(of_modalias_node);
9923f07af49SGrant Likely 
99364b60e09SAnton Vorontsov /**
99489751a7cSJeremy Kerr  * of_find_node_by_phandle - Find a node given a phandle
99589751a7cSJeremy Kerr  * @handle:	phandle of the node to find
99689751a7cSJeremy Kerr  *
99789751a7cSJeremy Kerr  * Returns a node pointer with refcount incremented, use
99889751a7cSJeremy Kerr  * of_node_put() on it when done.
99989751a7cSJeremy Kerr  */
100089751a7cSJeremy Kerr struct device_node *of_find_node_by_phandle(phandle handle)
100189751a7cSJeremy Kerr {
100289751a7cSJeremy Kerr 	struct device_node *np;
1003d25d8694SBenjamin Herrenschmidt 	unsigned long flags;
100489751a7cSJeremy Kerr 
1005fc59b447SGrant Likely 	if (!handle)
1006fc59b447SGrant Likely 		return NULL;
1007fc59b447SGrant Likely 
1008d25d8694SBenjamin Herrenschmidt 	raw_spin_lock_irqsave(&devtree_lock, flags);
10095063e25aSGrant Likely 	for_each_of_allnodes(np)
101089751a7cSJeremy Kerr 		if (np->phandle == handle)
101189751a7cSJeremy Kerr 			break;
101289751a7cSJeremy Kerr 	of_node_get(np);
1013d25d8694SBenjamin Herrenschmidt 	raw_spin_unlock_irqrestore(&devtree_lock, flags);
101489751a7cSJeremy Kerr 	return np;
101589751a7cSJeremy Kerr }
101689751a7cSJeremy Kerr EXPORT_SYMBOL(of_find_node_by_phandle);
101789751a7cSJeremy Kerr 
1018624cfca5SGrant Likely void of_print_phandle_args(const char *msg, const struct of_phandle_args *args)
1019624cfca5SGrant Likely {
1020624cfca5SGrant Likely 	int i;
10210d638a07SRob Herring 	printk("%s %pOF", msg, args->np);
10224aa66344SMarcin Nowakowski 	for (i = 0; i < args->args_count; i++) {
10234aa66344SMarcin Nowakowski 		const char delim = i ? ',' : ':';
10244aa66344SMarcin Nowakowski 
10254aa66344SMarcin Nowakowski 		pr_cont("%c%08x", delim, args->args[i]);
10264aa66344SMarcin Nowakowski 	}
10274aa66344SMarcin Nowakowski 	pr_cont("\n");
1028624cfca5SGrant Likely }
1029624cfca5SGrant Likely 
103074e1fbb1SJoerg Roedel int of_phandle_iterator_init(struct of_phandle_iterator *it,
103174e1fbb1SJoerg Roedel 		const struct device_node *np,
103274e1fbb1SJoerg Roedel 		const char *list_name,
103374e1fbb1SJoerg Roedel 		const char *cells_name,
103474e1fbb1SJoerg Roedel 		int cell_count)
103574e1fbb1SJoerg Roedel {
103674e1fbb1SJoerg Roedel 	const __be32 *list;
103774e1fbb1SJoerg Roedel 	int size;
103874e1fbb1SJoerg Roedel 
103974e1fbb1SJoerg Roedel 	memset(it, 0, sizeof(*it));
104074e1fbb1SJoerg Roedel 
104174e1fbb1SJoerg Roedel 	list = of_get_property(np, list_name, &size);
104274e1fbb1SJoerg Roedel 	if (!list)
104374e1fbb1SJoerg Roedel 		return -ENOENT;
104474e1fbb1SJoerg Roedel 
104574e1fbb1SJoerg Roedel 	it->cells_name = cells_name;
104674e1fbb1SJoerg Roedel 	it->cell_count = cell_count;
104774e1fbb1SJoerg Roedel 	it->parent = np;
104874e1fbb1SJoerg Roedel 	it->list_end = list + size / sizeof(*list);
104974e1fbb1SJoerg Roedel 	it->phandle_end = list;
105074e1fbb1SJoerg Roedel 	it->cur = list;
105174e1fbb1SJoerg Roedel 
105274e1fbb1SJoerg Roedel 	return 0;
105374e1fbb1SJoerg Roedel }
105400bab23fSKuninori Morimoto EXPORT_SYMBOL_GPL(of_phandle_iterator_init);
105574e1fbb1SJoerg Roedel 
1056cd209b41SJoerg Roedel int of_phandle_iterator_next(struct of_phandle_iterator *it)
1057cd209b41SJoerg Roedel {
1058cd209b41SJoerg Roedel 	uint32_t count = 0;
1059cd209b41SJoerg Roedel 
1060cd209b41SJoerg Roedel 	if (it->node) {
1061cd209b41SJoerg Roedel 		of_node_put(it->node);
1062cd209b41SJoerg Roedel 		it->node = NULL;
1063cd209b41SJoerg Roedel 	}
1064cd209b41SJoerg Roedel 
1065cd209b41SJoerg Roedel 	if (!it->cur || it->phandle_end >= it->list_end)
1066cd209b41SJoerg Roedel 		return -ENOENT;
1067cd209b41SJoerg Roedel 
1068cd209b41SJoerg Roedel 	it->cur = it->phandle_end;
1069cd209b41SJoerg Roedel 
1070cd209b41SJoerg Roedel 	/* If phandle is 0, then it is an empty entry with no arguments. */
1071cd209b41SJoerg Roedel 	it->phandle = be32_to_cpup(it->cur++);
1072cd209b41SJoerg Roedel 
1073cd209b41SJoerg Roedel 	if (it->phandle) {
1074cd209b41SJoerg Roedel 
1075cd209b41SJoerg Roedel 		/*
1076cd209b41SJoerg Roedel 		 * Find the provider node and parse the #*-cells property to
1077cd209b41SJoerg Roedel 		 * determine the argument length.
1078cd209b41SJoerg Roedel 		 */
1079cd209b41SJoerg Roedel 		it->node = of_find_node_by_phandle(it->phandle);
1080cd209b41SJoerg Roedel 
1081cd209b41SJoerg Roedel 		if (it->cells_name) {
1082cd209b41SJoerg Roedel 			if (!it->node) {
10830d638a07SRob Herring 				pr_err("%pOF: could not find phandle\n",
10840d638a07SRob Herring 				       it->parent);
1085cd209b41SJoerg Roedel 				goto err;
1086cd209b41SJoerg Roedel 			}
1087cd209b41SJoerg Roedel 
1088cd209b41SJoerg Roedel 			if (of_property_read_u32(it->node, it->cells_name,
1089cd209b41SJoerg Roedel 						 &count)) {
10900d638a07SRob Herring 				pr_err("%pOF: could not get %s for %pOF\n",
10910d638a07SRob Herring 				       it->parent,
1092cd209b41SJoerg Roedel 				       it->cells_name,
10930d638a07SRob Herring 				       it->node);
1094cd209b41SJoerg Roedel 				goto err;
1095cd209b41SJoerg Roedel 			}
1096cd209b41SJoerg Roedel 		} else {
1097cd209b41SJoerg Roedel 			count = it->cell_count;
1098cd209b41SJoerg Roedel 		}
1099cd209b41SJoerg Roedel 
1100cd209b41SJoerg Roedel 		/*
1101cd209b41SJoerg Roedel 		 * Make sure that the arguments actually fit in the remaining
1102cd209b41SJoerg Roedel 		 * property data length
1103cd209b41SJoerg Roedel 		 */
1104cd209b41SJoerg Roedel 		if (it->cur + count > it->list_end) {
11050d638a07SRob Herring 			pr_err("%pOF: arguments longer than property\n",
11060d638a07SRob Herring 			       it->parent);
1107cd209b41SJoerg Roedel 			goto err;
1108cd209b41SJoerg Roedel 		}
1109cd209b41SJoerg Roedel 	}
1110cd209b41SJoerg Roedel 
1111cd209b41SJoerg Roedel 	it->phandle_end = it->cur + count;
1112cd209b41SJoerg Roedel 	it->cur_count = count;
1113cd209b41SJoerg Roedel 
1114cd209b41SJoerg Roedel 	return 0;
1115cd209b41SJoerg Roedel 
1116cd209b41SJoerg Roedel err:
1117cd209b41SJoerg Roedel 	if (it->node) {
1118cd209b41SJoerg Roedel 		of_node_put(it->node);
1119cd209b41SJoerg Roedel 		it->node = NULL;
1120cd209b41SJoerg Roedel 	}
1121cd209b41SJoerg Roedel 
1122cd209b41SJoerg Roedel 	return -EINVAL;
1123cd209b41SJoerg Roedel }
112400bab23fSKuninori Morimoto EXPORT_SYMBOL_GPL(of_phandle_iterator_next);
1125cd209b41SJoerg Roedel 
1126abdaa77bSJoerg Roedel int of_phandle_iterator_args(struct of_phandle_iterator *it,
1127abdaa77bSJoerg Roedel 			     uint32_t *args,
1128abdaa77bSJoerg Roedel 			     int size)
1129abdaa77bSJoerg Roedel {
1130abdaa77bSJoerg Roedel 	int i, count;
1131abdaa77bSJoerg Roedel 
1132abdaa77bSJoerg Roedel 	count = it->cur_count;
1133abdaa77bSJoerg Roedel 
1134abdaa77bSJoerg Roedel 	if (WARN_ON(size < count))
1135abdaa77bSJoerg Roedel 		count = size;
1136abdaa77bSJoerg Roedel 
1137abdaa77bSJoerg Roedel 	for (i = 0; i < count; i++)
1138abdaa77bSJoerg Roedel 		args[i] = be32_to_cpup(it->cur++);
1139abdaa77bSJoerg Roedel 
1140abdaa77bSJoerg Roedel 	return count;
1141abdaa77bSJoerg Roedel }
1142abdaa77bSJoerg Roedel 
1143bd69f73fSGrant Likely static int __of_parse_phandle_with_args(const struct device_node *np,
1144bd69f73fSGrant Likely 					const char *list_name,
1145035fd948SStephen Warren 					const char *cells_name,
1146035fd948SStephen Warren 					int cell_count, int index,
114715c9a0acSGrant Likely 					struct of_phandle_args *out_args)
114864b60e09SAnton Vorontsov {
114974e1fbb1SJoerg Roedel 	struct of_phandle_iterator it;
115074e1fbb1SJoerg Roedel 	int rc, cur_index = 0;
115115c9a0acSGrant Likely 
115215c9a0acSGrant Likely 	/* Loop over the phandles until all the requested entry is found */
1153f623ce95SJoerg Roedel 	of_for_each_phandle(&it, rc, np, list_name, cells_name, cell_count) {
115415c9a0acSGrant Likely 		/*
1155cd209b41SJoerg Roedel 		 * All of the error cases bail out of the loop, so at
115615c9a0acSGrant Likely 		 * this point, the parsing is successful. If the requested
115715c9a0acSGrant Likely 		 * index matches, then fill the out_args structure and return,
115815c9a0acSGrant Likely 		 * or return -ENOENT for an empty entry.
115915c9a0acSGrant Likely 		 */
116023ce04c0SGrant Likely 		rc = -ENOENT;
116115c9a0acSGrant Likely 		if (cur_index == index) {
116274e1fbb1SJoerg Roedel 			if (!it.phandle)
116323ce04c0SGrant Likely 				goto err;
116415c9a0acSGrant Likely 
116515c9a0acSGrant Likely 			if (out_args) {
1166abdaa77bSJoerg Roedel 				int c;
1167abdaa77bSJoerg Roedel 
1168abdaa77bSJoerg Roedel 				c = of_phandle_iterator_args(&it,
1169abdaa77bSJoerg Roedel 							     out_args->args,
1170abdaa77bSJoerg Roedel 							     MAX_PHANDLE_ARGS);
117174e1fbb1SJoerg Roedel 				out_args->np = it.node;
1172abdaa77bSJoerg Roedel 				out_args->args_count = c;
1173b855f16bSTang Yuantian 			} else {
117474e1fbb1SJoerg Roedel 				of_node_put(it.node);
117515c9a0acSGrant Likely 			}
117623ce04c0SGrant Likely 
117723ce04c0SGrant Likely 			/* Found it! return success */
117815c9a0acSGrant Likely 			return 0;
117915c9a0acSGrant Likely 		}
118064b60e09SAnton Vorontsov 
118164b60e09SAnton Vorontsov 		cur_index++;
118264b60e09SAnton Vorontsov 	}
118364b60e09SAnton Vorontsov 
118423ce04c0SGrant Likely 	/*
118523ce04c0SGrant Likely 	 * Unlock node before returning result; will be one of:
118623ce04c0SGrant Likely 	 * -ENOENT : index is for empty phandle
118723ce04c0SGrant Likely 	 * -EINVAL : parsing error on data
118823ce04c0SGrant Likely 	 */
1189cd209b41SJoerg Roedel 
119023ce04c0SGrant Likely  err:
119174e1fbb1SJoerg Roedel 	of_node_put(it.node);
119223ce04c0SGrant Likely 	return rc;
119364b60e09SAnton Vorontsov }
1194bd69f73fSGrant Likely 
1195eded9dd4SStephen Warren /**
11965fba49e3SStephen Warren  * of_parse_phandle - Resolve a phandle property to a device_node pointer
11975fba49e3SStephen Warren  * @np: Pointer to device node holding phandle property
11985fba49e3SStephen Warren  * @phandle_name: Name of property holding a phandle value
11995fba49e3SStephen Warren  * @index: For properties holding a table of phandles, this is the index into
12005fba49e3SStephen Warren  *         the table
12015fba49e3SStephen Warren  *
12025fba49e3SStephen Warren  * Returns the device_node pointer with refcount incremented.  Use
12035fba49e3SStephen Warren  * of_node_put() on it when done.
12045fba49e3SStephen Warren  */
12055fba49e3SStephen Warren struct device_node *of_parse_phandle(const struct device_node *np,
12065fba49e3SStephen Warren 				     const char *phandle_name, int index)
12075fba49e3SStephen Warren {
120891d9942cSStephen Warren 	struct of_phandle_args args;
12095fba49e3SStephen Warren 
121091d9942cSStephen Warren 	if (index < 0)
12115fba49e3SStephen Warren 		return NULL;
12125fba49e3SStephen Warren 
121391d9942cSStephen Warren 	if (__of_parse_phandle_with_args(np, phandle_name, NULL, 0,
121491d9942cSStephen Warren 					 index, &args))
121591d9942cSStephen Warren 		return NULL;
121691d9942cSStephen Warren 
121791d9942cSStephen Warren 	return args.np;
12185fba49e3SStephen Warren }
12195fba49e3SStephen Warren EXPORT_SYMBOL(of_parse_phandle);
12205fba49e3SStephen Warren 
12215fba49e3SStephen Warren /**
1222eded9dd4SStephen Warren  * of_parse_phandle_with_args() - Find a node pointed by phandle in a list
1223eded9dd4SStephen Warren  * @np:		pointer to a device tree node containing a list
1224eded9dd4SStephen Warren  * @list_name:	property name that contains a list
1225eded9dd4SStephen Warren  * @cells_name:	property name that specifies phandles' arguments count
1226eded9dd4SStephen Warren  * @index:	index of a phandle to parse out
1227eded9dd4SStephen Warren  * @out_args:	optional pointer to output arguments structure (will be filled)
1228eded9dd4SStephen Warren  *
1229eded9dd4SStephen Warren  * This function is useful to parse lists of phandles and their arguments.
1230eded9dd4SStephen Warren  * Returns 0 on success and fills out_args, on error returns appropriate
1231eded9dd4SStephen Warren  * errno value.
1232eded9dd4SStephen Warren  *
1233d94a75c1SGeert Uytterhoeven  * Caller is responsible to call of_node_put() on the returned out_args->np
1234eded9dd4SStephen Warren  * pointer.
1235eded9dd4SStephen Warren  *
1236eded9dd4SStephen Warren  * Example:
1237eded9dd4SStephen Warren  *
1238eded9dd4SStephen Warren  * phandle1: node1 {
1239eded9dd4SStephen Warren  *	#list-cells = <2>;
1240eded9dd4SStephen Warren  * }
1241eded9dd4SStephen Warren  *
1242eded9dd4SStephen Warren  * phandle2: node2 {
1243eded9dd4SStephen Warren  *	#list-cells = <1>;
1244eded9dd4SStephen Warren  * }
1245eded9dd4SStephen Warren  *
1246eded9dd4SStephen Warren  * node3 {
1247eded9dd4SStephen Warren  *	list = <&phandle1 1 2 &phandle2 3>;
1248eded9dd4SStephen Warren  * }
1249eded9dd4SStephen Warren  *
1250eded9dd4SStephen Warren  * To get a device_node of the `node2' node you may call this:
1251eded9dd4SStephen Warren  * of_parse_phandle_with_args(node3, "list", "#list-cells", 1, &args);
1252eded9dd4SStephen Warren  */
1253bd69f73fSGrant Likely int of_parse_phandle_with_args(const struct device_node *np, const char *list_name,
1254bd69f73fSGrant Likely 				const char *cells_name, int index,
1255bd69f73fSGrant Likely 				struct of_phandle_args *out_args)
1256bd69f73fSGrant Likely {
1257bd69f73fSGrant Likely 	if (index < 0)
1258bd69f73fSGrant Likely 		return -EINVAL;
1259035fd948SStephen Warren 	return __of_parse_phandle_with_args(np, list_name, cells_name, 0,
1260035fd948SStephen Warren 					    index, out_args);
1261bd69f73fSGrant Likely }
126215c9a0acSGrant Likely EXPORT_SYMBOL(of_parse_phandle_with_args);
126302af11b0SGrant Likely 
1264bd69f73fSGrant Likely /**
1265035fd948SStephen Warren  * of_parse_phandle_with_fixed_args() - Find a node pointed by phandle in a list
1266035fd948SStephen Warren  * @np:		pointer to a device tree node containing a list
1267035fd948SStephen Warren  * @list_name:	property name that contains a list
1268035fd948SStephen Warren  * @cell_count: number of argument cells following the phandle
1269035fd948SStephen Warren  * @index:	index of a phandle to parse out
1270035fd948SStephen Warren  * @out_args:	optional pointer to output arguments structure (will be filled)
1271035fd948SStephen Warren  *
1272035fd948SStephen Warren  * This function is useful to parse lists of phandles and their arguments.
1273035fd948SStephen Warren  * Returns 0 on success and fills out_args, on error returns appropriate
1274035fd948SStephen Warren  * errno value.
1275035fd948SStephen Warren  *
1276d94a75c1SGeert Uytterhoeven  * Caller is responsible to call of_node_put() on the returned out_args->np
1277035fd948SStephen Warren  * pointer.
1278035fd948SStephen Warren  *
1279035fd948SStephen Warren  * Example:
1280035fd948SStephen Warren  *
1281035fd948SStephen Warren  * phandle1: node1 {
1282035fd948SStephen Warren  * }
1283035fd948SStephen Warren  *
1284035fd948SStephen Warren  * phandle2: node2 {
1285035fd948SStephen Warren  * }
1286035fd948SStephen Warren  *
1287035fd948SStephen Warren  * node3 {
1288035fd948SStephen Warren  *	list = <&phandle1 0 2 &phandle2 2 3>;
1289035fd948SStephen Warren  * }
1290035fd948SStephen Warren  *
1291035fd948SStephen Warren  * To get a device_node of the `node2' node you may call this:
1292035fd948SStephen Warren  * of_parse_phandle_with_fixed_args(node3, "list", 2, 1, &args);
1293035fd948SStephen Warren  */
1294035fd948SStephen Warren int of_parse_phandle_with_fixed_args(const struct device_node *np,
1295035fd948SStephen Warren 				const char *list_name, int cell_count,
1296035fd948SStephen Warren 				int index, struct of_phandle_args *out_args)
1297035fd948SStephen Warren {
1298035fd948SStephen Warren 	if (index < 0)
1299035fd948SStephen Warren 		return -EINVAL;
1300035fd948SStephen Warren 	return __of_parse_phandle_with_args(np, list_name, NULL, cell_count,
1301035fd948SStephen Warren 					   index, out_args);
1302035fd948SStephen Warren }
1303035fd948SStephen Warren EXPORT_SYMBOL(of_parse_phandle_with_fixed_args);
1304035fd948SStephen Warren 
1305035fd948SStephen Warren /**
1306bd69f73fSGrant Likely  * of_count_phandle_with_args() - Find the number of phandles references in a property
1307bd69f73fSGrant Likely  * @np:		pointer to a device tree node containing a list
1308bd69f73fSGrant Likely  * @list_name:	property name that contains a list
1309bd69f73fSGrant Likely  * @cells_name:	property name that specifies phandles' arguments count
1310bd69f73fSGrant Likely  *
1311bd69f73fSGrant Likely  * Returns the number of phandle + argument tuples within a property. It
1312bd69f73fSGrant Likely  * is a typical pattern to encode a list of phandle and variable
1313bd69f73fSGrant Likely  * arguments into a single property. The number of arguments is encoded
1314bd69f73fSGrant Likely  * by a property in the phandle-target node. For example, a gpios
1315bd69f73fSGrant Likely  * property would contain a list of GPIO specifies consisting of a
1316bd69f73fSGrant Likely  * phandle and 1 or more arguments. The number of arguments are
1317bd69f73fSGrant Likely  * determined by the #gpio-cells property in the node pointed to by the
1318bd69f73fSGrant Likely  * phandle.
1319bd69f73fSGrant Likely  */
1320bd69f73fSGrant Likely int of_count_phandle_with_args(const struct device_node *np, const char *list_name,
1321bd69f73fSGrant Likely 				const char *cells_name)
1322bd69f73fSGrant Likely {
13232021bd01SJoerg Roedel 	struct of_phandle_iterator it;
13242021bd01SJoerg Roedel 	int rc, cur_index = 0;
13252021bd01SJoerg Roedel 
13262021bd01SJoerg Roedel 	rc = of_phandle_iterator_init(&it, np, list_name, cells_name, 0);
13272021bd01SJoerg Roedel 	if (rc)
13282021bd01SJoerg Roedel 		return rc;
13292021bd01SJoerg Roedel 
13302021bd01SJoerg Roedel 	while ((rc = of_phandle_iterator_next(&it)) == 0)
13312021bd01SJoerg Roedel 		cur_index += 1;
13322021bd01SJoerg Roedel 
13332021bd01SJoerg Roedel 	if (rc != -ENOENT)
13342021bd01SJoerg Roedel 		return rc;
13352021bd01SJoerg Roedel 
13362021bd01SJoerg Roedel 	return cur_index;
1337bd69f73fSGrant Likely }
1338bd69f73fSGrant Likely EXPORT_SYMBOL(of_count_phandle_with_args);
1339bd69f73fSGrant Likely 
134002af11b0SGrant Likely /**
134162664f67SXiubo Li  * __of_add_property - Add a property to a node without lock operations
134262664f67SXiubo Li  */
1343d8c50088SPantelis Antoniou int __of_add_property(struct device_node *np, struct property *prop)
134462664f67SXiubo Li {
134562664f67SXiubo Li 	struct property **next;
134662664f67SXiubo Li 
134762664f67SXiubo Li 	prop->next = NULL;
134862664f67SXiubo Li 	next = &np->properties;
134962664f67SXiubo Li 	while (*next) {
135062664f67SXiubo Li 		if (strcmp(prop->name, (*next)->name) == 0)
135162664f67SXiubo Li 			/* duplicate ! don't insert it */
135262664f67SXiubo Li 			return -EEXIST;
135362664f67SXiubo Li 
135462664f67SXiubo Li 		next = &(*next)->next;
135562664f67SXiubo Li 	}
135662664f67SXiubo Li 	*next = prop;
135762664f67SXiubo Li 
135862664f67SXiubo Li 	return 0;
135962664f67SXiubo Li }
136062664f67SXiubo Li 
136162664f67SXiubo Li /**
136279d1c712SNathan Fontenot  * of_add_property - Add a property to a node
136302af11b0SGrant Likely  */
136479d1c712SNathan Fontenot int of_add_property(struct device_node *np, struct property *prop)
136502af11b0SGrant Likely {
136602af11b0SGrant Likely 	unsigned long flags;
13671cf3d8b3SNathan Fontenot 	int rc;
13681cf3d8b3SNathan Fontenot 
13698a2b22a2SGrant Likely 	mutex_lock(&of_mutex);
137002af11b0SGrant Likely 
1371d6d3c4e6SThomas Gleixner 	raw_spin_lock_irqsave(&devtree_lock, flags);
137262664f67SXiubo Li 	rc = __of_add_property(np, prop);
1373d6d3c4e6SThomas Gleixner 	raw_spin_unlock_irqrestore(&devtree_lock, flags);
137402af11b0SGrant Likely 
13758a2b22a2SGrant Likely 	if (!rc)
137675b57ecfSGrant Likely 		__of_add_property_sysfs(np, prop);
137702af11b0SGrant Likely 
13788a2b22a2SGrant Likely 	mutex_unlock(&of_mutex);
13798a2b22a2SGrant Likely 
1380259092a3SGrant Likely 	if (!rc)
1381259092a3SGrant Likely 		of_property_notify(OF_RECONFIG_ADD_PROPERTY, np, prop, NULL);
1382259092a3SGrant Likely 
138362664f67SXiubo Li 	return rc;
138402af11b0SGrant Likely }
138502af11b0SGrant Likely 
1386d8c50088SPantelis Antoniou int __of_remove_property(struct device_node *np, struct property *prop)
1387d8c50088SPantelis Antoniou {
1388d8c50088SPantelis Antoniou 	struct property **next;
1389d8c50088SPantelis Antoniou 
1390d8c50088SPantelis Antoniou 	for (next = &np->properties; *next; next = &(*next)->next) {
1391d8c50088SPantelis Antoniou 		if (*next == prop)
1392d8c50088SPantelis Antoniou 			break;
1393d8c50088SPantelis Antoniou 	}
1394d8c50088SPantelis Antoniou 	if (*next == NULL)
1395d8c50088SPantelis Antoniou 		return -ENODEV;
1396d8c50088SPantelis Antoniou 
1397d8c50088SPantelis Antoniou 	/* found the node */
1398d8c50088SPantelis Antoniou 	*next = prop->next;
1399d8c50088SPantelis Antoniou 	prop->next = np->deadprops;
1400d8c50088SPantelis Antoniou 	np->deadprops = prop;
1401d8c50088SPantelis Antoniou 
1402d8c50088SPantelis Antoniou 	return 0;
1403d8c50088SPantelis Antoniou }
1404d8c50088SPantelis Antoniou 
140502af11b0SGrant Likely /**
140679d1c712SNathan Fontenot  * of_remove_property - Remove a property from a node.
140702af11b0SGrant Likely  *
140802af11b0SGrant Likely  * Note that we don't actually remove it, since we have given out
140902af11b0SGrant Likely  * who-knows-how-many pointers to the data using get-property.
141002af11b0SGrant Likely  * Instead we just move the property to the "dead properties"
141102af11b0SGrant Likely  * list, so it won't be found any more.
141202af11b0SGrant Likely  */
141379d1c712SNathan Fontenot int of_remove_property(struct device_node *np, struct property *prop)
141402af11b0SGrant Likely {
141502af11b0SGrant Likely 	unsigned long flags;
14161cf3d8b3SNathan Fontenot 	int rc;
14171cf3d8b3SNathan Fontenot 
1418201b3fe5SSuraj Jitindar Singh 	if (!prop)
1419201b3fe5SSuraj Jitindar Singh 		return -ENODEV;
1420201b3fe5SSuraj Jitindar Singh 
14218a2b22a2SGrant Likely 	mutex_lock(&of_mutex);
142202af11b0SGrant Likely 
1423d6d3c4e6SThomas Gleixner 	raw_spin_lock_irqsave(&devtree_lock, flags);
1424d8c50088SPantelis Antoniou 	rc = __of_remove_property(np, prop);
1425d6d3c4e6SThomas Gleixner 	raw_spin_unlock_irqrestore(&devtree_lock, flags);
142602af11b0SGrant Likely 
14278a2b22a2SGrant Likely 	if (!rc)
14288a2b22a2SGrant Likely 		__of_remove_property_sysfs(np, prop);
142902af11b0SGrant Likely 
14308a2b22a2SGrant Likely 	mutex_unlock(&of_mutex);
14318a2b22a2SGrant Likely 
1432259092a3SGrant Likely 	if (!rc)
1433259092a3SGrant Likely 		of_property_notify(OF_RECONFIG_REMOVE_PROPERTY, np, prop, NULL);
1434259092a3SGrant Likely 
1435d8c50088SPantelis Antoniou 	return rc;
143602af11b0SGrant Likely }
143702af11b0SGrant Likely 
1438d8c50088SPantelis Antoniou int __of_update_property(struct device_node *np, struct property *newprop,
1439d8c50088SPantelis Antoniou 		struct property **oldpropp)
1440d8c50088SPantelis Antoniou {
1441d8c50088SPantelis Antoniou 	struct property **next, *oldprop;
1442d8c50088SPantelis Antoniou 
1443d8c50088SPantelis Antoniou 	for (next = &np->properties; *next; next = &(*next)->next) {
1444d8c50088SPantelis Antoniou 		if (of_prop_cmp((*next)->name, newprop->name) == 0)
1445d8c50088SPantelis Antoniou 			break;
1446d8c50088SPantelis Antoniou 	}
1447d8c50088SPantelis Antoniou 	*oldpropp = oldprop = *next;
1448d8c50088SPantelis Antoniou 
1449d8c50088SPantelis Antoniou 	if (oldprop) {
1450d8c50088SPantelis Antoniou 		/* replace the node */
1451d8c50088SPantelis Antoniou 		newprop->next = oldprop->next;
1452d8c50088SPantelis Antoniou 		*next = newprop;
1453d8c50088SPantelis Antoniou 		oldprop->next = np->deadprops;
1454d8c50088SPantelis Antoniou 		np->deadprops = oldprop;
1455d8c50088SPantelis Antoniou 	} else {
1456d8c50088SPantelis Antoniou 		/* new node */
1457d8c50088SPantelis Antoniou 		newprop->next = NULL;
1458d8c50088SPantelis Antoniou 		*next = newprop;
1459d8c50088SPantelis Antoniou 	}
1460d8c50088SPantelis Antoniou 
1461d8c50088SPantelis Antoniou 	return 0;
1462d8c50088SPantelis Antoniou }
1463d8c50088SPantelis Antoniou 
146402af11b0SGrant Likely /*
146579d1c712SNathan Fontenot  * of_update_property - Update a property in a node, if the property does
1466475d0094SDong Aisheng  * not exist, add it.
146702af11b0SGrant Likely  *
146802af11b0SGrant Likely  * Note that we don't actually remove it, since we have given out
146902af11b0SGrant Likely  * who-knows-how-many pointers to the data using get-property.
147002af11b0SGrant Likely  * Instead we just move the property to the "dead properties" list,
147102af11b0SGrant Likely  * and add the new property to the property list
147202af11b0SGrant Likely  */
147379d1c712SNathan Fontenot int of_update_property(struct device_node *np, struct property *newprop)
147402af11b0SGrant Likely {
1475d8c50088SPantelis Antoniou 	struct property *oldprop;
147602af11b0SGrant Likely 	unsigned long flags;
1477947fdaadSXiubo Li 	int rc;
14781cf3d8b3SNathan Fontenot 
1479475d0094SDong Aisheng 	if (!newprop->name)
1480475d0094SDong Aisheng 		return -EINVAL;
1481475d0094SDong Aisheng 
14828a2b22a2SGrant Likely 	mutex_lock(&of_mutex);
1483fcdeb7feSGrant Likely 
1484d6d3c4e6SThomas Gleixner 	raw_spin_lock_irqsave(&devtree_lock, flags);
1485d8c50088SPantelis Antoniou 	rc = __of_update_property(np, newprop, &oldprop);
1486d6d3c4e6SThomas Gleixner 	raw_spin_unlock_irqrestore(&devtree_lock, flags);
1487e81b3295SNathan Fontenot 
14888a2b22a2SGrant Likely 	if (!rc)
14898a2b22a2SGrant Likely 		__of_update_property_sysfs(np, newprop, oldprop);
1490fcdeb7feSGrant Likely 
14918a2b22a2SGrant Likely 	mutex_unlock(&of_mutex);
14921cf3d8b3SNathan Fontenot 
1493259092a3SGrant Likely 	if (!rc)
1494259092a3SGrant Likely 		of_property_notify(OF_RECONFIG_UPDATE_PROPERTY, np, newprop, oldprop);
1495fcdeb7feSGrant Likely 
14961cf3d8b3SNathan Fontenot 	return rc;
1497e81b3295SNathan Fontenot }
1498e81b3295SNathan Fontenot 
1499611cad72SShawn Guo static void of_alias_add(struct alias_prop *ap, struct device_node *np,
1500611cad72SShawn Guo 			 int id, const char *stem, int stem_len)
1501611cad72SShawn Guo {
1502611cad72SShawn Guo 	ap->np = np;
1503611cad72SShawn Guo 	ap->id = id;
1504611cad72SShawn Guo 	strncpy(ap->stem, stem, stem_len);
1505611cad72SShawn Guo 	ap->stem[stem_len] = 0;
1506611cad72SShawn Guo 	list_add_tail(&ap->link, &aliases_lookup);
15070d638a07SRob Herring 	pr_debug("adding DT alias:%s: stem=%s id=%i node=%pOF\n",
15080d638a07SRob Herring 		 ap->alias, ap->stem, ap->id, np);
1509611cad72SShawn Guo }
1510611cad72SShawn Guo 
1511611cad72SShawn Guo /**
15121821dda4SGeert Uytterhoeven  * of_alias_scan - Scan all properties of the 'aliases' node
1513611cad72SShawn Guo  *
15141821dda4SGeert Uytterhoeven  * The function scans all the properties of the 'aliases' node and populates
15151821dda4SGeert Uytterhoeven  * the global lookup table with the properties.  It returns the
15161821dda4SGeert Uytterhoeven  * number of alias properties found, or an error code in case of failure.
1517611cad72SShawn Guo  *
1518611cad72SShawn Guo  * @dt_alloc:	An allocator that provides a virtual address to memory
15191821dda4SGeert Uytterhoeven  *		for storing the resulting tree
1520611cad72SShawn Guo  */
1521611cad72SShawn Guo void of_alias_scan(void * (*dt_alloc)(u64 size, u64 align))
1522611cad72SShawn Guo {
1523611cad72SShawn Guo 	struct property *pp;
1524611cad72SShawn Guo 
15257dbe5849SLaurentiu Tudor 	of_aliases = of_find_node_by_path("/aliases");
1526611cad72SShawn Guo 	of_chosen = of_find_node_by_path("/chosen");
1527611cad72SShawn Guo 	if (of_chosen == NULL)
1528611cad72SShawn Guo 		of_chosen = of_find_node_by_path("/chosen@0");
15295c19e952SSascha Hauer 
15305c19e952SSascha Hauer 	if (of_chosen) {
1531a752ee56SGrant Likely 		/* linux,stdout-path and /aliases/stdout are for legacy compatibility */
1532b0d9d92fSSergei Shtylyov 		const char *name = NULL;
1533b0d9d92fSSergei Shtylyov 
1534b0d9d92fSSergei Shtylyov 		if (of_property_read_string(of_chosen, "stdout-path", &name))
1535b0d9d92fSSergei Shtylyov 			of_property_read_string(of_chosen, "linux,stdout-path",
1536b0d9d92fSSergei Shtylyov 						&name);
1537a752ee56SGrant Likely 		if (IS_ENABLED(CONFIG_PPC) && !name)
1538b0d9d92fSSergei Shtylyov 			of_property_read_string(of_aliases, "stdout", &name);
1539f64255b5SPeter Hurley 		if (name)
15407914a7c5SLeif Lindholm 			of_stdout = of_find_node_opts_by_path(name, &of_stdout_options);
15415c19e952SSascha Hauer 	}
15425c19e952SSascha Hauer 
1543611cad72SShawn Guo 	if (!of_aliases)
1544611cad72SShawn Guo 		return;
1545611cad72SShawn Guo 
15468af0da93SDong Aisheng 	for_each_property_of_node(of_aliases, pp) {
1547611cad72SShawn Guo 		const char *start = pp->name;
1548611cad72SShawn Guo 		const char *end = start + strlen(start);
1549611cad72SShawn Guo 		struct device_node *np;
1550611cad72SShawn Guo 		struct alias_prop *ap;
1551611cad72SShawn Guo 		int id, len;
1552611cad72SShawn Guo 
1553611cad72SShawn Guo 		/* Skip those we do not want to proceed */
1554611cad72SShawn Guo 		if (!strcmp(pp->name, "name") ||
1555611cad72SShawn Guo 		    !strcmp(pp->name, "phandle") ||
1556611cad72SShawn Guo 		    !strcmp(pp->name, "linux,phandle"))
1557611cad72SShawn Guo 			continue;
1558611cad72SShawn Guo 
1559611cad72SShawn Guo 		np = of_find_node_by_path(pp->value);
1560611cad72SShawn Guo 		if (!np)
1561611cad72SShawn Guo 			continue;
1562611cad72SShawn Guo 
1563611cad72SShawn Guo 		/* walk the alias backwards to extract the id and work out
1564611cad72SShawn Guo 		 * the 'stem' string */
1565611cad72SShawn Guo 		while (isdigit(*(end-1)) && end > start)
1566611cad72SShawn Guo 			end--;
1567611cad72SShawn Guo 		len = end - start;
1568611cad72SShawn Guo 
1569611cad72SShawn Guo 		if (kstrtoint(end, 10, &id) < 0)
1570611cad72SShawn Guo 			continue;
1571611cad72SShawn Guo 
1572611cad72SShawn Guo 		/* Allocate an alias_prop with enough space for the stem */
1573de96ec2aSPaul Burton 		ap = dt_alloc(sizeof(*ap) + len + 1, __alignof__(*ap));
1574611cad72SShawn Guo 		if (!ap)
1575611cad72SShawn Guo 			continue;
15760640332eSGrant Likely 		memset(ap, 0, sizeof(*ap) + len + 1);
1577611cad72SShawn Guo 		ap->alias = start;
1578611cad72SShawn Guo 		of_alias_add(ap, np, id, start, len);
1579611cad72SShawn Guo 	}
1580611cad72SShawn Guo }
1581611cad72SShawn Guo 
1582611cad72SShawn Guo /**
1583611cad72SShawn Guo  * of_alias_get_id - Get alias id for the given device_node
1584611cad72SShawn Guo  * @np:		Pointer to the given device_node
1585611cad72SShawn Guo  * @stem:	Alias stem of the given device_node
1586611cad72SShawn Guo  *
15875a53a07fSGeert Uytterhoeven  * The function travels the lookup table to get the alias id for the given
15885a53a07fSGeert Uytterhoeven  * device_node and alias stem.  It returns the alias id if found.
1589611cad72SShawn Guo  */
1590611cad72SShawn Guo int of_alias_get_id(struct device_node *np, const char *stem)
1591611cad72SShawn Guo {
1592611cad72SShawn Guo 	struct alias_prop *app;
1593611cad72SShawn Guo 	int id = -ENODEV;
1594611cad72SShawn Guo 
1595c05aba2bSPantelis Antoniou 	mutex_lock(&of_mutex);
1596611cad72SShawn Guo 	list_for_each_entry(app, &aliases_lookup, link) {
1597611cad72SShawn Guo 		if (strcmp(app->stem, stem) != 0)
1598611cad72SShawn Guo 			continue;
1599611cad72SShawn Guo 
1600611cad72SShawn Guo 		if (np == app->np) {
1601611cad72SShawn Guo 			id = app->id;
1602611cad72SShawn Guo 			break;
1603611cad72SShawn Guo 		}
1604611cad72SShawn Guo 	}
1605c05aba2bSPantelis Antoniou 	mutex_unlock(&of_mutex);
1606611cad72SShawn Guo 
1607611cad72SShawn Guo 	return id;
1608611cad72SShawn Guo }
1609611cad72SShawn Guo EXPORT_SYMBOL_GPL(of_alias_get_id);
1610c541adc6SStephen Warren 
1611351d224fSWolfram Sang /**
1612351d224fSWolfram Sang  * of_alias_get_highest_id - Get highest alias id for the given stem
1613351d224fSWolfram Sang  * @stem:	Alias stem to be examined
1614351d224fSWolfram Sang  *
1615351d224fSWolfram Sang  * The function travels the lookup table to get the highest alias id for the
1616351d224fSWolfram Sang  * given alias stem.  It returns the alias id if found.
1617351d224fSWolfram Sang  */
1618351d224fSWolfram Sang int of_alias_get_highest_id(const char *stem)
1619351d224fSWolfram Sang {
1620351d224fSWolfram Sang 	struct alias_prop *app;
1621351d224fSWolfram Sang 	int id = -ENODEV;
1622351d224fSWolfram Sang 
1623351d224fSWolfram Sang 	mutex_lock(&of_mutex);
1624351d224fSWolfram Sang 	list_for_each_entry(app, &aliases_lookup, link) {
1625351d224fSWolfram Sang 		if (strcmp(app->stem, stem) != 0)
1626351d224fSWolfram Sang 			continue;
1627351d224fSWolfram Sang 
1628351d224fSWolfram Sang 		if (app->id > id)
1629351d224fSWolfram Sang 			id = app->id;
1630351d224fSWolfram Sang 	}
1631351d224fSWolfram Sang 	mutex_unlock(&of_mutex);
1632351d224fSWolfram Sang 
1633351d224fSWolfram Sang 	return id;
1634351d224fSWolfram Sang }
1635351d224fSWolfram Sang EXPORT_SYMBOL_GPL(of_alias_get_highest_id);
1636351d224fSWolfram Sang 
16375c19e952SSascha Hauer /**
16383482f2c5SGrant Likely  * of_console_check() - Test and setup console for DT setup
16393482f2c5SGrant Likely  * @dn - Pointer to device node
16403482f2c5SGrant Likely  * @name - Name to use for preferred console without index. ex. "ttyS"
16413482f2c5SGrant Likely  * @index - Index to use for preferred console.
16425c19e952SSascha Hauer  *
16433482f2c5SGrant Likely  * Check if the given device node matches the stdout-path property in the
16443482f2c5SGrant Likely  * /chosen node. If it does then register it as the preferred console and return
16453482f2c5SGrant Likely  * TRUE. Otherwise return FALSE.
16465c19e952SSascha Hauer  */
16473482f2c5SGrant Likely bool of_console_check(struct device_node *dn, char *name, int index)
16485c19e952SSascha Hauer {
16493482f2c5SGrant Likely 	if (!dn || dn != of_stdout || console_set_on_cmdline)
16505c19e952SSascha Hauer 		return false;
16517914a7c5SLeif Lindholm 	return !add_preferred_console(name, index,
16527914a7c5SLeif Lindholm 				      kstrdup(of_stdout_options, GFP_KERNEL));
16535c19e952SSascha Hauer }
16543482f2c5SGrant Likely EXPORT_SYMBOL_GPL(of_console_check);
1655a3e31b45SSudeep KarkadaNagesha 
1656a3e31b45SSudeep KarkadaNagesha /**
1657a3e31b45SSudeep KarkadaNagesha  *	of_find_next_cache_node - Find a node's subsidiary cache
1658a3e31b45SSudeep KarkadaNagesha  *	@np:	node of type "cpu" or "cache"
1659a3e31b45SSudeep KarkadaNagesha  *
1660a3e31b45SSudeep KarkadaNagesha  *	Returns a node pointer with refcount incremented, use
1661a3e31b45SSudeep KarkadaNagesha  *	of_node_put() on it when done.  Caller should hold a reference
1662a3e31b45SSudeep KarkadaNagesha  *	to np.
1663a3e31b45SSudeep KarkadaNagesha  */
1664a3e31b45SSudeep KarkadaNagesha struct device_node *of_find_next_cache_node(const struct device_node *np)
1665a3e31b45SSudeep KarkadaNagesha {
166691d96749SRob Herring 	struct device_node *child, *cache_node;
1667a3e31b45SSudeep KarkadaNagesha 
166891d96749SRob Herring 	cache_node = of_parse_phandle(np, "l2-cache", 0);
166991d96749SRob Herring 	if (!cache_node)
167091d96749SRob Herring 		cache_node = of_parse_phandle(np, "next-level-cache", 0);
1671a3e31b45SSudeep KarkadaNagesha 
167291d96749SRob Herring 	if (cache_node)
167391d96749SRob Herring 		return cache_node;
1674a3e31b45SSudeep KarkadaNagesha 
1675a3e31b45SSudeep KarkadaNagesha 	/* OF on pmac has nodes instead of properties named "l2-cache"
1676a3e31b45SSudeep KarkadaNagesha 	 * beneath CPU nodes.
1677a3e31b45SSudeep KarkadaNagesha 	 */
1678a3e31b45SSudeep KarkadaNagesha 	if (!strcmp(np->type, "cpu"))
1679a3e31b45SSudeep KarkadaNagesha 		for_each_child_of_node(np, child)
1680a3e31b45SSudeep KarkadaNagesha 			if (!strcmp(child->type, "cache"))
1681a3e31b45SSudeep KarkadaNagesha 				return child;
1682a3e31b45SSudeep KarkadaNagesha 
1683a3e31b45SSudeep KarkadaNagesha 	return NULL;
1684a3e31b45SSudeep KarkadaNagesha }
1685fd9fdb78SPhilipp Zabel 
1686fd9fdb78SPhilipp Zabel /**
16875fa23530SSudeep Holla  * of_find_last_cache_level - Find the level at which the last cache is
16885fa23530SSudeep Holla  * 		present for the given logical cpu
16895fa23530SSudeep Holla  *
16905fa23530SSudeep Holla  * @cpu: cpu number(logical index) for which the last cache level is needed
16915fa23530SSudeep Holla  *
16925fa23530SSudeep Holla  * Returns the the level at which the last cache is present. It is exactly
16935fa23530SSudeep Holla  * same as  the total number of cache levels for the given logical cpu.
16945fa23530SSudeep Holla  */
16955fa23530SSudeep Holla int of_find_last_cache_level(unsigned int cpu)
16965fa23530SSudeep Holla {
16975fa23530SSudeep Holla 	u32 cache_level = 0;
16985fa23530SSudeep Holla 	struct device_node *prev = NULL, *np = of_cpu_device_node_get(cpu);
16995fa23530SSudeep Holla 
17005fa23530SSudeep Holla 	while (np) {
17015fa23530SSudeep Holla 		prev = np;
17025fa23530SSudeep Holla 		of_node_put(np);
17035fa23530SSudeep Holla 		np = of_find_next_cache_node(np);
17045fa23530SSudeep Holla 	}
17055fa23530SSudeep Holla 
17065fa23530SSudeep Holla 	of_property_read_u32(prev, "cache-level", &cache_level);
17075fa23530SSudeep Holla 
17085fa23530SSudeep Holla 	return cache_level;
17095fa23530SSudeep Holla }
1710