xref: /openbmc/linux/drivers/of/base.c (revision 25c7a1de)
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 
355063e25aSGrant Likely struct device_node *of_root;
365063e25aSGrant Likely EXPORT_SYMBOL(of_root);
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 
515063e25aSGrant Likely /* use when traversing tree through the 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 
141ef69d740SGaurav Minocha 	if (!IS_ENABLED(CONFIG_SYSFS))
142ef69d740SGaurav Minocha 		return 0;
143ef69d740SGaurav Minocha 
1448a2b22a2SGrant Likely 	if (!of_kset || !of_node_is_attached(np))
1458a2b22a2SGrant Likely 		return 0;
1468a2b22a2SGrant Likely 
14775b57ecfSGrant Likely 	sysfs_bin_attr_init(&pp->attr);
14875b57ecfSGrant Likely 	pp->attr.attr.name = safe_name(&np->kobj, pp->name);
14975b57ecfSGrant Likely 	pp->attr.attr.mode = secure ? S_IRUSR : S_IRUGO;
15075b57ecfSGrant Likely 	pp->attr.size = secure ? 0 : pp->length;
15175b57ecfSGrant Likely 	pp->attr.read = of_node_property_read;
15275b57ecfSGrant Likely 
15375b57ecfSGrant Likely 	rc = sysfs_create_bin_file(&np->kobj, &pp->attr);
15475b57ecfSGrant Likely 	WARN(rc, "error adding attribute %s to node %s\n", pp->name, np->full_name);
15575b57ecfSGrant Likely 	return rc;
15675b57ecfSGrant Likely }
15775b57ecfSGrant Likely 
1588a2b22a2SGrant Likely int __of_attach_node_sysfs(struct device_node *np)
15975b57ecfSGrant Likely {
16075b57ecfSGrant Likely 	const char *name;
16175b57ecfSGrant Likely 	struct property *pp;
16275b57ecfSGrant Likely 	int rc;
16375b57ecfSGrant Likely 
164ef69d740SGaurav Minocha 	if (!IS_ENABLED(CONFIG_SYSFS))
165ef69d740SGaurav Minocha 		return 0;
166ef69d740SGaurav Minocha 
1678a2b22a2SGrant Likely 	if (!of_kset)
1688a2b22a2SGrant Likely 		return 0;
1698a2b22a2SGrant Likely 
17075b57ecfSGrant Likely 	np->kobj.kset = of_kset;
17175b57ecfSGrant Likely 	if (!np->parent) {
17275b57ecfSGrant Likely 		/* Nodes without parents are new top level trees */
17328d3ee40SKees Cook 		rc = kobject_add(&np->kobj, NULL, "%s",
17428d3ee40SKees Cook 				 safe_name(&of_kset->kobj, "base"));
17575b57ecfSGrant Likely 	} else {
17675b57ecfSGrant Likely 		name = safe_name(&np->parent->kobj, kbasename(np->full_name));
17775b57ecfSGrant Likely 		if (!name || !name[0])
17875b57ecfSGrant Likely 			return -EINVAL;
17975b57ecfSGrant Likely 
18075b57ecfSGrant Likely 		rc = kobject_add(&np->kobj, &np->parent->kobj, "%s", name);
18175b57ecfSGrant Likely 	}
18275b57ecfSGrant Likely 	if (rc)
18375b57ecfSGrant Likely 		return rc;
18475b57ecfSGrant Likely 
18575b57ecfSGrant Likely 	for_each_property_of_node(np, pp)
18675b57ecfSGrant Likely 		__of_add_property_sysfs(np, pp);
18775b57ecfSGrant Likely 
18875b57ecfSGrant Likely 	return 0;
18975b57ecfSGrant Likely }
19075b57ecfSGrant Likely 
19175b57ecfSGrant Likely static int __init of_init(void)
19275b57ecfSGrant Likely {
19375b57ecfSGrant Likely 	struct device_node *np;
19475b57ecfSGrant Likely 
19575b57ecfSGrant Likely 	/* Create the kset, and register existing nodes */
196c05aba2bSPantelis Antoniou 	mutex_lock(&of_mutex);
19775b57ecfSGrant Likely 	of_kset = kset_create_and_add("devicetree", NULL, firmware_kobj);
19875b57ecfSGrant Likely 	if (!of_kset) {
199c05aba2bSPantelis Antoniou 		mutex_unlock(&of_mutex);
20075b57ecfSGrant Likely 		return -ENOMEM;
20175b57ecfSGrant Likely 	}
20275b57ecfSGrant Likely 	for_each_of_allnodes(np)
2038a2b22a2SGrant Likely 		__of_attach_node_sysfs(np);
204c05aba2bSPantelis Antoniou 	mutex_unlock(&of_mutex);
20575b57ecfSGrant Likely 
2068357041aSGrant Likely 	/* Symlink in /proc as required by userspace ABI */
2075063e25aSGrant Likely 	if (of_root)
20875b57ecfSGrant Likely 		proc_symlink("device-tree", NULL, "/sys/firmware/devicetree/base");
20975b57ecfSGrant Likely 
21075b57ecfSGrant Likely 	return 0;
21175b57ecfSGrant Likely }
21275b57ecfSGrant Likely core_initcall(of_init);
21375b57ecfSGrant Likely 
21428d0e36bSThomas Gleixner static struct property *__of_find_property(const struct device_node *np,
21528d0e36bSThomas Gleixner 					   const char *name, int *lenp)
216581b605aSStephen Rothwell {
217581b605aSStephen Rothwell 	struct property *pp;
218581b605aSStephen Rothwell 
21964e4566fSTimur Tabi 	if (!np)
22064e4566fSTimur Tabi 		return NULL;
22164e4566fSTimur Tabi 
222a3a7cab1SSachin Kamat 	for (pp = np->properties; pp; pp = pp->next) {
223581b605aSStephen Rothwell 		if (of_prop_cmp(pp->name, name) == 0) {
224a3a7cab1SSachin Kamat 			if (lenp)
225581b605aSStephen Rothwell 				*lenp = pp->length;
226581b605aSStephen Rothwell 			break;
227581b605aSStephen Rothwell 		}
228581b605aSStephen Rothwell 	}
22928d0e36bSThomas Gleixner 
23028d0e36bSThomas Gleixner 	return pp;
23128d0e36bSThomas Gleixner }
23228d0e36bSThomas Gleixner 
23328d0e36bSThomas Gleixner struct property *of_find_property(const struct device_node *np,
23428d0e36bSThomas Gleixner 				  const char *name,
23528d0e36bSThomas Gleixner 				  int *lenp)
23628d0e36bSThomas Gleixner {
23728d0e36bSThomas Gleixner 	struct property *pp;
238d6d3c4e6SThomas Gleixner 	unsigned long flags;
23928d0e36bSThomas Gleixner 
240d6d3c4e6SThomas Gleixner 	raw_spin_lock_irqsave(&devtree_lock, flags);
24128d0e36bSThomas Gleixner 	pp = __of_find_property(np, name, lenp);
242d6d3c4e6SThomas Gleixner 	raw_spin_unlock_irqrestore(&devtree_lock, flags);
243581b605aSStephen Rothwell 
244581b605aSStephen Rothwell 	return pp;
245581b605aSStephen Rothwell }
246581b605aSStephen Rothwell EXPORT_SYMBOL(of_find_property);
247581b605aSStephen Rothwell 
2485063e25aSGrant Likely struct device_node *__of_find_all_nodes(struct device_node *prev)
2495063e25aSGrant Likely {
2505063e25aSGrant Likely 	struct device_node *np;
2515063e25aSGrant Likely 	if (!prev) {
2525063e25aSGrant Likely 		np = of_root;
2535063e25aSGrant Likely 	} else if (prev->child) {
2545063e25aSGrant Likely 		np = prev->child;
2555063e25aSGrant Likely 	} else {
2565063e25aSGrant Likely 		/* Walk back up looking for a sibling, or the end of the structure */
2575063e25aSGrant Likely 		np = prev;
2585063e25aSGrant Likely 		while (np->parent && !np->sibling)
2595063e25aSGrant Likely 			np = np->parent;
2605063e25aSGrant Likely 		np = np->sibling; /* Might be null at the end of the tree */
2615063e25aSGrant Likely 	}
2625063e25aSGrant Likely 	return np;
2635063e25aSGrant Likely }
2645063e25aSGrant Likely 
265e91edcf5SGrant Likely /**
266e91edcf5SGrant Likely  * of_find_all_nodes - Get next node in global list
267e91edcf5SGrant Likely  * @prev:	Previous node or NULL to start iteration
268e91edcf5SGrant Likely  *		of_node_put() will be called on it
269e91edcf5SGrant Likely  *
270e91edcf5SGrant Likely  * Returns a node pointer with refcount incremented, use
271e91edcf5SGrant Likely  * of_node_put() on it when done.
272e91edcf5SGrant Likely  */
273e91edcf5SGrant Likely struct device_node *of_find_all_nodes(struct device_node *prev)
274e91edcf5SGrant Likely {
275e91edcf5SGrant Likely 	struct device_node *np;
276d25d8694SBenjamin Herrenschmidt 	unsigned long flags;
277e91edcf5SGrant Likely 
278d25d8694SBenjamin Herrenschmidt 	raw_spin_lock_irqsave(&devtree_lock, flags);
2795063e25aSGrant Likely 	np = __of_find_all_nodes(prev);
2805063e25aSGrant Likely 	of_node_get(np);
281e91edcf5SGrant Likely 	of_node_put(prev);
282d25d8694SBenjamin Herrenschmidt 	raw_spin_unlock_irqrestore(&devtree_lock, flags);
283e91edcf5SGrant Likely 	return np;
284e91edcf5SGrant Likely }
285e91edcf5SGrant Likely EXPORT_SYMBOL(of_find_all_nodes);
286e91edcf5SGrant Likely 
28797e873e5SStephen Rothwell /*
28897e873e5SStephen Rothwell  * Find a property with a given name for a given node
28997e873e5SStephen Rothwell  * and return the value.
29097e873e5SStephen Rothwell  */
291a25095d4SGrant Likely const void *__of_get_property(const struct device_node *np,
29228d0e36bSThomas Gleixner 			      const char *name, int *lenp)
29328d0e36bSThomas Gleixner {
29428d0e36bSThomas Gleixner 	struct property *pp = __of_find_property(np, name, lenp);
29528d0e36bSThomas Gleixner 
29628d0e36bSThomas Gleixner 	return pp ? pp->value : NULL;
29728d0e36bSThomas Gleixner }
29828d0e36bSThomas Gleixner 
29928d0e36bSThomas Gleixner /*
30028d0e36bSThomas Gleixner  * Find a property with a given name for a given node
30128d0e36bSThomas Gleixner  * and return the value.
30228d0e36bSThomas Gleixner  */
30397e873e5SStephen Rothwell const void *of_get_property(const struct device_node *np, const char *name,
30497e873e5SStephen Rothwell 			    int *lenp)
30597e873e5SStephen Rothwell {
30697e873e5SStephen Rothwell 	struct property *pp = of_find_property(np, name, lenp);
30797e873e5SStephen Rothwell 
30897e873e5SStephen Rothwell 	return pp ? pp->value : NULL;
30997e873e5SStephen Rothwell }
31097e873e5SStephen Rothwell EXPORT_SYMBOL(of_get_property);
3110081cbc3SStephen Rothwell 
312183912d3SSudeep KarkadaNagesha /*
313183912d3SSudeep KarkadaNagesha  * arch_match_cpu_phys_id - Match the given logical CPU and physical id
314183912d3SSudeep KarkadaNagesha  *
315183912d3SSudeep KarkadaNagesha  * @cpu: logical cpu index of a core/thread
316183912d3SSudeep KarkadaNagesha  * @phys_id: physical identifier of a core/thread
317183912d3SSudeep KarkadaNagesha  *
318183912d3SSudeep KarkadaNagesha  * CPU logical to physical index mapping is architecture specific.
319183912d3SSudeep KarkadaNagesha  * However this __weak function provides a default match of physical
320183912d3SSudeep KarkadaNagesha  * id to logical cpu index. phys_id provided here is usually values read
321183912d3SSudeep KarkadaNagesha  * from the device tree which must match the hardware internal registers.
322183912d3SSudeep KarkadaNagesha  *
323183912d3SSudeep KarkadaNagesha  * Returns true if the physical identifier and the logical cpu index
324183912d3SSudeep KarkadaNagesha  * correspond to the same core/thread, false otherwise.
325183912d3SSudeep KarkadaNagesha  */
326183912d3SSudeep KarkadaNagesha bool __weak arch_match_cpu_phys_id(int cpu, u64 phys_id)
327183912d3SSudeep KarkadaNagesha {
328183912d3SSudeep KarkadaNagesha 	return (u32)phys_id == cpu;
329183912d3SSudeep KarkadaNagesha }
330183912d3SSudeep KarkadaNagesha 
331183912d3SSudeep KarkadaNagesha /**
332183912d3SSudeep KarkadaNagesha  * Checks if the given "prop_name" property holds the physical id of the
333183912d3SSudeep KarkadaNagesha  * core/thread corresponding to the logical cpu 'cpu'. If 'thread' is not
334183912d3SSudeep KarkadaNagesha  * NULL, local thread number within the core is returned in it.
335183912d3SSudeep KarkadaNagesha  */
336183912d3SSudeep KarkadaNagesha static bool __of_find_n_match_cpu_property(struct device_node *cpun,
337183912d3SSudeep KarkadaNagesha 			const char *prop_name, int cpu, unsigned int *thread)
338183912d3SSudeep KarkadaNagesha {
339183912d3SSudeep KarkadaNagesha 	const __be32 *cell;
340183912d3SSudeep KarkadaNagesha 	int ac, prop_len, tid;
341183912d3SSudeep KarkadaNagesha 	u64 hwid;
342183912d3SSudeep KarkadaNagesha 
343183912d3SSudeep KarkadaNagesha 	ac = of_n_addr_cells(cpun);
344183912d3SSudeep KarkadaNagesha 	cell = of_get_property(cpun, prop_name, &prop_len);
345f3cea45aSGrant Likely 	if (!cell || !ac)
346183912d3SSudeep KarkadaNagesha 		return false;
347f3cea45aSGrant Likely 	prop_len /= sizeof(*cell) * ac;
348183912d3SSudeep KarkadaNagesha 	for (tid = 0; tid < prop_len; tid++) {
349183912d3SSudeep KarkadaNagesha 		hwid = of_read_number(cell, ac);
350183912d3SSudeep KarkadaNagesha 		if (arch_match_cpu_phys_id(cpu, hwid)) {
351183912d3SSudeep KarkadaNagesha 			if (thread)
352183912d3SSudeep KarkadaNagesha 				*thread = tid;
353183912d3SSudeep KarkadaNagesha 			return true;
354183912d3SSudeep KarkadaNagesha 		}
355183912d3SSudeep KarkadaNagesha 		cell += ac;
356183912d3SSudeep KarkadaNagesha 	}
357183912d3SSudeep KarkadaNagesha 	return false;
358183912d3SSudeep KarkadaNagesha }
359183912d3SSudeep KarkadaNagesha 
360d1cb9d1aSDavid Miller /*
361d1cb9d1aSDavid Miller  * arch_find_n_match_cpu_physical_id - See if the given device node is
362d1cb9d1aSDavid Miller  * for the cpu corresponding to logical cpu 'cpu'.  Return true if so,
363d1cb9d1aSDavid Miller  * else false.  If 'thread' is non-NULL, the local thread number within the
364d1cb9d1aSDavid Miller  * core is returned in it.
365d1cb9d1aSDavid Miller  */
366d1cb9d1aSDavid Miller bool __weak arch_find_n_match_cpu_physical_id(struct device_node *cpun,
367d1cb9d1aSDavid Miller 					      int cpu, unsigned int *thread)
368d1cb9d1aSDavid Miller {
369d1cb9d1aSDavid Miller 	/* Check for non-standard "ibm,ppc-interrupt-server#s" property
370d1cb9d1aSDavid Miller 	 * for thread ids on PowerPC. If it doesn't exist fallback to
371d1cb9d1aSDavid Miller 	 * standard "reg" property.
372d1cb9d1aSDavid Miller 	 */
373d1cb9d1aSDavid Miller 	if (IS_ENABLED(CONFIG_PPC) &&
374d1cb9d1aSDavid Miller 	    __of_find_n_match_cpu_property(cpun,
375d1cb9d1aSDavid Miller 					   "ibm,ppc-interrupt-server#s",
376d1cb9d1aSDavid Miller 					   cpu, thread))
377d1cb9d1aSDavid Miller 		return true;
378d1cb9d1aSDavid Miller 
379d1cb9d1aSDavid Miller 	if (__of_find_n_match_cpu_property(cpun, "reg", cpu, thread))
380d1cb9d1aSDavid Miller 		return true;
381d1cb9d1aSDavid Miller 
382d1cb9d1aSDavid Miller 	return false;
383d1cb9d1aSDavid Miller }
384d1cb9d1aSDavid Miller 
385183912d3SSudeep KarkadaNagesha /**
386183912d3SSudeep KarkadaNagesha  * of_get_cpu_node - Get device node associated with the given logical CPU
387183912d3SSudeep KarkadaNagesha  *
388183912d3SSudeep KarkadaNagesha  * @cpu: CPU number(logical index) for which device node is required
389183912d3SSudeep KarkadaNagesha  * @thread: if not NULL, local thread number within the physical core is
390183912d3SSudeep KarkadaNagesha  *          returned
391183912d3SSudeep KarkadaNagesha  *
392183912d3SSudeep KarkadaNagesha  * The main purpose of this function is to retrieve the device node for the
393183912d3SSudeep KarkadaNagesha  * given logical CPU index. It should be used to initialize the of_node in
394183912d3SSudeep KarkadaNagesha  * cpu device. Once of_node in cpu device is populated, all the further
395183912d3SSudeep KarkadaNagesha  * references can use that instead.
396183912d3SSudeep KarkadaNagesha  *
397183912d3SSudeep KarkadaNagesha  * CPU logical to physical index mapping is architecture specific and is built
398183912d3SSudeep KarkadaNagesha  * before booting secondary cores. This function uses arch_match_cpu_phys_id
399183912d3SSudeep KarkadaNagesha  * which can be overridden by architecture specific implementation.
400183912d3SSudeep KarkadaNagesha  *
401183912d3SSudeep KarkadaNagesha  * Returns a node pointer for the logical cpu if found, else NULL.
402183912d3SSudeep KarkadaNagesha  */
403183912d3SSudeep KarkadaNagesha struct device_node *of_get_cpu_node(int cpu, unsigned int *thread)
404183912d3SSudeep KarkadaNagesha {
405d1cb9d1aSDavid Miller 	struct device_node *cpun;
406183912d3SSudeep KarkadaNagesha 
407d1cb9d1aSDavid Miller 	for_each_node_by_type(cpun, "cpu") {
408d1cb9d1aSDavid Miller 		if (arch_find_n_match_cpu_physical_id(cpun, cpu, thread))
409183912d3SSudeep KarkadaNagesha 			return cpun;
410183912d3SSudeep KarkadaNagesha 	}
411183912d3SSudeep KarkadaNagesha 	return NULL;
412183912d3SSudeep KarkadaNagesha }
413183912d3SSudeep KarkadaNagesha EXPORT_SYMBOL(of_get_cpu_node);
414183912d3SSudeep KarkadaNagesha 
415215a14cfSKevin Hao /**
416215a14cfSKevin Hao  * __of_device_is_compatible() - Check if the node matches given constraints
417215a14cfSKevin Hao  * @device: pointer to node
418215a14cfSKevin Hao  * @compat: required compatible string, NULL or "" for any match
419215a14cfSKevin Hao  * @type: required device_type value, NULL or "" for any match
420215a14cfSKevin Hao  * @name: required node name, NULL or "" for any match
421215a14cfSKevin Hao  *
422215a14cfSKevin Hao  * Checks if the given @compat, @type and @name strings match the
423215a14cfSKevin Hao  * properties of the given @device. A constraints can be skipped by
424215a14cfSKevin Hao  * passing NULL or an empty string as the constraint.
425215a14cfSKevin Hao  *
426215a14cfSKevin Hao  * Returns 0 for no match, and a positive integer on match. The return
427215a14cfSKevin Hao  * value is a relative score with larger values indicating better
428215a14cfSKevin Hao  * matches. The score is weighted for the most specific compatible value
429215a14cfSKevin Hao  * to get the highest score. Matching type is next, followed by matching
430215a14cfSKevin Hao  * name. Practically speaking, this results in the following priority
431215a14cfSKevin Hao  * order for matches:
432215a14cfSKevin Hao  *
433215a14cfSKevin Hao  * 1. specific compatible && type && name
434215a14cfSKevin Hao  * 2. specific compatible && type
435215a14cfSKevin Hao  * 3. specific compatible && name
436215a14cfSKevin Hao  * 4. specific compatible
437215a14cfSKevin Hao  * 5. general compatible && type && name
438215a14cfSKevin Hao  * 6. general compatible && type
439215a14cfSKevin Hao  * 7. general compatible && name
440215a14cfSKevin Hao  * 8. general compatible
441215a14cfSKevin Hao  * 9. type && name
442215a14cfSKevin Hao  * 10. type
443215a14cfSKevin Hao  * 11. name
4440081cbc3SStephen Rothwell  */
44528d0e36bSThomas Gleixner static int __of_device_is_compatible(const struct device_node *device,
446215a14cfSKevin Hao 				     const char *compat, const char *type, const char *name)
4470081cbc3SStephen Rothwell {
448215a14cfSKevin Hao 	struct property *prop;
4490081cbc3SStephen Rothwell 	const char *cp;
450215a14cfSKevin Hao 	int index = 0, score = 0;
4510081cbc3SStephen Rothwell 
452215a14cfSKevin Hao 	/* Compatible match has highest priority */
453215a14cfSKevin Hao 	if (compat && compat[0]) {
454215a14cfSKevin Hao 		prop = __of_find_property(device, "compatible", NULL);
455215a14cfSKevin Hao 		for (cp = of_prop_next_string(prop, NULL); cp;
456215a14cfSKevin Hao 		     cp = of_prop_next_string(prop, cp), index++) {
457215a14cfSKevin Hao 			if (of_compat_cmp(cp, compat, strlen(compat)) == 0) {
458215a14cfSKevin Hao 				score = INT_MAX/2 - (index << 2);
459215a14cfSKevin Hao 				break;
460215a14cfSKevin Hao 			}
461215a14cfSKevin Hao 		}
462215a14cfSKevin Hao 		if (!score)
4630081cbc3SStephen Rothwell 			return 0;
4640081cbc3SStephen Rothwell 	}
4650081cbc3SStephen Rothwell 
466215a14cfSKevin Hao 	/* Matching type is better than matching name */
467215a14cfSKevin Hao 	if (type && type[0]) {
468215a14cfSKevin Hao 		if (!device->type || of_node_cmp(type, device->type))
4690081cbc3SStephen Rothwell 			return 0;
470215a14cfSKevin Hao 		score += 2;
471215a14cfSKevin Hao 	}
472215a14cfSKevin Hao 
473215a14cfSKevin Hao 	/* Matching name is a bit better than not */
474215a14cfSKevin Hao 	if (name && name[0]) {
475215a14cfSKevin Hao 		if (!device->name || of_node_cmp(name, device->name))
476215a14cfSKevin Hao 			return 0;
477215a14cfSKevin Hao 		score++;
478215a14cfSKevin Hao 	}
479215a14cfSKevin Hao 
480215a14cfSKevin Hao 	return score;
4810081cbc3SStephen Rothwell }
48228d0e36bSThomas Gleixner 
48328d0e36bSThomas Gleixner /** Checks if the given "compat" string matches one of the strings in
48428d0e36bSThomas Gleixner  * the device's "compatible" property
48528d0e36bSThomas Gleixner  */
48628d0e36bSThomas Gleixner int of_device_is_compatible(const struct device_node *device,
48728d0e36bSThomas Gleixner 		const char *compat)
48828d0e36bSThomas Gleixner {
489d6d3c4e6SThomas Gleixner 	unsigned long flags;
49028d0e36bSThomas Gleixner 	int res;
49128d0e36bSThomas Gleixner 
492d6d3c4e6SThomas Gleixner 	raw_spin_lock_irqsave(&devtree_lock, flags);
493215a14cfSKevin Hao 	res = __of_device_is_compatible(device, compat, NULL, NULL);
494d6d3c4e6SThomas Gleixner 	raw_spin_unlock_irqrestore(&devtree_lock, flags);
49528d0e36bSThomas Gleixner 	return res;
49628d0e36bSThomas Gleixner }
4970081cbc3SStephen Rothwell EXPORT_SYMBOL(of_device_is_compatible);
498e679c5f4SStephen Rothwell 
499e679c5f4SStephen Rothwell /**
50071a157e8SGrant Likely  * of_machine_is_compatible - Test root of device tree for a given compatible value
5011f43cfb9SGrant Likely  * @compat: compatible string to look for in root node's compatible property.
5021f43cfb9SGrant Likely  *
50325c7a1deSKevin Cernekee  * Returns a positive integer if the root node has the given value in its
5041f43cfb9SGrant Likely  * compatible property.
5051f43cfb9SGrant Likely  */
50671a157e8SGrant Likely int of_machine_is_compatible(const char *compat)
5071f43cfb9SGrant Likely {
5081f43cfb9SGrant Likely 	struct device_node *root;
5091f43cfb9SGrant Likely 	int rc = 0;
5101f43cfb9SGrant Likely 
5111f43cfb9SGrant Likely 	root = of_find_node_by_path("/");
5121f43cfb9SGrant Likely 	if (root) {
5131f43cfb9SGrant Likely 		rc = of_device_is_compatible(root, compat);
5141f43cfb9SGrant Likely 		of_node_put(root);
5151f43cfb9SGrant Likely 	}
5161f43cfb9SGrant Likely 	return rc;
5171f43cfb9SGrant Likely }
51871a157e8SGrant Likely EXPORT_SYMBOL(of_machine_is_compatible);
5191f43cfb9SGrant Likely 
5201f43cfb9SGrant Likely /**
521c31a0c05SStephen Warren  *  __of_device_is_available - check if a device is available for use
522834d97d4SJosh Boyer  *
523c31a0c05SStephen Warren  *  @device: Node to check for availability, with locks already held
524834d97d4SJosh Boyer  *
525834d97d4SJosh Boyer  *  Returns 1 if the status property is absent or set to "okay" or "ok",
526834d97d4SJosh Boyer  *  0 otherwise
527834d97d4SJosh Boyer  */
528c31a0c05SStephen Warren static int __of_device_is_available(const struct device_node *device)
529834d97d4SJosh Boyer {
530834d97d4SJosh Boyer 	const char *status;
531834d97d4SJosh Boyer 	int statlen;
532834d97d4SJosh Boyer 
53342ccd781SXiubo Li 	if (!device)
53442ccd781SXiubo Li 		return 0;
53542ccd781SXiubo Li 
536c31a0c05SStephen Warren 	status = __of_get_property(device, "status", &statlen);
537834d97d4SJosh Boyer 	if (status == NULL)
538834d97d4SJosh Boyer 		return 1;
539834d97d4SJosh Boyer 
540834d97d4SJosh Boyer 	if (statlen > 0) {
541834d97d4SJosh Boyer 		if (!strcmp(status, "okay") || !strcmp(status, "ok"))
542834d97d4SJosh Boyer 			return 1;
543834d97d4SJosh Boyer 	}
544834d97d4SJosh Boyer 
545834d97d4SJosh Boyer 	return 0;
546834d97d4SJosh Boyer }
547c31a0c05SStephen Warren 
548c31a0c05SStephen Warren /**
549c31a0c05SStephen Warren  *  of_device_is_available - check if a device is available for use
550c31a0c05SStephen Warren  *
551c31a0c05SStephen Warren  *  @device: Node to check for availability
552c31a0c05SStephen Warren  *
553c31a0c05SStephen Warren  *  Returns 1 if the status property is absent or set to "okay" or "ok",
554c31a0c05SStephen Warren  *  0 otherwise
555c31a0c05SStephen Warren  */
556c31a0c05SStephen Warren int of_device_is_available(const struct device_node *device)
557c31a0c05SStephen Warren {
558c31a0c05SStephen Warren 	unsigned long flags;
559c31a0c05SStephen Warren 	int res;
560c31a0c05SStephen Warren 
561c31a0c05SStephen Warren 	raw_spin_lock_irqsave(&devtree_lock, flags);
562c31a0c05SStephen Warren 	res = __of_device_is_available(device);
563c31a0c05SStephen Warren 	raw_spin_unlock_irqrestore(&devtree_lock, flags);
564c31a0c05SStephen Warren 	return res;
565c31a0c05SStephen Warren 
566c31a0c05SStephen Warren }
567834d97d4SJosh Boyer EXPORT_SYMBOL(of_device_is_available);
568834d97d4SJosh Boyer 
569834d97d4SJosh Boyer /**
570e679c5f4SStephen Rothwell  *	of_get_parent - Get a node's parent if any
571e679c5f4SStephen Rothwell  *	@node:	Node to get parent
572e679c5f4SStephen Rothwell  *
573e679c5f4SStephen Rothwell  *	Returns a node pointer with refcount incremented, use
574e679c5f4SStephen Rothwell  *	of_node_put() on it when done.
575e679c5f4SStephen Rothwell  */
576e679c5f4SStephen Rothwell struct device_node *of_get_parent(const struct device_node *node)
577e679c5f4SStephen Rothwell {
578e679c5f4SStephen Rothwell 	struct device_node *np;
579d6d3c4e6SThomas Gleixner 	unsigned long flags;
580e679c5f4SStephen Rothwell 
581e679c5f4SStephen Rothwell 	if (!node)
582e679c5f4SStephen Rothwell 		return NULL;
583e679c5f4SStephen Rothwell 
584d6d3c4e6SThomas Gleixner 	raw_spin_lock_irqsave(&devtree_lock, flags);
585e679c5f4SStephen Rothwell 	np = of_node_get(node->parent);
586d6d3c4e6SThomas Gleixner 	raw_spin_unlock_irqrestore(&devtree_lock, flags);
587e679c5f4SStephen Rothwell 	return np;
588e679c5f4SStephen Rothwell }
589e679c5f4SStephen Rothwell EXPORT_SYMBOL(of_get_parent);
590d1cd355aSStephen Rothwell 
591d1cd355aSStephen Rothwell /**
592f4eb0107SMichael Ellerman  *	of_get_next_parent - Iterate to a node's parent
593f4eb0107SMichael Ellerman  *	@node:	Node to get parent of
594f4eb0107SMichael Ellerman  *
595f4eb0107SMichael Ellerman  *	This is like of_get_parent() except that it drops the
596f4eb0107SMichael Ellerman  *	refcount on the passed node, making it suitable for iterating
597f4eb0107SMichael Ellerman  *	through a node's parents.
598f4eb0107SMichael Ellerman  *
599f4eb0107SMichael Ellerman  *	Returns a node pointer with refcount incremented, use
600f4eb0107SMichael Ellerman  *	of_node_put() on it when done.
601f4eb0107SMichael Ellerman  */
602f4eb0107SMichael Ellerman struct device_node *of_get_next_parent(struct device_node *node)
603f4eb0107SMichael Ellerman {
604f4eb0107SMichael Ellerman 	struct device_node *parent;
605d6d3c4e6SThomas Gleixner 	unsigned long flags;
606f4eb0107SMichael Ellerman 
607f4eb0107SMichael Ellerman 	if (!node)
608f4eb0107SMichael Ellerman 		return NULL;
609f4eb0107SMichael Ellerman 
610d6d3c4e6SThomas Gleixner 	raw_spin_lock_irqsave(&devtree_lock, flags);
611f4eb0107SMichael Ellerman 	parent = of_node_get(node->parent);
612f4eb0107SMichael Ellerman 	of_node_put(node);
613d6d3c4e6SThomas Gleixner 	raw_spin_unlock_irqrestore(&devtree_lock, flags);
614f4eb0107SMichael Ellerman 	return parent;
615f4eb0107SMichael Ellerman }
6166695be68SGuennadi Liakhovetski EXPORT_SYMBOL(of_get_next_parent);
617f4eb0107SMichael Ellerman 
6180d0e02d6SGrant Likely static struct device_node *__of_get_next_child(const struct device_node *node,
6190d0e02d6SGrant Likely 						struct device_node *prev)
6200d0e02d6SGrant Likely {
6210d0e02d6SGrant Likely 	struct device_node *next;
6220d0e02d6SGrant Likely 
62343cb4367SFlorian Fainelli 	if (!node)
62443cb4367SFlorian Fainelli 		return NULL;
62543cb4367SFlorian Fainelli 
6260d0e02d6SGrant Likely 	next = prev ? prev->sibling : node->child;
6270d0e02d6SGrant Likely 	for (; next; next = next->sibling)
6280d0e02d6SGrant Likely 		if (of_node_get(next))
6290d0e02d6SGrant Likely 			break;
6300d0e02d6SGrant Likely 	of_node_put(prev);
6310d0e02d6SGrant Likely 	return next;
6320d0e02d6SGrant Likely }
6330d0e02d6SGrant Likely #define __for_each_child_of_node(parent, child) \
6340d0e02d6SGrant Likely 	for (child = __of_get_next_child(parent, NULL); child != NULL; \
6350d0e02d6SGrant Likely 	     child = __of_get_next_child(parent, child))
6360d0e02d6SGrant Likely 
637f4eb0107SMichael Ellerman /**
638d1cd355aSStephen Rothwell  *	of_get_next_child - Iterate a node childs
639d1cd355aSStephen Rothwell  *	@node:	parent node
640d1cd355aSStephen Rothwell  *	@prev:	previous child of the parent node, or NULL to get first
641d1cd355aSStephen Rothwell  *
642d1cd355aSStephen Rothwell  *	Returns a node pointer with refcount incremented, use
643d1cd355aSStephen Rothwell  *	of_node_put() on it when done.
644d1cd355aSStephen Rothwell  */
645d1cd355aSStephen Rothwell struct device_node *of_get_next_child(const struct device_node *node,
646d1cd355aSStephen Rothwell 	struct device_node *prev)
647d1cd355aSStephen Rothwell {
648d1cd355aSStephen Rothwell 	struct device_node *next;
649d6d3c4e6SThomas Gleixner 	unsigned long flags;
650d1cd355aSStephen Rothwell 
651d6d3c4e6SThomas Gleixner 	raw_spin_lock_irqsave(&devtree_lock, flags);
6520d0e02d6SGrant Likely 	next = __of_get_next_child(node, prev);
653d6d3c4e6SThomas Gleixner 	raw_spin_unlock_irqrestore(&devtree_lock, flags);
654d1cd355aSStephen Rothwell 	return next;
655d1cd355aSStephen Rothwell }
656d1cd355aSStephen Rothwell EXPORT_SYMBOL(of_get_next_child);
6571ef4d424SStephen Rothwell 
6581ef4d424SStephen Rothwell /**
6593296193dSTimur Tabi  *	of_get_next_available_child - Find the next available child node
6603296193dSTimur Tabi  *	@node:	parent node
6613296193dSTimur Tabi  *	@prev:	previous child of the parent node, or NULL to get first
6623296193dSTimur Tabi  *
6633296193dSTimur Tabi  *      This function is like of_get_next_child(), except that it
6643296193dSTimur Tabi  *      automatically skips any disabled nodes (i.e. status = "disabled").
6653296193dSTimur Tabi  */
6663296193dSTimur Tabi struct device_node *of_get_next_available_child(const struct device_node *node,
6673296193dSTimur Tabi 	struct device_node *prev)
6683296193dSTimur Tabi {
6693296193dSTimur Tabi 	struct device_node *next;
670d25d8694SBenjamin Herrenschmidt 	unsigned long flags;
6713296193dSTimur Tabi 
67243cb4367SFlorian Fainelli 	if (!node)
67343cb4367SFlorian Fainelli 		return NULL;
67443cb4367SFlorian Fainelli 
675d25d8694SBenjamin Herrenschmidt 	raw_spin_lock_irqsave(&devtree_lock, flags);
6763296193dSTimur Tabi 	next = prev ? prev->sibling : node->child;
6773296193dSTimur Tabi 	for (; next; next = next->sibling) {
678c31a0c05SStephen Warren 		if (!__of_device_is_available(next))
6793296193dSTimur Tabi 			continue;
6803296193dSTimur Tabi 		if (of_node_get(next))
6813296193dSTimur Tabi 			break;
6823296193dSTimur Tabi 	}
6833296193dSTimur Tabi 	of_node_put(prev);
684d25d8694SBenjamin Herrenschmidt 	raw_spin_unlock_irqrestore(&devtree_lock, flags);
6853296193dSTimur Tabi 	return next;
6863296193dSTimur Tabi }
6873296193dSTimur Tabi EXPORT_SYMBOL(of_get_next_available_child);
6883296193dSTimur Tabi 
6893296193dSTimur Tabi /**
6909c19761aSSrinivas Kandagatla  *	of_get_child_by_name - Find the child node by name for a given parent
6919c19761aSSrinivas Kandagatla  *	@node:	parent node
6929c19761aSSrinivas Kandagatla  *	@name:	child name to look for.
6939c19761aSSrinivas Kandagatla  *
6949c19761aSSrinivas Kandagatla  *      This function looks for child node for given matching name
6959c19761aSSrinivas Kandagatla  *
6969c19761aSSrinivas Kandagatla  *	Returns a node pointer if found, with refcount incremented, use
6979c19761aSSrinivas Kandagatla  *	of_node_put() on it when done.
6989c19761aSSrinivas Kandagatla  *	Returns NULL if node is not found.
6999c19761aSSrinivas Kandagatla  */
7009c19761aSSrinivas Kandagatla struct device_node *of_get_child_by_name(const struct device_node *node,
7019c19761aSSrinivas Kandagatla 				const char *name)
7029c19761aSSrinivas Kandagatla {
7039c19761aSSrinivas Kandagatla 	struct device_node *child;
7049c19761aSSrinivas Kandagatla 
7059c19761aSSrinivas Kandagatla 	for_each_child_of_node(node, child)
7069c19761aSSrinivas Kandagatla 		if (child->name && (of_node_cmp(child->name, name) == 0))
7079c19761aSSrinivas Kandagatla 			break;
7089c19761aSSrinivas Kandagatla 	return child;
7099c19761aSSrinivas Kandagatla }
7109c19761aSSrinivas Kandagatla EXPORT_SYMBOL(of_get_child_by_name);
7119c19761aSSrinivas Kandagatla 
712c22e650eSGrant Likely static struct device_node *__of_find_node_by_path(struct device_node *parent,
713c22e650eSGrant Likely 						const char *path)
714c22e650eSGrant Likely {
715c22e650eSGrant Likely 	struct device_node *child;
716c22e650eSGrant Likely 	int len = strchrnul(path, '/') - path;
717c22e650eSGrant Likely 
718c22e650eSGrant Likely 	if (!len)
719c22e650eSGrant Likely 		return NULL;
720c22e650eSGrant Likely 
721c22e650eSGrant Likely 	__for_each_child_of_node(parent, child) {
722c22e650eSGrant Likely 		const char *name = strrchr(child->full_name, '/');
723c22e650eSGrant Likely 		if (WARN(!name, "malformed device_node %s\n", child->full_name))
724c22e650eSGrant Likely 			continue;
725c22e650eSGrant Likely 		name++;
726c22e650eSGrant Likely 		if (strncmp(path, name, len) == 0 && (strlen(name) == len))
727c22e650eSGrant Likely 			return child;
728c22e650eSGrant Likely 	}
729c22e650eSGrant Likely 	return NULL;
730c22e650eSGrant Likely }
731c22e650eSGrant Likely 
7329c19761aSSrinivas Kandagatla /**
7331ef4d424SStephen Rothwell  *	of_find_node_by_path - Find a node matching a full OF path
734c22e650eSGrant Likely  *	@path: Either the full path to match, or if the path does not
735c22e650eSGrant Likely  *	       start with '/', the name of a property of the /aliases
736c22e650eSGrant Likely  *	       node (an alias).  In the case of an alias, the node
737c22e650eSGrant Likely  *	       matching the alias' value will be returned.
738c22e650eSGrant Likely  *
739c22e650eSGrant Likely  *	Valid paths:
740c22e650eSGrant Likely  *		/foo/bar	Full path
741c22e650eSGrant Likely  *		foo		Valid alias
742c22e650eSGrant Likely  *		foo/bar		Valid alias + relative path
7431ef4d424SStephen Rothwell  *
7441ef4d424SStephen Rothwell  *	Returns a node pointer with refcount incremented, use
7451ef4d424SStephen Rothwell  *	of_node_put() on it when done.
7461ef4d424SStephen Rothwell  */
7471ef4d424SStephen Rothwell struct device_node *of_find_node_by_path(const char *path)
7481ef4d424SStephen Rothwell {
749c22e650eSGrant Likely 	struct device_node *np = NULL;
750c22e650eSGrant Likely 	struct property *pp;
751d6d3c4e6SThomas Gleixner 	unsigned long flags;
7521ef4d424SStephen Rothwell 
753c22e650eSGrant Likely 	if (strcmp(path, "/") == 0)
7545063e25aSGrant Likely 		return of_node_get(of_root);
755c22e650eSGrant Likely 
756c22e650eSGrant Likely 	/* The path could begin with an alias */
757c22e650eSGrant Likely 	if (*path != '/') {
758c22e650eSGrant Likely 		char *p = strchrnul(path, '/');
759c22e650eSGrant Likely 		int len = p - path;
760c22e650eSGrant Likely 
761c22e650eSGrant Likely 		/* of_aliases must not be NULL */
762c22e650eSGrant Likely 		if (!of_aliases)
763c22e650eSGrant Likely 			return NULL;
764c22e650eSGrant Likely 
765c22e650eSGrant Likely 		for_each_property_of_node(of_aliases, pp) {
766c22e650eSGrant Likely 			if (strlen(pp->name) == len && !strncmp(pp->name, path, len)) {
767c22e650eSGrant Likely 				np = of_find_node_by_path(pp->value);
7681ef4d424SStephen Rothwell 				break;
7691ef4d424SStephen Rothwell 			}
770c22e650eSGrant Likely 		}
771c22e650eSGrant Likely 		if (!np)
772c22e650eSGrant Likely 			return NULL;
773c22e650eSGrant Likely 		path = p;
774c22e650eSGrant Likely 	}
775c22e650eSGrant Likely 
776c22e650eSGrant Likely 	/* Step down the tree matching path components */
777c22e650eSGrant Likely 	raw_spin_lock_irqsave(&devtree_lock, flags);
778c22e650eSGrant Likely 	if (!np)
7795063e25aSGrant Likely 		np = of_node_get(of_root);
780c22e650eSGrant Likely 	while (np && *path == '/') {
781c22e650eSGrant Likely 		path++; /* Increment past '/' delimiter */
782c22e650eSGrant Likely 		np = __of_find_node_by_path(np, path);
783c22e650eSGrant Likely 		path = strchrnul(path, '/');
784c22e650eSGrant Likely 	}
785d6d3c4e6SThomas Gleixner 	raw_spin_unlock_irqrestore(&devtree_lock, flags);
7861ef4d424SStephen Rothwell 	return np;
7871ef4d424SStephen Rothwell }
7881ef4d424SStephen Rothwell EXPORT_SYMBOL(of_find_node_by_path);
7891ef4d424SStephen Rothwell 
7901ef4d424SStephen Rothwell /**
7911ef4d424SStephen Rothwell  *	of_find_node_by_name - Find a node by its "name" property
7921ef4d424SStephen Rothwell  *	@from:	The node to start searching from or NULL, the node
7931ef4d424SStephen Rothwell  *		you pass will not be searched, only the next one
7941ef4d424SStephen Rothwell  *		will; typically, you pass what the previous call
7951ef4d424SStephen Rothwell  *		returned. of_node_put() will be called on it
7961ef4d424SStephen Rothwell  *	@name:	The name string to match against
7971ef4d424SStephen Rothwell  *
7981ef4d424SStephen Rothwell  *	Returns a node pointer with refcount incremented, use
7991ef4d424SStephen Rothwell  *	of_node_put() on it when done.
8001ef4d424SStephen Rothwell  */
8011ef4d424SStephen Rothwell struct device_node *of_find_node_by_name(struct device_node *from,
8021ef4d424SStephen Rothwell 	const char *name)
8031ef4d424SStephen Rothwell {
8041ef4d424SStephen Rothwell 	struct device_node *np;
805d6d3c4e6SThomas Gleixner 	unsigned long flags;
8061ef4d424SStephen Rothwell 
807d6d3c4e6SThomas Gleixner 	raw_spin_lock_irqsave(&devtree_lock, flags);
8085063e25aSGrant Likely 	for_each_of_allnodes_from(from, np)
8091ef4d424SStephen Rothwell 		if (np->name && (of_node_cmp(np->name, name) == 0)
8101ef4d424SStephen Rothwell 		    && of_node_get(np))
8111ef4d424SStephen Rothwell 			break;
8121ef4d424SStephen Rothwell 	of_node_put(from);
813d6d3c4e6SThomas Gleixner 	raw_spin_unlock_irqrestore(&devtree_lock, flags);
8141ef4d424SStephen Rothwell 	return np;
8151ef4d424SStephen Rothwell }
8161ef4d424SStephen Rothwell EXPORT_SYMBOL(of_find_node_by_name);
8171ef4d424SStephen Rothwell 
8181ef4d424SStephen Rothwell /**
8191ef4d424SStephen Rothwell  *	of_find_node_by_type - Find a node by its "device_type" property
8201ef4d424SStephen Rothwell  *	@from:	The node to start searching from, or NULL to start searching
8211ef4d424SStephen Rothwell  *		the entire device tree. The node you pass will not be
8221ef4d424SStephen Rothwell  *		searched, only the next one will; typically, you pass
8231ef4d424SStephen Rothwell  *		what the previous call returned. of_node_put() will be
8241ef4d424SStephen Rothwell  *		called on from for you.
8251ef4d424SStephen Rothwell  *	@type:	The type string to match against
8261ef4d424SStephen Rothwell  *
8271ef4d424SStephen Rothwell  *	Returns a node pointer with refcount incremented, use
8281ef4d424SStephen Rothwell  *	of_node_put() on it when done.
8291ef4d424SStephen Rothwell  */
8301ef4d424SStephen Rothwell struct device_node *of_find_node_by_type(struct device_node *from,
8311ef4d424SStephen Rothwell 	const char *type)
8321ef4d424SStephen Rothwell {
8331ef4d424SStephen Rothwell 	struct device_node *np;
834d6d3c4e6SThomas Gleixner 	unsigned long flags;
8351ef4d424SStephen Rothwell 
836d6d3c4e6SThomas Gleixner 	raw_spin_lock_irqsave(&devtree_lock, flags);
8375063e25aSGrant Likely 	for_each_of_allnodes_from(from, np)
8381ef4d424SStephen Rothwell 		if (np->type && (of_node_cmp(np->type, type) == 0)
8391ef4d424SStephen Rothwell 		    && of_node_get(np))
8401ef4d424SStephen Rothwell 			break;
8411ef4d424SStephen Rothwell 	of_node_put(from);
842d6d3c4e6SThomas Gleixner 	raw_spin_unlock_irqrestore(&devtree_lock, flags);
8431ef4d424SStephen Rothwell 	return np;
8441ef4d424SStephen Rothwell }
8451ef4d424SStephen Rothwell EXPORT_SYMBOL(of_find_node_by_type);
8461ef4d424SStephen Rothwell 
8471ef4d424SStephen Rothwell /**
8481ef4d424SStephen Rothwell  *	of_find_compatible_node - Find a node based on type and one of the
8491ef4d424SStephen Rothwell  *                                tokens in its "compatible" property
8501ef4d424SStephen Rothwell  *	@from:		The node to start searching from or NULL, the node
8511ef4d424SStephen Rothwell  *			you pass will not be searched, only the next one
8521ef4d424SStephen Rothwell  *			will; typically, you pass what the previous call
8531ef4d424SStephen Rothwell  *			returned. of_node_put() will be called on it
8541ef4d424SStephen Rothwell  *	@type:		The type string to match "device_type" or NULL to ignore
8551ef4d424SStephen Rothwell  *	@compatible:	The string to match to one of the tokens in the device
8561ef4d424SStephen Rothwell  *			"compatible" list.
8571ef4d424SStephen Rothwell  *
8581ef4d424SStephen Rothwell  *	Returns a node pointer with refcount incremented, use
8591ef4d424SStephen Rothwell  *	of_node_put() on it when done.
8601ef4d424SStephen Rothwell  */
8611ef4d424SStephen Rothwell struct device_node *of_find_compatible_node(struct device_node *from,
8621ef4d424SStephen Rothwell 	const char *type, const char *compatible)
8631ef4d424SStephen Rothwell {
8641ef4d424SStephen Rothwell 	struct device_node *np;
865d6d3c4e6SThomas Gleixner 	unsigned long flags;
8661ef4d424SStephen Rothwell 
867d6d3c4e6SThomas Gleixner 	raw_spin_lock_irqsave(&devtree_lock, flags);
8685063e25aSGrant Likely 	for_each_of_allnodes_from(from, np)
869215a14cfSKevin Hao 		if (__of_device_is_compatible(np, compatible, type, NULL) &&
87028d0e36bSThomas Gleixner 		    of_node_get(np))
8711ef4d424SStephen Rothwell 			break;
8721ef4d424SStephen Rothwell 	of_node_put(from);
873d6d3c4e6SThomas Gleixner 	raw_spin_unlock_irqrestore(&devtree_lock, flags);
8741ef4d424SStephen Rothwell 	return np;
8751ef4d424SStephen Rothwell }
8761ef4d424SStephen Rothwell EXPORT_SYMBOL(of_find_compatible_node);
877283029d1SGrant Likely 
878283029d1SGrant Likely /**
8791e291b14SMichael Ellerman  *	of_find_node_with_property - Find a node which has a property with
8801e291b14SMichael Ellerman  *                                   the given name.
8811e291b14SMichael Ellerman  *	@from:		The node to start searching from or NULL, the node
8821e291b14SMichael Ellerman  *			you pass will not be searched, only the next one
8831e291b14SMichael Ellerman  *			will; typically, you pass what the previous call
8841e291b14SMichael Ellerman  *			returned. of_node_put() will be called on it
8851e291b14SMichael Ellerman  *	@prop_name:	The name of the property to look for.
8861e291b14SMichael Ellerman  *
8871e291b14SMichael Ellerman  *	Returns a node pointer with refcount incremented, use
8881e291b14SMichael Ellerman  *	of_node_put() on it when done.
8891e291b14SMichael Ellerman  */
8901e291b14SMichael Ellerman struct device_node *of_find_node_with_property(struct device_node *from,
8911e291b14SMichael Ellerman 	const char *prop_name)
8921e291b14SMichael Ellerman {
8931e291b14SMichael Ellerman 	struct device_node *np;
8941e291b14SMichael Ellerman 	struct property *pp;
895d6d3c4e6SThomas Gleixner 	unsigned long flags;
8961e291b14SMichael Ellerman 
897d6d3c4e6SThomas Gleixner 	raw_spin_lock_irqsave(&devtree_lock, flags);
8985063e25aSGrant Likely 	for_each_of_allnodes_from(from, np) {
899a3a7cab1SSachin Kamat 		for (pp = np->properties; pp; pp = pp->next) {
9001e291b14SMichael Ellerman 			if (of_prop_cmp(pp->name, prop_name) == 0) {
9011e291b14SMichael Ellerman 				of_node_get(np);
9021e291b14SMichael Ellerman 				goto out;
9031e291b14SMichael Ellerman 			}
9041e291b14SMichael Ellerman 		}
9051e291b14SMichael Ellerman 	}
9061e291b14SMichael Ellerman out:
9071e291b14SMichael Ellerman 	of_node_put(from);
908d6d3c4e6SThomas Gleixner 	raw_spin_unlock_irqrestore(&devtree_lock, flags);
9091e291b14SMichael Ellerman 	return np;
9101e291b14SMichael Ellerman }
9111e291b14SMichael Ellerman EXPORT_SYMBOL(of_find_node_with_property);
9121e291b14SMichael Ellerman 
91328d0e36bSThomas Gleixner static
91428d0e36bSThomas Gleixner const struct of_device_id *__of_match_node(const struct of_device_id *matches,
915283029d1SGrant Likely 					   const struct device_node *node)
916283029d1SGrant Likely {
917215a14cfSKevin Hao 	const struct of_device_id *best_match = NULL;
918215a14cfSKevin Hao 	int score, best_score = 0;
919215a14cfSKevin Hao 
920a52f07ecSGrant Likely 	if (!matches)
921a52f07ecSGrant Likely 		return NULL;
922a52f07ecSGrant Likely 
923215a14cfSKevin Hao 	for (; matches->name[0] || matches->type[0] || matches->compatible[0]; matches++) {
924215a14cfSKevin Hao 		score = __of_device_is_compatible(node, matches->compatible,
925215a14cfSKevin Hao 						  matches->type, matches->name);
926215a14cfSKevin Hao 		if (score > best_score) {
927215a14cfSKevin Hao 			best_match = matches;
928215a14cfSKevin Hao 			best_score = score;
929283029d1SGrant Likely 		}
930215a14cfSKevin Hao 	}
931215a14cfSKevin Hao 
932215a14cfSKevin Hao 	return best_match;
933283029d1SGrant Likely }
93428d0e36bSThomas Gleixner 
93528d0e36bSThomas Gleixner /**
936c50949d3SGeert Uytterhoeven  * of_match_node - Tell if a device_node has a matching of_match structure
93728d0e36bSThomas Gleixner  *	@matches:	array of of device match structures to search in
93828d0e36bSThomas Gleixner  *	@node:		the of device structure to match against
93928d0e36bSThomas Gleixner  *
94071c5498eSKevin Hao  *	Low level utility function used by device matching.
94128d0e36bSThomas Gleixner  */
94228d0e36bSThomas Gleixner const struct of_device_id *of_match_node(const struct of_device_id *matches,
94328d0e36bSThomas Gleixner 					 const struct device_node *node)
94428d0e36bSThomas Gleixner {
94528d0e36bSThomas Gleixner 	const struct of_device_id *match;
946d6d3c4e6SThomas Gleixner 	unsigned long flags;
94728d0e36bSThomas Gleixner 
948d6d3c4e6SThomas Gleixner 	raw_spin_lock_irqsave(&devtree_lock, flags);
94928d0e36bSThomas Gleixner 	match = __of_match_node(matches, node);
950d6d3c4e6SThomas Gleixner 	raw_spin_unlock_irqrestore(&devtree_lock, flags);
95128d0e36bSThomas Gleixner 	return match;
95228d0e36bSThomas Gleixner }
953283029d1SGrant Likely EXPORT_SYMBOL(of_match_node);
954283029d1SGrant Likely 
955283029d1SGrant Likely /**
95650c8af4cSStephen Warren  *	of_find_matching_node_and_match - Find a node based on an of_device_id
95750c8af4cSStephen Warren  *					  match table.
958283029d1SGrant Likely  *	@from:		The node to start searching from or NULL, the node
959283029d1SGrant Likely  *			you pass will not be searched, only the next one
960283029d1SGrant Likely  *			will; typically, you pass what the previous call
961283029d1SGrant Likely  *			returned. of_node_put() will be called on it
962283029d1SGrant Likely  *	@matches:	array of of device match structures to search in
96350c8af4cSStephen Warren  *	@match		Updated to point at the matches entry which matched
964283029d1SGrant Likely  *
965283029d1SGrant Likely  *	Returns a node pointer with refcount incremented, use
966283029d1SGrant Likely  *	of_node_put() on it when done.
967283029d1SGrant Likely  */
96850c8af4cSStephen Warren struct device_node *of_find_matching_node_and_match(struct device_node *from,
96950c8af4cSStephen Warren 					const struct of_device_id *matches,
97050c8af4cSStephen Warren 					const struct of_device_id **match)
971283029d1SGrant Likely {
972283029d1SGrant Likely 	struct device_node *np;
973dc71bcf1SThomas Abraham 	const struct of_device_id *m;
974d6d3c4e6SThomas Gleixner 	unsigned long flags;
975283029d1SGrant Likely 
97650c8af4cSStephen Warren 	if (match)
97750c8af4cSStephen Warren 		*match = NULL;
97850c8af4cSStephen Warren 
979d6d3c4e6SThomas Gleixner 	raw_spin_lock_irqsave(&devtree_lock, flags);
9805063e25aSGrant Likely 	for_each_of_allnodes_from(from, np) {
98128d0e36bSThomas Gleixner 		m = __of_match_node(matches, np);
982dc71bcf1SThomas Abraham 		if (m && of_node_get(np)) {
98350c8af4cSStephen Warren 			if (match)
984dc71bcf1SThomas Abraham 				*match = m;
985283029d1SGrant Likely 			break;
986283029d1SGrant Likely 		}
98750c8af4cSStephen Warren 	}
988283029d1SGrant Likely 	of_node_put(from);
989d6d3c4e6SThomas Gleixner 	raw_spin_unlock_irqrestore(&devtree_lock, flags);
990283029d1SGrant Likely 	return np;
991283029d1SGrant Likely }
99280c2022eSGrant Likely EXPORT_SYMBOL(of_find_matching_node_and_match);
9933f07af49SGrant Likely 
9943f07af49SGrant Likely /**
9953f07af49SGrant Likely  * of_modalias_node - Lookup appropriate modalias for a device node
9963f07af49SGrant Likely  * @node:	pointer to a device tree node
9973f07af49SGrant Likely  * @modalias:	Pointer to buffer that modalias value will be copied into
9983f07af49SGrant Likely  * @len:	Length of modalias value
9993f07af49SGrant Likely  *
10002ffe8c5fSGrant Likely  * Based on the value of the compatible property, this routine will attempt
10012ffe8c5fSGrant Likely  * to choose an appropriate modalias value for a particular device tree node.
10022ffe8c5fSGrant Likely  * It does this by stripping the manufacturer prefix (as delimited by a ',')
10032ffe8c5fSGrant Likely  * from the first entry in the compatible list property.
10043f07af49SGrant Likely  *
10052ffe8c5fSGrant Likely  * This routine returns 0 on success, <0 on failure.
10063f07af49SGrant Likely  */
10073f07af49SGrant Likely int of_modalias_node(struct device_node *node, char *modalias, int len)
10083f07af49SGrant Likely {
10092ffe8c5fSGrant Likely 	const char *compatible, *p;
10102ffe8c5fSGrant Likely 	int cplen;
10113f07af49SGrant Likely 
10123f07af49SGrant Likely 	compatible = of_get_property(node, "compatible", &cplen);
10132ffe8c5fSGrant Likely 	if (!compatible || strlen(compatible) > cplen)
10143f07af49SGrant Likely 		return -ENODEV;
10153f07af49SGrant Likely 	p = strchr(compatible, ',');
10162ffe8c5fSGrant Likely 	strlcpy(modalias, p ? p + 1 : compatible, len);
10173f07af49SGrant Likely 	return 0;
10183f07af49SGrant Likely }
10193f07af49SGrant Likely EXPORT_SYMBOL_GPL(of_modalias_node);
10203f07af49SGrant Likely 
102164b60e09SAnton Vorontsov /**
102289751a7cSJeremy Kerr  * of_find_node_by_phandle - Find a node given a phandle
102389751a7cSJeremy Kerr  * @handle:	phandle of the node to find
102489751a7cSJeremy Kerr  *
102589751a7cSJeremy Kerr  * Returns a node pointer with refcount incremented, use
102689751a7cSJeremy Kerr  * of_node_put() on it when done.
102789751a7cSJeremy Kerr  */
102889751a7cSJeremy Kerr struct device_node *of_find_node_by_phandle(phandle handle)
102989751a7cSJeremy Kerr {
103089751a7cSJeremy Kerr 	struct device_node *np;
1031d25d8694SBenjamin Herrenschmidt 	unsigned long flags;
103289751a7cSJeremy Kerr 
1033fc59b447SGrant Likely 	if (!handle)
1034fc59b447SGrant Likely 		return NULL;
1035fc59b447SGrant Likely 
1036d25d8694SBenjamin Herrenschmidt 	raw_spin_lock_irqsave(&devtree_lock, flags);
10375063e25aSGrant Likely 	for_each_of_allnodes(np)
103889751a7cSJeremy Kerr 		if (np->phandle == handle)
103989751a7cSJeremy Kerr 			break;
104089751a7cSJeremy Kerr 	of_node_get(np);
1041d25d8694SBenjamin Herrenschmidt 	raw_spin_unlock_irqrestore(&devtree_lock, flags);
104289751a7cSJeremy Kerr 	return np;
104389751a7cSJeremy Kerr }
104489751a7cSJeremy Kerr EXPORT_SYMBOL(of_find_node_by_phandle);
104589751a7cSJeremy Kerr 
104689751a7cSJeremy Kerr /**
1047ad54a0cfSHeiko Stuebner  * of_property_count_elems_of_size - Count the number of elements in a property
1048ad54a0cfSHeiko Stuebner  *
1049ad54a0cfSHeiko Stuebner  * @np:		device node from which the property value is to be read.
1050ad54a0cfSHeiko Stuebner  * @propname:	name of the property to be searched.
1051ad54a0cfSHeiko Stuebner  * @elem_size:	size of the individual element
1052ad54a0cfSHeiko Stuebner  *
1053ad54a0cfSHeiko Stuebner  * Search for a property in a device node and count the number of elements of
1054ad54a0cfSHeiko Stuebner  * size elem_size in it. Returns number of elements on sucess, -EINVAL if the
1055ad54a0cfSHeiko Stuebner  * property does not exist or its length does not match a multiple of elem_size
1056ad54a0cfSHeiko Stuebner  * and -ENODATA if the property does not have a value.
1057ad54a0cfSHeiko Stuebner  */
1058ad54a0cfSHeiko Stuebner int of_property_count_elems_of_size(const struct device_node *np,
1059ad54a0cfSHeiko Stuebner 				const char *propname, int elem_size)
1060ad54a0cfSHeiko Stuebner {
1061ad54a0cfSHeiko Stuebner 	struct property *prop = of_find_property(np, propname, NULL);
1062ad54a0cfSHeiko Stuebner 
1063ad54a0cfSHeiko Stuebner 	if (!prop)
1064ad54a0cfSHeiko Stuebner 		return -EINVAL;
1065ad54a0cfSHeiko Stuebner 	if (!prop->value)
1066ad54a0cfSHeiko Stuebner 		return -ENODATA;
1067ad54a0cfSHeiko Stuebner 
1068ad54a0cfSHeiko Stuebner 	if (prop->length % elem_size != 0) {
1069ad54a0cfSHeiko Stuebner 		pr_err("size of %s in node %s is not a multiple of %d\n",
1070ad54a0cfSHeiko Stuebner 		       propname, np->full_name, elem_size);
1071ad54a0cfSHeiko Stuebner 		return -EINVAL;
1072ad54a0cfSHeiko Stuebner 	}
1073ad54a0cfSHeiko Stuebner 
1074ad54a0cfSHeiko Stuebner 	return prop->length / elem_size;
1075ad54a0cfSHeiko Stuebner }
1076ad54a0cfSHeiko Stuebner EXPORT_SYMBOL_GPL(of_property_count_elems_of_size);
1077ad54a0cfSHeiko Stuebner 
1078ad54a0cfSHeiko Stuebner /**
1079daeec1f0STony Prisk  * of_find_property_value_of_size
1080daeec1f0STony Prisk  *
1081daeec1f0STony Prisk  * @np:		device node from which the property value is to be read.
1082daeec1f0STony Prisk  * @propname:	name of the property to be searched.
1083daeec1f0STony Prisk  * @len:	requested length of property value
1084daeec1f0STony Prisk  *
1085daeec1f0STony Prisk  * Search for a property in a device node and valid the requested size.
1086daeec1f0STony Prisk  * Returns the property value on success, -EINVAL if the property does not
1087daeec1f0STony Prisk  *  exist, -ENODATA if property does not have a value, and -EOVERFLOW if the
1088daeec1f0STony Prisk  * property data isn't large enough.
1089daeec1f0STony Prisk  *
1090daeec1f0STony Prisk  */
1091daeec1f0STony Prisk static void *of_find_property_value_of_size(const struct device_node *np,
1092daeec1f0STony Prisk 			const char *propname, u32 len)
1093daeec1f0STony Prisk {
1094daeec1f0STony Prisk 	struct property *prop = of_find_property(np, propname, NULL);
1095daeec1f0STony Prisk 
1096daeec1f0STony Prisk 	if (!prop)
1097daeec1f0STony Prisk 		return ERR_PTR(-EINVAL);
1098daeec1f0STony Prisk 	if (!prop->value)
1099daeec1f0STony Prisk 		return ERR_PTR(-ENODATA);
1100daeec1f0STony Prisk 	if (len > prop->length)
1101daeec1f0STony Prisk 		return ERR_PTR(-EOVERFLOW);
1102daeec1f0STony Prisk 
1103daeec1f0STony Prisk 	return prop->value;
1104daeec1f0STony Prisk }
1105daeec1f0STony Prisk 
1106daeec1f0STony Prisk /**
11073daf3726STony Prisk  * of_property_read_u32_index - Find and read a u32 from a multi-value property.
11083daf3726STony Prisk  *
11093daf3726STony Prisk  * @np:		device node from which the property value is to be read.
11103daf3726STony Prisk  * @propname:	name of the property to be searched.
11113daf3726STony Prisk  * @index:	index of the u32 in the list of values
11123daf3726STony Prisk  * @out_value:	pointer to return value, modified only if no error.
11133daf3726STony Prisk  *
11143daf3726STony Prisk  * Search for a property in a device node and read nth 32-bit value from
11153daf3726STony Prisk  * it. Returns 0 on success, -EINVAL if the property does not exist,
11163daf3726STony Prisk  * -ENODATA if property does not have a value, and -EOVERFLOW if the
11173daf3726STony Prisk  * property data isn't large enough.
11183daf3726STony Prisk  *
11193daf3726STony Prisk  * The out_value is modified only if a valid u32 value can be decoded.
11203daf3726STony Prisk  */
11213daf3726STony Prisk int of_property_read_u32_index(const struct device_node *np,
11223daf3726STony Prisk 				       const char *propname,
11233daf3726STony Prisk 				       u32 index, u32 *out_value)
11243daf3726STony Prisk {
1125daeec1f0STony Prisk 	const u32 *val = of_find_property_value_of_size(np, propname,
1126daeec1f0STony Prisk 					((index + 1) * sizeof(*out_value)));
11273daf3726STony Prisk 
1128daeec1f0STony Prisk 	if (IS_ERR(val))
1129daeec1f0STony Prisk 		return PTR_ERR(val);
11303daf3726STony Prisk 
1131daeec1f0STony Prisk 	*out_value = be32_to_cpup(((__be32 *)val) + index);
11323daf3726STony Prisk 	return 0;
11333daf3726STony Prisk }
11343daf3726STony Prisk EXPORT_SYMBOL_GPL(of_property_read_u32_index);
11353daf3726STony Prisk 
11363daf3726STony Prisk /**
1137be193249SViresh Kumar  * of_property_read_u8_array - Find and read an array of u8 from a property.
1138be193249SViresh Kumar  *
1139be193249SViresh Kumar  * @np:		device node from which the property value is to be read.
1140be193249SViresh Kumar  * @propname:	name of the property to be searched.
1141792efb84SLad, Prabhakar  * @out_values:	pointer to return value, modified only if return value is 0.
1142be193249SViresh Kumar  * @sz:		number of array elements to read
1143be193249SViresh Kumar  *
1144be193249SViresh Kumar  * Search for a property in a device node and read 8-bit value(s) from
1145be193249SViresh Kumar  * it. Returns 0 on success, -EINVAL if the property does not exist,
1146be193249SViresh Kumar  * -ENODATA if property does not have a value, and -EOVERFLOW if the
1147be193249SViresh Kumar  * property data isn't large enough.
1148be193249SViresh Kumar  *
1149be193249SViresh Kumar  * dts entry of array should be like:
1150be193249SViresh Kumar  *	property = /bits/ 8 <0x50 0x60 0x70>;
1151be193249SViresh Kumar  *
1152792efb84SLad, Prabhakar  * The out_values is modified only if a valid u8 value can be decoded.
1153be193249SViresh Kumar  */
1154be193249SViresh Kumar int of_property_read_u8_array(const struct device_node *np,
1155be193249SViresh Kumar 			const char *propname, u8 *out_values, size_t sz)
1156be193249SViresh Kumar {
1157daeec1f0STony Prisk 	const u8 *val = of_find_property_value_of_size(np, propname,
1158daeec1f0STony Prisk 						(sz * sizeof(*out_values)));
1159be193249SViresh Kumar 
1160daeec1f0STony Prisk 	if (IS_ERR(val))
1161daeec1f0STony Prisk 		return PTR_ERR(val);
1162be193249SViresh Kumar 
1163be193249SViresh Kumar 	while (sz--)
1164be193249SViresh Kumar 		*out_values++ = *val++;
1165be193249SViresh Kumar 	return 0;
1166be193249SViresh Kumar }
1167be193249SViresh Kumar EXPORT_SYMBOL_GPL(of_property_read_u8_array);
1168be193249SViresh Kumar 
1169be193249SViresh Kumar /**
1170be193249SViresh Kumar  * of_property_read_u16_array - Find and read an array of u16 from a property.
1171be193249SViresh Kumar  *
1172be193249SViresh Kumar  * @np:		device node from which the property value is to be read.
1173be193249SViresh Kumar  * @propname:	name of the property to be searched.
1174792efb84SLad, Prabhakar  * @out_values:	pointer to return value, modified only if return value is 0.
1175be193249SViresh Kumar  * @sz:		number of array elements to read
1176be193249SViresh Kumar  *
1177be193249SViresh Kumar  * Search for a property in a device node and read 16-bit value(s) from
1178be193249SViresh Kumar  * it. Returns 0 on success, -EINVAL if the property does not exist,
1179be193249SViresh Kumar  * -ENODATA if property does not have a value, and -EOVERFLOW if the
1180be193249SViresh Kumar  * property data isn't large enough.
1181be193249SViresh Kumar  *
1182be193249SViresh Kumar  * dts entry of array should be like:
1183be193249SViresh Kumar  *	property = /bits/ 16 <0x5000 0x6000 0x7000>;
1184be193249SViresh Kumar  *
1185792efb84SLad, Prabhakar  * The out_values is modified only if a valid u16 value can be decoded.
1186be193249SViresh Kumar  */
1187be193249SViresh Kumar int of_property_read_u16_array(const struct device_node *np,
1188be193249SViresh Kumar 			const char *propname, u16 *out_values, size_t sz)
1189be193249SViresh Kumar {
1190daeec1f0STony Prisk 	const __be16 *val = of_find_property_value_of_size(np, propname,
1191daeec1f0STony Prisk 						(sz * sizeof(*out_values)));
1192be193249SViresh Kumar 
1193daeec1f0STony Prisk 	if (IS_ERR(val))
1194daeec1f0STony Prisk 		return PTR_ERR(val);
1195be193249SViresh Kumar 
1196be193249SViresh Kumar 	while (sz--)
1197be193249SViresh Kumar 		*out_values++ = be16_to_cpup(val++);
1198be193249SViresh Kumar 	return 0;
1199be193249SViresh Kumar }
1200be193249SViresh Kumar EXPORT_SYMBOL_GPL(of_property_read_u16_array);
1201be193249SViresh Kumar 
1202be193249SViresh Kumar /**
12030e373639SRob Herring  * of_property_read_u32_array - Find and read an array of 32 bit integers
12040e373639SRob Herring  * from a property.
12050e373639SRob Herring  *
1206a3b85363SThomas Abraham  * @np:		device node from which the property value is to be read.
1207a3b85363SThomas Abraham  * @propname:	name of the property to be searched.
1208792efb84SLad, Prabhakar  * @out_values:	pointer to return value, modified only if return value is 0.
1209be193249SViresh Kumar  * @sz:		number of array elements to read
1210a3b85363SThomas Abraham  *
12110e373639SRob Herring  * Search for a property in a device node and read 32-bit value(s) from
1212a3b85363SThomas Abraham  * it. Returns 0 on success, -EINVAL if the property does not exist,
1213a3b85363SThomas Abraham  * -ENODATA if property does not have a value, and -EOVERFLOW if the
1214a3b85363SThomas Abraham  * property data isn't large enough.
1215a3b85363SThomas Abraham  *
1216792efb84SLad, Prabhakar  * The out_values is modified only if a valid u32 value can be decoded.
1217a3b85363SThomas Abraham  */
1218aac285c6SJamie Iles int of_property_read_u32_array(const struct device_node *np,
1219aac285c6SJamie Iles 			       const char *propname, u32 *out_values,
1220aac285c6SJamie Iles 			       size_t sz)
1221a3b85363SThomas Abraham {
1222daeec1f0STony Prisk 	const __be32 *val = of_find_property_value_of_size(np, propname,
1223daeec1f0STony Prisk 						(sz * sizeof(*out_values)));
1224a3b85363SThomas Abraham 
1225daeec1f0STony Prisk 	if (IS_ERR(val))
1226daeec1f0STony Prisk 		return PTR_ERR(val);
12270e373639SRob Herring 
12280e373639SRob Herring 	while (sz--)
12290e373639SRob Herring 		*out_values++ = be32_to_cpup(val++);
1230a3b85363SThomas Abraham 	return 0;
1231a3b85363SThomas Abraham }
12320e373639SRob Herring EXPORT_SYMBOL_GPL(of_property_read_u32_array);
1233a3b85363SThomas Abraham 
1234a3b85363SThomas Abraham /**
12354cd7f7a3SJamie Iles  * of_property_read_u64 - Find and read a 64 bit integer from a property
12364cd7f7a3SJamie Iles  * @np:		device node from which the property value is to be read.
12374cd7f7a3SJamie Iles  * @propname:	name of the property to be searched.
12384cd7f7a3SJamie Iles  * @out_value:	pointer to return value, modified only if return value is 0.
12394cd7f7a3SJamie Iles  *
12404cd7f7a3SJamie Iles  * Search for a property in a device node and read a 64-bit value from
12414cd7f7a3SJamie Iles  * it. Returns 0 on success, -EINVAL if the property does not exist,
12424cd7f7a3SJamie Iles  * -ENODATA if property does not have a value, and -EOVERFLOW if the
12434cd7f7a3SJamie Iles  * property data isn't large enough.
12444cd7f7a3SJamie Iles  *
12454cd7f7a3SJamie Iles  * The out_value is modified only if a valid u64 value can be decoded.
12464cd7f7a3SJamie Iles  */
12474cd7f7a3SJamie Iles int of_property_read_u64(const struct device_node *np, const char *propname,
12484cd7f7a3SJamie Iles 			 u64 *out_value)
12494cd7f7a3SJamie Iles {
1250daeec1f0STony Prisk 	const __be32 *val = of_find_property_value_of_size(np, propname,
1251daeec1f0STony Prisk 						sizeof(*out_value));
12524cd7f7a3SJamie Iles 
1253daeec1f0STony Prisk 	if (IS_ERR(val))
1254daeec1f0STony Prisk 		return PTR_ERR(val);
1255daeec1f0STony Prisk 
1256daeec1f0STony Prisk 	*out_value = of_read_number(val, 2);
12574cd7f7a3SJamie Iles 	return 0;
12584cd7f7a3SJamie Iles }
12594cd7f7a3SJamie Iles EXPORT_SYMBOL_GPL(of_property_read_u64);
12604cd7f7a3SJamie Iles 
12614cd7f7a3SJamie Iles /**
1262a3b85363SThomas Abraham  * of_property_read_string - Find and read a string from a property
1263a3b85363SThomas Abraham  * @np:		device node from which the property value is to be read.
1264a3b85363SThomas Abraham  * @propname:	name of the property to be searched.
1265a3b85363SThomas Abraham  * @out_string:	pointer to null terminated return string, modified only if
1266a3b85363SThomas Abraham  *		return value is 0.
1267a3b85363SThomas Abraham  *
1268a3b85363SThomas Abraham  * Search for a property in a device tree node and retrieve a null
1269a3b85363SThomas Abraham  * terminated string value (pointer to data, not a copy). Returns 0 on
1270a3b85363SThomas Abraham  * success, -EINVAL if the property does not exist, -ENODATA if property
1271a3b85363SThomas Abraham  * does not have a value, and -EILSEQ if the string is not null-terminated
1272a3b85363SThomas Abraham  * within the length of the property data.
1273a3b85363SThomas Abraham  *
1274a3b85363SThomas Abraham  * The out_string pointer is modified only if a valid string can be decoded.
1275a3b85363SThomas Abraham  */
1276aac285c6SJamie Iles int of_property_read_string(struct device_node *np, const char *propname,
1277f09bc831SShawn Guo 				const char **out_string)
1278a3b85363SThomas Abraham {
1279a3b85363SThomas Abraham 	struct property *prop = of_find_property(np, propname, NULL);
1280a3b85363SThomas Abraham 	if (!prop)
1281a3b85363SThomas Abraham 		return -EINVAL;
1282a3b85363SThomas Abraham 	if (!prop->value)
1283a3b85363SThomas Abraham 		return -ENODATA;
1284a3b85363SThomas Abraham 	if (strnlen(prop->value, prop->length) >= prop->length)
1285a3b85363SThomas Abraham 		return -EILSEQ;
1286a3b85363SThomas Abraham 	*out_string = prop->value;
1287a3b85363SThomas Abraham 	return 0;
1288a3b85363SThomas Abraham }
1289a3b85363SThomas Abraham EXPORT_SYMBOL_GPL(of_property_read_string);
1290a3b85363SThomas Abraham 
1291a3b85363SThomas Abraham /**
12927aff0fe3SGrant Likely  * of_property_match_string() - Find string in a list and return index
12937aff0fe3SGrant Likely  * @np: pointer to node containing string list property
12947aff0fe3SGrant Likely  * @propname: string list property name
12957aff0fe3SGrant Likely  * @string: pointer to string to search for in string list
12967aff0fe3SGrant Likely  *
12977aff0fe3SGrant Likely  * This function searches a string list property and returns the index
12987aff0fe3SGrant Likely  * of a specific string value.
12997aff0fe3SGrant Likely  */
13007aff0fe3SGrant Likely int of_property_match_string(struct device_node *np, const char *propname,
13017aff0fe3SGrant Likely 			     const char *string)
13027aff0fe3SGrant Likely {
13037aff0fe3SGrant Likely 	struct property *prop = of_find_property(np, propname, NULL);
13047aff0fe3SGrant Likely 	size_t l;
13057aff0fe3SGrant Likely 	int i;
13067aff0fe3SGrant Likely 	const char *p, *end;
13077aff0fe3SGrant Likely 
13087aff0fe3SGrant Likely 	if (!prop)
13097aff0fe3SGrant Likely 		return -EINVAL;
13107aff0fe3SGrant Likely 	if (!prop->value)
13117aff0fe3SGrant Likely 		return -ENODATA;
13127aff0fe3SGrant Likely 
13137aff0fe3SGrant Likely 	p = prop->value;
13147aff0fe3SGrant Likely 	end = p + prop->length;
13157aff0fe3SGrant Likely 
13167aff0fe3SGrant Likely 	for (i = 0; p < end; i++, p += l) {
1317a87fa1d8SGrant Likely 		l = strnlen(p, end - p) + 1;
13187aff0fe3SGrant Likely 		if (p + l > end)
13197aff0fe3SGrant Likely 			return -EILSEQ;
13207aff0fe3SGrant Likely 		pr_debug("comparing %s with %s\n", string, p);
13217aff0fe3SGrant Likely 		if (strcmp(string, p) == 0)
13227aff0fe3SGrant Likely 			return i; /* Found it; return index */
13237aff0fe3SGrant Likely 	}
13247aff0fe3SGrant Likely 	return -ENODATA;
13257aff0fe3SGrant Likely }
13267aff0fe3SGrant Likely EXPORT_SYMBOL_GPL(of_property_match_string);
13274fcd15a0SBenoit Cousson 
13284fcd15a0SBenoit Cousson /**
1329a87fa1d8SGrant Likely  * of_property_read_string_util() - Utility helper for parsing string properties
13304fcd15a0SBenoit Cousson  * @np:		device node from which the property value is to be read.
13314fcd15a0SBenoit Cousson  * @propname:	name of the property to be searched.
1332a87fa1d8SGrant Likely  * @out_strs:	output array of string pointers.
1333a87fa1d8SGrant Likely  * @sz:		number of array elements to read.
1334a87fa1d8SGrant Likely  * @skip:	Number of strings to skip over at beginning of list.
13354fcd15a0SBenoit Cousson  *
1336a87fa1d8SGrant Likely  * Don't call this function directly. It is a utility helper for the
1337a87fa1d8SGrant Likely  * of_property_read_string*() family of functions.
13384fcd15a0SBenoit Cousson  */
1339a87fa1d8SGrant Likely int of_property_read_string_helper(struct device_node *np, const char *propname,
1340a87fa1d8SGrant Likely 				   const char **out_strs, size_t sz, int skip)
13414fcd15a0SBenoit Cousson {
13424fcd15a0SBenoit Cousson 	struct property *prop = of_find_property(np, propname, NULL);
1343a87fa1d8SGrant Likely 	int l = 0, i = 0;
1344a87fa1d8SGrant Likely 	const char *p, *end;
13454fcd15a0SBenoit Cousson 
13464fcd15a0SBenoit Cousson 	if (!prop)
13474fcd15a0SBenoit Cousson 		return -EINVAL;
13484fcd15a0SBenoit Cousson 	if (!prop->value)
13494fcd15a0SBenoit Cousson 		return -ENODATA;
13504fcd15a0SBenoit Cousson 	p = prop->value;
1351a87fa1d8SGrant Likely 	end = p + prop->length;
13524fcd15a0SBenoit Cousson 
1353a87fa1d8SGrant Likely 	for (i = 0; p < end && (!out_strs || i < skip + sz); i++, p += l) {
1354a87fa1d8SGrant Likely 		l = strnlen(p, end - p) + 1;
1355a87fa1d8SGrant Likely 		if (p + l > end)
1356a87fa1d8SGrant Likely 			return -EILSEQ;
1357a87fa1d8SGrant Likely 		if (out_strs && i >= skip)
1358a87fa1d8SGrant Likely 			*out_strs++ = p;
13594fcd15a0SBenoit Cousson 	}
1360a87fa1d8SGrant Likely 	i -= skip;
1361a87fa1d8SGrant Likely 	return i <= 0 ? -ENODATA : i;
1362a87fa1d8SGrant Likely }
1363a87fa1d8SGrant Likely EXPORT_SYMBOL_GPL(of_property_read_string_helper);
13644fcd15a0SBenoit Cousson 
1365624cfca5SGrant Likely void of_print_phandle_args(const char *msg, const struct of_phandle_args *args)
1366624cfca5SGrant Likely {
1367624cfca5SGrant Likely 	int i;
1368624cfca5SGrant Likely 	printk("%s %s", msg, of_node_full_name(args->np));
1369624cfca5SGrant Likely 	for (i = 0; i < args->args_count; i++)
1370624cfca5SGrant Likely 		printk(i ? ",%08x" : ":%08x", args->args[i]);
1371624cfca5SGrant Likely 	printk("\n");
1372624cfca5SGrant Likely }
1373624cfca5SGrant Likely 
1374bd69f73fSGrant Likely static int __of_parse_phandle_with_args(const struct device_node *np,
1375bd69f73fSGrant Likely 					const char *list_name,
1376035fd948SStephen Warren 					const char *cells_name,
1377035fd948SStephen Warren 					int cell_count, int index,
137815c9a0acSGrant Likely 					struct of_phandle_args *out_args)
137964b60e09SAnton Vorontsov {
138015c9a0acSGrant Likely 	const __be32 *list, *list_end;
138123ce04c0SGrant Likely 	int rc = 0, size, cur_index = 0;
138215c9a0acSGrant Likely 	uint32_t count = 0;
138364b60e09SAnton Vorontsov 	struct device_node *node = NULL;
13849a6b2e58SGrant Likely 	phandle phandle;
138564b60e09SAnton Vorontsov 
138615c9a0acSGrant Likely 	/* Retrieve the phandle list property */
138715c9a0acSGrant Likely 	list = of_get_property(np, list_name, &size);
138815c9a0acSGrant Likely 	if (!list)
13891af4c7f1SAlexandre Courbot 		return -ENOENT;
139015c9a0acSGrant Likely 	list_end = list + size / sizeof(*list);
139115c9a0acSGrant Likely 
139215c9a0acSGrant Likely 	/* Loop over the phandles until all the requested entry is found */
139315c9a0acSGrant Likely 	while (list < list_end) {
139423ce04c0SGrant Likely 		rc = -EINVAL;
139515c9a0acSGrant Likely 		count = 0;
139615c9a0acSGrant Likely 
139715c9a0acSGrant Likely 		/*
139815c9a0acSGrant Likely 		 * If phandle is 0, then it is an empty entry with no
139915c9a0acSGrant Likely 		 * arguments.  Skip forward to the next entry.
140015c9a0acSGrant Likely 		 */
14019a6b2e58SGrant Likely 		phandle = be32_to_cpup(list++);
140215c9a0acSGrant Likely 		if (phandle) {
140315c9a0acSGrant Likely 			/*
140415c9a0acSGrant Likely 			 * Find the provider node and parse the #*-cells
140591d9942cSStephen Warren 			 * property to determine the argument length.
140691d9942cSStephen Warren 			 *
140791d9942cSStephen Warren 			 * This is not needed if the cell count is hard-coded
140891d9942cSStephen Warren 			 * (i.e. cells_name not set, but cell_count is set),
140991d9942cSStephen Warren 			 * except when we're going to return the found node
141091d9942cSStephen Warren 			 * below.
141115c9a0acSGrant Likely 			 */
141291d9942cSStephen Warren 			if (cells_name || cur_index == index) {
14139a6b2e58SGrant Likely 				node = of_find_node_by_phandle(phandle);
141464b60e09SAnton Vorontsov 				if (!node) {
141515c9a0acSGrant Likely 					pr_err("%s: could not find phandle\n",
141664b60e09SAnton Vorontsov 						np->full_name);
141723ce04c0SGrant Likely 					goto err;
141815c9a0acSGrant Likely 				}
141991d9942cSStephen Warren 			}
1420035fd948SStephen Warren 
1421035fd948SStephen Warren 			if (cells_name) {
1422035fd948SStephen Warren 				if (of_property_read_u32(node, cells_name,
1423035fd948SStephen Warren 							 &count)) {
142415c9a0acSGrant Likely 					pr_err("%s: could not get %s for %s\n",
142515c9a0acSGrant Likely 						np->full_name, cells_name,
142615c9a0acSGrant Likely 						node->full_name);
142723ce04c0SGrant Likely 					goto err;
142815c9a0acSGrant Likely 				}
1429035fd948SStephen Warren 			} else {
1430035fd948SStephen Warren 				count = cell_count;
1431035fd948SStephen Warren 			}
143215c9a0acSGrant Likely 
143315c9a0acSGrant Likely 			/*
143415c9a0acSGrant Likely 			 * Make sure that the arguments actually fit in the
143515c9a0acSGrant Likely 			 * remaining property data length
143615c9a0acSGrant Likely 			 */
143715c9a0acSGrant Likely 			if (list + count > list_end) {
143815c9a0acSGrant Likely 				pr_err("%s: arguments longer than property\n",
143915c9a0acSGrant Likely 					 np->full_name);
144023ce04c0SGrant Likely 				goto err;
144115c9a0acSGrant Likely 			}
144215c9a0acSGrant Likely 		}
144315c9a0acSGrant Likely 
144415c9a0acSGrant Likely 		/*
144515c9a0acSGrant Likely 		 * All of the error cases above bail out of the loop, so at
144615c9a0acSGrant Likely 		 * this point, the parsing is successful. If the requested
144715c9a0acSGrant Likely 		 * index matches, then fill the out_args structure and return,
144815c9a0acSGrant Likely 		 * or return -ENOENT for an empty entry.
144915c9a0acSGrant Likely 		 */
145023ce04c0SGrant Likely 		rc = -ENOENT;
145115c9a0acSGrant Likely 		if (cur_index == index) {
145215c9a0acSGrant Likely 			if (!phandle)
145323ce04c0SGrant Likely 				goto err;
145415c9a0acSGrant Likely 
145515c9a0acSGrant Likely 			if (out_args) {
145615c9a0acSGrant Likely 				int i;
145715c9a0acSGrant Likely 				if (WARN_ON(count > MAX_PHANDLE_ARGS))
145815c9a0acSGrant Likely 					count = MAX_PHANDLE_ARGS;
145915c9a0acSGrant Likely 				out_args->np = node;
146015c9a0acSGrant Likely 				out_args->args_count = count;
146115c9a0acSGrant Likely 				for (i = 0; i < count; i++)
146215c9a0acSGrant Likely 					out_args->args[i] = be32_to_cpup(list++);
1463b855f16bSTang Yuantian 			} else {
1464b855f16bSTang Yuantian 				of_node_put(node);
146515c9a0acSGrant Likely 			}
146623ce04c0SGrant Likely 
146723ce04c0SGrant Likely 			/* Found it! return success */
146815c9a0acSGrant Likely 			return 0;
146915c9a0acSGrant Likely 		}
147064b60e09SAnton Vorontsov 
147164b60e09SAnton Vorontsov 		of_node_put(node);
147264b60e09SAnton Vorontsov 		node = NULL;
147315c9a0acSGrant Likely 		list += count;
147464b60e09SAnton Vorontsov 		cur_index++;
147564b60e09SAnton Vorontsov 	}
147664b60e09SAnton Vorontsov 
147723ce04c0SGrant Likely 	/*
147823ce04c0SGrant Likely 	 * Unlock node before returning result; will be one of:
147923ce04c0SGrant Likely 	 * -ENOENT : index is for empty phandle
148023ce04c0SGrant Likely 	 * -EINVAL : parsing error on data
1481bd69f73fSGrant Likely 	 * [1..n]  : Number of phandle (count mode; when index = -1)
148223ce04c0SGrant Likely 	 */
1483bd69f73fSGrant Likely 	rc = index < 0 ? cur_index : -ENOENT;
148423ce04c0SGrant Likely  err:
148515c9a0acSGrant Likely 	if (node)
148664b60e09SAnton Vorontsov 		of_node_put(node);
148723ce04c0SGrant Likely 	return rc;
148864b60e09SAnton Vorontsov }
1489bd69f73fSGrant Likely 
1490eded9dd4SStephen Warren /**
14915fba49e3SStephen Warren  * of_parse_phandle - Resolve a phandle property to a device_node pointer
14925fba49e3SStephen Warren  * @np: Pointer to device node holding phandle property
14935fba49e3SStephen Warren  * @phandle_name: Name of property holding a phandle value
14945fba49e3SStephen Warren  * @index: For properties holding a table of phandles, this is the index into
14955fba49e3SStephen Warren  *         the table
14965fba49e3SStephen Warren  *
14975fba49e3SStephen Warren  * Returns the device_node pointer with refcount incremented.  Use
14985fba49e3SStephen Warren  * of_node_put() on it when done.
14995fba49e3SStephen Warren  */
15005fba49e3SStephen Warren struct device_node *of_parse_phandle(const struct device_node *np,
15015fba49e3SStephen Warren 				     const char *phandle_name, int index)
15025fba49e3SStephen Warren {
150391d9942cSStephen Warren 	struct of_phandle_args args;
15045fba49e3SStephen Warren 
150591d9942cSStephen Warren 	if (index < 0)
15065fba49e3SStephen Warren 		return NULL;
15075fba49e3SStephen Warren 
150891d9942cSStephen Warren 	if (__of_parse_phandle_with_args(np, phandle_name, NULL, 0,
150991d9942cSStephen Warren 					 index, &args))
151091d9942cSStephen Warren 		return NULL;
151191d9942cSStephen Warren 
151291d9942cSStephen Warren 	return args.np;
15135fba49e3SStephen Warren }
15145fba49e3SStephen Warren EXPORT_SYMBOL(of_parse_phandle);
15155fba49e3SStephen Warren 
15165fba49e3SStephen Warren /**
1517eded9dd4SStephen Warren  * of_parse_phandle_with_args() - Find a node pointed by phandle in a list
1518eded9dd4SStephen Warren  * @np:		pointer to a device tree node containing a list
1519eded9dd4SStephen Warren  * @list_name:	property name that contains a list
1520eded9dd4SStephen Warren  * @cells_name:	property name that specifies phandles' arguments count
1521eded9dd4SStephen Warren  * @index:	index of a phandle to parse out
1522eded9dd4SStephen Warren  * @out_args:	optional pointer to output arguments structure (will be filled)
1523eded9dd4SStephen Warren  *
1524eded9dd4SStephen Warren  * This function is useful to parse lists of phandles and their arguments.
1525eded9dd4SStephen Warren  * Returns 0 on success and fills out_args, on error returns appropriate
1526eded9dd4SStephen Warren  * errno value.
1527eded9dd4SStephen Warren  *
1528d94a75c1SGeert Uytterhoeven  * Caller is responsible to call of_node_put() on the returned out_args->np
1529eded9dd4SStephen Warren  * pointer.
1530eded9dd4SStephen Warren  *
1531eded9dd4SStephen Warren  * Example:
1532eded9dd4SStephen Warren  *
1533eded9dd4SStephen Warren  * phandle1: node1 {
1534eded9dd4SStephen Warren  *	#list-cells = <2>;
1535eded9dd4SStephen Warren  * }
1536eded9dd4SStephen Warren  *
1537eded9dd4SStephen Warren  * phandle2: node2 {
1538eded9dd4SStephen Warren  *	#list-cells = <1>;
1539eded9dd4SStephen Warren  * }
1540eded9dd4SStephen Warren  *
1541eded9dd4SStephen Warren  * node3 {
1542eded9dd4SStephen Warren  *	list = <&phandle1 1 2 &phandle2 3>;
1543eded9dd4SStephen Warren  * }
1544eded9dd4SStephen Warren  *
1545eded9dd4SStephen Warren  * To get a device_node of the `node2' node you may call this:
1546eded9dd4SStephen Warren  * of_parse_phandle_with_args(node3, "list", "#list-cells", 1, &args);
1547eded9dd4SStephen Warren  */
1548bd69f73fSGrant Likely int of_parse_phandle_with_args(const struct device_node *np, const char *list_name,
1549bd69f73fSGrant Likely 				const char *cells_name, int index,
1550bd69f73fSGrant Likely 				struct of_phandle_args *out_args)
1551bd69f73fSGrant Likely {
1552bd69f73fSGrant Likely 	if (index < 0)
1553bd69f73fSGrant Likely 		return -EINVAL;
1554035fd948SStephen Warren 	return __of_parse_phandle_with_args(np, list_name, cells_name, 0,
1555035fd948SStephen Warren 					    index, out_args);
1556bd69f73fSGrant Likely }
155715c9a0acSGrant Likely EXPORT_SYMBOL(of_parse_phandle_with_args);
155802af11b0SGrant Likely 
1559bd69f73fSGrant Likely /**
1560035fd948SStephen Warren  * of_parse_phandle_with_fixed_args() - Find a node pointed by phandle in a list
1561035fd948SStephen Warren  * @np:		pointer to a device tree node containing a list
1562035fd948SStephen Warren  * @list_name:	property name that contains a list
1563035fd948SStephen Warren  * @cell_count: number of argument cells following the phandle
1564035fd948SStephen Warren  * @index:	index of a phandle to parse out
1565035fd948SStephen Warren  * @out_args:	optional pointer to output arguments structure (will be filled)
1566035fd948SStephen Warren  *
1567035fd948SStephen Warren  * This function is useful to parse lists of phandles and their arguments.
1568035fd948SStephen Warren  * Returns 0 on success and fills out_args, on error returns appropriate
1569035fd948SStephen Warren  * errno value.
1570035fd948SStephen Warren  *
1571d94a75c1SGeert Uytterhoeven  * Caller is responsible to call of_node_put() on the returned out_args->np
1572035fd948SStephen Warren  * pointer.
1573035fd948SStephen Warren  *
1574035fd948SStephen Warren  * Example:
1575035fd948SStephen Warren  *
1576035fd948SStephen Warren  * phandle1: node1 {
1577035fd948SStephen Warren  * }
1578035fd948SStephen Warren  *
1579035fd948SStephen Warren  * phandle2: node2 {
1580035fd948SStephen Warren  * }
1581035fd948SStephen Warren  *
1582035fd948SStephen Warren  * node3 {
1583035fd948SStephen Warren  *	list = <&phandle1 0 2 &phandle2 2 3>;
1584035fd948SStephen Warren  * }
1585035fd948SStephen Warren  *
1586035fd948SStephen Warren  * To get a device_node of the `node2' node you may call this:
1587035fd948SStephen Warren  * of_parse_phandle_with_fixed_args(node3, "list", 2, 1, &args);
1588035fd948SStephen Warren  */
1589035fd948SStephen Warren int of_parse_phandle_with_fixed_args(const struct device_node *np,
1590035fd948SStephen Warren 				const char *list_name, int cell_count,
1591035fd948SStephen Warren 				int index, struct of_phandle_args *out_args)
1592035fd948SStephen Warren {
1593035fd948SStephen Warren 	if (index < 0)
1594035fd948SStephen Warren 		return -EINVAL;
1595035fd948SStephen Warren 	return __of_parse_phandle_with_args(np, list_name, NULL, cell_count,
1596035fd948SStephen Warren 					   index, out_args);
1597035fd948SStephen Warren }
1598035fd948SStephen Warren EXPORT_SYMBOL(of_parse_phandle_with_fixed_args);
1599035fd948SStephen Warren 
1600035fd948SStephen Warren /**
1601bd69f73fSGrant Likely  * of_count_phandle_with_args() - Find the number of phandles references in a property
1602bd69f73fSGrant Likely  * @np:		pointer to a device tree node containing a list
1603bd69f73fSGrant Likely  * @list_name:	property name that contains a list
1604bd69f73fSGrant Likely  * @cells_name:	property name that specifies phandles' arguments count
1605bd69f73fSGrant Likely  *
1606bd69f73fSGrant Likely  * Returns the number of phandle + argument tuples within a property. It
1607bd69f73fSGrant Likely  * is a typical pattern to encode a list of phandle and variable
1608bd69f73fSGrant Likely  * arguments into a single property. The number of arguments is encoded
1609bd69f73fSGrant Likely  * by a property in the phandle-target node. For example, a gpios
1610bd69f73fSGrant Likely  * property would contain a list of GPIO specifies consisting of a
1611bd69f73fSGrant Likely  * phandle and 1 or more arguments. The number of arguments are
1612bd69f73fSGrant Likely  * determined by the #gpio-cells property in the node pointed to by the
1613bd69f73fSGrant Likely  * phandle.
1614bd69f73fSGrant Likely  */
1615bd69f73fSGrant Likely int of_count_phandle_with_args(const struct device_node *np, const char *list_name,
1616bd69f73fSGrant Likely 				const char *cells_name)
1617bd69f73fSGrant Likely {
1618035fd948SStephen Warren 	return __of_parse_phandle_with_args(np, list_name, cells_name, 0, -1,
1619035fd948SStephen Warren 					    NULL);
1620bd69f73fSGrant Likely }
1621bd69f73fSGrant Likely EXPORT_SYMBOL(of_count_phandle_with_args);
1622bd69f73fSGrant Likely 
162302af11b0SGrant Likely /**
162462664f67SXiubo Li  * __of_add_property - Add a property to a node without lock operations
162562664f67SXiubo Li  */
1626d8c50088SPantelis Antoniou int __of_add_property(struct device_node *np, struct property *prop)
162762664f67SXiubo Li {
162862664f67SXiubo Li 	struct property **next;
162962664f67SXiubo Li 
163062664f67SXiubo Li 	prop->next = NULL;
163162664f67SXiubo Li 	next = &np->properties;
163262664f67SXiubo Li 	while (*next) {
163362664f67SXiubo Li 		if (strcmp(prop->name, (*next)->name) == 0)
163462664f67SXiubo Li 			/* duplicate ! don't insert it */
163562664f67SXiubo Li 			return -EEXIST;
163662664f67SXiubo Li 
163762664f67SXiubo Li 		next = &(*next)->next;
163862664f67SXiubo Li 	}
163962664f67SXiubo Li 	*next = prop;
164062664f67SXiubo Li 
164162664f67SXiubo Li 	return 0;
164262664f67SXiubo Li }
164362664f67SXiubo Li 
164462664f67SXiubo Li /**
164579d1c712SNathan Fontenot  * of_add_property - Add a property to a node
164602af11b0SGrant Likely  */
164779d1c712SNathan Fontenot int of_add_property(struct device_node *np, struct property *prop)
164802af11b0SGrant Likely {
164902af11b0SGrant Likely 	unsigned long flags;
16501cf3d8b3SNathan Fontenot 	int rc;
16511cf3d8b3SNathan Fontenot 
16528a2b22a2SGrant Likely 	mutex_lock(&of_mutex);
165302af11b0SGrant Likely 
1654d6d3c4e6SThomas Gleixner 	raw_spin_lock_irqsave(&devtree_lock, flags);
165562664f67SXiubo Li 	rc = __of_add_property(np, prop);
1656d6d3c4e6SThomas Gleixner 	raw_spin_unlock_irqrestore(&devtree_lock, flags);
165702af11b0SGrant Likely 
16588a2b22a2SGrant Likely 	if (!rc)
165975b57ecfSGrant Likely 		__of_add_property_sysfs(np, prop);
166002af11b0SGrant Likely 
16618a2b22a2SGrant Likely 	mutex_unlock(&of_mutex);
16628a2b22a2SGrant Likely 
1663259092a3SGrant Likely 	if (!rc)
1664259092a3SGrant Likely 		of_property_notify(OF_RECONFIG_ADD_PROPERTY, np, prop, NULL);
1665259092a3SGrant Likely 
166662664f67SXiubo Li 	return rc;
166702af11b0SGrant Likely }
166802af11b0SGrant Likely 
1669d8c50088SPantelis Antoniou int __of_remove_property(struct device_node *np, struct property *prop)
1670d8c50088SPantelis Antoniou {
1671d8c50088SPantelis Antoniou 	struct property **next;
1672d8c50088SPantelis Antoniou 
1673d8c50088SPantelis Antoniou 	for (next = &np->properties; *next; next = &(*next)->next) {
1674d8c50088SPantelis Antoniou 		if (*next == prop)
1675d8c50088SPantelis Antoniou 			break;
1676d8c50088SPantelis Antoniou 	}
1677d8c50088SPantelis Antoniou 	if (*next == NULL)
1678d8c50088SPantelis Antoniou 		return -ENODEV;
1679d8c50088SPantelis Antoniou 
1680d8c50088SPantelis Antoniou 	/* found the node */
1681d8c50088SPantelis Antoniou 	*next = prop->next;
1682d8c50088SPantelis Antoniou 	prop->next = np->deadprops;
1683d8c50088SPantelis Antoniou 	np->deadprops = prop;
1684d8c50088SPantelis Antoniou 
1685d8c50088SPantelis Antoniou 	return 0;
1686d8c50088SPantelis Antoniou }
1687d8c50088SPantelis Antoniou 
16888a2b22a2SGrant Likely void __of_remove_property_sysfs(struct device_node *np, struct property *prop)
16898a2b22a2SGrant Likely {
1690ef69d740SGaurav Minocha 	if (!IS_ENABLED(CONFIG_SYSFS))
1691ef69d740SGaurav Minocha 		return;
1692ef69d740SGaurav Minocha 
16938a2b22a2SGrant Likely 	/* at early boot, bail here and defer setup to of_init() */
16948a2b22a2SGrant Likely 	if (of_kset && of_node_is_attached(np))
16958a2b22a2SGrant Likely 		sysfs_remove_bin_file(&np->kobj, &prop->attr);
16968a2b22a2SGrant Likely }
16978a2b22a2SGrant Likely 
169802af11b0SGrant Likely /**
169979d1c712SNathan Fontenot  * of_remove_property - Remove a property from a node.
170002af11b0SGrant Likely  *
170102af11b0SGrant Likely  * Note that we don't actually remove it, since we have given out
170202af11b0SGrant Likely  * who-knows-how-many pointers to the data using get-property.
170302af11b0SGrant Likely  * Instead we just move the property to the "dead properties"
170402af11b0SGrant Likely  * list, so it won't be found any more.
170502af11b0SGrant Likely  */
170679d1c712SNathan Fontenot int of_remove_property(struct device_node *np, struct property *prop)
170702af11b0SGrant Likely {
170802af11b0SGrant Likely 	unsigned long flags;
17091cf3d8b3SNathan Fontenot 	int rc;
17101cf3d8b3SNathan Fontenot 
17118a2b22a2SGrant Likely 	mutex_lock(&of_mutex);
171202af11b0SGrant Likely 
1713d6d3c4e6SThomas Gleixner 	raw_spin_lock_irqsave(&devtree_lock, flags);
1714d8c50088SPantelis Antoniou 	rc = __of_remove_property(np, prop);
1715d6d3c4e6SThomas Gleixner 	raw_spin_unlock_irqrestore(&devtree_lock, flags);
171602af11b0SGrant Likely 
17178a2b22a2SGrant Likely 	if (!rc)
17188a2b22a2SGrant Likely 		__of_remove_property_sysfs(np, prop);
171902af11b0SGrant Likely 
17208a2b22a2SGrant Likely 	mutex_unlock(&of_mutex);
17218a2b22a2SGrant Likely 
1722259092a3SGrant Likely 	if (!rc)
1723259092a3SGrant Likely 		of_property_notify(OF_RECONFIG_REMOVE_PROPERTY, np, prop, NULL);
1724259092a3SGrant Likely 
1725d8c50088SPantelis Antoniou 	return rc;
172602af11b0SGrant Likely }
172702af11b0SGrant Likely 
1728d8c50088SPantelis Antoniou int __of_update_property(struct device_node *np, struct property *newprop,
1729d8c50088SPantelis Antoniou 		struct property **oldpropp)
1730d8c50088SPantelis Antoniou {
1731d8c50088SPantelis Antoniou 	struct property **next, *oldprop;
1732d8c50088SPantelis Antoniou 
1733d8c50088SPantelis Antoniou 	for (next = &np->properties; *next; next = &(*next)->next) {
1734d8c50088SPantelis Antoniou 		if (of_prop_cmp((*next)->name, newprop->name) == 0)
1735d8c50088SPantelis Antoniou 			break;
1736d8c50088SPantelis Antoniou 	}
1737d8c50088SPantelis Antoniou 	*oldpropp = oldprop = *next;
1738d8c50088SPantelis Antoniou 
1739d8c50088SPantelis Antoniou 	if (oldprop) {
1740d8c50088SPantelis Antoniou 		/* replace the node */
1741d8c50088SPantelis Antoniou 		newprop->next = oldprop->next;
1742d8c50088SPantelis Antoniou 		*next = newprop;
1743d8c50088SPantelis Antoniou 		oldprop->next = np->deadprops;
1744d8c50088SPantelis Antoniou 		np->deadprops = oldprop;
1745d8c50088SPantelis Antoniou 	} else {
1746d8c50088SPantelis Antoniou 		/* new node */
1747d8c50088SPantelis Antoniou 		newprop->next = NULL;
1748d8c50088SPantelis Antoniou 		*next = newprop;
1749d8c50088SPantelis Antoniou 	}
1750d8c50088SPantelis Antoniou 
1751d8c50088SPantelis Antoniou 	return 0;
1752d8c50088SPantelis Antoniou }
1753d8c50088SPantelis Antoniou 
17548a2b22a2SGrant Likely void __of_update_property_sysfs(struct device_node *np, struct property *newprop,
17558a2b22a2SGrant Likely 		struct property *oldprop)
17568a2b22a2SGrant Likely {
1757ef69d740SGaurav Minocha 	if (!IS_ENABLED(CONFIG_SYSFS))
1758ef69d740SGaurav Minocha 		return;
1759ef69d740SGaurav Minocha 
17608a2b22a2SGrant Likely 	/* At early boot, bail out and defer setup to of_init() */
176102af11b0SGrant Likely 	if (!of_kset)
17628a2b22a2SGrant Likely 		return;
176302af11b0SGrant Likely 
17648a2b22a2SGrant Likely 	if (oldprop)
17658a2b22a2SGrant Likely 		sysfs_remove_bin_file(&np->kobj, &oldprop->attr);
17668a2b22a2SGrant Likely 	__of_add_property_sysfs(np, newprop);
176702af11b0SGrant Likely }
176802af11b0SGrant Likely 
176902af11b0SGrant Likely /*
177079d1c712SNathan Fontenot  * of_update_property - Update a property in a node, if the property does
1771475d0094SDong Aisheng  * not exist, add it.
177202af11b0SGrant Likely  *
177302af11b0SGrant Likely  * Note that we don't actually remove it, since we have given out
177402af11b0SGrant Likely  * who-knows-how-many pointers to the data using get-property.
177502af11b0SGrant Likely  * Instead we just move the property to the "dead properties" list,
177602af11b0SGrant Likely  * and add the new property to the property list
177702af11b0SGrant Likely  */
177879d1c712SNathan Fontenot int of_update_property(struct device_node *np, struct property *newprop)
177902af11b0SGrant Likely {
1780d8c50088SPantelis Antoniou 	struct property *oldprop;
178102af11b0SGrant Likely 	unsigned long flags;
1782947fdaadSXiubo Li 	int rc;
17831cf3d8b3SNathan Fontenot 
1784475d0094SDong Aisheng 	if (!newprop->name)
1785475d0094SDong Aisheng 		return -EINVAL;
1786475d0094SDong Aisheng 
17878a2b22a2SGrant Likely 	mutex_lock(&of_mutex);
1788fcdeb7feSGrant Likely 
1789d6d3c4e6SThomas Gleixner 	raw_spin_lock_irqsave(&devtree_lock, flags);
1790d8c50088SPantelis Antoniou 	rc = __of_update_property(np, newprop, &oldprop);
1791d6d3c4e6SThomas Gleixner 	raw_spin_unlock_irqrestore(&devtree_lock, flags);
1792e81b3295SNathan Fontenot 
17938a2b22a2SGrant Likely 	if (!rc)
17948a2b22a2SGrant Likely 		__of_update_property_sysfs(np, newprop, oldprop);
1795fcdeb7feSGrant Likely 
17968a2b22a2SGrant Likely 	mutex_unlock(&of_mutex);
17971cf3d8b3SNathan Fontenot 
1798259092a3SGrant Likely 	if (!rc)
1799259092a3SGrant Likely 		of_property_notify(OF_RECONFIG_UPDATE_PROPERTY, np, newprop, oldprop);
1800fcdeb7feSGrant Likely 
18011cf3d8b3SNathan Fontenot 	return rc;
1802e81b3295SNathan Fontenot }
1803e81b3295SNathan Fontenot 
1804611cad72SShawn Guo static void of_alias_add(struct alias_prop *ap, struct device_node *np,
1805611cad72SShawn Guo 			 int id, const char *stem, int stem_len)
1806611cad72SShawn Guo {
1807611cad72SShawn Guo 	ap->np = np;
1808611cad72SShawn Guo 	ap->id = id;
1809611cad72SShawn Guo 	strncpy(ap->stem, stem, stem_len);
1810611cad72SShawn Guo 	ap->stem[stem_len] = 0;
1811611cad72SShawn Guo 	list_add_tail(&ap->link, &aliases_lookup);
1812611cad72SShawn Guo 	pr_debug("adding DT alias:%s: stem=%s id=%i node=%s\n",
181374a7f084SGrant Likely 		 ap->alias, ap->stem, ap->id, of_node_full_name(np));
1814611cad72SShawn Guo }
1815611cad72SShawn Guo 
1816611cad72SShawn Guo /**
18171821dda4SGeert Uytterhoeven  * of_alias_scan - Scan all properties of the 'aliases' node
1818611cad72SShawn Guo  *
18191821dda4SGeert Uytterhoeven  * The function scans all the properties of the 'aliases' node and populates
18201821dda4SGeert Uytterhoeven  * the global lookup table with the properties.  It returns the
18211821dda4SGeert Uytterhoeven  * number of alias properties found, or an error code in case of failure.
1822611cad72SShawn Guo  *
1823611cad72SShawn Guo  * @dt_alloc:	An allocator that provides a virtual address to memory
18241821dda4SGeert Uytterhoeven  *		for storing the resulting tree
1825611cad72SShawn Guo  */
1826611cad72SShawn Guo void of_alias_scan(void * (*dt_alloc)(u64 size, u64 align))
1827611cad72SShawn Guo {
1828611cad72SShawn Guo 	struct property *pp;
1829611cad72SShawn Guo 
18307dbe5849SLaurentiu Tudor 	of_aliases = of_find_node_by_path("/aliases");
1831611cad72SShawn Guo 	of_chosen = of_find_node_by_path("/chosen");
1832611cad72SShawn Guo 	if (of_chosen == NULL)
1833611cad72SShawn Guo 		of_chosen = of_find_node_by_path("/chosen@0");
18345c19e952SSascha Hauer 
18355c19e952SSascha Hauer 	if (of_chosen) {
1836a752ee56SGrant Likely 		/* linux,stdout-path and /aliases/stdout are for legacy compatibility */
1837676e1b2fSGrant Likely 		const char *name = of_get_property(of_chosen, "stdout-path", NULL);
1838676e1b2fSGrant Likely 		if (!name)
18395c19e952SSascha Hauer 			name = of_get_property(of_chosen, "linux,stdout-path", NULL);
1840a752ee56SGrant Likely 		if (IS_ENABLED(CONFIG_PPC) && !name)
1841a752ee56SGrant Likely 			name = of_get_property(of_aliases, "stdout", NULL);
18425c19e952SSascha Hauer 		if (name)
18435c19e952SSascha Hauer 			of_stdout = of_find_node_by_path(name);
18445c19e952SSascha Hauer 	}
18455c19e952SSascha Hauer 
1846611cad72SShawn Guo 	if (!of_aliases)
1847611cad72SShawn Guo 		return;
1848611cad72SShawn Guo 
18498af0da93SDong Aisheng 	for_each_property_of_node(of_aliases, pp) {
1850611cad72SShawn Guo 		const char *start = pp->name;
1851611cad72SShawn Guo 		const char *end = start + strlen(start);
1852611cad72SShawn Guo 		struct device_node *np;
1853611cad72SShawn Guo 		struct alias_prop *ap;
1854611cad72SShawn Guo 		int id, len;
1855611cad72SShawn Guo 
1856611cad72SShawn Guo 		/* Skip those we do not want to proceed */
1857611cad72SShawn Guo 		if (!strcmp(pp->name, "name") ||
1858611cad72SShawn Guo 		    !strcmp(pp->name, "phandle") ||
1859611cad72SShawn Guo 		    !strcmp(pp->name, "linux,phandle"))
1860611cad72SShawn Guo 			continue;
1861611cad72SShawn Guo 
1862611cad72SShawn Guo 		np = of_find_node_by_path(pp->value);
1863611cad72SShawn Guo 		if (!np)
1864611cad72SShawn Guo 			continue;
1865611cad72SShawn Guo 
1866611cad72SShawn Guo 		/* walk the alias backwards to extract the id and work out
1867611cad72SShawn Guo 		 * the 'stem' string */
1868611cad72SShawn Guo 		while (isdigit(*(end-1)) && end > start)
1869611cad72SShawn Guo 			end--;
1870611cad72SShawn Guo 		len = end - start;
1871611cad72SShawn Guo 
1872611cad72SShawn Guo 		if (kstrtoint(end, 10, &id) < 0)
1873611cad72SShawn Guo 			continue;
1874611cad72SShawn Guo 
1875611cad72SShawn Guo 		/* Allocate an alias_prop with enough space for the stem */
1876611cad72SShawn Guo 		ap = dt_alloc(sizeof(*ap) + len + 1, 4);
1877611cad72SShawn Guo 		if (!ap)
1878611cad72SShawn Guo 			continue;
18790640332eSGrant Likely 		memset(ap, 0, sizeof(*ap) + len + 1);
1880611cad72SShawn Guo 		ap->alias = start;
1881611cad72SShawn Guo 		of_alias_add(ap, np, id, start, len);
1882611cad72SShawn Guo 	}
1883611cad72SShawn Guo }
1884611cad72SShawn Guo 
1885611cad72SShawn Guo /**
1886611cad72SShawn Guo  * of_alias_get_id - Get alias id for the given device_node
1887611cad72SShawn Guo  * @np:		Pointer to the given device_node
1888611cad72SShawn Guo  * @stem:	Alias stem of the given device_node
1889611cad72SShawn Guo  *
18905a53a07fSGeert Uytterhoeven  * The function travels the lookup table to get the alias id for the given
18915a53a07fSGeert Uytterhoeven  * device_node and alias stem.  It returns the alias id if found.
1892611cad72SShawn Guo  */
1893611cad72SShawn Guo int of_alias_get_id(struct device_node *np, const char *stem)
1894611cad72SShawn Guo {
1895611cad72SShawn Guo 	struct alias_prop *app;
1896611cad72SShawn Guo 	int id = -ENODEV;
1897611cad72SShawn Guo 
1898c05aba2bSPantelis Antoniou 	mutex_lock(&of_mutex);
1899611cad72SShawn Guo 	list_for_each_entry(app, &aliases_lookup, link) {
1900611cad72SShawn Guo 		if (strcmp(app->stem, stem) != 0)
1901611cad72SShawn Guo 			continue;
1902611cad72SShawn Guo 
1903611cad72SShawn Guo 		if (np == app->np) {
1904611cad72SShawn Guo 			id = app->id;
1905611cad72SShawn Guo 			break;
1906611cad72SShawn Guo 		}
1907611cad72SShawn Guo 	}
1908c05aba2bSPantelis Antoniou 	mutex_unlock(&of_mutex);
1909611cad72SShawn Guo 
1910611cad72SShawn Guo 	return id;
1911611cad72SShawn Guo }
1912611cad72SShawn Guo EXPORT_SYMBOL_GPL(of_alias_get_id);
1913c541adc6SStephen Warren 
1914c541adc6SStephen Warren const __be32 *of_prop_next_u32(struct property *prop, const __be32 *cur,
1915c541adc6SStephen Warren 			       u32 *pu)
1916c541adc6SStephen Warren {
1917c541adc6SStephen Warren 	const void *curv = cur;
1918c541adc6SStephen Warren 
1919c541adc6SStephen Warren 	if (!prop)
1920c541adc6SStephen Warren 		return NULL;
1921c541adc6SStephen Warren 
1922c541adc6SStephen Warren 	if (!cur) {
1923c541adc6SStephen Warren 		curv = prop->value;
1924c541adc6SStephen Warren 		goto out_val;
1925c541adc6SStephen Warren 	}
1926c541adc6SStephen Warren 
1927c541adc6SStephen Warren 	curv += sizeof(*cur);
1928c541adc6SStephen Warren 	if (curv >= prop->value + prop->length)
1929c541adc6SStephen Warren 		return NULL;
1930c541adc6SStephen Warren 
1931c541adc6SStephen Warren out_val:
1932c541adc6SStephen Warren 	*pu = be32_to_cpup(curv);
1933c541adc6SStephen Warren 	return curv;
1934c541adc6SStephen Warren }
1935c541adc6SStephen Warren EXPORT_SYMBOL_GPL(of_prop_next_u32);
1936c541adc6SStephen Warren 
1937c541adc6SStephen Warren const char *of_prop_next_string(struct property *prop, const char *cur)
1938c541adc6SStephen Warren {
1939c541adc6SStephen Warren 	const void *curv = cur;
1940c541adc6SStephen Warren 
1941c541adc6SStephen Warren 	if (!prop)
1942c541adc6SStephen Warren 		return NULL;
1943c541adc6SStephen Warren 
1944c541adc6SStephen Warren 	if (!cur)
1945c541adc6SStephen Warren 		return prop->value;
1946c541adc6SStephen Warren 
1947c541adc6SStephen Warren 	curv += strlen(cur) + 1;
1948c541adc6SStephen Warren 	if (curv >= prop->value + prop->length)
1949c541adc6SStephen Warren 		return NULL;
1950c541adc6SStephen Warren 
1951c541adc6SStephen Warren 	return curv;
1952c541adc6SStephen Warren }
1953c541adc6SStephen Warren EXPORT_SYMBOL_GPL(of_prop_next_string);
19545c19e952SSascha Hauer 
19555c19e952SSascha Hauer /**
19563482f2c5SGrant Likely  * of_console_check() - Test and setup console for DT setup
19573482f2c5SGrant Likely  * @dn - Pointer to device node
19583482f2c5SGrant Likely  * @name - Name to use for preferred console without index. ex. "ttyS"
19593482f2c5SGrant Likely  * @index - Index to use for preferred console.
19605c19e952SSascha Hauer  *
19613482f2c5SGrant Likely  * Check if the given device node matches the stdout-path property in the
19623482f2c5SGrant Likely  * /chosen node. If it does then register it as the preferred console and return
19633482f2c5SGrant Likely  * TRUE. Otherwise return FALSE.
19645c19e952SSascha Hauer  */
19653482f2c5SGrant Likely bool of_console_check(struct device_node *dn, char *name, int index)
19665c19e952SSascha Hauer {
19673482f2c5SGrant Likely 	if (!dn || dn != of_stdout || console_set_on_cmdline)
19685c19e952SSascha Hauer 		return false;
19695f74d8b7SBrian Norris 	return !add_preferred_console(name, index, NULL);
19705c19e952SSascha Hauer }
19713482f2c5SGrant Likely EXPORT_SYMBOL_GPL(of_console_check);
1972a3e31b45SSudeep KarkadaNagesha 
1973a3e31b45SSudeep KarkadaNagesha /**
1974a3e31b45SSudeep KarkadaNagesha  *	of_find_next_cache_node - Find a node's subsidiary cache
1975a3e31b45SSudeep KarkadaNagesha  *	@np:	node of type "cpu" or "cache"
1976a3e31b45SSudeep KarkadaNagesha  *
1977a3e31b45SSudeep KarkadaNagesha  *	Returns a node pointer with refcount incremented, use
1978a3e31b45SSudeep KarkadaNagesha  *	of_node_put() on it when done.  Caller should hold a reference
1979a3e31b45SSudeep KarkadaNagesha  *	to np.
1980a3e31b45SSudeep KarkadaNagesha  */
1981a3e31b45SSudeep KarkadaNagesha struct device_node *of_find_next_cache_node(const struct device_node *np)
1982a3e31b45SSudeep KarkadaNagesha {
1983a3e31b45SSudeep KarkadaNagesha 	struct device_node *child;
1984a3e31b45SSudeep KarkadaNagesha 	const phandle *handle;
1985a3e31b45SSudeep KarkadaNagesha 
1986a3e31b45SSudeep KarkadaNagesha 	handle = of_get_property(np, "l2-cache", NULL);
1987a3e31b45SSudeep KarkadaNagesha 	if (!handle)
1988a3e31b45SSudeep KarkadaNagesha 		handle = of_get_property(np, "next-level-cache", NULL);
1989a3e31b45SSudeep KarkadaNagesha 
1990a3e31b45SSudeep KarkadaNagesha 	if (handle)
1991a3e31b45SSudeep KarkadaNagesha 		return of_find_node_by_phandle(be32_to_cpup(handle));
1992a3e31b45SSudeep KarkadaNagesha 
1993a3e31b45SSudeep KarkadaNagesha 	/* OF on pmac has nodes instead of properties named "l2-cache"
1994a3e31b45SSudeep KarkadaNagesha 	 * beneath CPU nodes.
1995a3e31b45SSudeep KarkadaNagesha 	 */
1996a3e31b45SSudeep KarkadaNagesha 	if (!strcmp(np->type, "cpu"))
1997a3e31b45SSudeep KarkadaNagesha 		for_each_child_of_node(np, child)
1998a3e31b45SSudeep KarkadaNagesha 			if (!strcmp(child->type, "cache"))
1999a3e31b45SSudeep KarkadaNagesha 				return child;
2000a3e31b45SSudeep KarkadaNagesha 
2001a3e31b45SSudeep KarkadaNagesha 	return NULL;
2002a3e31b45SSudeep KarkadaNagesha }
2003fd9fdb78SPhilipp Zabel 
2004fd9fdb78SPhilipp Zabel /**
2005f2a575f6SPhilipp Zabel  * of_graph_parse_endpoint() - parse common endpoint node properties
2006f2a575f6SPhilipp Zabel  * @node: pointer to endpoint device_node
2007f2a575f6SPhilipp Zabel  * @endpoint: pointer to the OF endpoint data structure
2008f2a575f6SPhilipp Zabel  *
2009f2a575f6SPhilipp Zabel  * The caller should hold a reference to @node.
2010f2a575f6SPhilipp Zabel  */
2011f2a575f6SPhilipp Zabel int of_graph_parse_endpoint(const struct device_node *node,
2012f2a575f6SPhilipp Zabel 			    struct of_endpoint *endpoint)
2013f2a575f6SPhilipp Zabel {
2014f2a575f6SPhilipp Zabel 	struct device_node *port_node = of_get_parent(node);
2015f2a575f6SPhilipp Zabel 
2016d484700aSPhilipp Zabel 	WARN_ONCE(!port_node, "%s(): endpoint %s has no parent node\n",
2017d484700aSPhilipp Zabel 		  __func__, node->full_name);
2018d484700aSPhilipp Zabel 
2019f2a575f6SPhilipp Zabel 	memset(endpoint, 0, sizeof(*endpoint));
2020f2a575f6SPhilipp Zabel 
2021f2a575f6SPhilipp Zabel 	endpoint->local_node = node;
2022f2a575f6SPhilipp Zabel 	/*
2023f2a575f6SPhilipp Zabel 	 * It doesn't matter whether the two calls below succeed.
2024f2a575f6SPhilipp Zabel 	 * If they don't then the default value 0 is used.
2025f2a575f6SPhilipp Zabel 	 */
2026f2a575f6SPhilipp Zabel 	of_property_read_u32(port_node, "reg", &endpoint->port);
2027f2a575f6SPhilipp Zabel 	of_property_read_u32(node, "reg", &endpoint->id);
2028f2a575f6SPhilipp Zabel 
2029f2a575f6SPhilipp Zabel 	of_node_put(port_node);
2030f2a575f6SPhilipp Zabel 
2031f2a575f6SPhilipp Zabel 	return 0;
2032f2a575f6SPhilipp Zabel }
2033f2a575f6SPhilipp Zabel EXPORT_SYMBOL(of_graph_parse_endpoint);
2034f2a575f6SPhilipp Zabel 
2035f2a575f6SPhilipp Zabel /**
2036fd9fdb78SPhilipp Zabel  * of_graph_get_next_endpoint() - get next endpoint node
2037fd9fdb78SPhilipp Zabel  * @parent: pointer to the parent device node
2038fd9fdb78SPhilipp Zabel  * @prev: previous endpoint node, or NULL to get first
2039fd9fdb78SPhilipp Zabel  *
2040fd9fdb78SPhilipp Zabel  * Return: An 'endpoint' node pointer with refcount incremented. Refcount
2041fd9fdb78SPhilipp Zabel  * of the passed @prev node is not decremented, the caller have to use
2042fd9fdb78SPhilipp Zabel  * of_node_put() on it when done.
2043fd9fdb78SPhilipp Zabel  */
2044fd9fdb78SPhilipp Zabel struct device_node *of_graph_get_next_endpoint(const struct device_node *parent,
2045fd9fdb78SPhilipp Zabel 					struct device_node *prev)
2046fd9fdb78SPhilipp Zabel {
2047fd9fdb78SPhilipp Zabel 	struct device_node *endpoint;
20483c83e61eSLinus Torvalds 	struct device_node *port;
2049fd9fdb78SPhilipp Zabel 
2050fd9fdb78SPhilipp Zabel 	if (!parent)
2051fd9fdb78SPhilipp Zabel 		return NULL;
2052fd9fdb78SPhilipp Zabel 
20533c83e61eSLinus Torvalds 	/*
20543c83e61eSLinus Torvalds 	 * Start by locating the port node. If no previous endpoint is specified
20553c83e61eSLinus Torvalds 	 * search for the first port node, otherwise get the previous endpoint
20563c83e61eSLinus Torvalds 	 * parent port node.
20573c83e61eSLinus Torvalds 	 */
2058fd9fdb78SPhilipp Zabel 	if (!prev) {
2059fd9fdb78SPhilipp Zabel 		struct device_node *node;
20603c83e61eSLinus Torvalds 
2061fd9fdb78SPhilipp Zabel 		node = of_get_child_by_name(parent, "ports");
2062fd9fdb78SPhilipp Zabel 		if (node)
2063fd9fdb78SPhilipp Zabel 			parent = node;
2064fd9fdb78SPhilipp Zabel 
2065fd9fdb78SPhilipp Zabel 		port = of_get_child_by_name(parent, "port");
2066fd9fdb78SPhilipp Zabel 		of_node_put(node);
20674329b93bSPhilipp Zabel 
20683c83e61eSLinus Torvalds 		if (!port) {
20693c83e61eSLinus Torvalds 			pr_err("%s(): no port node found in %s\n",
20703c83e61eSLinus Torvalds 			       __func__, parent->full_name);
20713c83e61eSLinus Torvalds 			return NULL;
20724329b93bSPhilipp Zabel 		}
20733c83e61eSLinus Torvalds 	} else {
2074fd9fdb78SPhilipp Zabel 		port = of_get_parent(prev);
20756ff60d39SPhilipp Zabel 		if (WARN_ONCE(!port, "%s(): endpoint %s has no parent node\n",
20766ff60d39SPhilipp Zabel 			      __func__, prev->full_name))
2077fd9fdb78SPhilipp Zabel 			return NULL;
2078fd9fdb78SPhilipp Zabel 
20793c83e61eSLinus Torvalds 		/*
20803c83e61eSLinus Torvalds 		 * Avoid dropping prev node refcount to 0 when getting the next
20813c83e61eSLinus Torvalds 		 * child below.
20823c83e61eSLinus Torvalds 		 */
2083fd9fdb78SPhilipp Zabel 		of_node_get(prev);
20843c83e61eSLinus Torvalds 	}
20853c83e61eSLinus Torvalds 
20863c83e61eSLinus Torvalds 	while (1) {
20873c83e61eSLinus Torvalds 		/*
20883c83e61eSLinus Torvalds 		 * Now that we have a port node, get the next endpoint by
20893c83e61eSLinus Torvalds 		 * getting the next child. If the previous endpoint is NULL this
20903c83e61eSLinus Torvalds 		 * will return the first child.
20913c83e61eSLinus Torvalds 		 */
2092fd9fdb78SPhilipp Zabel 		endpoint = of_get_next_child(port, prev);
2093fd9fdb78SPhilipp Zabel 		if (endpoint) {
2094fd9fdb78SPhilipp Zabel 			of_node_put(port);
2095fd9fdb78SPhilipp Zabel 			return endpoint;
2096fd9fdb78SPhilipp Zabel 		}
2097fd9fdb78SPhilipp Zabel 
2098fd9fdb78SPhilipp Zabel 		/* No more endpoints under this port, try the next one. */
20993c83e61eSLinus Torvalds 		prev = NULL;
21003c83e61eSLinus Torvalds 
2101fd9fdb78SPhilipp Zabel 		do {
2102fd9fdb78SPhilipp Zabel 			port = of_get_next_child(parent, port);
2103fd9fdb78SPhilipp Zabel 			if (!port)
2104fd9fdb78SPhilipp Zabel 				return NULL;
2105fd9fdb78SPhilipp Zabel 		} while (of_node_cmp(port->name, "port"));
21063c83e61eSLinus Torvalds 	}
2107fd9fdb78SPhilipp Zabel }
2108fd9fdb78SPhilipp Zabel EXPORT_SYMBOL(of_graph_get_next_endpoint);
2109fd9fdb78SPhilipp Zabel 
2110fd9fdb78SPhilipp Zabel /**
2111fd9fdb78SPhilipp Zabel  * of_graph_get_remote_port_parent() - get remote port's parent node
2112fd9fdb78SPhilipp Zabel  * @node: pointer to a local endpoint device_node
2113fd9fdb78SPhilipp Zabel  *
2114fd9fdb78SPhilipp Zabel  * Return: Remote device node associated with remote endpoint node linked
2115fd9fdb78SPhilipp Zabel  *	   to @node. Use of_node_put() on it when done.
2116fd9fdb78SPhilipp Zabel  */
2117fd9fdb78SPhilipp Zabel struct device_node *of_graph_get_remote_port_parent(
2118fd9fdb78SPhilipp Zabel 			       const struct device_node *node)
2119fd9fdb78SPhilipp Zabel {
2120fd9fdb78SPhilipp Zabel 	struct device_node *np;
2121fd9fdb78SPhilipp Zabel 	unsigned int depth;
2122fd9fdb78SPhilipp Zabel 
2123fd9fdb78SPhilipp Zabel 	/* Get remote endpoint node. */
2124fd9fdb78SPhilipp Zabel 	np = of_parse_phandle(node, "remote-endpoint", 0);
2125fd9fdb78SPhilipp Zabel 
2126fd9fdb78SPhilipp Zabel 	/* Walk 3 levels up only if there is 'ports' node. */
2127fd9fdb78SPhilipp Zabel 	for (depth = 3; depth && np; depth--) {
2128fd9fdb78SPhilipp Zabel 		np = of_get_next_parent(np);
2129fd9fdb78SPhilipp Zabel 		if (depth == 2 && of_node_cmp(np->name, "ports"))
2130fd9fdb78SPhilipp Zabel 			break;
2131fd9fdb78SPhilipp Zabel 	}
2132fd9fdb78SPhilipp Zabel 	return np;
2133fd9fdb78SPhilipp Zabel }
2134fd9fdb78SPhilipp Zabel EXPORT_SYMBOL(of_graph_get_remote_port_parent);
2135fd9fdb78SPhilipp Zabel 
2136fd9fdb78SPhilipp Zabel /**
2137fd9fdb78SPhilipp Zabel  * of_graph_get_remote_port() - get remote port node
2138fd9fdb78SPhilipp Zabel  * @node: pointer to a local endpoint device_node
2139fd9fdb78SPhilipp Zabel  *
2140fd9fdb78SPhilipp Zabel  * Return: Remote port node associated with remote endpoint node linked
2141fd9fdb78SPhilipp Zabel  *	   to @node. Use of_node_put() on it when done.
2142fd9fdb78SPhilipp Zabel  */
2143fd9fdb78SPhilipp Zabel struct device_node *of_graph_get_remote_port(const struct device_node *node)
2144fd9fdb78SPhilipp Zabel {
2145fd9fdb78SPhilipp Zabel 	struct device_node *np;
2146fd9fdb78SPhilipp Zabel 
2147fd9fdb78SPhilipp Zabel 	/* Get remote endpoint node. */
2148fd9fdb78SPhilipp Zabel 	np = of_parse_phandle(node, "remote-endpoint", 0);
2149fd9fdb78SPhilipp Zabel 	if (!np)
2150fd9fdb78SPhilipp Zabel 		return NULL;
2151fd9fdb78SPhilipp Zabel 	return of_get_next_parent(np);
2152fd9fdb78SPhilipp Zabel }
2153fd9fdb78SPhilipp Zabel EXPORT_SYMBOL(of_graph_get_remote_port);
2154