xref: /openbmc/linux/drivers/of/base.c (revision 5f74d8b7)
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  */
203482f2c5SGrant Likely #include <linux/console.h>
21611cad72SShawn Guo #include <linux/ctype.h>
22183912d3SSudeep KarkadaNagesha #include <linux/cpu.h>
2397e873e5SStephen Rothwell #include <linux/module.h>
2497e873e5SStephen Rothwell #include <linux/of.h>
25fd9fdb78SPhilipp Zabel #include <linux/of_graph.h>
26581b605aSStephen Rothwell #include <linux/spinlock.h>
275a0e3ad6STejun Heo #include <linux/slab.h>
2875b57ecfSGrant Likely #include <linux/string.h>
29a9f2f63aSJeremy Kerr #include <linux/proc_fs.h>
30581b605aSStephen Rothwell 
31ced4eec9SStepan Moskovchenko #include "of_private.h"
32611cad72SShawn Guo 
33ced4eec9SStepan Moskovchenko LIST_HEAD(aliases_lookup);
34611cad72SShawn Guo 
35465aac6dSRandy Dunlap struct device_node *of_allnodes;
36465aac6dSRandy Dunlap EXPORT_SYMBOL(of_allnodes);
37fc0bdae4SGrant Likely struct device_node *of_chosen;
38611cad72SShawn Guo struct device_node *of_aliases;
39a752ee56SGrant Likely struct device_node *of_stdout;
40611cad72SShawn Guo 
418a2b22a2SGrant Likely struct kset *of_kset;
4275b57ecfSGrant Likely 
4375b57ecfSGrant Likely /*
448a2b22a2SGrant Likely  * Used to protect the of_aliases, to hold off addition of nodes to sysfs.
458a2b22a2SGrant Likely  * This mutex must be held whenever modifications are being made to the
468a2b22a2SGrant Likely  * device tree. The of_{attach,detach}_node() and
478a2b22a2SGrant Likely  * of_{add,remove,update}_property() helpers make sure this happens.
4875b57ecfSGrant Likely  */
49c05aba2bSPantelis Antoniou DEFINE_MUTEX(of_mutex);
501ef4d424SStephen Rothwell 
51581b605aSStephen Rothwell /* use when traversing tree through the allnext, child, sibling,
52581b605aSStephen Rothwell  * or parent members of struct device_node.
53581b605aSStephen Rothwell  */
54d6d3c4e6SThomas Gleixner DEFINE_RAW_SPINLOCK(devtree_lock);
5597e873e5SStephen Rothwell 
5697e873e5SStephen Rothwell int of_n_addr_cells(struct device_node *np)
5797e873e5SStephen Rothwell {
58a9fadeefSJeremy Kerr 	const __be32 *ip;
5997e873e5SStephen Rothwell 
6097e873e5SStephen Rothwell 	do {
6197e873e5SStephen Rothwell 		if (np->parent)
6297e873e5SStephen Rothwell 			np = np->parent;
6397e873e5SStephen Rothwell 		ip = of_get_property(np, "#address-cells", NULL);
6497e873e5SStephen Rothwell 		if (ip)
6533714881SJeremy Kerr 			return be32_to_cpup(ip);
6697e873e5SStephen Rothwell 	} while (np->parent);
6797e873e5SStephen Rothwell 	/* No #address-cells property for the root node */
6897e873e5SStephen Rothwell 	return OF_ROOT_NODE_ADDR_CELLS_DEFAULT;
6997e873e5SStephen Rothwell }
7097e873e5SStephen Rothwell EXPORT_SYMBOL(of_n_addr_cells);
7197e873e5SStephen Rothwell 
7297e873e5SStephen Rothwell int of_n_size_cells(struct device_node *np)
7397e873e5SStephen Rothwell {
74a9fadeefSJeremy Kerr 	const __be32 *ip;
7597e873e5SStephen Rothwell 
7697e873e5SStephen Rothwell 	do {
7797e873e5SStephen Rothwell 		if (np->parent)
7897e873e5SStephen Rothwell 			np = np->parent;
7997e873e5SStephen Rothwell 		ip = of_get_property(np, "#size-cells", NULL);
8097e873e5SStephen Rothwell 		if (ip)
8133714881SJeremy Kerr 			return be32_to_cpup(ip);
8297e873e5SStephen Rothwell 	} while (np->parent);
8397e873e5SStephen Rothwell 	/* No #size-cells property for the root node */
8497e873e5SStephen Rothwell 	return OF_ROOT_NODE_SIZE_CELLS_DEFAULT;
8597e873e5SStephen Rothwell }
8697e873e5SStephen Rothwell EXPORT_SYMBOL(of_n_size_cells);
8797e873e5SStephen Rothwell 
880c3f061cSRob Herring #ifdef CONFIG_NUMA
890c3f061cSRob Herring int __weak of_node_to_nid(struct device_node *np)
900c3f061cSRob Herring {
910c3f061cSRob Herring 	return numa_node_id();
920c3f061cSRob Herring }
930c3f061cSRob Herring #endif
940c3f061cSRob Herring 
956afc0dc3SGrant Likely #ifndef CONFIG_OF_DYNAMIC
9675b57ecfSGrant Likely static void of_node_release(struct kobject *kobj)
9775b57ecfSGrant Likely {
9875b57ecfSGrant Likely 	/* Without CONFIG_OF_DYNAMIC, no nodes gets freed */
9975b57ecfSGrant Likely }
1000f22dd39SGrant Likely #endif /* CONFIG_OF_DYNAMIC */
101923f7e30SGrant Likely 
10275b57ecfSGrant Likely struct kobj_type of_node_ktype = {
10375b57ecfSGrant Likely 	.release = of_node_release,
10475b57ecfSGrant Likely };
10575b57ecfSGrant Likely 
10675b57ecfSGrant Likely static ssize_t of_node_property_read(struct file *filp, struct kobject *kobj,
10775b57ecfSGrant Likely 				struct bin_attribute *bin_attr, char *buf,
10875b57ecfSGrant Likely 				loff_t offset, size_t count)
10975b57ecfSGrant Likely {
11075b57ecfSGrant Likely 	struct property *pp = container_of(bin_attr, struct property, attr);
11175b57ecfSGrant Likely 	return memory_read_from_buffer(buf, count, &offset, pp->value, pp->length);
11275b57ecfSGrant Likely }
11375b57ecfSGrant Likely 
11475b57ecfSGrant Likely static const char *safe_name(struct kobject *kobj, const char *orig_name)
11575b57ecfSGrant Likely {
11675b57ecfSGrant Likely 	const char *name = orig_name;
11775b57ecfSGrant Likely 	struct kernfs_node *kn;
11875b57ecfSGrant Likely 	int i = 0;
11975b57ecfSGrant Likely 
12075b57ecfSGrant Likely 	/* don't be a hero. After 16 tries give up */
12175b57ecfSGrant Likely 	while (i < 16 && (kn = sysfs_get_dirent(kobj->sd, name))) {
12275b57ecfSGrant Likely 		sysfs_put(kn);
12375b57ecfSGrant Likely 		if (name != orig_name)
12475b57ecfSGrant Likely 			kfree(name);
12575b57ecfSGrant Likely 		name = kasprintf(GFP_KERNEL, "%s#%i", orig_name, ++i);
12675b57ecfSGrant Likely 	}
12775b57ecfSGrant Likely 
12875b57ecfSGrant Likely 	if (name != orig_name)
12975b57ecfSGrant Likely 		pr_warn("device-tree: Duplicate name in %s, renamed to \"%s\"\n",
13075b57ecfSGrant Likely 			kobject_name(kobj), name);
13175b57ecfSGrant Likely 	return name;
13275b57ecfSGrant Likely }
13375b57ecfSGrant Likely 
1348a2b22a2SGrant Likely int __of_add_property_sysfs(struct device_node *np, struct property *pp)
13575b57ecfSGrant Likely {
13675b57ecfSGrant Likely 	int rc;
13775b57ecfSGrant Likely 
13875b57ecfSGrant Likely 	/* Important: Don't leak passwords */
13975b57ecfSGrant Likely 	bool secure = strncmp(pp->name, "security-", 9) == 0;
14075b57ecfSGrant Likely 
1418a2b22a2SGrant Likely 	if (!of_kset || !of_node_is_attached(np))
1428a2b22a2SGrant Likely 		return 0;
1438a2b22a2SGrant Likely 
14475b57ecfSGrant Likely 	sysfs_bin_attr_init(&pp->attr);
14575b57ecfSGrant Likely 	pp->attr.attr.name = safe_name(&np->kobj, pp->name);
14675b57ecfSGrant Likely 	pp->attr.attr.mode = secure ? S_IRUSR : S_IRUGO;
14775b57ecfSGrant Likely 	pp->attr.size = secure ? 0 : pp->length;
14875b57ecfSGrant Likely 	pp->attr.read = of_node_property_read;
14975b57ecfSGrant Likely 
15075b57ecfSGrant Likely 	rc = sysfs_create_bin_file(&np->kobj, &pp->attr);
15175b57ecfSGrant Likely 	WARN(rc, "error adding attribute %s to node %s\n", pp->name, np->full_name);
15275b57ecfSGrant Likely 	return rc;
15375b57ecfSGrant Likely }
15475b57ecfSGrant Likely 
1558a2b22a2SGrant Likely int __of_attach_node_sysfs(struct device_node *np)
15675b57ecfSGrant Likely {
15775b57ecfSGrant Likely 	const char *name;
15875b57ecfSGrant Likely 	struct property *pp;
15975b57ecfSGrant Likely 	int rc;
16075b57ecfSGrant Likely 
1618a2b22a2SGrant Likely 	if (!of_kset)
1628a2b22a2SGrant Likely 		return 0;
1638a2b22a2SGrant Likely 
16475b57ecfSGrant Likely 	np->kobj.kset = of_kset;
16575b57ecfSGrant Likely 	if (!np->parent) {
16675b57ecfSGrant Likely 		/* Nodes without parents are new top level trees */
16728d3ee40SKees Cook 		rc = kobject_add(&np->kobj, NULL, "%s",
16828d3ee40SKees Cook 				 safe_name(&of_kset->kobj, "base"));
16975b57ecfSGrant Likely 	} else {
17075b57ecfSGrant Likely 		name = safe_name(&np->parent->kobj, kbasename(np->full_name));
17175b57ecfSGrant Likely 		if (!name || !name[0])
17275b57ecfSGrant Likely 			return -EINVAL;
17375b57ecfSGrant Likely 
17475b57ecfSGrant Likely 		rc = kobject_add(&np->kobj, &np->parent->kobj, "%s", name);
17575b57ecfSGrant Likely 	}
17675b57ecfSGrant Likely 	if (rc)
17775b57ecfSGrant Likely 		return rc;
17875b57ecfSGrant Likely 
17975b57ecfSGrant Likely 	for_each_property_of_node(np, pp)
18075b57ecfSGrant Likely 		__of_add_property_sysfs(np, pp);
18175b57ecfSGrant Likely 
18275b57ecfSGrant Likely 	return 0;
18375b57ecfSGrant Likely }
18475b57ecfSGrant Likely 
18575b57ecfSGrant Likely static int __init of_init(void)
18675b57ecfSGrant Likely {
18775b57ecfSGrant Likely 	struct device_node *np;
18875b57ecfSGrant Likely 
18975b57ecfSGrant Likely 	/* Create the kset, and register existing nodes */
190c05aba2bSPantelis Antoniou 	mutex_lock(&of_mutex);
19175b57ecfSGrant Likely 	of_kset = kset_create_and_add("devicetree", NULL, firmware_kobj);
19275b57ecfSGrant Likely 	if (!of_kset) {
193c05aba2bSPantelis Antoniou 		mutex_unlock(&of_mutex);
19475b57ecfSGrant Likely 		return -ENOMEM;
19575b57ecfSGrant Likely 	}
19675b57ecfSGrant Likely 	for_each_of_allnodes(np)
1978a2b22a2SGrant Likely 		__of_attach_node_sysfs(np);
198c05aba2bSPantelis Antoniou 	mutex_unlock(&of_mutex);
19975b57ecfSGrant Likely 
2008357041aSGrant Likely 	/* Symlink in /proc as required by userspace ABI */
20175b57ecfSGrant Likely 	if (of_allnodes)
20275b57ecfSGrant Likely 		proc_symlink("device-tree", NULL, "/sys/firmware/devicetree/base");
20375b57ecfSGrant Likely 
20475b57ecfSGrant Likely 	return 0;
20575b57ecfSGrant Likely }
20675b57ecfSGrant Likely core_initcall(of_init);
20775b57ecfSGrant Likely 
20828d0e36bSThomas Gleixner static struct property *__of_find_property(const struct device_node *np,
20928d0e36bSThomas Gleixner 					   const char *name, int *lenp)
210581b605aSStephen Rothwell {
211581b605aSStephen Rothwell 	struct property *pp;
212581b605aSStephen Rothwell 
21364e4566fSTimur Tabi 	if (!np)
21464e4566fSTimur Tabi 		return NULL;
21564e4566fSTimur Tabi 
216a3a7cab1SSachin Kamat 	for (pp = np->properties; pp; pp = pp->next) {
217581b605aSStephen Rothwell 		if (of_prop_cmp(pp->name, name) == 0) {
218a3a7cab1SSachin Kamat 			if (lenp)
219581b605aSStephen Rothwell 				*lenp = pp->length;
220581b605aSStephen Rothwell 			break;
221581b605aSStephen Rothwell 		}
222581b605aSStephen Rothwell 	}
22328d0e36bSThomas Gleixner 
22428d0e36bSThomas Gleixner 	return pp;
22528d0e36bSThomas Gleixner }
22628d0e36bSThomas Gleixner 
22728d0e36bSThomas Gleixner struct property *of_find_property(const struct device_node *np,
22828d0e36bSThomas Gleixner 				  const char *name,
22928d0e36bSThomas Gleixner 				  int *lenp)
23028d0e36bSThomas Gleixner {
23128d0e36bSThomas Gleixner 	struct property *pp;
232d6d3c4e6SThomas Gleixner 	unsigned long flags;
23328d0e36bSThomas Gleixner 
234d6d3c4e6SThomas Gleixner 	raw_spin_lock_irqsave(&devtree_lock, flags);
23528d0e36bSThomas Gleixner 	pp = __of_find_property(np, name, lenp);
236d6d3c4e6SThomas Gleixner 	raw_spin_unlock_irqrestore(&devtree_lock, flags);
237581b605aSStephen Rothwell 
238581b605aSStephen Rothwell 	return pp;
239581b605aSStephen Rothwell }
240581b605aSStephen Rothwell EXPORT_SYMBOL(of_find_property);
241581b605aSStephen Rothwell 
242e91edcf5SGrant Likely /**
243e91edcf5SGrant Likely  * of_find_all_nodes - Get next node in global list
244e91edcf5SGrant Likely  * @prev:	Previous node or NULL to start iteration
245e91edcf5SGrant Likely  *		of_node_put() will be called on it
246e91edcf5SGrant Likely  *
247e91edcf5SGrant Likely  * Returns a node pointer with refcount incremented, use
248e91edcf5SGrant Likely  * of_node_put() on it when done.
249e91edcf5SGrant Likely  */
250e91edcf5SGrant Likely struct device_node *of_find_all_nodes(struct device_node *prev)
251e91edcf5SGrant Likely {
252e91edcf5SGrant Likely 	struct device_node *np;
253d25d8694SBenjamin Herrenschmidt 	unsigned long flags;
254e91edcf5SGrant Likely 
255d25d8694SBenjamin Herrenschmidt 	raw_spin_lock_irqsave(&devtree_lock, flags);
256465aac6dSRandy Dunlap 	np = prev ? prev->allnext : of_allnodes;
257e91edcf5SGrant Likely 	for (; np != NULL; np = np->allnext)
258e91edcf5SGrant Likely 		if (of_node_get(np))
259e91edcf5SGrant Likely 			break;
260e91edcf5SGrant Likely 	of_node_put(prev);
261d25d8694SBenjamin Herrenschmidt 	raw_spin_unlock_irqrestore(&devtree_lock, flags);
262e91edcf5SGrant Likely 	return np;
263e91edcf5SGrant Likely }
264e91edcf5SGrant Likely EXPORT_SYMBOL(of_find_all_nodes);
265e91edcf5SGrant Likely 
26697e873e5SStephen Rothwell /*
26797e873e5SStephen Rothwell  * Find a property with a given name for a given node
26897e873e5SStephen Rothwell  * and return the value.
26997e873e5SStephen Rothwell  */
270a25095d4SGrant Likely const void *__of_get_property(const struct device_node *np,
27128d0e36bSThomas Gleixner 			      const char *name, int *lenp)
27228d0e36bSThomas Gleixner {
27328d0e36bSThomas Gleixner 	struct property *pp = __of_find_property(np, name, lenp);
27428d0e36bSThomas Gleixner 
27528d0e36bSThomas Gleixner 	return pp ? pp->value : NULL;
27628d0e36bSThomas Gleixner }
27728d0e36bSThomas Gleixner 
27828d0e36bSThomas Gleixner /*
27928d0e36bSThomas Gleixner  * Find a property with a given name for a given node
28028d0e36bSThomas Gleixner  * and return the value.
28128d0e36bSThomas Gleixner  */
28297e873e5SStephen Rothwell const void *of_get_property(const struct device_node *np, const char *name,
28397e873e5SStephen Rothwell 			    int *lenp)
28497e873e5SStephen Rothwell {
28597e873e5SStephen Rothwell 	struct property *pp = of_find_property(np, name, lenp);
28697e873e5SStephen Rothwell 
28797e873e5SStephen Rothwell 	return pp ? pp->value : NULL;
28897e873e5SStephen Rothwell }
28997e873e5SStephen Rothwell EXPORT_SYMBOL(of_get_property);
2900081cbc3SStephen Rothwell 
291183912d3SSudeep KarkadaNagesha /*
292183912d3SSudeep KarkadaNagesha  * arch_match_cpu_phys_id - Match the given logical CPU and physical id
293183912d3SSudeep KarkadaNagesha  *
294183912d3SSudeep KarkadaNagesha  * @cpu: logical cpu index of a core/thread
295183912d3SSudeep KarkadaNagesha  * @phys_id: physical identifier of a core/thread
296183912d3SSudeep KarkadaNagesha  *
297183912d3SSudeep KarkadaNagesha  * CPU logical to physical index mapping is architecture specific.
298183912d3SSudeep KarkadaNagesha  * However this __weak function provides a default match of physical
299183912d3SSudeep KarkadaNagesha  * id to logical cpu index. phys_id provided here is usually values read
300183912d3SSudeep KarkadaNagesha  * from the device tree which must match the hardware internal registers.
301183912d3SSudeep KarkadaNagesha  *
302183912d3SSudeep KarkadaNagesha  * Returns true if the physical identifier and the logical cpu index
303183912d3SSudeep KarkadaNagesha  * correspond to the same core/thread, false otherwise.
304183912d3SSudeep KarkadaNagesha  */
305183912d3SSudeep KarkadaNagesha bool __weak arch_match_cpu_phys_id(int cpu, u64 phys_id)
306183912d3SSudeep KarkadaNagesha {
307183912d3SSudeep KarkadaNagesha 	return (u32)phys_id == cpu;
308183912d3SSudeep KarkadaNagesha }
309183912d3SSudeep KarkadaNagesha 
310183912d3SSudeep KarkadaNagesha /**
311183912d3SSudeep KarkadaNagesha  * Checks if the given "prop_name" property holds the physical id of the
312183912d3SSudeep KarkadaNagesha  * core/thread corresponding to the logical cpu 'cpu'. If 'thread' is not
313183912d3SSudeep KarkadaNagesha  * NULL, local thread number within the core is returned in it.
314183912d3SSudeep KarkadaNagesha  */
315183912d3SSudeep KarkadaNagesha static bool __of_find_n_match_cpu_property(struct device_node *cpun,
316183912d3SSudeep KarkadaNagesha 			const char *prop_name, int cpu, unsigned int *thread)
317183912d3SSudeep KarkadaNagesha {
318183912d3SSudeep KarkadaNagesha 	const __be32 *cell;
319183912d3SSudeep KarkadaNagesha 	int ac, prop_len, tid;
320183912d3SSudeep KarkadaNagesha 	u64 hwid;
321183912d3SSudeep KarkadaNagesha 
322183912d3SSudeep KarkadaNagesha 	ac = of_n_addr_cells(cpun);
323183912d3SSudeep KarkadaNagesha 	cell = of_get_property(cpun, prop_name, &prop_len);
324f3cea45aSGrant Likely 	if (!cell || !ac)
325183912d3SSudeep KarkadaNagesha 		return false;
326f3cea45aSGrant Likely 	prop_len /= sizeof(*cell) * ac;
327183912d3SSudeep KarkadaNagesha 	for (tid = 0; tid < prop_len; tid++) {
328183912d3SSudeep KarkadaNagesha 		hwid = of_read_number(cell, ac);
329183912d3SSudeep KarkadaNagesha 		if (arch_match_cpu_phys_id(cpu, hwid)) {
330183912d3SSudeep KarkadaNagesha 			if (thread)
331183912d3SSudeep KarkadaNagesha 				*thread = tid;
332183912d3SSudeep KarkadaNagesha 			return true;
333183912d3SSudeep KarkadaNagesha 		}
334183912d3SSudeep KarkadaNagesha 		cell += ac;
335183912d3SSudeep KarkadaNagesha 	}
336183912d3SSudeep KarkadaNagesha 	return false;
337183912d3SSudeep KarkadaNagesha }
338183912d3SSudeep KarkadaNagesha 
339d1cb9d1aSDavid Miller /*
340d1cb9d1aSDavid Miller  * arch_find_n_match_cpu_physical_id - See if the given device node is
341d1cb9d1aSDavid Miller  * for the cpu corresponding to logical cpu 'cpu'.  Return true if so,
342d1cb9d1aSDavid Miller  * else false.  If 'thread' is non-NULL, the local thread number within the
343d1cb9d1aSDavid Miller  * core is returned in it.
344d1cb9d1aSDavid Miller  */
345d1cb9d1aSDavid Miller bool __weak arch_find_n_match_cpu_physical_id(struct device_node *cpun,
346d1cb9d1aSDavid Miller 					      int cpu, unsigned int *thread)
347d1cb9d1aSDavid Miller {
348d1cb9d1aSDavid Miller 	/* Check for non-standard "ibm,ppc-interrupt-server#s" property
349d1cb9d1aSDavid Miller 	 * for thread ids on PowerPC. If it doesn't exist fallback to
350d1cb9d1aSDavid Miller 	 * standard "reg" property.
351d1cb9d1aSDavid Miller 	 */
352d1cb9d1aSDavid Miller 	if (IS_ENABLED(CONFIG_PPC) &&
353d1cb9d1aSDavid Miller 	    __of_find_n_match_cpu_property(cpun,
354d1cb9d1aSDavid Miller 					   "ibm,ppc-interrupt-server#s",
355d1cb9d1aSDavid Miller 					   cpu, thread))
356d1cb9d1aSDavid Miller 		return true;
357d1cb9d1aSDavid Miller 
358d1cb9d1aSDavid Miller 	if (__of_find_n_match_cpu_property(cpun, "reg", cpu, thread))
359d1cb9d1aSDavid Miller 		return true;
360d1cb9d1aSDavid Miller 
361d1cb9d1aSDavid Miller 	return false;
362d1cb9d1aSDavid Miller }
363d1cb9d1aSDavid Miller 
364183912d3SSudeep KarkadaNagesha /**
365183912d3SSudeep KarkadaNagesha  * of_get_cpu_node - Get device node associated with the given logical CPU
366183912d3SSudeep KarkadaNagesha  *
367183912d3SSudeep KarkadaNagesha  * @cpu: CPU number(logical index) for which device node is required
368183912d3SSudeep KarkadaNagesha  * @thread: if not NULL, local thread number within the physical core is
369183912d3SSudeep KarkadaNagesha  *          returned
370183912d3SSudeep KarkadaNagesha  *
371183912d3SSudeep KarkadaNagesha  * The main purpose of this function is to retrieve the device node for the
372183912d3SSudeep KarkadaNagesha  * given logical CPU index. It should be used to initialize the of_node in
373183912d3SSudeep KarkadaNagesha  * cpu device. Once of_node in cpu device is populated, all the further
374183912d3SSudeep KarkadaNagesha  * references can use that instead.
375183912d3SSudeep KarkadaNagesha  *
376183912d3SSudeep KarkadaNagesha  * CPU logical to physical index mapping is architecture specific and is built
377183912d3SSudeep KarkadaNagesha  * before booting secondary cores. This function uses arch_match_cpu_phys_id
378183912d3SSudeep KarkadaNagesha  * which can be overridden by architecture specific implementation.
379183912d3SSudeep KarkadaNagesha  *
380183912d3SSudeep KarkadaNagesha  * Returns a node pointer for the logical cpu if found, else NULL.
381183912d3SSudeep KarkadaNagesha  */
382183912d3SSudeep KarkadaNagesha struct device_node *of_get_cpu_node(int cpu, unsigned int *thread)
383183912d3SSudeep KarkadaNagesha {
384d1cb9d1aSDavid Miller 	struct device_node *cpun;
385183912d3SSudeep KarkadaNagesha 
386d1cb9d1aSDavid Miller 	for_each_node_by_type(cpun, "cpu") {
387d1cb9d1aSDavid Miller 		if (arch_find_n_match_cpu_physical_id(cpun, cpu, thread))
388183912d3SSudeep KarkadaNagesha 			return cpun;
389183912d3SSudeep KarkadaNagesha 	}
390183912d3SSudeep KarkadaNagesha 	return NULL;
391183912d3SSudeep KarkadaNagesha }
392183912d3SSudeep KarkadaNagesha EXPORT_SYMBOL(of_get_cpu_node);
393183912d3SSudeep KarkadaNagesha 
394215a14cfSKevin Hao /**
395215a14cfSKevin Hao  * __of_device_is_compatible() - Check if the node matches given constraints
396215a14cfSKevin Hao  * @device: pointer to node
397215a14cfSKevin Hao  * @compat: required compatible string, NULL or "" for any match
398215a14cfSKevin Hao  * @type: required device_type value, NULL or "" for any match
399215a14cfSKevin Hao  * @name: required node name, NULL or "" for any match
400215a14cfSKevin Hao  *
401215a14cfSKevin Hao  * Checks if the given @compat, @type and @name strings match the
402215a14cfSKevin Hao  * properties of the given @device. A constraints can be skipped by
403215a14cfSKevin Hao  * passing NULL or an empty string as the constraint.
404215a14cfSKevin Hao  *
405215a14cfSKevin Hao  * Returns 0 for no match, and a positive integer on match. The return
406215a14cfSKevin Hao  * value is a relative score with larger values indicating better
407215a14cfSKevin Hao  * matches. The score is weighted for the most specific compatible value
408215a14cfSKevin Hao  * to get the highest score. Matching type is next, followed by matching
409215a14cfSKevin Hao  * name. Practically speaking, this results in the following priority
410215a14cfSKevin Hao  * order for matches:
411215a14cfSKevin Hao  *
412215a14cfSKevin Hao  * 1. specific compatible && type && name
413215a14cfSKevin Hao  * 2. specific compatible && type
414215a14cfSKevin Hao  * 3. specific compatible && name
415215a14cfSKevin Hao  * 4. specific compatible
416215a14cfSKevin Hao  * 5. general compatible && type && name
417215a14cfSKevin Hao  * 6. general compatible && type
418215a14cfSKevin Hao  * 7. general compatible && name
419215a14cfSKevin Hao  * 8. general compatible
420215a14cfSKevin Hao  * 9. type && name
421215a14cfSKevin Hao  * 10. type
422215a14cfSKevin Hao  * 11. name
4230081cbc3SStephen Rothwell  */
42428d0e36bSThomas Gleixner static int __of_device_is_compatible(const struct device_node *device,
425215a14cfSKevin Hao 				     const char *compat, const char *type, const char *name)
4260081cbc3SStephen Rothwell {
427215a14cfSKevin Hao 	struct property *prop;
4280081cbc3SStephen Rothwell 	const char *cp;
429215a14cfSKevin Hao 	int index = 0, score = 0;
4300081cbc3SStephen Rothwell 
431215a14cfSKevin Hao 	/* Compatible match has highest priority */
432215a14cfSKevin Hao 	if (compat && compat[0]) {
433215a14cfSKevin Hao 		prop = __of_find_property(device, "compatible", NULL);
434215a14cfSKevin Hao 		for (cp = of_prop_next_string(prop, NULL); cp;
435215a14cfSKevin Hao 		     cp = of_prop_next_string(prop, cp), index++) {
436215a14cfSKevin Hao 			if (of_compat_cmp(cp, compat, strlen(compat)) == 0) {
437215a14cfSKevin Hao 				score = INT_MAX/2 - (index << 2);
438215a14cfSKevin Hao 				break;
439215a14cfSKevin Hao 			}
440215a14cfSKevin Hao 		}
441215a14cfSKevin Hao 		if (!score)
4420081cbc3SStephen Rothwell 			return 0;
4430081cbc3SStephen Rothwell 	}
4440081cbc3SStephen Rothwell 
445215a14cfSKevin Hao 	/* Matching type is better than matching name */
446215a14cfSKevin Hao 	if (type && type[0]) {
447215a14cfSKevin Hao 		if (!device->type || of_node_cmp(type, device->type))
4480081cbc3SStephen Rothwell 			return 0;
449215a14cfSKevin Hao 		score += 2;
450215a14cfSKevin Hao 	}
451215a14cfSKevin Hao 
452215a14cfSKevin Hao 	/* Matching name is a bit better than not */
453215a14cfSKevin Hao 	if (name && name[0]) {
454215a14cfSKevin Hao 		if (!device->name || of_node_cmp(name, device->name))
455215a14cfSKevin Hao 			return 0;
456215a14cfSKevin Hao 		score++;
457215a14cfSKevin Hao 	}
458215a14cfSKevin Hao 
459215a14cfSKevin Hao 	return score;
4600081cbc3SStephen Rothwell }
46128d0e36bSThomas Gleixner 
46228d0e36bSThomas Gleixner /** Checks if the given "compat" string matches one of the strings in
46328d0e36bSThomas Gleixner  * the device's "compatible" property
46428d0e36bSThomas Gleixner  */
46528d0e36bSThomas Gleixner int of_device_is_compatible(const struct device_node *device,
46628d0e36bSThomas Gleixner 		const char *compat)
46728d0e36bSThomas Gleixner {
468d6d3c4e6SThomas Gleixner 	unsigned long flags;
46928d0e36bSThomas Gleixner 	int res;
47028d0e36bSThomas Gleixner 
471d6d3c4e6SThomas Gleixner 	raw_spin_lock_irqsave(&devtree_lock, flags);
472215a14cfSKevin Hao 	res = __of_device_is_compatible(device, compat, NULL, NULL);
473d6d3c4e6SThomas Gleixner 	raw_spin_unlock_irqrestore(&devtree_lock, flags);
47428d0e36bSThomas Gleixner 	return res;
47528d0e36bSThomas Gleixner }
4760081cbc3SStephen Rothwell EXPORT_SYMBOL(of_device_is_compatible);
477e679c5f4SStephen Rothwell 
478e679c5f4SStephen Rothwell /**
47971a157e8SGrant Likely  * of_machine_is_compatible - Test root of device tree for a given compatible value
4801f43cfb9SGrant Likely  * @compat: compatible string to look for in root node's compatible property.
4811f43cfb9SGrant Likely  *
4821f43cfb9SGrant Likely  * Returns true if the root node has the given value in its
4831f43cfb9SGrant Likely  * compatible property.
4841f43cfb9SGrant Likely  */
48571a157e8SGrant Likely int of_machine_is_compatible(const char *compat)
4861f43cfb9SGrant Likely {
4871f43cfb9SGrant Likely 	struct device_node *root;
4881f43cfb9SGrant Likely 	int rc = 0;
4891f43cfb9SGrant Likely 
4901f43cfb9SGrant Likely 	root = of_find_node_by_path("/");
4911f43cfb9SGrant Likely 	if (root) {
4921f43cfb9SGrant Likely 		rc = of_device_is_compatible(root, compat);
4931f43cfb9SGrant Likely 		of_node_put(root);
4941f43cfb9SGrant Likely 	}
4951f43cfb9SGrant Likely 	return rc;
4961f43cfb9SGrant Likely }
49771a157e8SGrant Likely EXPORT_SYMBOL(of_machine_is_compatible);
4981f43cfb9SGrant Likely 
4991f43cfb9SGrant Likely /**
500c31a0c05SStephen Warren  *  __of_device_is_available - check if a device is available for use
501834d97d4SJosh Boyer  *
502c31a0c05SStephen Warren  *  @device: Node to check for availability, with locks already held
503834d97d4SJosh Boyer  *
504834d97d4SJosh Boyer  *  Returns 1 if the status property is absent or set to "okay" or "ok",
505834d97d4SJosh Boyer  *  0 otherwise
506834d97d4SJosh Boyer  */
507c31a0c05SStephen Warren static int __of_device_is_available(const struct device_node *device)
508834d97d4SJosh Boyer {
509834d97d4SJosh Boyer 	const char *status;
510834d97d4SJosh Boyer 	int statlen;
511834d97d4SJosh Boyer 
51242ccd781SXiubo Li 	if (!device)
51342ccd781SXiubo Li 		return 0;
51442ccd781SXiubo Li 
515c31a0c05SStephen Warren 	status = __of_get_property(device, "status", &statlen);
516834d97d4SJosh Boyer 	if (status == NULL)
517834d97d4SJosh Boyer 		return 1;
518834d97d4SJosh Boyer 
519834d97d4SJosh Boyer 	if (statlen > 0) {
520834d97d4SJosh Boyer 		if (!strcmp(status, "okay") || !strcmp(status, "ok"))
521834d97d4SJosh Boyer 			return 1;
522834d97d4SJosh Boyer 	}
523834d97d4SJosh Boyer 
524834d97d4SJosh Boyer 	return 0;
525834d97d4SJosh Boyer }
526c31a0c05SStephen Warren 
527c31a0c05SStephen Warren /**
528c31a0c05SStephen Warren  *  of_device_is_available - check if a device is available for use
529c31a0c05SStephen Warren  *
530c31a0c05SStephen Warren  *  @device: Node to check for availability
531c31a0c05SStephen Warren  *
532c31a0c05SStephen Warren  *  Returns 1 if the status property is absent or set to "okay" or "ok",
533c31a0c05SStephen Warren  *  0 otherwise
534c31a0c05SStephen Warren  */
535c31a0c05SStephen Warren int of_device_is_available(const struct device_node *device)
536c31a0c05SStephen Warren {
537c31a0c05SStephen Warren 	unsigned long flags;
538c31a0c05SStephen Warren 	int res;
539c31a0c05SStephen Warren 
540c31a0c05SStephen Warren 	raw_spin_lock_irqsave(&devtree_lock, flags);
541c31a0c05SStephen Warren 	res = __of_device_is_available(device);
542c31a0c05SStephen Warren 	raw_spin_unlock_irqrestore(&devtree_lock, flags);
543c31a0c05SStephen Warren 	return res;
544c31a0c05SStephen Warren 
545c31a0c05SStephen Warren }
546834d97d4SJosh Boyer EXPORT_SYMBOL(of_device_is_available);
547834d97d4SJosh Boyer 
548834d97d4SJosh Boyer /**
549e679c5f4SStephen Rothwell  *	of_get_parent - Get a node's parent if any
550e679c5f4SStephen Rothwell  *	@node:	Node to get parent
551e679c5f4SStephen Rothwell  *
552e679c5f4SStephen Rothwell  *	Returns a node pointer with refcount incremented, use
553e679c5f4SStephen Rothwell  *	of_node_put() on it when done.
554e679c5f4SStephen Rothwell  */
555e679c5f4SStephen Rothwell struct device_node *of_get_parent(const struct device_node *node)
556e679c5f4SStephen Rothwell {
557e679c5f4SStephen Rothwell 	struct device_node *np;
558d6d3c4e6SThomas Gleixner 	unsigned long flags;
559e679c5f4SStephen Rothwell 
560e679c5f4SStephen Rothwell 	if (!node)
561e679c5f4SStephen Rothwell 		return NULL;
562e679c5f4SStephen Rothwell 
563d6d3c4e6SThomas Gleixner 	raw_spin_lock_irqsave(&devtree_lock, flags);
564e679c5f4SStephen Rothwell 	np = of_node_get(node->parent);
565d6d3c4e6SThomas Gleixner 	raw_spin_unlock_irqrestore(&devtree_lock, flags);
566e679c5f4SStephen Rothwell 	return np;
567e679c5f4SStephen Rothwell }
568e679c5f4SStephen Rothwell EXPORT_SYMBOL(of_get_parent);
569d1cd355aSStephen Rothwell 
570d1cd355aSStephen Rothwell /**
571f4eb0107SMichael Ellerman  *	of_get_next_parent - Iterate to a node's parent
572f4eb0107SMichael Ellerman  *	@node:	Node to get parent of
573f4eb0107SMichael Ellerman  *
574f4eb0107SMichael Ellerman  * 	This is like of_get_parent() except that it drops the
575f4eb0107SMichael Ellerman  * 	refcount on the passed node, making it suitable for iterating
576f4eb0107SMichael Ellerman  * 	through a node's parents.
577f4eb0107SMichael Ellerman  *
578f4eb0107SMichael Ellerman  *	Returns a node pointer with refcount incremented, use
579f4eb0107SMichael Ellerman  *	of_node_put() on it when done.
580f4eb0107SMichael Ellerman  */
581f4eb0107SMichael Ellerman struct device_node *of_get_next_parent(struct device_node *node)
582f4eb0107SMichael Ellerman {
583f4eb0107SMichael Ellerman 	struct device_node *parent;
584d6d3c4e6SThomas Gleixner 	unsigned long flags;
585f4eb0107SMichael Ellerman 
586f4eb0107SMichael Ellerman 	if (!node)
587f4eb0107SMichael Ellerman 		return NULL;
588f4eb0107SMichael Ellerman 
589d6d3c4e6SThomas Gleixner 	raw_spin_lock_irqsave(&devtree_lock, flags);
590f4eb0107SMichael Ellerman 	parent = of_node_get(node->parent);
591f4eb0107SMichael Ellerman 	of_node_put(node);
592d6d3c4e6SThomas Gleixner 	raw_spin_unlock_irqrestore(&devtree_lock, flags);
593f4eb0107SMichael Ellerman 	return parent;
594f4eb0107SMichael Ellerman }
5956695be68SGuennadi Liakhovetski EXPORT_SYMBOL(of_get_next_parent);
596f4eb0107SMichael Ellerman 
5970d0e02d6SGrant Likely static struct device_node *__of_get_next_child(const struct device_node *node,
5980d0e02d6SGrant Likely 						struct device_node *prev)
5990d0e02d6SGrant Likely {
6000d0e02d6SGrant Likely 	struct device_node *next;
6010d0e02d6SGrant Likely 
60243cb4367SFlorian Fainelli 	if (!node)
60343cb4367SFlorian Fainelli 		return NULL;
60443cb4367SFlorian Fainelli 
6050d0e02d6SGrant Likely 	next = prev ? prev->sibling : node->child;
6060d0e02d6SGrant Likely 	for (; next; next = next->sibling)
6070d0e02d6SGrant Likely 		if (of_node_get(next))
6080d0e02d6SGrant Likely 			break;
6090d0e02d6SGrant Likely 	of_node_put(prev);
6100d0e02d6SGrant Likely 	return next;
6110d0e02d6SGrant Likely }
6120d0e02d6SGrant Likely #define __for_each_child_of_node(parent, child) \
6130d0e02d6SGrant Likely 	for (child = __of_get_next_child(parent, NULL); child != NULL; \
6140d0e02d6SGrant Likely 	     child = __of_get_next_child(parent, child))
6150d0e02d6SGrant Likely 
616f4eb0107SMichael Ellerman /**
617d1cd355aSStephen Rothwell  *	of_get_next_child - Iterate a node childs
618d1cd355aSStephen Rothwell  *	@node:	parent node
619d1cd355aSStephen Rothwell  *	@prev:	previous child of the parent node, or NULL to get first
620d1cd355aSStephen Rothwell  *
621d1cd355aSStephen Rothwell  *	Returns a node pointer with refcount incremented, use
622d1cd355aSStephen Rothwell  *	of_node_put() on it when done.
623d1cd355aSStephen Rothwell  */
624d1cd355aSStephen Rothwell struct device_node *of_get_next_child(const struct device_node *node,
625d1cd355aSStephen Rothwell 	struct device_node *prev)
626d1cd355aSStephen Rothwell {
627d1cd355aSStephen Rothwell 	struct device_node *next;
628d6d3c4e6SThomas Gleixner 	unsigned long flags;
629d1cd355aSStephen Rothwell 
630d6d3c4e6SThomas Gleixner 	raw_spin_lock_irqsave(&devtree_lock, flags);
6310d0e02d6SGrant Likely 	next = __of_get_next_child(node, prev);
632d6d3c4e6SThomas Gleixner 	raw_spin_unlock_irqrestore(&devtree_lock, flags);
633d1cd355aSStephen Rothwell 	return next;
634d1cd355aSStephen Rothwell }
635d1cd355aSStephen Rothwell EXPORT_SYMBOL(of_get_next_child);
6361ef4d424SStephen Rothwell 
6371ef4d424SStephen Rothwell /**
6383296193dSTimur Tabi  *	of_get_next_available_child - Find the next available child node
6393296193dSTimur Tabi  *	@node:	parent node
6403296193dSTimur Tabi  *	@prev:	previous child of the parent node, or NULL to get first
6413296193dSTimur Tabi  *
6423296193dSTimur Tabi  *      This function is like of_get_next_child(), except that it
6433296193dSTimur Tabi  *      automatically skips any disabled nodes (i.e. status = "disabled").
6443296193dSTimur Tabi  */
6453296193dSTimur Tabi struct device_node *of_get_next_available_child(const struct device_node *node,
6463296193dSTimur Tabi 	struct device_node *prev)
6473296193dSTimur Tabi {
6483296193dSTimur Tabi 	struct device_node *next;
649d25d8694SBenjamin Herrenschmidt 	unsigned long flags;
6503296193dSTimur Tabi 
65143cb4367SFlorian Fainelli 	if (!node)
65243cb4367SFlorian Fainelli 		return NULL;
65343cb4367SFlorian Fainelli 
654d25d8694SBenjamin Herrenschmidt 	raw_spin_lock_irqsave(&devtree_lock, flags);
6553296193dSTimur Tabi 	next = prev ? prev->sibling : node->child;
6563296193dSTimur Tabi 	for (; next; next = next->sibling) {
657c31a0c05SStephen Warren 		if (!__of_device_is_available(next))
6583296193dSTimur Tabi 			continue;
6593296193dSTimur Tabi 		if (of_node_get(next))
6603296193dSTimur Tabi 			break;
6613296193dSTimur Tabi 	}
6623296193dSTimur Tabi 	of_node_put(prev);
663d25d8694SBenjamin Herrenschmidt 	raw_spin_unlock_irqrestore(&devtree_lock, flags);
6643296193dSTimur Tabi 	return next;
6653296193dSTimur Tabi }
6663296193dSTimur Tabi EXPORT_SYMBOL(of_get_next_available_child);
6673296193dSTimur Tabi 
6683296193dSTimur Tabi /**
6699c19761aSSrinivas Kandagatla  *	of_get_child_by_name - Find the child node by name for a given parent
6709c19761aSSrinivas Kandagatla  *	@node:	parent node
6719c19761aSSrinivas Kandagatla  *	@name:	child name to look for.
6729c19761aSSrinivas Kandagatla  *
6739c19761aSSrinivas Kandagatla  *      This function looks for child node for given matching name
6749c19761aSSrinivas Kandagatla  *
6759c19761aSSrinivas Kandagatla  *	Returns a node pointer if found, with refcount incremented, use
6769c19761aSSrinivas Kandagatla  *	of_node_put() on it when done.
6779c19761aSSrinivas Kandagatla  *	Returns NULL if node is not found.
6789c19761aSSrinivas Kandagatla  */
6799c19761aSSrinivas Kandagatla struct device_node *of_get_child_by_name(const struct device_node *node,
6809c19761aSSrinivas Kandagatla 				const char *name)
6819c19761aSSrinivas Kandagatla {
6829c19761aSSrinivas Kandagatla 	struct device_node *child;
6839c19761aSSrinivas Kandagatla 
6849c19761aSSrinivas Kandagatla 	for_each_child_of_node(node, child)
6859c19761aSSrinivas Kandagatla 		if (child->name && (of_node_cmp(child->name, name) == 0))
6869c19761aSSrinivas Kandagatla 			break;
6879c19761aSSrinivas Kandagatla 	return child;
6889c19761aSSrinivas Kandagatla }
6899c19761aSSrinivas Kandagatla EXPORT_SYMBOL(of_get_child_by_name);
6909c19761aSSrinivas Kandagatla 
691c22e650eSGrant Likely static struct device_node *__of_find_node_by_path(struct device_node *parent,
692c22e650eSGrant Likely 						const char *path)
693c22e650eSGrant Likely {
694c22e650eSGrant Likely 	struct device_node *child;
695c22e650eSGrant Likely 	int len = strchrnul(path, '/') - path;
696c22e650eSGrant Likely 
697c22e650eSGrant Likely 	if (!len)
698c22e650eSGrant Likely 		return NULL;
699c22e650eSGrant Likely 
700c22e650eSGrant Likely 	__for_each_child_of_node(parent, child) {
701c22e650eSGrant Likely 		const char *name = strrchr(child->full_name, '/');
702c22e650eSGrant Likely 		if (WARN(!name, "malformed device_node %s\n", child->full_name))
703c22e650eSGrant Likely 			continue;
704c22e650eSGrant Likely 		name++;
705c22e650eSGrant Likely 		if (strncmp(path, name, len) == 0 && (strlen(name) == len))
706c22e650eSGrant Likely 			return child;
707c22e650eSGrant Likely 	}
708c22e650eSGrant Likely 	return NULL;
709c22e650eSGrant Likely }
710c22e650eSGrant Likely 
7119c19761aSSrinivas Kandagatla /**
7121ef4d424SStephen Rothwell  *	of_find_node_by_path - Find a node matching a full OF path
713c22e650eSGrant Likely  *	@path: Either the full path to match, or if the path does not
714c22e650eSGrant Likely  *	       start with '/', the name of a property of the /aliases
715c22e650eSGrant Likely  *	       node (an alias).  In the case of an alias, the node
716c22e650eSGrant Likely  *	       matching the alias' value will be returned.
717c22e650eSGrant Likely  *
718c22e650eSGrant Likely  *	Valid paths:
719c22e650eSGrant Likely  *		/foo/bar	Full path
720c22e650eSGrant Likely  *		foo		Valid alias
721c22e650eSGrant Likely  *		foo/bar		Valid alias + relative path
7221ef4d424SStephen Rothwell  *
7231ef4d424SStephen Rothwell  *	Returns a node pointer with refcount incremented, use
7241ef4d424SStephen Rothwell  *	of_node_put() on it when done.
7251ef4d424SStephen Rothwell  */
7261ef4d424SStephen Rothwell struct device_node *of_find_node_by_path(const char *path)
7271ef4d424SStephen Rothwell {
728c22e650eSGrant Likely 	struct device_node *np = NULL;
729c22e650eSGrant Likely 	struct property *pp;
730d6d3c4e6SThomas Gleixner 	unsigned long flags;
7311ef4d424SStephen Rothwell 
732c22e650eSGrant Likely 	if (strcmp(path, "/") == 0)
733c22e650eSGrant Likely 		return of_node_get(of_allnodes);
734c22e650eSGrant Likely 
735c22e650eSGrant Likely 	/* The path could begin with an alias */
736c22e650eSGrant Likely 	if (*path != '/') {
737c22e650eSGrant Likely 		char *p = strchrnul(path, '/');
738c22e650eSGrant Likely 		int len = p - path;
739c22e650eSGrant Likely 
740c22e650eSGrant Likely 		/* of_aliases must not be NULL */
741c22e650eSGrant Likely 		if (!of_aliases)
742c22e650eSGrant Likely 			return NULL;
743c22e650eSGrant Likely 
744c22e650eSGrant Likely 		for_each_property_of_node(of_aliases, pp) {
745c22e650eSGrant Likely 			if (strlen(pp->name) == len && !strncmp(pp->name, path, len)) {
746c22e650eSGrant Likely 				np = of_find_node_by_path(pp->value);
7471ef4d424SStephen Rothwell 				break;
7481ef4d424SStephen Rothwell 			}
749c22e650eSGrant Likely 		}
750c22e650eSGrant Likely 		if (!np)
751c22e650eSGrant Likely 			return NULL;
752c22e650eSGrant Likely 		path = p;
753c22e650eSGrant Likely 	}
754c22e650eSGrant Likely 
755c22e650eSGrant Likely 	/* Step down the tree matching path components */
756c22e650eSGrant Likely 	raw_spin_lock_irqsave(&devtree_lock, flags);
757c22e650eSGrant Likely 	if (!np)
758c22e650eSGrant Likely 		np = of_node_get(of_allnodes);
759c22e650eSGrant Likely 	while (np && *path == '/') {
760c22e650eSGrant Likely 		path++; /* Increment past '/' delimiter */
761c22e650eSGrant Likely 		np = __of_find_node_by_path(np, path);
762c22e650eSGrant Likely 		path = strchrnul(path, '/');
763c22e650eSGrant Likely 	}
764d6d3c4e6SThomas Gleixner 	raw_spin_unlock_irqrestore(&devtree_lock, flags);
7651ef4d424SStephen Rothwell 	return np;
7661ef4d424SStephen Rothwell }
7671ef4d424SStephen Rothwell EXPORT_SYMBOL(of_find_node_by_path);
7681ef4d424SStephen Rothwell 
7691ef4d424SStephen Rothwell /**
7701ef4d424SStephen Rothwell  *	of_find_node_by_name - Find a node by its "name" property
7711ef4d424SStephen Rothwell  *	@from:	The node to start searching from or NULL, the node
7721ef4d424SStephen Rothwell  *		you pass will not be searched, only the next one
7731ef4d424SStephen Rothwell  *		will; typically, you pass what the previous call
7741ef4d424SStephen Rothwell  *		returned. of_node_put() will be called on it
7751ef4d424SStephen Rothwell  *	@name:	The name string to match against
7761ef4d424SStephen Rothwell  *
7771ef4d424SStephen Rothwell  *	Returns a node pointer with refcount incremented, use
7781ef4d424SStephen Rothwell  *	of_node_put() on it when done.
7791ef4d424SStephen Rothwell  */
7801ef4d424SStephen Rothwell struct device_node *of_find_node_by_name(struct device_node *from,
7811ef4d424SStephen Rothwell 	const char *name)
7821ef4d424SStephen Rothwell {
7831ef4d424SStephen Rothwell 	struct device_node *np;
784d6d3c4e6SThomas Gleixner 	unsigned long flags;
7851ef4d424SStephen Rothwell 
786d6d3c4e6SThomas Gleixner 	raw_spin_lock_irqsave(&devtree_lock, flags);
787465aac6dSRandy Dunlap 	np = from ? from->allnext : of_allnodes;
7881ef4d424SStephen Rothwell 	for (; np; np = np->allnext)
7891ef4d424SStephen Rothwell 		if (np->name && (of_node_cmp(np->name, name) == 0)
7901ef4d424SStephen Rothwell 		    && of_node_get(np))
7911ef4d424SStephen Rothwell 			break;
7921ef4d424SStephen Rothwell 	of_node_put(from);
793d6d3c4e6SThomas Gleixner 	raw_spin_unlock_irqrestore(&devtree_lock, flags);
7941ef4d424SStephen Rothwell 	return np;
7951ef4d424SStephen Rothwell }
7961ef4d424SStephen Rothwell EXPORT_SYMBOL(of_find_node_by_name);
7971ef4d424SStephen Rothwell 
7981ef4d424SStephen Rothwell /**
7991ef4d424SStephen Rothwell  *	of_find_node_by_type - Find a node by its "device_type" property
8001ef4d424SStephen Rothwell  *	@from:	The node to start searching from, or NULL to start searching
8011ef4d424SStephen Rothwell  *		the entire device tree. The node you pass will not be
8021ef4d424SStephen Rothwell  *		searched, only the next one will; typically, you pass
8031ef4d424SStephen Rothwell  *		what the previous call returned. of_node_put() will be
8041ef4d424SStephen Rothwell  *		called on from for you.
8051ef4d424SStephen Rothwell  *	@type:	The type string to match against
8061ef4d424SStephen Rothwell  *
8071ef4d424SStephen Rothwell  *	Returns a node pointer with refcount incremented, use
8081ef4d424SStephen Rothwell  *	of_node_put() on it when done.
8091ef4d424SStephen Rothwell  */
8101ef4d424SStephen Rothwell struct device_node *of_find_node_by_type(struct device_node *from,
8111ef4d424SStephen Rothwell 	const char *type)
8121ef4d424SStephen Rothwell {
8131ef4d424SStephen Rothwell 	struct device_node *np;
814d6d3c4e6SThomas Gleixner 	unsigned long flags;
8151ef4d424SStephen Rothwell 
816d6d3c4e6SThomas Gleixner 	raw_spin_lock_irqsave(&devtree_lock, flags);
817465aac6dSRandy Dunlap 	np = from ? from->allnext : of_allnodes;
8181ef4d424SStephen Rothwell 	for (; np; np = np->allnext)
8191ef4d424SStephen Rothwell 		if (np->type && (of_node_cmp(np->type, type) == 0)
8201ef4d424SStephen Rothwell 		    && of_node_get(np))
8211ef4d424SStephen Rothwell 			break;
8221ef4d424SStephen Rothwell 	of_node_put(from);
823d6d3c4e6SThomas Gleixner 	raw_spin_unlock_irqrestore(&devtree_lock, flags);
8241ef4d424SStephen Rothwell 	return np;
8251ef4d424SStephen Rothwell }
8261ef4d424SStephen Rothwell EXPORT_SYMBOL(of_find_node_by_type);
8271ef4d424SStephen Rothwell 
8281ef4d424SStephen Rothwell /**
8291ef4d424SStephen Rothwell  *	of_find_compatible_node - Find a node based on type and one of the
8301ef4d424SStephen Rothwell  *                                tokens in its "compatible" property
8311ef4d424SStephen Rothwell  *	@from:		The node to start searching from or NULL, the node
8321ef4d424SStephen Rothwell  *			you pass will not be searched, only the next one
8331ef4d424SStephen Rothwell  *			will; typically, you pass what the previous call
8341ef4d424SStephen Rothwell  *			returned. of_node_put() will be called on it
8351ef4d424SStephen Rothwell  *	@type:		The type string to match "device_type" or NULL to ignore
8361ef4d424SStephen Rothwell  *	@compatible:	The string to match to one of the tokens in the device
8371ef4d424SStephen Rothwell  *			"compatible" list.
8381ef4d424SStephen Rothwell  *
8391ef4d424SStephen Rothwell  *	Returns a node pointer with refcount incremented, use
8401ef4d424SStephen Rothwell  *	of_node_put() on it when done.
8411ef4d424SStephen Rothwell  */
8421ef4d424SStephen Rothwell struct device_node *of_find_compatible_node(struct device_node *from,
8431ef4d424SStephen Rothwell 	const char *type, const char *compatible)
8441ef4d424SStephen Rothwell {
8451ef4d424SStephen Rothwell 	struct device_node *np;
846d6d3c4e6SThomas Gleixner 	unsigned long flags;
8471ef4d424SStephen Rothwell 
848d6d3c4e6SThomas Gleixner 	raw_spin_lock_irqsave(&devtree_lock, flags);
849465aac6dSRandy Dunlap 	np = from ? from->allnext : of_allnodes;
8501ef4d424SStephen Rothwell 	for (; np; np = np->allnext) {
851215a14cfSKevin Hao 		if (__of_device_is_compatible(np, compatible, type, NULL) &&
85228d0e36bSThomas Gleixner 		    of_node_get(np))
8531ef4d424SStephen Rothwell 			break;
8541ef4d424SStephen Rothwell 	}
8551ef4d424SStephen Rothwell 	of_node_put(from);
856d6d3c4e6SThomas Gleixner 	raw_spin_unlock_irqrestore(&devtree_lock, flags);
8571ef4d424SStephen Rothwell 	return np;
8581ef4d424SStephen Rothwell }
8591ef4d424SStephen Rothwell EXPORT_SYMBOL(of_find_compatible_node);
860283029d1SGrant Likely 
861283029d1SGrant Likely /**
8621e291b14SMichael Ellerman  *	of_find_node_with_property - Find a node which has a property with
8631e291b14SMichael Ellerman  *                                   the given name.
8641e291b14SMichael Ellerman  *	@from:		The node to start searching from or NULL, the node
8651e291b14SMichael Ellerman  *			you pass will not be searched, only the next one
8661e291b14SMichael Ellerman  *			will; typically, you pass what the previous call
8671e291b14SMichael Ellerman  *			returned. of_node_put() will be called on it
8681e291b14SMichael Ellerman  *	@prop_name:	The name of the property to look for.
8691e291b14SMichael Ellerman  *
8701e291b14SMichael Ellerman  *	Returns a node pointer with refcount incremented, use
8711e291b14SMichael Ellerman  *	of_node_put() on it when done.
8721e291b14SMichael Ellerman  */
8731e291b14SMichael Ellerman struct device_node *of_find_node_with_property(struct device_node *from,
8741e291b14SMichael Ellerman 	const char *prop_name)
8751e291b14SMichael Ellerman {
8761e291b14SMichael Ellerman 	struct device_node *np;
8771e291b14SMichael Ellerman 	struct property *pp;
878d6d3c4e6SThomas Gleixner 	unsigned long flags;
8791e291b14SMichael Ellerman 
880d6d3c4e6SThomas Gleixner 	raw_spin_lock_irqsave(&devtree_lock, flags);
881465aac6dSRandy Dunlap 	np = from ? from->allnext : of_allnodes;
8821e291b14SMichael Ellerman 	for (; np; np = np->allnext) {
883a3a7cab1SSachin Kamat 		for (pp = np->properties; pp; pp = pp->next) {
8841e291b14SMichael Ellerman 			if (of_prop_cmp(pp->name, prop_name) == 0) {
8851e291b14SMichael Ellerman 				of_node_get(np);
8861e291b14SMichael Ellerman 				goto out;
8871e291b14SMichael Ellerman 			}
8881e291b14SMichael Ellerman 		}
8891e291b14SMichael Ellerman 	}
8901e291b14SMichael Ellerman out:
8911e291b14SMichael Ellerman 	of_node_put(from);
892d6d3c4e6SThomas Gleixner 	raw_spin_unlock_irqrestore(&devtree_lock, flags);
8931e291b14SMichael Ellerman 	return np;
8941e291b14SMichael Ellerman }
8951e291b14SMichael Ellerman EXPORT_SYMBOL(of_find_node_with_property);
8961e291b14SMichael Ellerman 
89728d0e36bSThomas Gleixner static
89828d0e36bSThomas Gleixner const struct of_device_id *__of_match_node(const struct of_device_id *matches,
899283029d1SGrant Likely 					   const struct device_node *node)
900283029d1SGrant Likely {
901215a14cfSKevin Hao 	const struct of_device_id *best_match = NULL;
902215a14cfSKevin Hao 	int score, best_score = 0;
903215a14cfSKevin Hao 
904a52f07ecSGrant Likely 	if (!matches)
905a52f07ecSGrant Likely 		return NULL;
906a52f07ecSGrant Likely 
907215a14cfSKevin Hao 	for (; matches->name[0] || matches->type[0] || matches->compatible[0]; matches++) {
908215a14cfSKevin Hao 		score = __of_device_is_compatible(node, matches->compatible,
909215a14cfSKevin Hao 						  matches->type, matches->name);
910215a14cfSKevin Hao 		if (score > best_score) {
911215a14cfSKevin Hao 			best_match = matches;
912215a14cfSKevin Hao 			best_score = score;
913283029d1SGrant Likely 		}
914215a14cfSKevin Hao 	}
915215a14cfSKevin Hao 
916215a14cfSKevin Hao 	return best_match;
917283029d1SGrant Likely }
91828d0e36bSThomas Gleixner 
91928d0e36bSThomas Gleixner /**
92028d0e36bSThomas Gleixner  * of_match_node - Tell if an device_node has a matching of_match structure
92128d0e36bSThomas Gleixner  *	@matches:	array of of device match structures to search in
92228d0e36bSThomas Gleixner  *	@node:		the of device structure to match against
92328d0e36bSThomas Gleixner  *
92471c5498eSKevin Hao  *	Low level utility function used by device matching.
92528d0e36bSThomas Gleixner  */
92628d0e36bSThomas Gleixner const struct of_device_id *of_match_node(const struct of_device_id *matches,
92728d0e36bSThomas Gleixner 					 const struct device_node *node)
92828d0e36bSThomas Gleixner {
92928d0e36bSThomas Gleixner 	const struct of_device_id *match;
930d6d3c4e6SThomas Gleixner 	unsigned long flags;
93128d0e36bSThomas Gleixner 
932d6d3c4e6SThomas Gleixner 	raw_spin_lock_irqsave(&devtree_lock, flags);
93328d0e36bSThomas Gleixner 	match = __of_match_node(matches, node);
934d6d3c4e6SThomas Gleixner 	raw_spin_unlock_irqrestore(&devtree_lock, flags);
93528d0e36bSThomas Gleixner 	return match;
93628d0e36bSThomas Gleixner }
937283029d1SGrant Likely EXPORT_SYMBOL(of_match_node);
938283029d1SGrant Likely 
939283029d1SGrant Likely /**
94050c8af4cSStephen Warren  *	of_find_matching_node_and_match - Find a node based on an of_device_id
94150c8af4cSStephen Warren  *					  match table.
942283029d1SGrant Likely  *	@from:		The node to start searching from or NULL, the node
943283029d1SGrant Likely  *			you pass will not be searched, only the next one
944283029d1SGrant Likely  *			will; typically, you pass what the previous call
945283029d1SGrant Likely  *			returned. of_node_put() will be called on it
946283029d1SGrant Likely  *	@matches:	array of of device match structures to search in
94750c8af4cSStephen Warren  *	@match		Updated to point at the matches entry which matched
948283029d1SGrant Likely  *
949283029d1SGrant Likely  *	Returns a node pointer with refcount incremented, use
950283029d1SGrant Likely  *	of_node_put() on it when done.
951283029d1SGrant Likely  */
95250c8af4cSStephen Warren struct device_node *of_find_matching_node_and_match(struct device_node *from,
95350c8af4cSStephen Warren 					const struct of_device_id *matches,
95450c8af4cSStephen Warren 					const struct of_device_id **match)
955283029d1SGrant Likely {
956283029d1SGrant Likely 	struct device_node *np;
957dc71bcf1SThomas Abraham 	const struct of_device_id *m;
958d6d3c4e6SThomas Gleixner 	unsigned long flags;
959283029d1SGrant Likely 
96050c8af4cSStephen Warren 	if (match)
96150c8af4cSStephen Warren 		*match = NULL;
96250c8af4cSStephen Warren 
963d6d3c4e6SThomas Gleixner 	raw_spin_lock_irqsave(&devtree_lock, flags);
964465aac6dSRandy Dunlap 	np = from ? from->allnext : of_allnodes;
965283029d1SGrant Likely 	for (; np; np = np->allnext) {
96628d0e36bSThomas Gleixner 		m = __of_match_node(matches, np);
967dc71bcf1SThomas Abraham 		if (m && of_node_get(np)) {
96850c8af4cSStephen Warren 			if (match)
969dc71bcf1SThomas Abraham 				*match = m;
970283029d1SGrant Likely 			break;
971283029d1SGrant Likely 		}
97250c8af4cSStephen Warren 	}
973283029d1SGrant Likely 	of_node_put(from);
974d6d3c4e6SThomas Gleixner 	raw_spin_unlock_irqrestore(&devtree_lock, flags);
975283029d1SGrant Likely 	return np;
976283029d1SGrant Likely }
97780c2022eSGrant Likely EXPORT_SYMBOL(of_find_matching_node_and_match);
9783f07af49SGrant Likely 
9793f07af49SGrant Likely /**
9803f07af49SGrant Likely  * of_modalias_node - Lookup appropriate modalias for a device node
9813f07af49SGrant Likely  * @node:	pointer to a device tree node
9823f07af49SGrant Likely  * @modalias:	Pointer to buffer that modalias value will be copied into
9833f07af49SGrant Likely  * @len:	Length of modalias value
9843f07af49SGrant Likely  *
9852ffe8c5fSGrant Likely  * Based on the value of the compatible property, this routine will attempt
9862ffe8c5fSGrant Likely  * to choose an appropriate modalias value for a particular device tree node.
9872ffe8c5fSGrant Likely  * It does this by stripping the manufacturer prefix (as delimited by a ',')
9882ffe8c5fSGrant Likely  * from the first entry in the compatible list property.
9893f07af49SGrant Likely  *
9902ffe8c5fSGrant Likely  * This routine returns 0 on success, <0 on failure.
9913f07af49SGrant Likely  */
9923f07af49SGrant Likely int of_modalias_node(struct device_node *node, char *modalias, int len)
9933f07af49SGrant Likely {
9942ffe8c5fSGrant Likely 	const char *compatible, *p;
9952ffe8c5fSGrant Likely 	int cplen;
9963f07af49SGrant Likely 
9973f07af49SGrant Likely 	compatible = of_get_property(node, "compatible", &cplen);
9982ffe8c5fSGrant Likely 	if (!compatible || strlen(compatible) > cplen)
9993f07af49SGrant Likely 		return -ENODEV;
10003f07af49SGrant Likely 	p = strchr(compatible, ',');
10012ffe8c5fSGrant Likely 	strlcpy(modalias, p ? p + 1 : compatible, len);
10023f07af49SGrant Likely 	return 0;
10033f07af49SGrant Likely }
10043f07af49SGrant Likely EXPORT_SYMBOL_GPL(of_modalias_node);
10053f07af49SGrant Likely 
100664b60e09SAnton Vorontsov /**
100789751a7cSJeremy Kerr  * of_find_node_by_phandle - Find a node given a phandle
100889751a7cSJeremy Kerr  * @handle:	phandle of the node to find
100989751a7cSJeremy Kerr  *
101089751a7cSJeremy Kerr  * Returns a node pointer with refcount incremented, use
101189751a7cSJeremy Kerr  * of_node_put() on it when done.
101289751a7cSJeremy Kerr  */
101389751a7cSJeremy Kerr struct device_node *of_find_node_by_phandle(phandle handle)
101489751a7cSJeremy Kerr {
101589751a7cSJeremy Kerr 	struct device_node *np;
1016d25d8694SBenjamin Herrenschmidt 	unsigned long flags;
101789751a7cSJeremy Kerr 
1018d25d8694SBenjamin Herrenschmidt 	raw_spin_lock_irqsave(&devtree_lock, flags);
1019465aac6dSRandy Dunlap 	for (np = of_allnodes; np; np = np->allnext)
102089751a7cSJeremy Kerr 		if (np->phandle == handle)
102189751a7cSJeremy Kerr 			break;
102289751a7cSJeremy Kerr 	of_node_get(np);
1023d25d8694SBenjamin Herrenschmidt 	raw_spin_unlock_irqrestore(&devtree_lock, flags);
102489751a7cSJeremy Kerr 	return np;
102589751a7cSJeremy Kerr }
102689751a7cSJeremy Kerr EXPORT_SYMBOL(of_find_node_by_phandle);
102789751a7cSJeremy Kerr 
102889751a7cSJeremy Kerr /**
1029ad54a0cfSHeiko Stuebner  * of_property_count_elems_of_size - Count the number of elements in a property
1030ad54a0cfSHeiko Stuebner  *
1031ad54a0cfSHeiko Stuebner  * @np:		device node from which the property value is to be read.
1032ad54a0cfSHeiko Stuebner  * @propname:	name of the property to be searched.
1033ad54a0cfSHeiko Stuebner  * @elem_size:	size of the individual element
1034ad54a0cfSHeiko Stuebner  *
1035ad54a0cfSHeiko Stuebner  * Search for a property in a device node and count the number of elements of
1036ad54a0cfSHeiko Stuebner  * size elem_size in it. Returns number of elements on sucess, -EINVAL if the
1037ad54a0cfSHeiko Stuebner  * property does not exist or its length does not match a multiple of elem_size
1038ad54a0cfSHeiko Stuebner  * and -ENODATA if the property does not have a value.
1039ad54a0cfSHeiko Stuebner  */
1040ad54a0cfSHeiko Stuebner int of_property_count_elems_of_size(const struct device_node *np,
1041ad54a0cfSHeiko Stuebner 				const char *propname, int elem_size)
1042ad54a0cfSHeiko Stuebner {
1043ad54a0cfSHeiko Stuebner 	struct property *prop = of_find_property(np, propname, NULL);
1044ad54a0cfSHeiko Stuebner 
1045ad54a0cfSHeiko Stuebner 	if (!prop)
1046ad54a0cfSHeiko Stuebner 		return -EINVAL;
1047ad54a0cfSHeiko Stuebner 	if (!prop->value)
1048ad54a0cfSHeiko Stuebner 		return -ENODATA;
1049ad54a0cfSHeiko Stuebner 
1050ad54a0cfSHeiko Stuebner 	if (prop->length % elem_size != 0) {
1051ad54a0cfSHeiko Stuebner 		pr_err("size of %s in node %s is not a multiple of %d\n",
1052ad54a0cfSHeiko Stuebner 		       propname, np->full_name, elem_size);
1053ad54a0cfSHeiko Stuebner 		return -EINVAL;
1054ad54a0cfSHeiko Stuebner 	}
1055ad54a0cfSHeiko Stuebner 
1056ad54a0cfSHeiko Stuebner 	return prop->length / elem_size;
1057ad54a0cfSHeiko Stuebner }
1058ad54a0cfSHeiko Stuebner EXPORT_SYMBOL_GPL(of_property_count_elems_of_size);
1059ad54a0cfSHeiko Stuebner 
1060ad54a0cfSHeiko Stuebner /**
1061daeec1f0STony Prisk  * of_find_property_value_of_size
1062daeec1f0STony Prisk  *
1063daeec1f0STony Prisk  * @np:		device node from which the property value is to be read.
1064daeec1f0STony Prisk  * @propname:	name of the property to be searched.
1065daeec1f0STony Prisk  * @len:	requested length of property value
1066daeec1f0STony Prisk  *
1067daeec1f0STony Prisk  * Search for a property in a device node and valid the requested size.
1068daeec1f0STony Prisk  * Returns the property value on success, -EINVAL if the property does not
1069daeec1f0STony Prisk  *  exist, -ENODATA if property does not have a value, and -EOVERFLOW if the
1070daeec1f0STony Prisk  * property data isn't large enough.
1071daeec1f0STony Prisk  *
1072daeec1f0STony Prisk  */
1073daeec1f0STony Prisk static void *of_find_property_value_of_size(const struct device_node *np,
1074daeec1f0STony Prisk 			const char *propname, u32 len)
1075daeec1f0STony Prisk {
1076daeec1f0STony Prisk 	struct property *prop = of_find_property(np, propname, NULL);
1077daeec1f0STony Prisk 
1078daeec1f0STony Prisk 	if (!prop)
1079daeec1f0STony Prisk 		return ERR_PTR(-EINVAL);
1080daeec1f0STony Prisk 	if (!prop->value)
1081daeec1f0STony Prisk 		return ERR_PTR(-ENODATA);
1082daeec1f0STony Prisk 	if (len > prop->length)
1083daeec1f0STony Prisk 		return ERR_PTR(-EOVERFLOW);
1084daeec1f0STony Prisk 
1085daeec1f0STony Prisk 	return prop->value;
1086daeec1f0STony Prisk }
1087daeec1f0STony Prisk 
1088daeec1f0STony Prisk /**
10893daf3726STony Prisk  * of_property_read_u32_index - Find and read a u32 from a multi-value property.
10903daf3726STony Prisk  *
10913daf3726STony Prisk  * @np:		device node from which the property value is to be read.
10923daf3726STony Prisk  * @propname:	name of the property to be searched.
10933daf3726STony Prisk  * @index:	index of the u32 in the list of values
10943daf3726STony Prisk  * @out_value:	pointer to return value, modified only if no error.
10953daf3726STony Prisk  *
10963daf3726STony Prisk  * Search for a property in a device node and read nth 32-bit value from
10973daf3726STony Prisk  * it. Returns 0 on success, -EINVAL if the property does not exist,
10983daf3726STony Prisk  * -ENODATA if property does not have a value, and -EOVERFLOW if the
10993daf3726STony Prisk  * property data isn't large enough.
11003daf3726STony Prisk  *
11013daf3726STony Prisk  * The out_value is modified only if a valid u32 value can be decoded.
11023daf3726STony Prisk  */
11033daf3726STony Prisk int of_property_read_u32_index(const struct device_node *np,
11043daf3726STony Prisk 				       const char *propname,
11053daf3726STony Prisk 				       u32 index, u32 *out_value)
11063daf3726STony Prisk {
1107daeec1f0STony Prisk 	const u32 *val = of_find_property_value_of_size(np, propname,
1108daeec1f0STony Prisk 					((index + 1) * sizeof(*out_value)));
11093daf3726STony Prisk 
1110daeec1f0STony Prisk 	if (IS_ERR(val))
1111daeec1f0STony Prisk 		return PTR_ERR(val);
11123daf3726STony Prisk 
1113daeec1f0STony Prisk 	*out_value = be32_to_cpup(((__be32 *)val) + index);
11143daf3726STony Prisk 	return 0;
11153daf3726STony Prisk }
11163daf3726STony Prisk EXPORT_SYMBOL_GPL(of_property_read_u32_index);
11173daf3726STony Prisk 
11183daf3726STony Prisk /**
1119be193249SViresh Kumar  * of_property_read_u8_array - Find and read an array of u8 from a property.
1120be193249SViresh Kumar  *
1121be193249SViresh Kumar  * @np:		device node from which the property value is to be read.
1122be193249SViresh Kumar  * @propname:	name of the property to be searched.
1123792efb84SLad, Prabhakar  * @out_values:	pointer to return value, modified only if return value is 0.
1124be193249SViresh Kumar  * @sz:		number of array elements to read
1125be193249SViresh Kumar  *
1126be193249SViresh Kumar  * Search for a property in a device node and read 8-bit value(s) from
1127be193249SViresh Kumar  * it. Returns 0 on success, -EINVAL if the property does not exist,
1128be193249SViresh Kumar  * -ENODATA if property does not have a value, and -EOVERFLOW if the
1129be193249SViresh Kumar  * property data isn't large enough.
1130be193249SViresh Kumar  *
1131be193249SViresh Kumar  * dts entry of array should be like:
1132be193249SViresh Kumar  *	property = /bits/ 8 <0x50 0x60 0x70>;
1133be193249SViresh Kumar  *
1134792efb84SLad, Prabhakar  * The out_values is modified only if a valid u8 value can be decoded.
1135be193249SViresh Kumar  */
1136be193249SViresh Kumar int of_property_read_u8_array(const struct device_node *np,
1137be193249SViresh Kumar 			const char *propname, u8 *out_values, size_t sz)
1138be193249SViresh Kumar {
1139daeec1f0STony Prisk 	const u8 *val = of_find_property_value_of_size(np, propname,
1140daeec1f0STony Prisk 						(sz * sizeof(*out_values)));
1141be193249SViresh Kumar 
1142daeec1f0STony Prisk 	if (IS_ERR(val))
1143daeec1f0STony Prisk 		return PTR_ERR(val);
1144be193249SViresh Kumar 
1145be193249SViresh Kumar 	while (sz--)
1146be193249SViresh Kumar 		*out_values++ = *val++;
1147be193249SViresh Kumar 	return 0;
1148be193249SViresh Kumar }
1149be193249SViresh Kumar EXPORT_SYMBOL_GPL(of_property_read_u8_array);
1150be193249SViresh Kumar 
1151be193249SViresh Kumar /**
1152be193249SViresh Kumar  * of_property_read_u16_array - Find and read an array of u16 from a property.
1153be193249SViresh Kumar  *
1154be193249SViresh Kumar  * @np:		device node from which the property value is to be read.
1155be193249SViresh Kumar  * @propname:	name of the property to be searched.
1156792efb84SLad, Prabhakar  * @out_values:	pointer to return value, modified only if return value is 0.
1157be193249SViresh Kumar  * @sz:		number of array elements to read
1158be193249SViresh Kumar  *
1159be193249SViresh Kumar  * Search for a property in a device node and read 16-bit value(s) from
1160be193249SViresh Kumar  * it. Returns 0 on success, -EINVAL if the property does not exist,
1161be193249SViresh Kumar  * -ENODATA if property does not have a value, and -EOVERFLOW if the
1162be193249SViresh Kumar  * property data isn't large enough.
1163be193249SViresh Kumar  *
1164be193249SViresh Kumar  * dts entry of array should be like:
1165be193249SViresh Kumar  *	property = /bits/ 16 <0x5000 0x6000 0x7000>;
1166be193249SViresh Kumar  *
1167792efb84SLad, Prabhakar  * The out_values is modified only if a valid u16 value can be decoded.
1168be193249SViresh Kumar  */
1169be193249SViresh Kumar int of_property_read_u16_array(const struct device_node *np,
1170be193249SViresh Kumar 			const char *propname, u16 *out_values, size_t sz)
1171be193249SViresh Kumar {
1172daeec1f0STony Prisk 	const __be16 *val = of_find_property_value_of_size(np, propname,
1173daeec1f0STony Prisk 						(sz * sizeof(*out_values)));
1174be193249SViresh Kumar 
1175daeec1f0STony Prisk 	if (IS_ERR(val))
1176daeec1f0STony Prisk 		return PTR_ERR(val);
1177be193249SViresh Kumar 
1178be193249SViresh Kumar 	while (sz--)
1179be193249SViresh Kumar 		*out_values++ = be16_to_cpup(val++);
1180be193249SViresh Kumar 	return 0;
1181be193249SViresh Kumar }
1182be193249SViresh Kumar EXPORT_SYMBOL_GPL(of_property_read_u16_array);
1183be193249SViresh Kumar 
1184be193249SViresh Kumar /**
11850e373639SRob Herring  * of_property_read_u32_array - Find and read an array of 32 bit integers
11860e373639SRob Herring  * from a property.
11870e373639SRob Herring  *
1188a3b85363SThomas Abraham  * @np:		device node from which the property value is to be read.
1189a3b85363SThomas Abraham  * @propname:	name of the property to be searched.
1190792efb84SLad, Prabhakar  * @out_values:	pointer to return value, modified only if return value is 0.
1191be193249SViresh Kumar  * @sz:		number of array elements to read
1192a3b85363SThomas Abraham  *
11930e373639SRob Herring  * Search for a property in a device node and read 32-bit value(s) from
1194a3b85363SThomas Abraham  * it. Returns 0 on success, -EINVAL if the property does not exist,
1195a3b85363SThomas Abraham  * -ENODATA if property does not have a value, and -EOVERFLOW if the
1196a3b85363SThomas Abraham  * property data isn't large enough.
1197a3b85363SThomas Abraham  *
1198792efb84SLad, Prabhakar  * The out_values is modified only if a valid u32 value can be decoded.
1199a3b85363SThomas Abraham  */
1200aac285c6SJamie Iles int of_property_read_u32_array(const struct device_node *np,
1201aac285c6SJamie Iles 			       const char *propname, u32 *out_values,
1202aac285c6SJamie Iles 			       size_t sz)
1203a3b85363SThomas Abraham {
1204daeec1f0STony Prisk 	const __be32 *val = of_find_property_value_of_size(np, propname,
1205daeec1f0STony Prisk 						(sz * sizeof(*out_values)));
1206a3b85363SThomas Abraham 
1207daeec1f0STony Prisk 	if (IS_ERR(val))
1208daeec1f0STony Prisk 		return PTR_ERR(val);
12090e373639SRob Herring 
12100e373639SRob Herring 	while (sz--)
12110e373639SRob Herring 		*out_values++ = be32_to_cpup(val++);
1212a3b85363SThomas Abraham 	return 0;
1213a3b85363SThomas Abraham }
12140e373639SRob Herring EXPORT_SYMBOL_GPL(of_property_read_u32_array);
1215a3b85363SThomas Abraham 
1216a3b85363SThomas Abraham /**
12174cd7f7a3SJamie Iles  * of_property_read_u64 - Find and read a 64 bit integer from a property
12184cd7f7a3SJamie Iles  * @np:		device node from which the property value is to be read.
12194cd7f7a3SJamie Iles  * @propname:	name of the property to be searched.
12204cd7f7a3SJamie Iles  * @out_value:	pointer to return value, modified only if return value is 0.
12214cd7f7a3SJamie Iles  *
12224cd7f7a3SJamie Iles  * Search for a property in a device node and read a 64-bit value from
12234cd7f7a3SJamie Iles  * it. Returns 0 on success, -EINVAL if the property does not exist,
12244cd7f7a3SJamie Iles  * -ENODATA if property does not have a value, and -EOVERFLOW if the
12254cd7f7a3SJamie Iles  * property data isn't large enough.
12264cd7f7a3SJamie Iles  *
12274cd7f7a3SJamie Iles  * The out_value is modified only if a valid u64 value can be decoded.
12284cd7f7a3SJamie Iles  */
12294cd7f7a3SJamie Iles int of_property_read_u64(const struct device_node *np, const char *propname,
12304cd7f7a3SJamie Iles 			 u64 *out_value)
12314cd7f7a3SJamie Iles {
1232daeec1f0STony Prisk 	const __be32 *val = of_find_property_value_of_size(np, propname,
1233daeec1f0STony Prisk 						sizeof(*out_value));
12344cd7f7a3SJamie Iles 
1235daeec1f0STony Prisk 	if (IS_ERR(val))
1236daeec1f0STony Prisk 		return PTR_ERR(val);
1237daeec1f0STony Prisk 
1238daeec1f0STony Prisk 	*out_value = of_read_number(val, 2);
12394cd7f7a3SJamie Iles 	return 0;
12404cd7f7a3SJamie Iles }
12414cd7f7a3SJamie Iles EXPORT_SYMBOL_GPL(of_property_read_u64);
12424cd7f7a3SJamie Iles 
12434cd7f7a3SJamie Iles /**
1244a3b85363SThomas Abraham  * of_property_read_string - Find and read a string from a property
1245a3b85363SThomas Abraham  * @np:		device node from which the property value is to be read.
1246a3b85363SThomas Abraham  * @propname:	name of the property to be searched.
1247a3b85363SThomas Abraham  * @out_string:	pointer to null terminated return string, modified only if
1248a3b85363SThomas Abraham  *		return value is 0.
1249a3b85363SThomas Abraham  *
1250a3b85363SThomas Abraham  * Search for a property in a device tree node and retrieve a null
1251a3b85363SThomas Abraham  * terminated string value (pointer to data, not a copy). Returns 0 on
1252a3b85363SThomas Abraham  * success, -EINVAL if the property does not exist, -ENODATA if property
1253a3b85363SThomas Abraham  * does not have a value, and -EILSEQ if the string is not null-terminated
1254a3b85363SThomas Abraham  * within the length of the property data.
1255a3b85363SThomas Abraham  *
1256a3b85363SThomas Abraham  * The out_string pointer is modified only if a valid string can be decoded.
1257a3b85363SThomas Abraham  */
1258aac285c6SJamie Iles int of_property_read_string(struct device_node *np, const char *propname,
1259f09bc831SShawn Guo 				const char **out_string)
1260a3b85363SThomas Abraham {
1261a3b85363SThomas Abraham 	struct property *prop = of_find_property(np, propname, NULL);
1262a3b85363SThomas Abraham 	if (!prop)
1263a3b85363SThomas Abraham 		return -EINVAL;
1264a3b85363SThomas Abraham 	if (!prop->value)
1265a3b85363SThomas Abraham 		return -ENODATA;
1266a3b85363SThomas Abraham 	if (strnlen(prop->value, prop->length) >= prop->length)
1267a3b85363SThomas Abraham 		return -EILSEQ;
1268a3b85363SThomas Abraham 	*out_string = prop->value;
1269a3b85363SThomas Abraham 	return 0;
1270a3b85363SThomas Abraham }
1271a3b85363SThomas Abraham EXPORT_SYMBOL_GPL(of_property_read_string);
1272a3b85363SThomas Abraham 
1273a3b85363SThomas Abraham /**
12744fcd15a0SBenoit Cousson  * of_property_read_string_index - Find and read a string from a multiple
12754fcd15a0SBenoit Cousson  * strings property.
12764fcd15a0SBenoit Cousson  * @np:		device node from which the property value is to be read.
12774fcd15a0SBenoit Cousson  * @propname:	name of the property to be searched.
12784fcd15a0SBenoit Cousson  * @index:	index of the string in the list of strings
12794fcd15a0SBenoit Cousson  * @out_string:	pointer to null terminated return string, modified only if
12804fcd15a0SBenoit Cousson  *		return value is 0.
12814fcd15a0SBenoit Cousson  *
12824fcd15a0SBenoit Cousson  * Search for a property in a device tree node and retrieve a null
12834fcd15a0SBenoit Cousson  * terminated string value (pointer to data, not a copy) in the list of strings
12844fcd15a0SBenoit Cousson  * contained in that property.
12854fcd15a0SBenoit Cousson  * Returns 0 on success, -EINVAL if the property does not exist, -ENODATA if
12864fcd15a0SBenoit Cousson  * property does not have a value, and -EILSEQ if the string is not
12874fcd15a0SBenoit Cousson  * null-terminated within the length of the property data.
12884fcd15a0SBenoit Cousson  *
12894fcd15a0SBenoit Cousson  * The out_string pointer is modified only if a valid string can be decoded.
12904fcd15a0SBenoit Cousson  */
12914fcd15a0SBenoit Cousson int of_property_read_string_index(struct device_node *np, const char *propname,
12924fcd15a0SBenoit Cousson 				  int index, const char **output)
12934fcd15a0SBenoit Cousson {
12944fcd15a0SBenoit Cousson 	struct property *prop = of_find_property(np, propname, NULL);
12954fcd15a0SBenoit Cousson 	int i = 0;
12964fcd15a0SBenoit Cousson 	size_t l = 0, total = 0;
12974fcd15a0SBenoit Cousson 	const char *p;
12984fcd15a0SBenoit Cousson 
12994fcd15a0SBenoit Cousson 	if (!prop)
13004fcd15a0SBenoit Cousson 		return -EINVAL;
13014fcd15a0SBenoit Cousson 	if (!prop->value)
13024fcd15a0SBenoit Cousson 		return -ENODATA;
13034fcd15a0SBenoit Cousson 	if (strnlen(prop->value, prop->length) >= prop->length)
13044fcd15a0SBenoit Cousson 		return -EILSEQ;
13054fcd15a0SBenoit Cousson 
13064fcd15a0SBenoit Cousson 	p = prop->value;
13074fcd15a0SBenoit Cousson 
13084fcd15a0SBenoit Cousson 	for (i = 0; total < prop->length; total += l, p += l) {
13094fcd15a0SBenoit Cousson 		l = strlen(p) + 1;
131088af7f58SBenoit Cousson 		if (i++ == index) {
13114fcd15a0SBenoit Cousson 			*output = p;
13124fcd15a0SBenoit Cousson 			return 0;
13134fcd15a0SBenoit Cousson 		}
13144fcd15a0SBenoit Cousson 	}
13154fcd15a0SBenoit Cousson 	return -ENODATA;
13164fcd15a0SBenoit Cousson }
13174fcd15a0SBenoit Cousson EXPORT_SYMBOL_GPL(of_property_read_string_index);
13184fcd15a0SBenoit Cousson 
13197aff0fe3SGrant Likely /**
13207aff0fe3SGrant Likely  * of_property_match_string() - Find string in a list and return index
13217aff0fe3SGrant Likely  * @np: pointer to node containing string list property
13227aff0fe3SGrant Likely  * @propname: string list property name
13237aff0fe3SGrant Likely  * @string: pointer to string to search for in string list
13247aff0fe3SGrant Likely  *
13257aff0fe3SGrant Likely  * This function searches a string list property and returns the index
13267aff0fe3SGrant Likely  * of a specific string value.
13277aff0fe3SGrant Likely  */
13287aff0fe3SGrant Likely int of_property_match_string(struct device_node *np, const char *propname,
13297aff0fe3SGrant Likely 			     const char *string)
13307aff0fe3SGrant Likely {
13317aff0fe3SGrant Likely 	struct property *prop = of_find_property(np, propname, NULL);
13327aff0fe3SGrant Likely 	size_t l;
13337aff0fe3SGrant Likely 	int i;
13347aff0fe3SGrant Likely 	const char *p, *end;
13357aff0fe3SGrant Likely 
13367aff0fe3SGrant Likely 	if (!prop)
13377aff0fe3SGrant Likely 		return -EINVAL;
13387aff0fe3SGrant Likely 	if (!prop->value)
13397aff0fe3SGrant Likely 		return -ENODATA;
13407aff0fe3SGrant Likely 
13417aff0fe3SGrant Likely 	p = prop->value;
13427aff0fe3SGrant Likely 	end = p + prop->length;
13437aff0fe3SGrant Likely 
13447aff0fe3SGrant Likely 	for (i = 0; p < end; i++, p += l) {
13457aff0fe3SGrant Likely 		l = strlen(p) + 1;
13467aff0fe3SGrant Likely 		if (p + l > end)
13477aff0fe3SGrant Likely 			return -EILSEQ;
13487aff0fe3SGrant Likely 		pr_debug("comparing %s with %s\n", string, p);
13497aff0fe3SGrant Likely 		if (strcmp(string, p) == 0)
13507aff0fe3SGrant Likely 			return i; /* Found it; return index */
13517aff0fe3SGrant Likely 	}
13527aff0fe3SGrant Likely 	return -ENODATA;
13537aff0fe3SGrant Likely }
13547aff0fe3SGrant Likely EXPORT_SYMBOL_GPL(of_property_match_string);
13554fcd15a0SBenoit Cousson 
13564fcd15a0SBenoit Cousson /**
13574fcd15a0SBenoit Cousson  * of_property_count_strings - Find and return the number of strings from a
13584fcd15a0SBenoit Cousson  * multiple strings property.
13594fcd15a0SBenoit Cousson  * @np:		device node from which the property value is to be read.
13604fcd15a0SBenoit Cousson  * @propname:	name of the property to be searched.
13614fcd15a0SBenoit Cousson  *
13624fcd15a0SBenoit Cousson  * Search for a property in a device tree node and retrieve the number of null
13634fcd15a0SBenoit Cousson  * terminated string contain in it. Returns the number of strings on
13644fcd15a0SBenoit Cousson  * success, -EINVAL if the property does not exist, -ENODATA if property
13654fcd15a0SBenoit Cousson  * does not have a value, and -EILSEQ if the string is not null-terminated
13664fcd15a0SBenoit Cousson  * within the length of the property data.
13674fcd15a0SBenoit Cousson  */
13684fcd15a0SBenoit Cousson int of_property_count_strings(struct device_node *np, const char *propname)
13694fcd15a0SBenoit Cousson {
13704fcd15a0SBenoit Cousson 	struct property *prop = of_find_property(np, propname, NULL);
13714fcd15a0SBenoit Cousson 	int i = 0;
13724fcd15a0SBenoit Cousson 	size_t l = 0, total = 0;
13734fcd15a0SBenoit Cousson 	const char *p;
13744fcd15a0SBenoit Cousson 
13754fcd15a0SBenoit Cousson 	if (!prop)
13764fcd15a0SBenoit Cousson 		return -EINVAL;
13774fcd15a0SBenoit Cousson 	if (!prop->value)
13784fcd15a0SBenoit Cousson 		return -ENODATA;
13794fcd15a0SBenoit Cousson 	if (strnlen(prop->value, prop->length) >= prop->length)
13804fcd15a0SBenoit Cousson 		return -EILSEQ;
13814fcd15a0SBenoit Cousson 
13824fcd15a0SBenoit Cousson 	p = prop->value;
13834fcd15a0SBenoit Cousson 
138488af7f58SBenoit Cousson 	for (i = 0; total < prop->length; total += l, p += l, i++)
13854fcd15a0SBenoit Cousson 		l = strlen(p) + 1;
138688af7f58SBenoit Cousson 
13874fcd15a0SBenoit Cousson 	return i;
13884fcd15a0SBenoit Cousson }
13894fcd15a0SBenoit Cousson EXPORT_SYMBOL_GPL(of_property_count_strings);
13904fcd15a0SBenoit Cousson 
1391624cfca5SGrant Likely void of_print_phandle_args(const char *msg, const struct of_phandle_args *args)
1392624cfca5SGrant Likely {
1393624cfca5SGrant Likely 	int i;
1394624cfca5SGrant Likely 	printk("%s %s", msg, of_node_full_name(args->np));
1395624cfca5SGrant Likely 	for (i = 0; i < args->args_count; i++)
1396624cfca5SGrant Likely 		printk(i ? ",%08x" : ":%08x", args->args[i]);
1397624cfca5SGrant Likely 	printk("\n");
1398624cfca5SGrant Likely }
1399624cfca5SGrant Likely 
1400bd69f73fSGrant Likely static int __of_parse_phandle_with_args(const struct device_node *np,
1401bd69f73fSGrant Likely 					const char *list_name,
1402035fd948SStephen Warren 					const char *cells_name,
1403035fd948SStephen Warren 					int cell_count, int index,
140415c9a0acSGrant Likely 					struct of_phandle_args *out_args)
140564b60e09SAnton Vorontsov {
140615c9a0acSGrant Likely 	const __be32 *list, *list_end;
140723ce04c0SGrant Likely 	int rc = 0, size, cur_index = 0;
140815c9a0acSGrant Likely 	uint32_t count = 0;
140964b60e09SAnton Vorontsov 	struct device_node *node = NULL;
14109a6b2e58SGrant Likely 	phandle phandle;
141164b60e09SAnton Vorontsov 
141215c9a0acSGrant Likely 	/* Retrieve the phandle list property */
141315c9a0acSGrant Likely 	list = of_get_property(np, list_name, &size);
141415c9a0acSGrant Likely 	if (!list)
14151af4c7f1SAlexandre Courbot 		return -ENOENT;
141615c9a0acSGrant Likely 	list_end = list + size / sizeof(*list);
141715c9a0acSGrant Likely 
141815c9a0acSGrant Likely 	/* Loop over the phandles until all the requested entry is found */
141915c9a0acSGrant Likely 	while (list < list_end) {
142023ce04c0SGrant Likely 		rc = -EINVAL;
142115c9a0acSGrant Likely 		count = 0;
142215c9a0acSGrant Likely 
142315c9a0acSGrant Likely 		/*
142415c9a0acSGrant Likely 		 * If phandle is 0, then it is an empty entry with no
142515c9a0acSGrant Likely 		 * arguments.  Skip forward to the next entry.
142615c9a0acSGrant Likely 		 */
14279a6b2e58SGrant Likely 		phandle = be32_to_cpup(list++);
142815c9a0acSGrant Likely 		if (phandle) {
142915c9a0acSGrant Likely 			/*
143015c9a0acSGrant Likely 			 * Find the provider node and parse the #*-cells
143191d9942cSStephen Warren 			 * property to determine the argument length.
143291d9942cSStephen Warren 			 *
143391d9942cSStephen Warren 			 * This is not needed if the cell count is hard-coded
143491d9942cSStephen Warren 			 * (i.e. cells_name not set, but cell_count is set),
143591d9942cSStephen Warren 			 * except when we're going to return the found node
143691d9942cSStephen Warren 			 * below.
143715c9a0acSGrant Likely 			 */
143891d9942cSStephen Warren 			if (cells_name || cur_index == index) {
14399a6b2e58SGrant Likely 				node = of_find_node_by_phandle(phandle);
144064b60e09SAnton Vorontsov 				if (!node) {
144115c9a0acSGrant Likely 					pr_err("%s: could not find phandle\n",
144264b60e09SAnton Vorontsov 						np->full_name);
144323ce04c0SGrant Likely 					goto err;
144415c9a0acSGrant Likely 				}
144591d9942cSStephen Warren 			}
1446035fd948SStephen Warren 
1447035fd948SStephen Warren 			if (cells_name) {
1448035fd948SStephen Warren 				if (of_property_read_u32(node, cells_name,
1449035fd948SStephen Warren 							 &count)) {
145015c9a0acSGrant Likely 					pr_err("%s: could not get %s for %s\n",
145115c9a0acSGrant Likely 						np->full_name, cells_name,
145215c9a0acSGrant Likely 						node->full_name);
145323ce04c0SGrant Likely 					goto err;
145415c9a0acSGrant Likely 				}
1455035fd948SStephen Warren 			} else {
1456035fd948SStephen Warren 				count = cell_count;
1457035fd948SStephen Warren 			}
145815c9a0acSGrant Likely 
145915c9a0acSGrant Likely 			/*
146015c9a0acSGrant Likely 			 * Make sure that the arguments actually fit in the
146115c9a0acSGrant Likely 			 * remaining property data length
146215c9a0acSGrant Likely 			 */
146315c9a0acSGrant Likely 			if (list + count > list_end) {
146415c9a0acSGrant Likely 				pr_err("%s: arguments longer than property\n",
146515c9a0acSGrant Likely 					 np->full_name);
146623ce04c0SGrant Likely 				goto err;
146715c9a0acSGrant Likely 			}
146815c9a0acSGrant Likely 		}
146915c9a0acSGrant Likely 
147015c9a0acSGrant Likely 		/*
147115c9a0acSGrant Likely 		 * All of the error cases above bail out of the loop, so at
147215c9a0acSGrant Likely 		 * this point, the parsing is successful. If the requested
147315c9a0acSGrant Likely 		 * index matches, then fill the out_args structure and return,
147415c9a0acSGrant Likely 		 * or return -ENOENT for an empty entry.
147515c9a0acSGrant Likely 		 */
147623ce04c0SGrant Likely 		rc = -ENOENT;
147715c9a0acSGrant Likely 		if (cur_index == index) {
147815c9a0acSGrant Likely 			if (!phandle)
147923ce04c0SGrant Likely 				goto err;
148015c9a0acSGrant Likely 
148115c9a0acSGrant Likely 			if (out_args) {
148215c9a0acSGrant Likely 				int i;
148315c9a0acSGrant Likely 				if (WARN_ON(count > MAX_PHANDLE_ARGS))
148415c9a0acSGrant Likely 					count = MAX_PHANDLE_ARGS;
148515c9a0acSGrant Likely 				out_args->np = node;
148615c9a0acSGrant Likely 				out_args->args_count = count;
148715c9a0acSGrant Likely 				for (i = 0; i < count; i++)
148815c9a0acSGrant Likely 					out_args->args[i] = be32_to_cpup(list++);
1489b855f16bSTang Yuantian 			} else {
1490b855f16bSTang Yuantian 				of_node_put(node);
149115c9a0acSGrant Likely 			}
149223ce04c0SGrant Likely 
149323ce04c0SGrant Likely 			/* Found it! return success */
149415c9a0acSGrant Likely 			return 0;
149515c9a0acSGrant Likely 		}
149664b60e09SAnton Vorontsov 
149764b60e09SAnton Vorontsov 		of_node_put(node);
149864b60e09SAnton Vorontsov 		node = NULL;
149915c9a0acSGrant Likely 		list += count;
150064b60e09SAnton Vorontsov 		cur_index++;
150164b60e09SAnton Vorontsov 	}
150264b60e09SAnton Vorontsov 
150323ce04c0SGrant Likely 	/*
150423ce04c0SGrant Likely 	 * Unlock node before returning result; will be one of:
150523ce04c0SGrant Likely 	 * -ENOENT : index is for empty phandle
150623ce04c0SGrant Likely 	 * -EINVAL : parsing error on data
1507bd69f73fSGrant Likely 	 * [1..n]  : Number of phandle (count mode; when index = -1)
150823ce04c0SGrant Likely 	 */
1509bd69f73fSGrant Likely 	rc = index < 0 ? cur_index : -ENOENT;
151023ce04c0SGrant Likely  err:
151115c9a0acSGrant Likely 	if (node)
151264b60e09SAnton Vorontsov 		of_node_put(node);
151323ce04c0SGrant Likely 	return rc;
151464b60e09SAnton Vorontsov }
1515bd69f73fSGrant Likely 
1516eded9dd4SStephen Warren /**
15175fba49e3SStephen Warren  * of_parse_phandle - Resolve a phandle property to a device_node pointer
15185fba49e3SStephen Warren  * @np: Pointer to device node holding phandle property
15195fba49e3SStephen Warren  * @phandle_name: Name of property holding a phandle value
15205fba49e3SStephen Warren  * @index: For properties holding a table of phandles, this is the index into
15215fba49e3SStephen Warren  *         the table
15225fba49e3SStephen Warren  *
15235fba49e3SStephen Warren  * Returns the device_node pointer with refcount incremented.  Use
15245fba49e3SStephen Warren  * of_node_put() on it when done.
15255fba49e3SStephen Warren  */
15265fba49e3SStephen Warren struct device_node *of_parse_phandle(const struct device_node *np,
15275fba49e3SStephen Warren 				     const char *phandle_name, int index)
15285fba49e3SStephen Warren {
152991d9942cSStephen Warren 	struct of_phandle_args args;
15305fba49e3SStephen Warren 
153191d9942cSStephen Warren 	if (index < 0)
15325fba49e3SStephen Warren 		return NULL;
15335fba49e3SStephen Warren 
153491d9942cSStephen Warren 	if (__of_parse_phandle_with_args(np, phandle_name, NULL, 0,
153591d9942cSStephen Warren 					 index, &args))
153691d9942cSStephen Warren 		return NULL;
153791d9942cSStephen Warren 
153891d9942cSStephen Warren 	return args.np;
15395fba49e3SStephen Warren }
15405fba49e3SStephen Warren EXPORT_SYMBOL(of_parse_phandle);
15415fba49e3SStephen Warren 
15425fba49e3SStephen Warren /**
1543eded9dd4SStephen Warren  * of_parse_phandle_with_args() - Find a node pointed by phandle in a list
1544eded9dd4SStephen Warren  * @np:		pointer to a device tree node containing a list
1545eded9dd4SStephen Warren  * @list_name:	property name that contains a list
1546eded9dd4SStephen Warren  * @cells_name:	property name that specifies phandles' arguments count
1547eded9dd4SStephen Warren  * @index:	index of a phandle to parse out
1548eded9dd4SStephen Warren  * @out_args:	optional pointer to output arguments structure (will be filled)
1549eded9dd4SStephen Warren  *
1550eded9dd4SStephen Warren  * This function is useful to parse lists of phandles and their arguments.
1551eded9dd4SStephen Warren  * Returns 0 on success and fills out_args, on error returns appropriate
1552eded9dd4SStephen Warren  * errno value.
1553eded9dd4SStephen Warren  *
1554eded9dd4SStephen Warren  * Caller is responsible to call of_node_put() on the returned out_args->node
1555eded9dd4SStephen Warren  * pointer.
1556eded9dd4SStephen Warren  *
1557eded9dd4SStephen Warren  * Example:
1558eded9dd4SStephen Warren  *
1559eded9dd4SStephen Warren  * phandle1: node1 {
1560eded9dd4SStephen Warren  * 	#list-cells = <2>;
1561eded9dd4SStephen Warren  * }
1562eded9dd4SStephen Warren  *
1563eded9dd4SStephen Warren  * phandle2: node2 {
1564eded9dd4SStephen Warren  * 	#list-cells = <1>;
1565eded9dd4SStephen Warren  * }
1566eded9dd4SStephen Warren  *
1567eded9dd4SStephen Warren  * node3 {
1568eded9dd4SStephen Warren  * 	list = <&phandle1 1 2 &phandle2 3>;
1569eded9dd4SStephen Warren  * }
1570eded9dd4SStephen Warren  *
1571eded9dd4SStephen Warren  * To get a device_node of the `node2' node you may call this:
1572eded9dd4SStephen Warren  * of_parse_phandle_with_args(node3, "list", "#list-cells", 1, &args);
1573eded9dd4SStephen Warren  */
1574bd69f73fSGrant Likely int of_parse_phandle_with_args(const struct device_node *np, const char *list_name,
1575bd69f73fSGrant Likely 				const char *cells_name, int index,
1576bd69f73fSGrant Likely 				struct of_phandle_args *out_args)
1577bd69f73fSGrant Likely {
1578bd69f73fSGrant Likely 	if (index < 0)
1579bd69f73fSGrant Likely 		return -EINVAL;
1580035fd948SStephen Warren 	return __of_parse_phandle_with_args(np, list_name, cells_name, 0,
1581035fd948SStephen Warren 					    index, out_args);
1582bd69f73fSGrant Likely }
158315c9a0acSGrant Likely EXPORT_SYMBOL(of_parse_phandle_with_args);
158402af11b0SGrant Likely 
1585bd69f73fSGrant Likely /**
1586035fd948SStephen Warren  * of_parse_phandle_with_fixed_args() - Find a node pointed by phandle in a list
1587035fd948SStephen Warren  * @np:		pointer to a device tree node containing a list
1588035fd948SStephen Warren  * @list_name:	property name that contains a list
1589035fd948SStephen Warren  * @cell_count: number of argument cells following the phandle
1590035fd948SStephen Warren  * @index:	index of a phandle to parse out
1591035fd948SStephen Warren  * @out_args:	optional pointer to output arguments structure (will be filled)
1592035fd948SStephen Warren  *
1593035fd948SStephen Warren  * This function is useful to parse lists of phandles and their arguments.
1594035fd948SStephen Warren  * Returns 0 on success and fills out_args, on error returns appropriate
1595035fd948SStephen Warren  * errno value.
1596035fd948SStephen Warren  *
1597035fd948SStephen Warren  * Caller is responsible to call of_node_put() on the returned out_args->node
1598035fd948SStephen Warren  * pointer.
1599035fd948SStephen Warren  *
1600035fd948SStephen Warren  * Example:
1601035fd948SStephen Warren  *
1602035fd948SStephen Warren  * phandle1: node1 {
1603035fd948SStephen Warren  * }
1604035fd948SStephen Warren  *
1605035fd948SStephen Warren  * phandle2: node2 {
1606035fd948SStephen Warren  * }
1607035fd948SStephen Warren  *
1608035fd948SStephen Warren  * node3 {
1609035fd948SStephen Warren  * 	list = <&phandle1 0 2 &phandle2 2 3>;
1610035fd948SStephen Warren  * }
1611035fd948SStephen Warren  *
1612035fd948SStephen Warren  * To get a device_node of the `node2' node you may call this:
1613035fd948SStephen Warren  * of_parse_phandle_with_fixed_args(node3, "list", 2, 1, &args);
1614035fd948SStephen Warren  */
1615035fd948SStephen Warren int of_parse_phandle_with_fixed_args(const struct device_node *np,
1616035fd948SStephen Warren 				const char *list_name, int cell_count,
1617035fd948SStephen Warren 				int index, struct of_phandle_args *out_args)
1618035fd948SStephen Warren {
1619035fd948SStephen Warren 	if (index < 0)
1620035fd948SStephen Warren 		return -EINVAL;
1621035fd948SStephen Warren 	return __of_parse_phandle_with_args(np, list_name, NULL, cell_count,
1622035fd948SStephen Warren 					   index, out_args);
1623035fd948SStephen Warren }
1624035fd948SStephen Warren EXPORT_SYMBOL(of_parse_phandle_with_fixed_args);
1625035fd948SStephen Warren 
1626035fd948SStephen Warren /**
1627bd69f73fSGrant Likely  * of_count_phandle_with_args() - Find the number of phandles references in a property
1628bd69f73fSGrant Likely  * @np:		pointer to a device tree node containing a list
1629bd69f73fSGrant Likely  * @list_name:	property name that contains a list
1630bd69f73fSGrant Likely  * @cells_name:	property name that specifies phandles' arguments count
1631bd69f73fSGrant Likely  *
1632bd69f73fSGrant Likely  * Returns the number of phandle + argument tuples within a property. It
1633bd69f73fSGrant Likely  * is a typical pattern to encode a list of phandle and variable
1634bd69f73fSGrant Likely  * arguments into a single property. The number of arguments is encoded
1635bd69f73fSGrant Likely  * by a property in the phandle-target node. For example, a gpios
1636bd69f73fSGrant Likely  * property would contain a list of GPIO specifies consisting of a
1637bd69f73fSGrant Likely  * phandle and 1 or more arguments. The number of arguments are
1638bd69f73fSGrant Likely  * determined by the #gpio-cells property in the node pointed to by the
1639bd69f73fSGrant Likely  * phandle.
1640bd69f73fSGrant Likely  */
1641bd69f73fSGrant Likely int of_count_phandle_with_args(const struct device_node *np, const char *list_name,
1642bd69f73fSGrant Likely 				const char *cells_name)
1643bd69f73fSGrant Likely {
1644035fd948SStephen Warren 	return __of_parse_phandle_with_args(np, list_name, cells_name, 0, -1,
1645035fd948SStephen Warren 					    NULL);
1646bd69f73fSGrant Likely }
1647bd69f73fSGrant Likely EXPORT_SYMBOL(of_count_phandle_with_args);
1648bd69f73fSGrant Likely 
164902af11b0SGrant Likely /**
165062664f67SXiubo Li  * __of_add_property - Add a property to a node without lock operations
165162664f67SXiubo Li  */
1652d8c50088SPantelis Antoniou int __of_add_property(struct device_node *np, struct property *prop)
165362664f67SXiubo Li {
165462664f67SXiubo Li 	struct property **next;
165562664f67SXiubo Li 
165662664f67SXiubo Li 	prop->next = NULL;
165762664f67SXiubo Li 	next = &np->properties;
165862664f67SXiubo Li 	while (*next) {
165962664f67SXiubo Li 		if (strcmp(prop->name, (*next)->name) == 0)
166062664f67SXiubo Li 			/* duplicate ! don't insert it */
166162664f67SXiubo Li 			return -EEXIST;
166262664f67SXiubo Li 
166362664f67SXiubo Li 		next = &(*next)->next;
166462664f67SXiubo Li 	}
166562664f67SXiubo Li 	*next = prop;
166662664f67SXiubo Li 
166762664f67SXiubo Li 	return 0;
166862664f67SXiubo Li }
166962664f67SXiubo Li 
167062664f67SXiubo Li /**
167179d1c712SNathan Fontenot  * of_add_property - Add a property to a node
167202af11b0SGrant Likely  */
167379d1c712SNathan Fontenot int of_add_property(struct device_node *np, struct property *prop)
167402af11b0SGrant Likely {
167502af11b0SGrant Likely 	unsigned long flags;
16761cf3d8b3SNathan Fontenot 	int rc;
16771cf3d8b3SNathan Fontenot 
16788a2b22a2SGrant Likely 	mutex_lock(&of_mutex);
167902af11b0SGrant Likely 
1680d6d3c4e6SThomas Gleixner 	raw_spin_lock_irqsave(&devtree_lock, flags);
168162664f67SXiubo Li 	rc = __of_add_property(np, prop);
1682d6d3c4e6SThomas Gleixner 	raw_spin_unlock_irqrestore(&devtree_lock, flags);
168302af11b0SGrant Likely 
16848a2b22a2SGrant Likely 	if (!rc)
168575b57ecfSGrant Likely 		__of_add_property_sysfs(np, prop);
168602af11b0SGrant Likely 
16878a2b22a2SGrant Likely 	mutex_unlock(&of_mutex);
16888a2b22a2SGrant Likely 
1689259092a3SGrant Likely 	if (!rc)
1690259092a3SGrant Likely 		of_property_notify(OF_RECONFIG_ADD_PROPERTY, np, prop, NULL);
1691259092a3SGrant Likely 
169262664f67SXiubo Li 	return rc;
169302af11b0SGrant Likely }
169402af11b0SGrant Likely 
1695d8c50088SPantelis Antoniou int __of_remove_property(struct device_node *np, struct property *prop)
1696d8c50088SPantelis Antoniou {
1697d8c50088SPantelis Antoniou 	struct property **next;
1698d8c50088SPantelis Antoniou 
1699d8c50088SPantelis Antoniou 	for (next = &np->properties; *next; next = &(*next)->next) {
1700d8c50088SPantelis Antoniou 		if (*next == prop)
1701d8c50088SPantelis Antoniou 			break;
1702d8c50088SPantelis Antoniou 	}
1703d8c50088SPantelis Antoniou 	if (*next == NULL)
1704d8c50088SPantelis Antoniou 		return -ENODEV;
1705d8c50088SPantelis Antoniou 
1706d8c50088SPantelis Antoniou 	/* found the node */
1707d8c50088SPantelis Antoniou 	*next = prop->next;
1708d8c50088SPantelis Antoniou 	prop->next = np->deadprops;
1709d8c50088SPantelis Antoniou 	np->deadprops = prop;
1710d8c50088SPantelis Antoniou 
1711d8c50088SPantelis Antoniou 	return 0;
1712d8c50088SPantelis Antoniou }
1713d8c50088SPantelis Antoniou 
17148a2b22a2SGrant Likely void __of_remove_property_sysfs(struct device_node *np, struct property *prop)
17158a2b22a2SGrant Likely {
17168a2b22a2SGrant Likely 	/* at early boot, bail here and defer setup to of_init() */
17178a2b22a2SGrant Likely 	if (of_kset && of_node_is_attached(np))
17188a2b22a2SGrant Likely 		sysfs_remove_bin_file(&np->kobj, &prop->attr);
17198a2b22a2SGrant Likely }
17208a2b22a2SGrant Likely 
172102af11b0SGrant Likely /**
172279d1c712SNathan Fontenot  * of_remove_property - Remove a property from a node.
172302af11b0SGrant Likely  *
172402af11b0SGrant Likely  * Note that we don't actually remove it, since we have given out
172502af11b0SGrant Likely  * who-knows-how-many pointers to the data using get-property.
172602af11b0SGrant Likely  * Instead we just move the property to the "dead properties"
172702af11b0SGrant Likely  * list, so it won't be found any more.
172802af11b0SGrant Likely  */
172979d1c712SNathan Fontenot int of_remove_property(struct device_node *np, struct property *prop)
173002af11b0SGrant Likely {
173102af11b0SGrant Likely 	unsigned long flags;
17321cf3d8b3SNathan Fontenot 	int rc;
17331cf3d8b3SNathan Fontenot 
17348a2b22a2SGrant Likely 	mutex_lock(&of_mutex);
173502af11b0SGrant Likely 
1736d6d3c4e6SThomas Gleixner 	raw_spin_lock_irqsave(&devtree_lock, flags);
1737d8c50088SPantelis Antoniou 	rc = __of_remove_property(np, prop);
1738d6d3c4e6SThomas Gleixner 	raw_spin_unlock_irqrestore(&devtree_lock, flags);
173902af11b0SGrant Likely 
17408a2b22a2SGrant Likely 	if (!rc)
17418a2b22a2SGrant Likely 		__of_remove_property_sysfs(np, prop);
174202af11b0SGrant Likely 
17438a2b22a2SGrant Likely 	mutex_unlock(&of_mutex);
17448a2b22a2SGrant Likely 
1745259092a3SGrant Likely 	if (!rc)
1746259092a3SGrant Likely 		of_property_notify(OF_RECONFIG_REMOVE_PROPERTY, np, prop, NULL);
1747259092a3SGrant Likely 
1748d8c50088SPantelis Antoniou 	return rc;
174902af11b0SGrant Likely }
175002af11b0SGrant Likely 
1751d8c50088SPantelis Antoniou int __of_update_property(struct device_node *np, struct property *newprop,
1752d8c50088SPantelis Antoniou 		struct property **oldpropp)
1753d8c50088SPantelis Antoniou {
1754d8c50088SPantelis Antoniou 	struct property **next, *oldprop;
1755d8c50088SPantelis Antoniou 
1756d8c50088SPantelis Antoniou 	for (next = &np->properties; *next; next = &(*next)->next) {
1757d8c50088SPantelis Antoniou 		if (of_prop_cmp((*next)->name, newprop->name) == 0)
1758d8c50088SPantelis Antoniou 			break;
1759d8c50088SPantelis Antoniou 	}
1760d8c50088SPantelis Antoniou 	*oldpropp = oldprop = *next;
1761d8c50088SPantelis Antoniou 
1762d8c50088SPantelis Antoniou 	if (oldprop) {
1763d8c50088SPantelis Antoniou 		/* replace the node */
1764d8c50088SPantelis Antoniou 		newprop->next = oldprop->next;
1765d8c50088SPantelis Antoniou 		*next = newprop;
1766d8c50088SPantelis Antoniou 		oldprop->next = np->deadprops;
1767d8c50088SPantelis Antoniou 		np->deadprops = oldprop;
1768d8c50088SPantelis Antoniou 	} else {
1769d8c50088SPantelis Antoniou 		/* new node */
1770d8c50088SPantelis Antoniou 		newprop->next = NULL;
1771d8c50088SPantelis Antoniou 		*next = newprop;
1772d8c50088SPantelis Antoniou 	}
1773d8c50088SPantelis Antoniou 
1774d8c50088SPantelis Antoniou 	return 0;
1775d8c50088SPantelis Antoniou }
1776d8c50088SPantelis Antoniou 
17778a2b22a2SGrant Likely void __of_update_property_sysfs(struct device_node *np, struct property *newprop,
17788a2b22a2SGrant Likely 		struct property *oldprop)
17798a2b22a2SGrant Likely {
17808a2b22a2SGrant Likely 	/* At early boot, bail out and defer setup to of_init() */
178102af11b0SGrant Likely 	if (!of_kset)
17828a2b22a2SGrant Likely 		return;
178302af11b0SGrant Likely 
17848a2b22a2SGrant Likely 	if (oldprop)
17858a2b22a2SGrant Likely 		sysfs_remove_bin_file(&np->kobj, &oldprop->attr);
17868a2b22a2SGrant Likely 	__of_add_property_sysfs(np, newprop);
178702af11b0SGrant Likely }
178802af11b0SGrant Likely 
178902af11b0SGrant Likely /*
179079d1c712SNathan Fontenot  * of_update_property - Update a property in a node, if the property does
1791475d0094SDong Aisheng  * not exist, add it.
179202af11b0SGrant Likely  *
179302af11b0SGrant Likely  * Note that we don't actually remove it, since we have given out
179402af11b0SGrant Likely  * who-knows-how-many pointers to the data using get-property.
179502af11b0SGrant Likely  * Instead we just move the property to the "dead properties" list,
179602af11b0SGrant Likely  * and add the new property to the property list
179702af11b0SGrant Likely  */
179879d1c712SNathan Fontenot int of_update_property(struct device_node *np, struct property *newprop)
179902af11b0SGrant Likely {
1800d8c50088SPantelis Antoniou 	struct property *oldprop;
180102af11b0SGrant Likely 	unsigned long flags;
1802947fdaadSXiubo Li 	int rc;
18031cf3d8b3SNathan Fontenot 
1804475d0094SDong Aisheng 	if (!newprop->name)
1805475d0094SDong Aisheng 		return -EINVAL;
1806475d0094SDong Aisheng 
18078a2b22a2SGrant Likely 	mutex_lock(&of_mutex);
1808fcdeb7feSGrant Likely 
1809d6d3c4e6SThomas Gleixner 	raw_spin_lock_irqsave(&devtree_lock, flags);
1810d8c50088SPantelis Antoniou 	rc = __of_update_property(np, newprop, &oldprop);
1811d6d3c4e6SThomas Gleixner 	raw_spin_unlock_irqrestore(&devtree_lock, flags);
1812e81b3295SNathan Fontenot 
18138a2b22a2SGrant Likely 	if (!rc)
18148a2b22a2SGrant Likely 		__of_update_property_sysfs(np, newprop, oldprop);
1815fcdeb7feSGrant Likely 
18168a2b22a2SGrant Likely 	mutex_unlock(&of_mutex);
18171cf3d8b3SNathan Fontenot 
1818259092a3SGrant Likely 	if (!rc)
1819259092a3SGrant Likely 		of_property_notify(OF_RECONFIG_UPDATE_PROPERTY, np, newprop, oldprop);
1820fcdeb7feSGrant Likely 
18211cf3d8b3SNathan Fontenot 	return rc;
1822e81b3295SNathan Fontenot }
1823e81b3295SNathan Fontenot 
1824611cad72SShawn Guo static void of_alias_add(struct alias_prop *ap, struct device_node *np,
1825611cad72SShawn Guo 			 int id, const char *stem, int stem_len)
1826611cad72SShawn Guo {
1827611cad72SShawn Guo 	ap->np = np;
1828611cad72SShawn Guo 	ap->id = id;
1829611cad72SShawn Guo 	strncpy(ap->stem, stem, stem_len);
1830611cad72SShawn Guo 	ap->stem[stem_len] = 0;
1831611cad72SShawn Guo 	list_add_tail(&ap->link, &aliases_lookup);
1832611cad72SShawn Guo 	pr_debug("adding DT alias:%s: stem=%s id=%i node=%s\n",
183374a7f084SGrant Likely 		 ap->alias, ap->stem, ap->id, of_node_full_name(np));
1834611cad72SShawn Guo }
1835611cad72SShawn Guo 
1836611cad72SShawn Guo /**
1837611cad72SShawn Guo  * of_alias_scan - Scan all properties of 'aliases' node
1838611cad72SShawn Guo  *
1839611cad72SShawn Guo  * The function scans all the properties of 'aliases' node and populate
1840611cad72SShawn Guo  * the the global lookup table with the properties.  It returns the
1841611cad72SShawn Guo  * number of alias_prop found, or error code in error case.
1842611cad72SShawn Guo  *
1843611cad72SShawn Guo  * @dt_alloc:	An allocator that provides a virtual address to memory
1844611cad72SShawn Guo  *		for the resulting tree
1845611cad72SShawn Guo  */
1846611cad72SShawn Guo void of_alias_scan(void * (*dt_alloc)(u64 size, u64 align))
1847611cad72SShawn Guo {
1848611cad72SShawn Guo 	struct property *pp;
1849611cad72SShawn Guo 
1850611cad72SShawn Guo 	of_chosen = of_find_node_by_path("/chosen");
1851611cad72SShawn Guo 	if (of_chosen == NULL)
1852611cad72SShawn Guo 		of_chosen = of_find_node_by_path("/chosen@0");
18535c19e952SSascha Hauer 
18545c19e952SSascha Hauer 	if (of_chosen) {
1855a752ee56SGrant Likely 		/* linux,stdout-path and /aliases/stdout are for legacy compatibility */
1856676e1b2fSGrant Likely 		const char *name = of_get_property(of_chosen, "stdout-path", NULL);
1857676e1b2fSGrant Likely 		if (!name)
18585c19e952SSascha Hauer 			name = of_get_property(of_chosen, "linux,stdout-path", NULL);
1859a752ee56SGrant Likely 		if (IS_ENABLED(CONFIG_PPC) && !name)
1860a752ee56SGrant Likely 			name = of_get_property(of_aliases, "stdout", NULL);
18615c19e952SSascha Hauer 		if (name)
18625c19e952SSascha Hauer 			of_stdout = of_find_node_by_path(name);
18635c19e952SSascha Hauer 	}
18645c19e952SSascha Hauer 
1865611cad72SShawn Guo 	of_aliases = of_find_node_by_path("/aliases");
1866611cad72SShawn Guo 	if (!of_aliases)
1867611cad72SShawn Guo 		return;
1868611cad72SShawn Guo 
18698af0da93SDong Aisheng 	for_each_property_of_node(of_aliases, pp) {
1870611cad72SShawn Guo 		const char *start = pp->name;
1871611cad72SShawn Guo 		const char *end = start + strlen(start);
1872611cad72SShawn Guo 		struct device_node *np;
1873611cad72SShawn Guo 		struct alias_prop *ap;
1874611cad72SShawn Guo 		int id, len;
1875611cad72SShawn Guo 
1876611cad72SShawn Guo 		/* Skip those we do not want to proceed */
1877611cad72SShawn Guo 		if (!strcmp(pp->name, "name") ||
1878611cad72SShawn Guo 		    !strcmp(pp->name, "phandle") ||
1879611cad72SShawn Guo 		    !strcmp(pp->name, "linux,phandle"))
1880611cad72SShawn Guo 			continue;
1881611cad72SShawn Guo 
1882611cad72SShawn Guo 		np = of_find_node_by_path(pp->value);
1883611cad72SShawn Guo 		if (!np)
1884611cad72SShawn Guo 			continue;
1885611cad72SShawn Guo 
1886611cad72SShawn Guo 		/* walk the alias backwards to extract the id and work out
1887611cad72SShawn Guo 		 * the 'stem' string */
1888611cad72SShawn Guo 		while (isdigit(*(end-1)) && end > start)
1889611cad72SShawn Guo 			end--;
1890611cad72SShawn Guo 		len = end - start;
1891611cad72SShawn Guo 
1892611cad72SShawn Guo 		if (kstrtoint(end, 10, &id) < 0)
1893611cad72SShawn Guo 			continue;
1894611cad72SShawn Guo 
1895611cad72SShawn Guo 		/* Allocate an alias_prop with enough space for the stem */
1896611cad72SShawn Guo 		ap = dt_alloc(sizeof(*ap) + len + 1, 4);
1897611cad72SShawn Guo 		if (!ap)
1898611cad72SShawn Guo 			continue;
18990640332eSGrant Likely 		memset(ap, 0, sizeof(*ap) + len + 1);
1900611cad72SShawn Guo 		ap->alias = start;
1901611cad72SShawn Guo 		of_alias_add(ap, np, id, start, len);
1902611cad72SShawn Guo 	}
1903611cad72SShawn Guo }
1904611cad72SShawn Guo 
1905611cad72SShawn Guo /**
1906611cad72SShawn Guo  * of_alias_get_id - Get alias id for the given device_node
1907611cad72SShawn Guo  * @np:		Pointer to the given device_node
1908611cad72SShawn Guo  * @stem:	Alias stem of the given device_node
1909611cad72SShawn Guo  *
19105a53a07fSGeert Uytterhoeven  * The function travels the lookup table to get the alias id for the given
19115a53a07fSGeert Uytterhoeven  * device_node and alias stem.  It returns the alias id if found.
1912611cad72SShawn Guo  */
1913611cad72SShawn Guo int of_alias_get_id(struct device_node *np, const char *stem)
1914611cad72SShawn Guo {
1915611cad72SShawn Guo 	struct alias_prop *app;
1916611cad72SShawn Guo 	int id = -ENODEV;
1917611cad72SShawn Guo 
1918c05aba2bSPantelis Antoniou 	mutex_lock(&of_mutex);
1919611cad72SShawn Guo 	list_for_each_entry(app, &aliases_lookup, link) {
1920611cad72SShawn Guo 		if (strcmp(app->stem, stem) != 0)
1921611cad72SShawn Guo 			continue;
1922611cad72SShawn Guo 
1923611cad72SShawn Guo 		if (np == app->np) {
1924611cad72SShawn Guo 			id = app->id;
1925611cad72SShawn Guo 			break;
1926611cad72SShawn Guo 		}
1927611cad72SShawn Guo 	}
1928c05aba2bSPantelis Antoniou 	mutex_unlock(&of_mutex);
1929611cad72SShawn Guo 
1930611cad72SShawn Guo 	return id;
1931611cad72SShawn Guo }
1932611cad72SShawn Guo EXPORT_SYMBOL_GPL(of_alias_get_id);
1933c541adc6SStephen Warren 
1934c541adc6SStephen Warren const __be32 *of_prop_next_u32(struct property *prop, const __be32 *cur,
1935c541adc6SStephen Warren 			       u32 *pu)
1936c541adc6SStephen Warren {
1937c541adc6SStephen Warren 	const void *curv = cur;
1938c541adc6SStephen Warren 
1939c541adc6SStephen Warren 	if (!prop)
1940c541adc6SStephen Warren 		return NULL;
1941c541adc6SStephen Warren 
1942c541adc6SStephen Warren 	if (!cur) {
1943c541adc6SStephen Warren 		curv = prop->value;
1944c541adc6SStephen Warren 		goto out_val;
1945c541adc6SStephen Warren 	}
1946c541adc6SStephen Warren 
1947c541adc6SStephen Warren 	curv += sizeof(*cur);
1948c541adc6SStephen Warren 	if (curv >= prop->value + prop->length)
1949c541adc6SStephen Warren 		return NULL;
1950c541adc6SStephen Warren 
1951c541adc6SStephen Warren out_val:
1952c541adc6SStephen Warren 	*pu = be32_to_cpup(curv);
1953c541adc6SStephen Warren 	return curv;
1954c541adc6SStephen Warren }
1955c541adc6SStephen Warren EXPORT_SYMBOL_GPL(of_prop_next_u32);
1956c541adc6SStephen Warren 
1957c541adc6SStephen Warren const char *of_prop_next_string(struct property *prop, const char *cur)
1958c541adc6SStephen Warren {
1959c541adc6SStephen Warren 	const void *curv = cur;
1960c541adc6SStephen Warren 
1961c541adc6SStephen Warren 	if (!prop)
1962c541adc6SStephen Warren 		return NULL;
1963c541adc6SStephen Warren 
1964c541adc6SStephen Warren 	if (!cur)
1965c541adc6SStephen Warren 		return prop->value;
1966c541adc6SStephen Warren 
1967c541adc6SStephen Warren 	curv += strlen(cur) + 1;
1968c541adc6SStephen Warren 	if (curv >= prop->value + prop->length)
1969c541adc6SStephen Warren 		return NULL;
1970c541adc6SStephen Warren 
1971c541adc6SStephen Warren 	return curv;
1972c541adc6SStephen Warren }
1973c541adc6SStephen Warren EXPORT_SYMBOL_GPL(of_prop_next_string);
19745c19e952SSascha Hauer 
19755c19e952SSascha Hauer /**
19763482f2c5SGrant Likely  * of_console_check() - Test and setup console for DT setup
19773482f2c5SGrant Likely  * @dn - Pointer to device node
19783482f2c5SGrant Likely  * @name - Name to use for preferred console without index. ex. "ttyS"
19793482f2c5SGrant Likely  * @index - Index to use for preferred console.
19805c19e952SSascha Hauer  *
19813482f2c5SGrant Likely  * Check if the given device node matches the stdout-path property in the
19823482f2c5SGrant Likely  * /chosen node. If it does then register it as the preferred console and return
19833482f2c5SGrant Likely  * TRUE. Otherwise return FALSE.
19845c19e952SSascha Hauer  */
19853482f2c5SGrant Likely bool of_console_check(struct device_node *dn, char *name, int index)
19865c19e952SSascha Hauer {
19873482f2c5SGrant Likely 	if (!dn || dn != of_stdout || console_set_on_cmdline)
19885c19e952SSascha Hauer 		return false;
19895f74d8b7SBrian Norris 	return !add_preferred_console(name, index, NULL);
19905c19e952SSascha Hauer }
19913482f2c5SGrant Likely EXPORT_SYMBOL_GPL(of_console_check);
1992a3e31b45SSudeep KarkadaNagesha 
1993a3e31b45SSudeep KarkadaNagesha /**
1994a3e31b45SSudeep KarkadaNagesha  *	of_find_next_cache_node - Find a node's subsidiary cache
1995a3e31b45SSudeep KarkadaNagesha  *	@np:	node of type "cpu" or "cache"
1996a3e31b45SSudeep KarkadaNagesha  *
1997a3e31b45SSudeep KarkadaNagesha  *	Returns a node pointer with refcount incremented, use
1998a3e31b45SSudeep KarkadaNagesha  *	of_node_put() on it when done.  Caller should hold a reference
1999a3e31b45SSudeep KarkadaNagesha  *	to np.
2000a3e31b45SSudeep KarkadaNagesha  */
2001a3e31b45SSudeep KarkadaNagesha struct device_node *of_find_next_cache_node(const struct device_node *np)
2002a3e31b45SSudeep KarkadaNagesha {
2003a3e31b45SSudeep KarkadaNagesha 	struct device_node *child;
2004a3e31b45SSudeep KarkadaNagesha 	const phandle *handle;
2005a3e31b45SSudeep KarkadaNagesha 
2006a3e31b45SSudeep KarkadaNagesha 	handle = of_get_property(np, "l2-cache", NULL);
2007a3e31b45SSudeep KarkadaNagesha 	if (!handle)
2008a3e31b45SSudeep KarkadaNagesha 		handle = of_get_property(np, "next-level-cache", NULL);
2009a3e31b45SSudeep KarkadaNagesha 
2010a3e31b45SSudeep KarkadaNagesha 	if (handle)
2011a3e31b45SSudeep KarkadaNagesha 		return of_find_node_by_phandle(be32_to_cpup(handle));
2012a3e31b45SSudeep KarkadaNagesha 
2013a3e31b45SSudeep KarkadaNagesha 	/* OF on pmac has nodes instead of properties named "l2-cache"
2014a3e31b45SSudeep KarkadaNagesha 	 * beneath CPU nodes.
2015a3e31b45SSudeep KarkadaNagesha 	 */
2016a3e31b45SSudeep KarkadaNagesha 	if (!strcmp(np->type, "cpu"))
2017a3e31b45SSudeep KarkadaNagesha 		for_each_child_of_node(np, child)
2018a3e31b45SSudeep KarkadaNagesha 			if (!strcmp(child->type, "cache"))
2019a3e31b45SSudeep KarkadaNagesha 				return child;
2020a3e31b45SSudeep KarkadaNagesha 
2021a3e31b45SSudeep KarkadaNagesha 	return NULL;
2022a3e31b45SSudeep KarkadaNagesha }
2023fd9fdb78SPhilipp Zabel 
2024fd9fdb78SPhilipp Zabel /**
2025f2a575f6SPhilipp Zabel  * of_graph_parse_endpoint() - parse common endpoint node properties
2026f2a575f6SPhilipp Zabel  * @node: pointer to endpoint device_node
2027f2a575f6SPhilipp Zabel  * @endpoint: pointer to the OF endpoint data structure
2028f2a575f6SPhilipp Zabel  *
2029f2a575f6SPhilipp Zabel  * The caller should hold a reference to @node.
2030f2a575f6SPhilipp Zabel  */
2031f2a575f6SPhilipp Zabel int of_graph_parse_endpoint(const struct device_node *node,
2032f2a575f6SPhilipp Zabel 			    struct of_endpoint *endpoint)
2033f2a575f6SPhilipp Zabel {
2034f2a575f6SPhilipp Zabel 	struct device_node *port_node = of_get_parent(node);
2035f2a575f6SPhilipp Zabel 
2036d484700aSPhilipp Zabel 	WARN_ONCE(!port_node, "%s(): endpoint %s has no parent node\n",
2037d484700aSPhilipp Zabel 		  __func__, node->full_name);
2038d484700aSPhilipp Zabel 
2039f2a575f6SPhilipp Zabel 	memset(endpoint, 0, sizeof(*endpoint));
2040f2a575f6SPhilipp Zabel 
2041f2a575f6SPhilipp Zabel 	endpoint->local_node = node;
2042f2a575f6SPhilipp Zabel 	/*
2043f2a575f6SPhilipp Zabel 	 * It doesn't matter whether the two calls below succeed.
2044f2a575f6SPhilipp Zabel 	 * If they don't then the default value 0 is used.
2045f2a575f6SPhilipp Zabel 	 */
2046f2a575f6SPhilipp Zabel 	of_property_read_u32(port_node, "reg", &endpoint->port);
2047f2a575f6SPhilipp Zabel 	of_property_read_u32(node, "reg", &endpoint->id);
2048f2a575f6SPhilipp Zabel 
2049f2a575f6SPhilipp Zabel 	of_node_put(port_node);
2050f2a575f6SPhilipp Zabel 
2051f2a575f6SPhilipp Zabel 	return 0;
2052f2a575f6SPhilipp Zabel }
2053f2a575f6SPhilipp Zabel EXPORT_SYMBOL(of_graph_parse_endpoint);
2054f2a575f6SPhilipp Zabel 
2055f2a575f6SPhilipp Zabel /**
2056fd9fdb78SPhilipp Zabel  * of_graph_get_next_endpoint() - get next endpoint node
2057fd9fdb78SPhilipp Zabel  * @parent: pointer to the parent device node
2058fd9fdb78SPhilipp Zabel  * @prev: previous endpoint node, or NULL to get first
2059fd9fdb78SPhilipp Zabel  *
2060fd9fdb78SPhilipp Zabel  * Return: An 'endpoint' node pointer with refcount incremented. Refcount
2061fd9fdb78SPhilipp Zabel  * of the passed @prev node is not decremented, the caller have to use
2062fd9fdb78SPhilipp Zabel  * of_node_put() on it when done.
2063fd9fdb78SPhilipp Zabel  */
2064fd9fdb78SPhilipp Zabel struct device_node *of_graph_get_next_endpoint(const struct device_node *parent,
2065fd9fdb78SPhilipp Zabel 					struct device_node *prev)
2066fd9fdb78SPhilipp Zabel {
2067fd9fdb78SPhilipp Zabel 	struct device_node *endpoint;
20683c83e61eSLinus Torvalds 	struct device_node *port;
2069fd9fdb78SPhilipp Zabel 
2070fd9fdb78SPhilipp Zabel 	if (!parent)
2071fd9fdb78SPhilipp Zabel 		return NULL;
2072fd9fdb78SPhilipp Zabel 
20733c83e61eSLinus Torvalds 	/*
20743c83e61eSLinus Torvalds 	 * Start by locating the port node. If no previous endpoint is specified
20753c83e61eSLinus Torvalds 	 * search for the first port node, otherwise get the previous endpoint
20763c83e61eSLinus Torvalds 	 * parent port node.
20773c83e61eSLinus Torvalds 	 */
2078fd9fdb78SPhilipp Zabel 	if (!prev) {
2079fd9fdb78SPhilipp Zabel 		struct device_node *node;
20803c83e61eSLinus Torvalds 
2081fd9fdb78SPhilipp Zabel 		node = of_get_child_by_name(parent, "ports");
2082fd9fdb78SPhilipp Zabel 		if (node)
2083fd9fdb78SPhilipp Zabel 			parent = node;
2084fd9fdb78SPhilipp Zabel 
2085fd9fdb78SPhilipp Zabel 		port = of_get_child_by_name(parent, "port");
2086fd9fdb78SPhilipp Zabel 		of_node_put(node);
20874329b93bSPhilipp Zabel 
20883c83e61eSLinus Torvalds 		if (!port) {
20893c83e61eSLinus Torvalds 			pr_err("%s(): no port node found in %s\n",
20903c83e61eSLinus Torvalds 			       __func__, parent->full_name);
20913c83e61eSLinus Torvalds 			return NULL;
20924329b93bSPhilipp Zabel 		}
20933c83e61eSLinus Torvalds 	} else {
2094fd9fdb78SPhilipp Zabel 		port = of_get_parent(prev);
20956ff60d39SPhilipp Zabel 		if (WARN_ONCE(!port, "%s(): endpoint %s has no parent node\n",
20966ff60d39SPhilipp Zabel 			      __func__, prev->full_name))
2097fd9fdb78SPhilipp Zabel 			return NULL;
2098fd9fdb78SPhilipp Zabel 
20993c83e61eSLinus Torvalds 		/*
21003c83e61eSLinus Torvalds 		 * Avoid dropping prev node refcount to 0 when getting the next
21013c83e61eSLinus Torvalds 		 * child below.
21023c83e61eSLinus Torvalds 		 */
2103fd9fdb78SPhilipp Zabel 		of_node_get(prev);
21043c83e61eSLinus Torvalds 	}
21053c83e61eSLinus Torvalds 
21063c83e61eSLinus Torvalds 	while (1) {
21073c83e61eSLinus Torvalds 		/*
21083c83e61eSLinus Torvalds 		 * Now that we have a port node, get the next endpoint by
21093c83e61eSLinus Torvalds 		 * getting the next child. If the previous endpoint is NULL this
21103c83e61eSLinus Torvalds 		 * will return the first child.
21113c83e61eSLinus Torvalds 		 */
2112fd9fdb78SPhilipp Zabel 		endpoint = of_get_next_child(port, prev);
2113fd9fdb78SPhilipp Zabel 		if (endpoint) {
2114fd9fdb78SPhilipp Zabel 			of_node_put(port);
2115fd9fdb78SPhilipp Zabel 			return endpoint;
2116fd9fdb78SPhilipp Zabel 		}
2117fd9fdb78SPhilipp Zabel 
2118fd9fdb78SPhilipp Zabel 		/* No more endpoints under this port, try the next one. */
21193c83e61eSLinus Torvalds 		prev = NULL;
21203c83e61eSLinus Torvalds 
2121fd9fdb78SPhilipp Zabel 		do {
2122fd9fdb78SPhilipp Zabel 			port = of_get_next_child(parent, port);
2123fd9fdb78SPhilipp Zabel 			if (!port)
2124fd9fdb78SPhilipp Zabel 				return NULL;
2125fd9fdb78SPhilipp Zabel 		} while (of_node_cmp(port->name, "port"));
21263c83e61eSLinus Torvalds 	}
2127fd9fdb78SPhilipp Zabel }
2128fd9fdb78SPhilipp Zabel EXPORT_SYMBOL(of_graph_get_next_endpoint);
2129fd9fdb78SPhilipp Zabel 
2130fd9fdb78SPhilipp Zabel /**
2131fd9fdb78SPhilipp Zabel  * of_graph_get_remote_port_parent() - get remote port's parent node
2132fd9fdb78SPhilipp Zabel  * @node: pointer to a local endpoint device_node
2133fd9fdb78SPhilipp Zabel  *
2134fd9fdb78SPhilipp Zabel  * Return: Remote device node associated with remote endpoint node linked
2135fd9fdb78SPhilipp Zabel  *	   to @node. Use of_node_put() on it when done.
2136fd9fdb78SPhilipp Zabel  */
2137fd9fdb78SPhilipp Zabel struct device_node *of_graph_get_remote_port_parent(
2138fd9fdb78SPhilipp Zabel 			       const struct device_node *node)
2139fd9fdb78SPhilipp Zabel {
2140fd9fdb78SPhilipp Zabel 	struct device_node *np;
2141fd9fdb78SPhilipp Zabel 	unsigned int depth;
2142fd9fdb78SPhilipp Zabel 
2143fd9fdb78SPhilipp Zabel 	/* Get remote endpoint node. */
2144fd9fdb78SPhilipp Zabel 	np = of_parse_phandle(node, "remote-endpoint", 0);
2145fd9fdb78SPhilipp Zabel 
2146fd9fdb78SPhilipp Zabel 	/* Walk 3 levels up only if there is 'ports' node. */
2147fd9fdb78SPhilipp Zabel 	for (depth = 3; depth && np; depth--) {
2148fd9fdb78SPhilipp Zabel 		np = of_get_next_parent(np);
2149fd9fdb78SPhilipp Zabel 		if (depth == 2 && of_node_cmp(np->name, "ports"))
2150fd9fdb78SPhilipp Zabel 			break;
2151fd9fdb78SPhilipp Zabel 	}
2152fd9fdb78SPhilipp Zabel 	return np;
2153fd9fdb78SPhilipp Zabel }
2154fd9fdb78SPhilipp Zabel EXPORT_SYMBOL(of_graph_get_remote_port_parent);
2155fd9fdb78SPhilipp Zabel 
2156fd9fdb78SPhilipp Zabel /**
2157fd9fdb78SPhilipp Zabel  * of_graph_get_remote_port() - get remote port node
2158fd9fdb78SPhilipp Zabel  * @node: pointer to a local endpoint device_node
2159fd9fdb78SPhilipp Zabel  *
2160fd9fdb78SPhilipp Zabel  * Return: Remote port node associated with remote endpoint node linked
2161fd9fdb78SPhilipp Zabel  *	   to @node. Use of_node_put() on it when done.
2162fd9fdb78SPhilipp Zabel  */
2163fd9fdb78SPhilipp Zabel struct device_node *of_graph_get_remote_port(const struct device_node *node)
2164fd9fdb78SPhilipp Zabel {
2165fd9fdb78SPhilipp Zabel 	struct device_node *np;
2166fd9fdb78SPhilipp Zabel 
2167fd9fdb78SPhilipp Zabel 	/* Get remote endpoint node. */
2168fd9fdb78SPhilipp Zabel 	np = of_parse_phandle(node, "remote-endpoint", 0);
2169fd9fdb78SPhilipp Zabel 	if (!np)
2170fd9fdb78SPhilipp Zabel 		return NULL;
2171fd9fdb78SPhilipp Zabel 	return of_get_next_parent(np);
2172fd9fdb78SPhilipp Zabel }
2173fd9fdb78SPhilipp Zabel EXPORT_SYMBOL(of_graph_get_remote_port);
2174