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