197e873e5SStephen Rothwell /* 297e873e5SStephen Rothwell * Procedures for creating, accessing and interpreting the device tree. 397e873e5SStephen Rothwell * 497e873e5SStephen Rothwell * Paul Mackerras August 1996. 597e873e5SStephen Rothwell * Copyright (C) 1996-2005 Paul Mackerras. 697e873e5SStephen Rothwell * 797e873e5SStephen Rothwell * Adapted for 64bit PowerPC by Dave Engebretsen and Peter Bergner. 897e873e5SStephen Rothwell * {engebret|bergner}@us.ibm.com 997e873e5SStephen Rothwell * 1097e873e5SStephen Rothwell * Adapted for sparc and sparc64 by David S. Miller davem@davemloft.net 1197e873e5SStephen Rothwell * 12e91edcf5SGrant Likely * Reconsolidated from arch/x/kernel/prom.c by Stephen Rothwell and 13e91edcf5SGrant Likely * Grant Likely. 1497e873e5SStephen Rothwell * 1597e873e5SStephen Rothwell * This program is free software; you can redistribute it and/or 1697e873e5SStephen Rothwell * modify it under the terms of the GNU General Public License 1797e873e5SStephen Rothwell * as published by the Free Software Foundation; either version 1897e873e5SStephen Rothwell * 2 of the License, or (at your option) any later version. 1997e873e5SStephen Rothwell */ 203482f2c5SGrant Likely #include <linux/console.h> 21611cad72SShawn Guo #include <linux/ctype.h> 22183912d3SSudeep KarkadaNagesha #include <linux/cpu.h> 2397e873e5SStephen Rothwell #include <linux/module.h> 2497e873e5SStephen Rothwell #include <linux/of.h> 25fd9fdb78SPhilipp Zabel #include <linux/of_graph.h> 26581b605aSStephen Rothwell #include <linux/spinlock.h> 275a0e3ad6STejun Heo #include <linux/slab.h> 2875b57ecfSGrant Likely #include <linux/string.h> 29a9f2f63aSJeremy Kerr #include <linux/proc_fs.h> 30581b605aSStephen Rothwell 31ced4eec9SStepan Moskovchenko #include "of_private.h" 32611cad72SShawn Guo 33ced4eec9SStepan Moskovchenko LIST_HEAD(aliases_lookup); 34611cad72SShawn Guo 355063e25aSGrant Likely struct device_node *of_root; 365063e25aSGrant Likely EXPORT_SYMBOL(of_root); 37fc0bdae4SGrant Likely struct device_node *of_chosen; 38611cad72SShawn Guo struct device_node *of_aliases; 39a752ee56SGrant Likely struct device_node *of_stdout; 407914a7c5SLeif Lindholm static const char *of_stdout_options; 41611cad72SShawn Guo 428a2b22a2SGrant Likely struct kset *of_kset; 4375b57ecfSGrant Likely 4475b57ecfSGrant Likely /* 458a2b22a2SGrant Likely * Used to protect the of_aliases, to hold off addition of nodes to sysfs. 468a2b22a2SGrant Likely * This mutex must be held whenever modifications are being made to the 478a2b22a2SGrant Likely * device tree. The of_{attach,detach}_node() and 488a2b22a2SGrant Likely * of_{add,remove,update}_property() helpers make sure this happens. 4975b57ecfSGrant Likely */ 50c05aba2bSPantelis Antoniou DEFINE_MUTEX(of_mutex); 511ef4d424SStephen Rothwell 525063e25aSGrant Likely /* use when traversing tree through the child, sibling, 53581b605aSStephen Rothwell * or parent members of struct device_node. 54581b605aSStephen Rothwell */ 55d6d3c4e6SThomas Gleixner DEFINE_RAW_SPINLOCK(devtree_lock); 5697e873e5SStephen Rothwell 5797e873e5SStephen Rothwell int of_n_addr_cells(struct device_node *np) 5897e873e5SStephen Rothwell { 59a9fadeefSJeremy Kerr const __be32 *ip; 6097e873e5SStephen Rothwell 6197e873e5SStephen Rothwell do { 6297e873e5SStephen Rothwell if (np->parent) 6397e873e5SStephen Rothwell np = np->parent; 6497e873e5SStephen Rothwell ip = of_get_property(np, "#address-cells", NULL); 6597e873e5SStephen Rothwell if (ip) 6633714881SJeremy Kerr return be32_to_cpup(ip); 6797e873e5SStephen Rothwell } while (np->parent); 6897e873e5SStephen Rothwell /* No #address-cells property for the root node */ 6997e873e5SStephen Rothwell return OF_ROOT_NODE_ADDR_CELLS_DEFAULT; 7097e873e5SStephen Rothwell } 7197e873e5SStephen Rothwell EXPORT_SYMBOL(of_n_addr_cells); 7297e873e5SStephen Rothwell 7397e873e5SStephen Rothwell int of_n_size_cells(struct device_node *np) 7497e873e5SStephen Rothwell { 75a9fadeefSJeremy Kerr const __be32 *ip; 7697e873e5SStephen Rothwell 7797e873e5SStephen Rothwell do { 7897e873e5SStephen Rothwell if (np->parent) 7997e873e5SStephen Rothwell np = np->parent; 8097e873e5SStephen Rothwell ip = of_get_property(np, "#size-cells", NULL); 8197e873e5SStephen Rothwell if (ip) 8233714881SJeremy Kerr return be32_to_cpup(ip); 8397e873e5SStephen Rothwell } while (np->parent); 8497e873e5SStephen Rothwell /* No #size-cells property for the root node */ 8597e873e5SStephen Rothwell return OF_ROOT_NODE_SIZE_CELLS_DEFAULT; 8697e873e5SStephen Rothwell } 8797e873e5SStephen Rothwell EXPORT_SYMBOL(of_n_size_cells); 8897e873e5SStephen Rothwell 890c3f061cSRob Herring #ifdef CONFIG_NUMA 900c3f061cSRob Herring int __weak of_node_to_nid(struct device_node *np) 910c3f061cSRob Herring { 92c8fff7bcSKonstantin Khlebnikov return NUMA_NO_NODE; 930c3f061cSRob Herring } 940c3f061cSRob Herring #endif 950c3f061cSRob Herring 966afc0dc3SGrant Likely #ifndef CONFIG_OF_DYNAMIC 9775b57ecfSGrant Likely static void of_node_release(struct kobject *kobj) 9875b57ecfSGrant Likely { 9975b57ecfSGrant Likely /* Without CONFIG_OF_DYNAMIC, no nodes gets freed */ 10075b57ecfSGrant Likely } 1010f22dd39SGrant Likely #endif /* CONFIG_OF_DYNAMIC */ 102923f7e30SGrant Likely 10375b57ecfSGrant Likely struct kobj_type of_node_ktype = { 10475b57ecfSGrant Likely .release = of_node_release, 10575b57ecfSGrant Likely }; 10675b57ecfSGrant Likely 10775b57ecfSGrant Likely static ssize_t of_node_property_read(struct file *filp, struct kobject *kobj, 10875b57ecfSGrant Likely struct bin_attribute *bin_attr, char *buf, 10975b57ecfSGrant Likely loff_t offset, size_t count) 11075b57ecfSGrant Likely { 11175b57ecfSGrant Likely struct property *pp = container_of(bin_attr, struct property, attr); 11275b57ecfSGrant Likely return memory_read_from_buffer(buf, count, &offset, pp->value, pp->length); 11375b57ecfSGrant Likely } 11475b57ecfSGrant Likely 11575b57ecfSGrant Likely static const char *safe_name(struct kobject *kobj, const char *orig_name) 11675b57ecfSGrant Likely { 11775b57ecfSGrant Likely const char *name = orig_name; 11875b57ecfSGrant Likely struct kernfs_node *kn; 11975b57ecfSGrant Likely int i = 0; 12075b57ecfSGrant Likely 12175b57ecfSGrant Likely /* don't be a hero. After 16 tries give up */ 12275b57ecfSGrant Likely while (i < 16 && (kn = sysfs_get_dirent(kobj->sd, name))) { 12375b57ecfSGrant Likely sysfs_put(kn); 12475b57ecfSGrant Likely if (name != orig_name) 12575b57ecfSGrant Likely kfree(name); 12675b57ecfSGrant Likely name = kasprintf(GFP_KERNEL, "%s#%i", orig_name, ++i); 12775b57ecfSGrant Likely } 12875b57ecfSGrant Likely 12975b57ecfSGrant Likely if (name != orig_name) 13075b57ecfSGrant Likely pr_warn("device-tree: Duplicate name in %s, renamed to \"%s\"\n", 13175b57ecfSGrant Likely kobject_name(kobj), name); 13275b57ecfSGrant Likely return name; 13375b57ecfSGrant Likely } 13475b57ecfSGrant Likely 1358a2b22a2SGrant Likely int __of_add_property_sysfs(struct device_node *np, struct property *pp) 13675b57ecfSGrant Likely { 13775b57ecfSGrant Likely int rc; 13875b57ecfSGrant Likely 13975b57ecfSGrant Likely /* Important: Don't leak passwords */ 14075b57ecfSGrant Likely bool secure = strncmp(pp->name, "security-", 9) == 0; 14175b57ecfSGrant Likely 142ef69d740SGaurav Minocha if (!IS_ENABLED(CONFIG_SYSFS)) 143ef69d740SGaurav Minocha return 0; 144ef69d740SGaurav Minocha 1458a2b22a2SGrant Likely if (!of_kset || !of_node_is_attached(np)) 1468a2b22a2SGrant Likely return 0; 1478a2b22a2SGrant Likely 14875b57ecfSGrant Likely sysfs_bin_attr_init(&pp->attr); 14975b57ecfSGrant Likely pp->attr.attr.name = safe_name(&np->kobj, pp->name); 15075b57ecfSGrant Likely pp->attr.attr.mode = secure ? S_IRUSR : S_IRUGO; 15175b57ecfSGrant Likely pp->attr.size = secure ? 0 : pp->length; 15275b57ecfSGrant Likely pp->attr.read = of_node_property_read; 15375b57ecfSGrant Likely 15475b57ecfSGrant Likely rc = sysfs_create_bin_file(&np->kobj, &pp->attr); 15575b57ecfSGrant Likely WARN(rc, "error adding attribute %s to node %s\n", pp->name, np->full_name); 15675b57ecfSGrant Likely return rc; 15775b57ecfSGrant Likely } 15875b57ecfSGrant Likely 1598a2b22a2SGrant Likely int __of_attach_node_sysfs(struct device_node *np) 16075b57ecfSGrant Likely { 16175b57ecfSGrant Likely const char *name; 16275b57ecfSGrant Likely struct property *pp; 16375b57ecfSGrant Likely int rc; 16475b57ecfSGrant Likely 165ef69d740SGaurav Minocha if (!IS_ENABLED(CONFIG_SYSFS)) 166ef69d740SGaurav Minocha return 0; 167ef69d740SGaurav Minocha 1688a2b22a2SGrant Likely if (!of_kset) 1698a2b22a2SGrant Likely return 0; 1708a2b22a2SGrant Likely 17175b57ecfSGrant Likely np->kobj.kset = of_kset; 17275b57ecfSGrant Likely if (!np->parent) { 17375b57ecfSGrant Likely /* Nodes without parents are new top level trees */ 17428d3ee40SKees Cook rc = kobject_add(&np->kobj, NULL, "%s", 17528d3ee40SKees Cook safe_name(&of_kset->kobj, "base")); 17675b57ecfSGrant Likely } else { 17775b57ecfSGrant Likely name = safe_name(&np->parent->kobj, kbasename(np->full_name)); 17875b57ecfSGrant Likely if (!name || !name[0]) 17975b57ecfSGrant Likely return -EINVAL; 18075b57ecfSGrant Likely 18175b57ecfSGrant Likely rc = kobject_add(&np->kobj, &np->parent->kobj, "%s", name); 18275b57ecfSGrant Likely } 18375b57ecfSGrant Likely if (rc) 18475b57ecfSGrant Likely return rc; 18575b57ecfSGrant Likely 18675b57ecfSGrant Likely for_each_property_of_node(np, pp) 18775b57ecfSGrant Likely __of_add_property_sysfs(np, pp); 18875b57ecfSGrant Likely 18975b57ecfSGrant Likely return 0; 19075b57ecfSGrant Likely } 19175b57ecfSGrant Likely 192194ec936SSudeep Holla void __init of_core_init(void) 19375b57ecfSGrant Likely { 19475b57ecfSGrant Likely struct device_node *np; 19575b57ecfSGrant Likely 19675b57ecfSGrant Likely /* Create the kset, and register existing nodes */ 197c05aba2bSPantelis Antoniou mutex_lock(&of_mutex); 19875b57ecfSGrant Likely of_kset = kset_create_and_add("devicetree", NULL, firmware_kobj); 19975b57ecfSGrant Likely if (!of_kset) { 200c05aba2bSPantelis Antoniou mutex_unlock(&of_mutex); 201194ec936SSudeep Holla pr_err("devicetree: failed to register existing nodes\n"); 202194ec936SSudeep Holla return; 20375b57ecfSGrant Likely } 20475b57ecfSGrant Likely for_each_of_allnodes(np) 2058a2b22a2SGrant Likely __of_attach_node_sysfs(np); 206c05aba2bSPantelis Antoniou mutex_unlock(&of_mutex); 20775b57ecfSGrant Likely 2088357041aSGrant Likely /* Symlink in /proc as required by userspace ABI */ 2095063e25aSGrant Likely if (of_root) 21075b57ecfSGrant Likely proc_symlink("device-tree", NULL, "/sys/firmware/devicetree/base"); 21175b57ecfSGrant Likely } 21275b57ecfSGrant Likely 21328d0e36bSThomas Gleixner static struct property *__of_find_property(const struct device_node *np, 21428d0e36bSThomas Gleixner const char *name, int *lenp) 215581b605aSStephen Rothwell { 216581b605aSStephen Rothwell struct property *pp; 217581b605aSStephen Rothwell 21864e4566fSTimur Tabi if (!np) 21964e4566fSTimur Tabi return NULL; 22064e4566fSTimur Tabi 221a3a7cab1SSachin Kamat for (pp = np->properties; pp; pp = pp->next) { 222581b605aSStephen Rothwell if (of_prop_cmp(pp->name, name) == 0) { 223a3a7cab1SSachin Kamat if (lenp) 224581b605aSStephen Rothwell *lenp = pp->length; 225581b605aSStephen Rothwell break; 226581b605aSStephen Rothwell } 227581b605aSStephen Rothwell } 22828d0e36bSThomas Gleixner 22928d0e36bSThomas Gleixner return pp; 23028d0e36bSThomas Gleixner } 23128d0e36bSThomas Gleixner 23228d0e36bSThomas Gleixner struct property *of_find_property(const struct device_node *np, 23328d0e36bSThomas Gleixner const char *name, 23428d0e36bSThomas Gleixner int *lenp) 23528d0e36bSThomas Gleixner { 23628d0e36bSThomas Gleixner struct property *pp; 237d6d3c4e6SThomas Gleixner unsigned long flags; 23828d0e36bSThomas Gleixner 239d6d3c4e6SThomas Gleixner raw_spin_lock_irqsave(&devtree_lock, flags); 24028d0e36bSThomas Gleixner pp = __of_find_property(np, name, lenp); 241d6d3c4e6SThomas Gleixner raw_spin_unlock_irqrestore(&devtree_lock, flags); 242581b605aSStephen Rothwell 243581b605aSStephen Rothwell return pp; 244581b605aSStephen Rothwell } 245581b605aSStephen Rothwell EXPORT_SYMBOL(of_find_property); 246581b605aSStephen Rothwell 2475063e25aSGrant Likely struct device_node *__of_find_all_nodes(struct device_node *prev) 2485063e25aSGrant Likely { 2495063e25aSGrant Likely struct device_node *np; 2505063e25aSGrant Likely if (!prev) { 2515063e25aSGrant Likely np = of_root; 2525063e25aSGrant Likely } else if (prev->child) { 2535063e25aSGrant Likely np = prev->child; 2545063e25aSGrant Likely } else { 2555063e25aSGrant Likely /* Walk back up looking for a sibling, or the end of the structure */ 2565063e25aSGrant Likely np = prev; 2575063e25aSGrant Likely while (np->parent && !np->sibling) 2585063e25aSGrant Likely np = np->parent; 2595063e25aSGrant Likely np = np->sibling; /* Might be null at the end of the tree */ 2605063e25aSGrant Likely } 2615063e25aSGrant Likely return np; 2625063e25aSGrant Likely } 2635063e25aSGrant Likely 264e91edcf5SGrant Likely /** 265e91edcf5SGrant Likely * of_find_all_nodes - Get next node in global list 266e91edcf5SGrant Likely * @prev: Previous node or NULL to start iteration 267e91edcf5SGrant Likely * of_node_put() will be called on it 268e91edcf5SGrant Likely * 269e91edcf5SGrant Likely * Returns a node pointer with refcount incremented, use 270e91edcf5SGrant Likely * of_node_put() on it when done. 271e91edcf5SGrant Likely */ 272e91edcf5SGrant Likely struct device_node *of_find_all_nodes(struct device_node *prev) 273e91edcf5SGrant Likely { 274e91edcf5SGrant Likely struct device_node *np; 275d25d8694SBenjamin Herrenschmidt unsigned long flags; 276e91edcf5SGrant Likely 277d25d8694SBenjamin Herrenschmidt raw_spin_lock_irqsave(&devtree_lock, flags); 2785063e25aSGrant Likely np = __of_find_all_nodes(prev); 2795063e25aSGrant Likely of_node_get(np); 280e91edcf5SGrant Likely of_node_put(prev); 281d25d8694SBenjamin Herrenschmidt raw_spin_unlock_irqrestore(&devtree_lock, flags); 282e91edcf5SGrant Likely return np; 283e91edcf5SGrant Likely } 284e91edcf5SGrant Likely EXPORT_SYMBOL(of_find_all_nodes); 285e91edcf5SGrant Likely 28697e873e5SStephen Rothwell /* 28797e873e5SStephen Rothwell * Find a property with a given name for a given node 28897e873e5SStephen Rothwell * and return the value. 28997e873e5SStephen Rothwell */ 290a25095d4SGrant Likely const void *__of_get_property(const struct device_node *np, 29128d0e36bSThomas Gleixner const char *name, int *lenp) 29228d0e36bSThomas Gleixner { 29328d0e36bSThomas Gleixner struct property *pp = __of_find_property(np, name, lenp); 29428d0e36bSThomas Gleixner 29528d0e36bSThomas Gleixner return pp ? pp->value : NULL; 29628d0e36bSThomas Gleixner } 29728d0e36bSThomas Gleixner 29828d0e36bSThomas Gleixner /* 29928d0e36bSThomas Gleixner * Find a property with a given name for a given node 30028d0e36bSThomas Gleixner * and return the value. 30128d0e36bSThomas Gleixner */ 30297e873e5SStephen Rothwell const void *of_get_property(const struct device_node *np, const char *name, 30397e873e5SStephen Rothwell int *lenp) 30497e873e5SStephen Rothwell { 30597e873e5SStephen Rothwell struct property *pp = of_find_property(np, name, lenp); 30697e873e5SStephen Rothwell 30797e873e5SStephen Rothwell return pp ? pp->value : NULL; 30897e873e5SStephen Rothwell } 30997e873e5SStephen Rothwell EXPORT_SYMBOL(of_get_property); 3100081cbc3SStephen Rothwell 311183912d3SSudeep KarkadaNagesha /* 312183912d3SSudeep KarkadaNagesha * arch_match_cpu_phys_id - Match the given logical CPU and physical id 313183912d3SSudeep KarkadaNagesha * 314183912d3SSudeep KarkadaNagesha * @cpu: logical cpu index of a core/thread 315183912d3SSudeep KarkadaNagesha * @phys_id: physical identifier of a core/thread 316183912d3SSudeep KarkadaNagesha * 317183912d3SSudeep KarkadaNagesha * CPU logical to physical index mapping is architecture specific. 318183912d3SSudeep KarkadaNagesha * However this __weak function provides a default match of physical 319183912d3SSudeep KarkadaNagesha * id to logical cpu index. phys_id provided here is usually values read 320183912d3SSudeep KarkadaNagesha * from the device tree which must match the hardware internal registers. 321183912d3SSudeep KarkadaNagesha * 322183912d3SSudeep KarkadaNagesha * Returns true if the physical identifier and the logical cpu index 323183912d3SSudeep KarkadaNagesha * correspond to the same core/thread, false otherwise. 324183912d3SSudeep KarkadaNagesha */ 325183912d3SSudeep KarkadaNagesha bool __weak arch_match_cpu_phys_id(int cpu, u64 phys_id) 326183912d3SSudeep KarkadaNagesha { 327183912d3SSudeep KarkadaNagesha return (u32)phys_id == cpu; 328183912d3SSudeep KarkadaNagesha } 329183912d3SSudeep KarkadaNagesha 330183912d3SSudeep KarkadaNagesha /** 331183912d3SSudeep KarkadaNagesha * Checks if the given "prop_name" property holds the physical id of the 332183912d3SSudeep KarkadaNagesha * core/thread corresponding to the logical cpu 'cpu'. If 'thread' is not 333183912d3SSudeep KarkadaNagesha * NULL, local thread number within the core is returned in it. 334183912d3SSudeep KarkadaNagesha */ 335183912d3SSudeep KarkadaNagesha static bool __of_find_n_match_cpu_property(struct device_node *cpun, 336183912d3SSudeep KarkadaNagesha const char *prop_name, int cpu, unsigned int *thread) 337183912d3SSudeep KarkadaNagesha { 338183912d3SSudeep KarkadaNagesha const __be32 *cell; 339183912d3SSudeep KarkadaNagesha int ac, prop_len, tid; 340183912d3SSudeep KarkadaNagesha u64 hwid; 341183912d3SSudeep KarkadaNagesha 342183912d3SSudeep KarkadaNagesha ac = of_n_addr_cells(cpun); 343183912d3SSudeep KarkadaNagesha cell = of_get_property(cpun, prop_name, &prop_len); 344f3cea45aSGrant Likely if (!cell || !ac) 345183912d3SSudeep KarkadaNagesha return false; 346f3cea45aSGrant Likely prop_len /= sizeof(*cell) * ac; 347183912d3SSudeep KarkadaNagesha for (tid = 0; tid < prop_len; tid++) { 348183912d3SSudeep KarkadaNagesha hwid = of_read_number(cell, ac); 349183912d3SSudeep KarkadaNagesha if (arch_match_cpu_phys_id(cpu, hwid)) { 350183912d3SSudeep KarkadaNagesha if (thread) 351183912d3SSudeep KarkadaNagesha *thread = tid; 352183912d3SSudeep KarkadaNagesha return true; 353183912d3SSudeep KarkadaNagesha } 354183912d3SSudeep KarkadaNagesha cell += ac; 355183912d3SSudeep KarkadaNagesha } 356183912d3SSudeep KarkadaNagesha return false; 357183912d3SSudeep KarkadaNagesha } 358183912d3SSudeep KarkadaNagesha 359d1cb9d1aSDavid Miller /* 360d1cb9d1aSDavid Miller * arch_find_n_match_cpu_physical_id - See if the given device node is 361d1cb9d1aSDavid Miller * for the cpu corresponding to logical cpu 'cpu'. Return true if so, 362d1cb9d1aSDavid Miller * else false. If 'thread' is non-NULL, the local thread number within the 363d1cb9d1aSDavid Miller * core is returned in it. 364d1cb9d1aSDavid Miller */ 365d1cb9d1aSDavid Miller bool __weak arch_find_n_match_cpu_physical_id(struct device_node *cpun, 366d1cb9d1aSDavid Miller int cpu, unsigned int *thread) 367d1cb9d1aSDavid Miller { 368d1cb9d1aSDavid Miller /* Check for non-standard "ibm,ppc-interrupt-server#s" property 369d1cb9d1aSDavid Miller * for thread ids on PowerPC. If it doesn't exist fallback to 370d1cb9d1aSDavid Miller * standard "reg" property. 371d1cb9d1aSDavid Miller */ 372d1cb9d1aSDavid Miller if (IS_ENABLED(CONFIG_PPC) && 373d1cb9d1aSDavid Miller __of_find_n_match_cpu_property(cpun, 374d1cb9d1aSDavid Miller "ibm,ppc-interrupt-server#s", 375d1cb9d1aSDavid Miller cpu, thread)) 376d1cb9d1aSDavid Miller return true; 377d1cb9d1aSDavid Miller 378510bd068SMasahiro Yamada return __of_find_n_match_cpu_property(cpun, "reg", cpu, thread); 379d1cb9d1aSDavid Miller } 380d1cb9d1aSDavid Miller 381183912d3SSudeep KarkadaNagesha /** 382183912d3SSudeep KarkadaNagesha * of_get_cpu_node - Get device node associated with the given logical CPU 383183912d3SSudeep KarkadaNagesha * 384183912d3SSudeep KarkadaNagesha * @cpu: CPU number(logical index) for which device node is required 385183912d3SSudeep KarkadaNagesha * @thread: if not NULL, local thread number within the physical core is 386183912d3SSudeep KarkadaNagesha * returned 387183912d3SSudeep KarkadaNagesha * 388183912d3SSudeep KarkadaNagesha * The main purpose of this function is to retrieve the device node for the 389183912d3SSudeep KarkadaNagesha * given logical CPU index. It should be used to initialize the of_node in 390183912d3SSudeep KarkadaNagesha * cpu device. Once of_node in cpu device is populated, all the further 391183912d3SSudeep KarkadaNagesha * references can use that instead. 392183912d3SSudeep KarkadaNagesha * 393183912d3SSudeep KarkadaNagesha * CPU logical to physical index mapping is architecture specific and is built 394183912d3SSudeep KarkadaNagesha * before booting secondary cores. This function uses arch_match_cpu_phys_id 395183912d3SSudeep KarkadaNagesha * which can be overridden by architecture specific implementation. 396183912d3SSudeep KarkadaNagesha * 397183912d3SSudeep KarkadaNagesha * Returns a node pointer for the logical cpu if found, else NULL. 398183912d3SSudeep KarkadaNagesha */ 399183912d3SSudeep KarkadaNagesha struct device_node *of_get_cpu_node(int cpu, unsigned int *thread) 400183912d3SSudeep KarkadaNagesha { 401d1cb9d1aSDavid Miller struct device_node *cpun; 402183912d3SSudeep KarkadaNagesha 403d1cb9d1aSDavid Miller for_each_node_by_type(cpun, "cpu") { 404d1cb9d1aSDavid Miller if (arch_find_n_match_cpu_physical_id(cpun, cpu, thread)) 405183912d3SSudeep KarkadaNagesha return cpun; 406183912d3SSudeep KarkadaNagesha } 407183912d3SSudeep KarkadaNagesha return NULL; 408183912d3SSudeep KarkadaNagesha } 409183912d3SSudeep KarkadaNagesha EXPORT_SYMBOL(of_get_cpu_node); 410183912d3SSudeep KarkadaNagesha 411215a14cfSKevin Hao /** 412215a14cfSKevin Hao * __of_device_is_compatible() - Check if the node matches given constraints 413215a14cfSKevin Hao * @device: pointer to node 414215a14cfSKevin Hao * @compat: required compatible string, NULL or "" for any match 415215a14cfSKevin Hao * @type: required device_type value, NULL or "" for any match 416215a14cfSKevin Hao * @name: required node name, NULL or "" for any match 417215a14cfSKevin Hao * 418215a14cfSKevin Hao * Checks if the given @compat, @type and @name strings match the 419215a14cfSKevin Hao * properties of the given @device. A constraints can be skipped by 420215a14cfSKevin Hao * passing NULL or an empty string as the constraint. 421215a14cfSKevin Hao * 422215a14cfSKevin Hao * Returns 0 for no match, and a positive integer on match. The return 423215a14cfSKevin Hao * value is a relative score with larger values indicating better 424215a14cfSKevin Hao * matches. The score is weighted for the most specific compatible value 425215a14cfSKevin Hao * to get the highest score. Matching type is next, followed by matching 426215a14cfSKevin Hao * name. Practically speaking, this results in the following priority 427215a14cfSKevin Hao * order for matches: 428215a14cfSKevin Hao * 429215a14cfSKevin Hao * 1. specific compatible && type && name 430215a14cfSKevin Hao * 2. specific compatible && type 431215a14cfSKevin Hao * 3. specific compatible && name 432215a14cfSKevin Hao * 4. specific compatible 433215a14cfSKevin Hao * 5. general compatible && type && name 434215a14cfSKevin Hao * 6. general compatible && type 435215a14cfSKevin Hao * 7. general compatible && name 436215a14cfSKevin Hao * 8. general compatible 437215a14cfSKevin Hao * 9. type && name 438215a14cfSKevin Hao * 10. type 439215a14cfSKevin Hao * 11. name 4400081cbc3SStephen Rothwell */ 44128d0e36bSThomas Gleixner static int __of_device_is_compatible(const struct device_node *device, 442215a14cfSKevin Hao const char *compat, const char *type, const char *name) 4430081cbc3SStephen Rothwell { 444215a14cfSKevin Hao struct property *prop; 4450081cbc3SStephen Rothwell const char *cp; 446215a14cfSKevin Hao int index = 0, score = 0; 4470081cbc3SStephen Rothwell 448215a14cfSKevin Hao /* Compatible match has highest priority */ 449215a14cfSKevin Hao if (compat && compat[0]) { 450215a14cfSKevin Hao prop = __of_find_property(device, "compatible", NULL); 451215a14cfSKevin Hao for (cp = of_prop_next_string(prop, NULL); cp; 452215a14cfSKevin Hao cp = of_prop_next_string(prop, cp), index++) { 453215a14cfSKevin Hao if (of_compat_cmp(cp, compat, strlen(compat)) == 0) { 454215a14cfSKevin Hao score = INT_MAX/2 - (index << 2); 455215a14cfSKevin Hao break; 456215a14cfSKevin Hao } 457215a14cfSKevin Hao } 458215a14cfSKevin Hao if (!score) 4590081cbc3SStephen Rothwell return 0; 4600081cbc3SStephen Rothwell } 4610081cbc3SStephen Rothwell 462215a14cfSKevin Hao /* Matching type is better than matching name */ 463215a14cfSKevin Hao if (type && type[0]) { 464215a14cfSKevin Hao if (!device->type || of_node_cmp(type, device->type)) 4650081cbc3SStephen Rothwell return 0; 466215a14cfSKevin Hao score += 2; 467215a14cfSKevin Hao } 468215a14cfSKevin Hao 469215a14cfSKevin Hao /* Matching name is a bit better than not */ 470215a14cfSKevin Hao if (name && name[0]) { 471215a14cfSKevin Hao if (!device->name || of_node_cmp(name, device->name)) 472215a14cfSKevin Hao return 0; 473215a14cfSKevin Hao score++; 474215a14cfSKevin Hao } 475215a14cfSKevin Hao 476215a14cfSKevin Hao return score; 4770081cbc3SStephen Rothwell } 47828d0e36bSThomas Gleixner 47928d0e36bSThomas Gleixner /** Checks if the given "compat" string matches one of the strings in 48028d0e36bSThomas Gleixner * the device's "compatible" property 48128d0e36bSThomas Gleixner */ 48228d0e36bSThomas Gleixner int of_device_is_compatible(const struct device_node *device, 48328d0e36bSThomas Gleixner const char *compat) 48428d0e36bSThomas Gleixner { 485d6d3c4e6SThomas Gleixner unsigned long flags; 48628d0e36bSThomas Gleixner int res; 48728d0e36bSThomas Gleixner 488d6d3c4e6SThomas Gleixner raw_spin_lock_irqsave(&devtree_lock, flags); 489215a14cfSKevin Hao res = __of_device_is_compatible(device, compat, NULL, NULL); 490d6d3c4e6SThomas Gleixner raw_spin_unlock_irqrestore(&devtree_lock, flags); 49128d0e36bSThomas Gleixner return res; 49228d0e36bSThomas Gleixner } 4930081cbc3SStephen Rothwell EXPORT_SYMBOL(of_device_is_compatible); 494e679c5f4SStephen Rothwell 495e679c5f4SStephen Rothwell /** 49671a157e8SGrant Likely * of_machine_is_compatible - Test root of device tree for a given compatible value 4971f43cfb9SGrant Likely * @compat: compatible string to look for in root node's compatible property. 4981f43cfb9SGrant Likely * 49925c7a1deSKevin Cernekee * Returns a positive integer if the root node has the given value in its 5001f43cfb9SGrant Likely * compatible property. 5011f43cfb9SGrant Likely */ 50271a157e8SGrant Likely int of_machine_is_compatible(const char *compat) 5031f43cfb9SGrant Likely { 5041f43cfb9SGrant Likely struct device_node *root; 5051f43cfb9SGrant Likely int rc = 0; 5061f43cfb9SGrant Likely 5071f43cfb9SGrant Likely root = of_find_node_by_path("/"); 5081f43cfb9SGrant Likely if (root) { 5091f43cfb9SGrant Likely rc = of_device_is_compatible(root, compat); 5101f43cfb9SGrant Likely of_node_put(root); 5111f43cfb9SGrant Likely } 5121f43cfb9SGrant Likely return rc; 5131f43cfb9SGrant Likely } 51471a157e8SGrant Likely EXPORT_SYMBOL(of_machine_is_compatible); 5151f43cfb9SGrant Likely 5161f43cfb9SGrant Likely /** 517c31a0c05SStephen Warren * __of_device_is_available - check if a device is available for use 518834d97d4SJosh Boyer * 519c31a0c05SStephen Warren * @device: Node to check for availability, with locks already held 520834d97d4SJosh Boyer * 52153a4ab96SKevin Cernekee * Returns true if the status property is absent or set to "okay" or "ok", 52253a4ab96SKevin Cernekee * false otherwise 523834d97d4SJosh Boyer */ 52453a4ab96SKevin Cernekee static bool __of_device_is_available(const struct device_node *device) 525834d97d4SJosh Boyer { 526834d97d4SJosh Boyer const char *status; 527834d97d4SJosh Boyer int statlen; 528834d97d4SJosh Boyer 52942ccd781SXiubo Li if (!device) 53053a4ab96SKevin Cernekee return false; 53142ccd781SXiubo Li 532c31a0c05SStephen Warren status = __of_get_property(device, "status", &statlen); 533834d97d4SJosh Boyer if (status == NULL) 53453a4ab96SKevin Cernekee return true; 535834d97d4SJosh Boyer 536834d97d4SJosh Boyer if (statlen > 0) { 537834d97d4SJosh Boyer if (!strcmp(status, "okay") || !strcmp(status, "ok")) 53853a4ab96SKevin Cernekee return true; 539834d97d4SJosh Boyer } 540834d97d4SJosh Boyer 54153a4ab96SKevin Cernekee return false; 542834d97d4SJosh Boyer } 543c31a0c05SStephen Warren 544c31a0c05SStephen Warren /** 545c31a0c05SStephen Warren * of_device_is_available - check if a device is available for use 546c31a0c05SStephen Warren * 547c31a0c05SStephen Warren * @device: Node to check for availability 548c31a0c05SStephen Warren * 54953a4ab96SKevin Cernekee * Returns true if the status property is absent or set to "okay" or "ok", 55053a4ab96SKevin Cernekee * false otherwise 551c31a0c05SStephen Warren */ 55253a4ab96SKevin Cernekee bool of_device_is_available(const struct device_node *device) 553c31a0c05SStephen Warren { 554c31a0c05SStephen Warren unsigned long flags; 55553a4ab96SKevin Cernekee bool res; 556c31a0c05SStephen Warren 557c31a0c05SStephen Warren raw_spin_lock_irqsave(&devtree_lock, flags); 558c31a0c05SStephen Warren res = __of_device_is_available(device); 559c31a0c05SStephen Warren raw_spin_unlock_irqrestore(&devtree_lock, flags); 560c31a0c05SStephen Warren return res; 561c31a0c05SStephen Warren 562c31a0c05SStephen Warren } 563834d97d4SJosh Boyer EXPORT_SYMBOL(of_device_is_available); 564834d97d4SJosh Boyer 565834d97d4SJosh Boyer /** 56637786c7fSKevin Cernekee * of_device_is_big_endian - check if a device has BE registers 56737786c7fSKevin Cernekee * 56837786c7fSKevin Cernekee * @device: Node to check for endianness 56937786c7fSKevin Cernekee * 57037786c7fSKevin Cernekee * Returns true if the device has a "big-endian" property, or if the kernel 57137786c7fSKevin Cernekee * was compiled for BE *and* the device has a "native-endian" property. 57237786c7fSKevin Cernekee * Returns false otherwise. 57337786c7fSKevin Cernekee * 57437786c7fSKevin Cernekee * Callers would nominally use ioread32be/iowrite32be if 57537786c7fSKevin Cernekee * of_device_is_big_endian() == true, or readl/writel otherwise. 57637786c7fSKevin Cernekee */ 57737786c7fSKevin Cernekee bool of_device_is_big_endian(const struct device_node *device) 57837786c7fSKevin Cernekee { 57937786c7fSKevin Cernekee if (of_property_read_bool(device, "big-endian")) 58037786c7fSKevin Cernekee return true; 58137786c7fSKevin Cernekee if (IS_ENABLED(CONFIG_CPU_BIG_ENDIAN) && 58237786c7fSKevin Cernekee of_property_read_bool(device, "native-endian")) 58337786c7fSKevin Cernekee return true; 58437786c7fSKevin Cernekee return false; 58537786c7fSKevin Cernekee } 58637786c7fSKevin Cernekee EXPORT_SYMBOL(of_device_is_big_endian); 58737786c7fSKevin Cernekee 58837786c7fSKevin Cernekee /** 589e679c5f4SStephen Rothwell * of_get_parent - Get a node's parent if any 590e679c5f4SStephen Rothwell * @node: Node to get parent 591e679c5f4SStephen Rothwell * 592e679c5f4SStephen Rothwell * Returns a node pointer with refcount incremented, use 593e679c5f4SStephen Rothwell * of_node_put() on it when done. 594e679c5f4SStephen Rothwell */ 595e679c5f4SStephen Rothwell struct device_node *of_get_parent(const struct device_node *node) 596e679c5f4SStephen Rothwell { 597e679c5f4SStephen Rothwell struct device_node *np; 598d6d3c4e6SThomas Gleixner unsigned long flags; 599e679c5f4SStephen Rothwell 600e679c5f4SStephen Rothwell if (!node) 601e679c5f4SStephen Rothwell return NULL; 602e679c5f4SStephen Rothwell 603d6d3c4e6SThomas Gleixner raw_spin_lock_irqsave(&devtree_lock, flags); 604e679c5f4SStephen Rothwell np = of_node_get(node->parent); 605d6d3c4e6SThomas Gleixner raw_spin_unlock_irqrestore(&devtree_lock, flags); 606e679c5f4SStephen Rothwell return np; 607e679c5f4SStephen Rothwell } 608e679c5f4SStephen Rothwell EXPORT_SYMBOL(of_get_parent); 609d1cd355aSStephen Rothwell 610d1cd355aSStephen Rothwell /** 611f4eb0107SMichael Ellerman * of_get_next_parent - Iterate to a node's parent 612f4eb0107SMichael Ellerman * @node: Node to get parent of 613f4eb0107SMichael Ellerman * 614f4eb0107SMichael Ellerman * This is like of_get_parent() except that it drops the 615f4eb0107SMichael Ellerman * refcount on the passed node, making it suitable for iterating 616f4eb0107SMichael Ellerman * through a node's parents. 617f4eb0107SMichael Ellerman * 618f4eb0107SMichael Ellerman * Returns a node pointer with refcount incremented, use 619f4eb0107SMichael Ellerman * of_node_put() on it when done. 620f4eb0107SMichael Ellerman */ 621f4eb0107SMichael Ellerman struct device_node *of_get_next_parent(struct device_node *node) 622f4eb0107SMichael Ellerman { 623f4eb0107SMichael Ellerman struct device_node *parent; 624d6d3c4e6SThomas Gleixner unsigned long flags; 625f4eb0107SMichael Ellerman 626f4eb0107SMichael Ellerman if (!node) 627f4eb0107SMichael Ellerman return NULL; 628f4eb0107SMichael Ellerman 629d6d3c4e6SThomas Gleixner raw_spin_lock_irqsave(&devtree_lock, flags); 630f4eb0107SMichael Ellerman parent = of_node_get(node->parent); 631f4eb0107SMichael Ellerman of_node_put(node); 632d6d3c4e6SThomas Gleixner raw_spin_unlock_irqrestore(&devtree_lock, flags); 633f4eb0107SMichael Ellerman return parent; 634f4eb0107SMichael Ellerman } 6356695be68SGuennadi Liakhovetski EXPORT_SYMBOL(of_get_next_parent); 636f4eb0107SMichael Ellerman 6370d0e02d6SGrant Likely static struct device_node *__of_get_next_child(const struct device_node *node, 6380d0e02d6SGrant Likely struct device_node *prev) 6390d0e02d6SGrant Likely { 6400d0e02d6SGrant Likely struct device_node *next; 6410d0e02d6SGrant Likely 64243cb4367SFlorian Fainelli if (!node) 64343cb4367SFlorian Fainelli return NULL; 64443cb4367SFlorian Fainelli 6450d0e02d6SGrant Likely next = prev ? prev->sibling : node->child; 6460d0e02d6SGrant Likely for (; next; next = next->sibling) 6470d0e02d6SGrant Likely if (of_node_get(next)) 6480d0e02d6SGrant Likely break; 6490d0e02d6SGrant Likely of_node_put(prev); 6500d0e02d6SGrant Likely return next; 6510d0e02d6SGrant Likely } 6520d0e02d6SGrant Likely #define __for_each_child_of_node(parent, child) \ 6530d0e02d6SGrant Likely for (child = __of_get_next_child(parent, NULL); child != NULL; \ 6540d0e02d6SGrant Likely child = __of_get_next_child(parent, child)) 6550d0e02d6SGrant Likely 656f4eb0107SMichael Ellerman /** 657d1cd355aSStephen Rothwell * of_get_next_child - Iterate a node childs 658d1cd355aSStephen Rothwell * @node: parent node 659d1cd355aSStephen Rothwell * @prev: previous child of the parent node, or NULL to get first 660d1cd355aSStephen Rothwell * 66164808273SBaruch Siach * Returns a node pointer with refcount incremented, use of_node_put() on 66264808273SBaruch Siach * it when done. Returns NULL when prev is the last child. Decrements the 66364808273SBaruch Siach * refcount of prev. 664d1cd355aSStephen Rothwell */ 665d1cd355aSStephen Rothwell struct device_node *of_get_next_child(const struct device_node *node, 666d1cd355aSStephen Rothwell struct device_node *prev) 667d1cd355aSStephen Rothwell { 668d1cd355aSStephen Rothwell struct device_node *next; 669d6d3c4e6SThomas Gleixner unsigned long flags; 670d1cd355aSStephen Rothwell 671d6d3c4e6SThomas Gleixner raw_spin_lock_irqsave(&devtree_lock, flags); 6720d0e02d6SGrant Likely next = __of_get_next_child(node, prev); 673d6d3c4e6SThomas Gleixner raw_spin_unlock_irqrestore(&devtree_lock, flags); 674d1cd355aSStephen Rothwell return next; 675d1cd355aSStephen Rothwell } 676d1cd355aSStephen Rothwell EXPORT_SYMBOL(of_get_next_child); 6771ef4d424SStephen Rothwell 6781ef4d424SStephen Rothwell /** 6793296193dSTimur Tabi * of_get_next_available_child - Find the next available child node 6803296193dSTimur Tabi * @node: parent node 6813296193dSTimur Tabi * @prev: previous child of the parent node, or NULL to get first 6823296193dSTimur Tabi * 6833296193dSTimur Tabi * This function is like of_get_next_child(), except that it 6843296193dSTimur Tabi * automatically skips any disabled nodes (i.e. status = "disabled"). 6853296193dSTimur Tabi */ 6863296193dSTimur Tabi struct device_node *of_get_next_available_child(const struct device_node *node, 6873296193dSTimur Tabi struct device_node *prev) 6883296193dSTimur Tabi { 6893296193dSTimur Tabi struct device_node *next; 690d25d8694SBenjamin Herrenschmidt unsigned long flags; 6913296193dSTimur Tabi 69243cb4367SFlorian Fainelli if (!node) 69343cb4367SFlorian Fainelli return NULL; 69443cb4367SFlorian Fainelli 695d25d8694SBenjamin Herrenschmidt raw_spin_lock_irqsave(&devtree_lock, flags); 6963296193dSTimur Tabi next = prev ? prev->sibling : node->child; 6973296193dSTimur Tabi for (; next; next = next->sibling) { 698c31a0c05SStephen Warren if (!__of_device_is_available(next)) 6993296193dSTimur Tabi continue; 7003296193dSTimur Tabi if (of_node_get(next)) 7013296193dSTimur Tabi break; 7023296193dSTimur Tabi } 7033296193dSTimur Tabi of_node_put(prev); 704d25d8694SBenjamin Herrenschmidt raw_spin_unlock_irqrestore(&devtree_lock, flags); 7053296193dSTimur Tabi return next; 7063296193dSTimur Tabi } 7073296193dSTimur Tabi EXPORT_SYMBOL(of_get_next_available_child); 7083296193dSTimur Tabi 7093296193dSTimur Tabi /** 7109c19761aSSrinivas Kandagatla * of_get_child_by_name - Find the child node by name for a given parent 7119c19761aSSrinivas Kandagatla * @node: parent node 7129c19761aSSrinivas Kandagatla * @name: child name to look for. 7139c19761aSSrinivas Kandagatla * 7149c19761aSSrinivas Kandagatla * This function looks for child node for given matching name 7159c19761aSSrinivas Kandagatla * 7169c19761aSSrinivas Kandagatla * Returns a node pointer if found, with refcount incremented, use 7179c19761aSSrinivas Kandagatla * of_node_put() on it when done. 7189c19761aSSrinivas Kandagatla * Returns NULL if node is not found. 7199c19761aSSrinivas Kandagatla */ 7209c19761aSSrinivas Kandagatla struct device_node *of_get_child_by_name(const struct device_node *node, 7219c19761aSSrinivas Kandagatla const char *name) 7229c19761aSSrinivas Kandagatla { 7239c19761aSSrinivas Kandagatla struct device_node *child; 7249c19761aSSrinivas Kandagatla 7259c19761aSSrinivas Kandagatla for_each_child_of_node(node, child) 7269c19761aSSrinivas Kandagatla if (child->name && (of_node_cmp(child->name, name) == 0)) 7279c19761aSSrinivas Kandagatla break; 7289c19761aSSrinivas Kandagatla return child; 7299c19761aSSrinivas Kandagatla } 7309c19761aSSrinivas Kandagatla EXPORT_SYMBOL(of_get_child_by_name); 7319c19761aSSrinivas Kandagatla 732c22e650eSGrant Likely static struct device_node *__of_find_node_by_path(struct device_node *parent, 733c22e650eSGrant Likely const char *path) 734c22e650eSGrant Likely { 735c22e650eSGrant Likely struct device_node *child; 736106937e8SLeif Lindholm int len; 737c22e650eSGrant Likely 738721a09e9SBrian Norris len = strcspn(path, "/:"); 739c22e650eSGrant Likely if (!len) 740c22e650eSGrant Likely return NULL; 741c22e650eSGrant Likely 742c22e650eSGrant Likely __for_each_child_of_node(parent, child) { 743c22e650eSGrant Likely const char *name = strrchr(child->full_name, '/'); 744c22e650eSGrant Likely if (WARN(!name, "malformed device_node %s\n", child->full_name)) 745c22e650eSGrant Likely continue; 746c22e650eSGrant Likely name++; 747c22e650eSGrant Likely if (strncmp(path, name, len) == 0 && (strlen(name) == len)) 748c22e650eSGrant Likely return child; 749c22e650eSGrant Likely } 750c22e650eSGrant Likely return NULL; 751c22e650eSGrant Likely } 752c22e650eSGrant Likely 7539c19761aSSrinivas Kandagatla /** 75475c28c09SLeif Lindholm * of_find_node_opts_by_path - Find a node matching a full OF path 755c22e650eSGrant Likely * @path: Either the full path to match, or if the path does not 756c22e650eSGrant Likely * start with '/', the name of a property of the /aliases 757c22e650eSGrant Likely * node (an alias). In the case of an alias, the node 758c22e650eSGrant Likely * matching the alias' value will be returned. 75975c28c09SLeif Lindholm * @opts: Address of a pointer into which to store the start of 76075c28c09SLeif Lindholm * an options string appended to the end of the path with 76175c28c09SLeif Lindholm * a ':' separator. 762c22e650eSGrant Likely * 763c22e650eSGrant Likely * Valid paths: 764c22e650eSGrant Likely * /foo/bar Full path 765c22e650eSGrant Likely * foo Valid alias 766c22e650eSGrant Likely * foo/bar Valid alias + relative path 7671ef4d424SStephen Rothwell * 7681ef4d424SStephen Rothwell * Returns a node pointer with refcount incremented, use 7691ef4d424SStephen Rothwell * of_node_put() on it when done. 7701ef4d424SStephen Rothwell */ 77175c28c09SLeif Lindholm struct device_node *of_find_node_opts_by_path(const char *path, const char **opts) 7721ef4d424SStephen Rothwell { 773c22e650eSGrant Likely struct device_node *np = NULL; 774c22e650eSGrant Likely struct property *pp; 775d6d3c4e6SThomas Gleixner unsigned long flags; 77675c28c09SLeif Lindholm const char *separator = strchr(path, ':'); 77775c28c09SLeif Lindholm 77875c28c09SLeif Lindholm if (opts) 77975c28c09SLeif Lindholm *opts = separator ? separator + 1 : NULL; 7801ef4d424SStephen Rothwell 781c22e650eSGrant Likely if (strcmp(path, "/") == 0) 7825063e25aSGrant Likely return of_node_get(of_root); 783c22e650eSGrant Likely 784c22e650eSGrant Likely /* The path could begin with an alias */ 785c22e650eSGrant Likely if (*path != '/') { 786106937e8SLeif Lindholm int len; 787106937e8SLeif Lindholm const char *p = separator; 788106937e8SLeif Lindholm 789106937e8SLeif Lindholm if (!p) 790106937e8SLeif Lindholm p = strchrnul(path, '/'); 791106937e8SLeif Lindholm len = p - path; 792c22e650eSGrant Likely 793c22e650eSGrant Likely /* of_aliases must not be NULL */ 794c22e650eSGrant Likely if (!of_aliases) 795c22e650eSGrant Likely return NULL; 796c22e650eSGrant Likely 797c22e650eSGrant Likely for_each_property_of_node(of_aliases, pp) { 798c22e650eSGrant Likely if (strlen(pp->name) == len && !strncmp(pp->name, path, len)) { 799c22e650eSGrant Likely np = of_find_node_by_path(pp->value); 8001ef4d424SStephen Rothwell break; 8011ef4d424SStephen Rothwell } 802c22e650eSGrant Likely } 803c22e650eSGrant Likely if (!np) 804c22e650eSGrant Likely return NULL; 805c22e650eSGrant Likely path = p; 806c22e650eSGrant Likely } 807c22e650eSGrant Likely 808c22e650eSGrant Likely /* Step down the tree matching path components */ 809c22e650eSGrant Likely raw_spin_lock_irqsave(&devtree_lock, flags); 810c22e650eSGrant Likely if (!np) 8115063e25aSGrant Likely np = of_node_get(of_root); 812c22e650eSGrant Likely while (np && *path == '/') { 813c22e650eSGrant Likely path++; /* Increment past '/' delimiter */ 814c22e650eSGrant Likely np = __of_find_node_by_path(np, path); 815c22e650eSGrant Likely path = strchrnul(path, '/'); 816106937e8SLeif Lindholm if (separator && separator < path) 817106937e8SLeif Lindholm break; 818c22e650eSGrant Likely } 819d6d3c4e6SThomas Gleixner raw_spin_unlock_irqrestore(&devtree_lock, flags); 8201ef4d424SStephen Rothwell return np; 8211ef4d424SStephen Rothwell } 82275c28c09SLeif Lindholm EXPORT_SYMBOL(of_find_node_opts_by_path); 8231ef4d424SStephen Rothwell 8241ef4d424SStephen Rothwell /** 8251ef4d424SStephen Rothwell * of_find_node_by_name - Find a node by its "name" property 8261ef4d424SStephen Rothwell * @from: The node to start searching from or NULL, the node 8271ef4d424SStephen Rothwell * you pass will not be searched, only the next one 8281ef4d424SStephen Rothwell * will; typically, you pass what the previous call 8291ef4d424SStephen Rothwell * returned. of_node_put() will be called on it 8301ef4d424SStephen Rothwell * @name: The name string to match against 8311ef4d424SStephen Rothwell * 8321ef4d424SStephen Rothwell * Returns a node pointer with refcount incremented, use 8331ef4d424SStephen Rothwell * of_node_put() on it when done. 8341ef4d424SStephen Rothwell */ 8351ef4d424SStephen Rothwell struct device_node *of_find_node_by_name(struct device_node *from, 8361ef4d424SStephen Rothwell const char *name) 8371ef4d424SStephen Rothwell { 8381ef4d424SStephen Rothwell struct device_node *np; 839d6d3c4e6SThomas Gleixner unsigned long flags; 8401ef4d424SStephen Rothwell 841d6d3c4e6SThomas Gleixner raw_spin_lock_irqsave(&devtree_lock, flags); 8425063e25aSGrant Likely for_each_of_allnodes_from(from, np) 8431ef4d424SStephen Rothwell if (np->name && (of_node_cmp(np->name, name) == 0) 8441ef4d424SStephen Rothwell && of_node_get(np)) 8451ef4d424SStephen Rothwell break; 8461ef4d424SStephen Rothwell of_node_put(from); 847d6d3c4e6SThomas Gleixner raw_spin_unlock_irqrestore(&devtree_lock, flags); 8481ef4d424SStephen Rothwell return np; 8491ef4d424SStephen Rothwell } 8501ef4d424SStephen Rothwell EXPORT_SYMBOL(of_find_node_by_name); 8511ef4d424SStephen Rothwell 8521ef4d424SStephen Rothwell /** 8531ef4d424SStephen Rothwell * of_find_node_by_type - Find a node by its "device_type" property 8541ef4d424SStephen Rothwell * @from: The node to start searching from, or NULL to start searching 8551ef4d424SStephen Rothwell * the entire device tree. The node you pass will not be 8561ef4d424SStephen Rothwell * searched, only the next one will; typically, you pass 8571ef4d424SStephen Rothwell * what the previous call returned. of_node_put() will be 8581ef4d424SStephen Rothwell * called on from for you. 8591ef4d424SStephen Rothwell * @type: The type string to match against 8601ef4d424SStephen Rothwell * 8611ef4d424SStephen Rothwell * Returns a node pointer with refcount incremented, use 8621ef4d424SStephen Rothwell * of_node_put() on it when done. 8631ef4d424SStephen Rothwell */ 8641ef4d424SStephen Rothwell struct device_node *of_find_node_by_type(struct device_node *from, 8651ef4d424SStephen Rothwell const char *type) 8661ef4d424SStephen Rothwell { 8671ef4d424SStephen Rothwell struct device_node *np; 868d6d3c4e6SThomas Gleixner unsigned long flags; 8691ef4d424SStephen Rothwell 870d6d3c4e6SThomas Gleixner raw_spin_lock_irqsave(&devtree_lock, flags); 8715063e25aSGrant Likely for_each_of_allnodes_from(from, np) 8721ef4d424SStephen Rothwell if (np->type && (of_node_cmp(np->type, type) == 0) 8731ef4d424SStephen Rothwell && of_node_get(np)) 8741ef4d424SStephen Rothwell break; 8751ef4d424SStephen Rothwell of_node_put(from); 876d6d3c4e6SThomas Gleixner raw_spin_unlock_irqrestore(&devtree_lock, flags); 8771ef4d424SStephen Rothwell return np; 8781ef4d424SStephen Rothwell } 8791ef4d424SStephen Rothwell EXPORT_SYMBOL(of_find_node_by_type); 8801ef4d424SStephen Rothwell 8811ef4d424SStephen Rothwell /** 8821ef4d424SStephen Rothwell * of_find_compatible_node - Find a node based on type and one of the 8831ef4d424SStephen Rothwell * tokens in its "compatible" property 8841ef4d424SStephen Rothwell * @from: The node to start searching from or NULL, the node 8851ef4d424SStephen Rothwell * you pass will not be searched, only the next one 8861ef4d424SStephen Rothwell * will; typically, you pass what the previous call 8871ef4d424SStephen Rothwell * returned. of_node_put() will be called on it 8881ef4d424SStephen Rothwell * @type: The type string to match "device_type" or NULL to ignore 8891ef4d424SStephen Rothwell * @compatible: The string to match to one of the tokens in the device 8901ef4d424SStephen Rothwell * "compatible" list. 8911ef4d424SStephen Rothwell * 8921ef4d424SStephen Rothwell * Returns a node pointer with refcount incremented, use 8931ef4d424SStephen Rothwell * of_node_put() on it when done. 8941ef4d424SStephen Rothwell */ 8951ef4d424SStephen Rothwell struct device_node *of_find_compatible_node(struct device_node *from, 8961ef4d424SStephen Rothwell const char *type, const char *compatible) 8971ef4d424SStephen Rothwell { 8981ef4d424SStephen Rothwell struct device_node *np; 899d6d3c4e6SThomas Gleixner unsigned long flags; 9001ef4d424SStephen Rothwell 901d6d3c4e6SThomas Gleixner raw_spin_lock_irqsave(&devtree_lock, flags); 9025063e25aSGrant Likely for_each_of_allnodes_from(from, np) 903215a14cfSKevin Hao if (__of_device_is_compatible(np, compatible, type, NULL) && 90428d0e36bSThomas Gleixner of_node_get(np)) 9051ef4d424SStephen Rothwell break; 9061ef4d424SStephen Rothwell of_node_put(from); 907d6d3c4e6SThomas Gleixner raw_spin_unlock_irqrestore(&devtree_lock, flags); 9081ef4d424SStephen Rothwell return np; 9091ef4d424SStephen Rothwell } 9101ef4d424SStephen Rothwell EXPORT_SYMBOL(of_find_compatible_node); 911283029d1SGrant Likely 912283029d1SGrant Likely /** 9131e291b14SMichael Ellerman * of_find_node_with_property - Find a node which has a property with 9141e291b14SMichael Ellerman * the given name. 9151e291b14SMichael Ellerman * @from: The node to start searching from or NULL, the node 9161e291b14SMichael Ellerman * you pass will not be searched, only the next one 9171e291b14SMichael Ellerman * will; typically, you pass what the previous call 9181e291b14SMichael Ellerman * returned. of_node_put() will be called on it 9191e291b14SMichael Ellerman * @prop_name: The name of the property to look for. 9201e291b14SMichael Ellerman * 9211e291b14SMichael Ellerman * Returns a node pointer with refcount incremented, use 9221e291b14SMichael Ellerman * of_node_put() on it when done. 9231e291b14SMichael Ellerman */ 9241e291b14SMichael Ellerman struct device_node *of_find_node_with_property(struct device_node *from, 9251e291b14SMichael Ellerman const char *prop_name) 9261e291b14SMichael Ellerman { 9271e291b14SMichael Ellerman struct device_node *np; 9281e291b14SMichael Ellerman struct property *pp; 929d6d3c4e6SThomas Gleixner unsigned long flags; 9301e291b14SMichael Ellerman 931d6d3c4e6SThomas Gleixner raw_spin_lock_irqsave(&devtree_lock, flags); 9325063e25aSGrant Likely for_each_of_allnodes_from(from, np) { 933a3a7cab1SSachin Kamat for (pp = np->properties; pp; pp = pp->next) { 9341e291b14SMichael Ellerman if (of_prop_cmp(pp->name, prop_name) == 0) { 9351e291b14SMichael Ellerman of_node_get(np); 9361e291b14SMichael Ellerman goto out; 9371e291b14SMichael Ellerman } 9381e291b14SMichael Ellerman } 9391e291b14SMichael Ellerman } 9401e291b14SMichael Ellerman out: 9411e291b14SMichael Ellerman of_node_put(from); 942d6d3c4e6SThomas Gleixner raw_spin_unlock_irqrestore(&devtree_lock, flags); 9431e291b14SMichael Ellerman return np; 9441e291b14SMichael Ellerman } 9451e291b14SMichael Ellerman EXPORT_SYMBOL(of_find_node_with_property); 9461e291b14SMichael Ellerman 94728d0e36bSThomas Gleixner static 94828d0e36bSThomas Gleixner const struct of_device_id *__of_match_node(const struct of_device_id *matches, 949283029d1SGrant Likely const struct device_node *node) 950283029d1SGrant Likely { 951215a14cfSKevin Hao const struct of_device_id *best_match = NULL; 952215a14cfSKevin Hao int score, best_score = 0; 953215a14cfSKevin Hao 954a52f07ecSGrant Likely if (!matches) 955a52f07ecSGrant Likely return NULL; 956a52f07ecSGrant Likely 957215a14cfSKevin Hao for (; matches->name[0] || matches->type[0] || matches->compatible[0]; matches++) { 958215a14cfSKevin Hao score = __of_device_is_compatible(node, matches->compatible, 959215a14cfSKevin Hao matches->type, matches->name); 960215a14cfSKevin Hao if (score > best_score) { 961215a14cfSKevin Hao best_match = matches; 962215a14cfSKevin Hao best_score = score; 963283029d1SGrant Likely } 964215a14cfSKevin Hao } 965215a14cfSKevin Hao 966215a14cfSKevin Hao return best_match; 967283029d1SGrant Likely } 96828d0e36bSThomas Gleixner 96928d0e36bSThomas Gleixner /** 970c50949d3SGeert Uytterhoeven * of_match_node - Tell if a device_node has a matching of_match structure 97128d0e36bSThomas Gleixner * @matches: array of of device match structures to search in 97228d0e36bSThomas Gleixner * @node: the of device structure to match against 97328d0e36bSThomas Gleixner * 97471c5498eSKevin Hao * Low level utility function used by device matching. 97528d0e36bSThomas Gleixner */ 97628d0e36bSThomas Gleixner const struct of_device_id *of_match_node(const struct of_device_id *matches, 97728d0e36bSThomas Gleixner const struct device_node *node) 97828d0e36bSThomas Gleixner { 97928d0e36bSThomas Gleixner const struct of_device_id *match; 980d6d3c4e6SThomas Gleixner unsigned long flags; 98128d0e36bSThomas Gleixner 982d6d3c4e6SThomas Gleixner raw_spin_lock_irqsave(&devtree_lock, flags); 98328d0e36bSThomas Gleixner match = __of_match_node(matches, node); 984d6d3c4e6SThomas Gleixner raw_spin_unlock_irqrestore(&devtree_lock, flags); 98528d0e36bSThomas Gleixner return match; 98628d0e36bSThomas Gleixner } 987283029d1SGrant Likely EXPORT_SYMBOL(of_match_node); 988283029d1SGrant Likely 989283029d1SGrant Likely /** 99050c8af4cSStephen Warren * of_find_matching_node_and_match - Find a node based on an of_device_id 99150c8af4cSStephen Warren * match table. 992283029d1SGrant Likely * @from: The node to start searching from or NULL, the node 993283029d1SGrant Likely * you pass will not be searched, only the next one 994283029d1SGrant Likely * will; typically, you pass what the previous call 995283029d1SGrant Likely * returned. of_node_put() will be called on it 996283029d1SGrant Likely * @matches: array of of device match structures to search in 99750c8af4cSStephen Warren * @match Updated to point at the matches entry which matched 998283029d1SGrant Likely * 999283029d1SGrant Likely * Returns a node pointer with refcount incremented, use 1000283029d1SGrant Likely * of_node_put() on it when done. 1001283029d1SGrant Likely */ 100250c8af4cSStephen Warren struct device_node *of_find_matching_node_and_match(struct device_node *from, 100350c8af4cSStephen Warren const struct of_device_id *matches, 100450c8af4cSStephen Warren const struct of_device_id **match) 1005283029d1SGrant Likely { 1006283029d1SGrant Likely struct device_node *np; 1007dc71bcf1SThomas Abraham const struct of_device_id *m; 1008d6d3c4e6SThomas Gleixner unsigned long flags; 1009283029d1SGrant Likely 101050c8af4cSStephen Warren if (match) 101150c8af4cSStephen Warren *match = NULL; 101250c8af4cSStephen Warren 1013d6d3c4e6SThomas Gleixner raw_spin_lock_irqsave(&devtree_lock, flags); 10145063e25aSGrant Likely for_each_of_allnodes_from(from, np) { 101528d0e36bSThomas Gleixner m = __of_match_node(matches, np); 1016dc71bcf1SThomas Abraham if (m && of_node_get(np)) { 101750c8af4cSStephen Warren if (match) 1018dc71bcf1SThomas Abraham *match = m; 1019283029d1SGrant Likely break; 1020283029d1SGrant Likely } 102150c8af4cSStephen Warren } 1022283029d1SGrant Likely of_node_put(from); 1023d6d3c4e6SThomas Gleixner raw_spin_unlock_irqrestore(&devtree_lock, flags); 1024283029d1SGrant Likely return np; 1025283029d1SGrant Likely } 102680c2022eSGrant Likely EXPORT_SYMBOL(of_find_matching_node_and_match); 10273f07af49SGrant Likely 10283f07af49SGrant Likely /** 10293f07af49SGrant Likely * of_modalias_node - Lookup appropriate modalias for a device node 10303f07af49SGrant Likely * @node: pointer to a device tree node 10313f07af49SGrant Likely * @modalias: Pointer to buffer that modalias value will be copied into 10323f07af49SGrant Likely * @len: Length of modalias value 10333f07af49SGrant Likely * 10342ffe8c5fSGrant Likely * Based on the value of the compatible property, this routine will attempt 10352ffe8c5fSGrant Likely * to choose an appropriate modalias value for a particular device tree node. 10362ffe8c5fSGrant Likely * It does this by stripping the manufacturer prefix (as delimited by a ',') 10372ffe8c5fSGrant Likely * from the first entry in the compatible list property. 10383f07af49SGrant Likely * 10392ffe8c5fSGrant Likely * This routine returns 0 on success, <0 on failure. 10403f07af49SGrant Likely */ 10413f07af49SGrant Likely int of_modalias_node(struct device_node *node, char *modalias, int len) 10423f07af49SGrant Likely { 10432ffe8c5fSGrant Likely const char *compatible, *p; 10442ffe8c5fSGrant Likely int cplen; 10453f07af49SGrant Likely 10463f07af49SGrant Likely compatible = of_get_property(node, "compatible", &cplen); 10472ffe8c5fSGrant Likely if (!compatible || strlen(compatible) > cplen) 10483f07af49SGrant Likely return -ENODEV; 10493f07af49SGrant Likely p = strchr(compatible, ','); 10502ffe8c5fSGrant Likely strlcpy(modalias, p ? p + 1 : compatible, len); 10513f07af49SGrant Likely return 0; 10523f07af49SGrant Likely } 10533f07af49SGrant Likely EXPORT_SYMBOL_GPL(of_modalias_node); 10543f07af49SGrant Likely 105564b60e09SAnton Vorontsov /** 105689751a7cSJeremy Kerr * of_find_node_by_phandle - Find a node given a phandle 105789751a7cSJeremy Kerr * @handle: phandle of the node to find 105889751a7cSJeremy Kerr * 105989751a7cSJeremy Kerr * Returns a node pointer with refcount incremented, use 106089751a7cSJeremy Kerr * of_node_put() on it when done. 106189751a7cSJeremy Kerr */ 106289751a7cSJeremy Kerr struct device_node *of_find_node_by_phandle(phandle handle) 106389751a7cSJeremy Kerr { 106489751a7cSJeremy Kerr struct device_node *np; 1065d25d8694SBenjamin Herrenschmidt unsigned long flags; 106689751a7cSJeremy Kerr 1067fc59b447SGrant Likely if (!handle) 1068fc59b447SGrant Likely return NULL; 1069fc59b447SGrant Likely 1070d25d8694SBenjamin Herrenschmidt raw_spin_lock_irqsave(&devtree_lock, flags); 10715063e25aSGrant Likely for_each_of_allnodes(np) 107289751a7cSJeremy Kerr if (np->phandle == handle) 107389751a7cSJeremy Kerr break; 107489751a7cSJeremy Kerr of_node_get(np); 1075d25d8694SBenjamin Herrenschmidt raw_spin_unlock_irqrestore(&devtree_lock, flags); 107689751a7cSJeremy Kerr return np; 107789751a7cSJeremy Kerr } 107889751a7cSJeremy Kerr EXPORT_SYMBOL(of_find_node_by_phandle); 107989751a7cSJeremy Kerr 108089751a7cSJeremy Kerr /** 1081ad54a0cfSHeiko Stuebner * of_property_count_elems_of_size - Count the number of elements in a property 1082ad54a0cfSHeiko Stuebner * 1083ad54a0cfSHeiko Stuebner * @np: device node from which the property value is to be read. 1084ad54a0cfSHeiko Stuebner * @propname: name of the property to be searched. 1085ad54a0cfSHeiko Stuebner * @elem_size: size of the individual element 1086ad54a0cfSHeiko Stuebner * 1087ad54a0cfSHeiko Stuebner * Search for a property in a device node and count the number of elements of 1088ad54a0cfSHeiko Stuebner * size elem_size in it. Returns number of elements on sucess, -EINVAL if the 1089ad54a0cfSHeiko Stuebner * property does not exist or its length does not match a multiple of elem_size 1090ad54a0cfSHeiko Stuebner * and -ENODATA if the property does not have a value. 1091ad54a0cfSHeiko Stuebner */ 1092ad54a0cfSHeiko Stuebner int of_property_count_elems_of_size(const struct device_node *np, 1093ad54a0cfSHeiko Stuebner const char *propname, int elem_size) 1094ad54a0cfSHeiko Stuebner { 1095ad54a0cfSHeiko Stuebner struct property *prop = of_find_property(np, propname, NULL); 1096ad54a0cfSHeiko Stuebner 1097ad54a0cfSHeiko Stuebner if (!prop) 1098ad54a0cfSHeiko Stuebner return -EINVAL; 1099ad54a0cfSHeiko Stuebner if (!prop->value) 1100ad54a0cfSHeiko Stuebner return -ENODATA; 1101ad54a0cfSHeiko Stuebner 1102ad54a0cfSHeiko Stuebner if (prop->length % elem_size != 0) { 1103ad54a0cfSHeiko Stuebner pr_err("size of %s in node %s is not a multiple of %d\n", 1104ad54a0cfSHeiko Stuebner propname, np->full_name, elem_size); 1105ad54a0cfSHeiko Stuebner return -EINVAL; 1106ad54a0cfSHeiko Stuebner } 1107ad54a0cfSHeiko Stuebner 1108ad54a0cfSHeiko Stuebner return prop->length / elem_size; 1109ad54a0cfSHeiko Stuebner } 1110ad54a0cfSHeiko Stuebner EXPORT_SYMBOL_GPL(of_property_count_elems_of_size); 1111ad54a0cfSHeiko Stuebner 1112ad54a0cfSHeiko Stuebner /** 1113daeec1f0STony Prisk * of_find_property_value_of_size 1114daeec1f0STony Prisk * 1115daeec1f0STony Prisk * @np: device node from which the property value is to be read. 1116daeec1f0STony Prisk * @propname: name of the property to be searched. 1117daeec1f0STony Prisk * @len: requested length of property value 1118daeec1f0STony Prisk * 1119daeec1f0STony Prisk * Search for a property in a device node and valid the requested size. 1120daeec1f0STony Prisk * Returns the property value on success, -EINVAL if the property does not 1121daeec1f0STony Prisk * exist, -ENODATA if property does not have a value, and -EOVERFLOW if the 1122daeec1f0STony Prisk * property data isn't large enough. 1123daeec1f0STony Prisk * 1124daeec1f0STony Prisk */ 1125daeec1f0STony Prisk static void *of_find_property_value_of_size(const struct device_node *np, 1126daeec1f0STony Prisk const char *propname, u32 len) 1127daeec1f0STony Prisk { 1128daeec1f0STony Prisk struct property *prop = of_find_property(np, propname, NULL); 1129daeec1f0STony Prisk 1130daeec1f0STony Prisk if (!prop) 1131daeec1f0STony Prisk return ERR_PTR(-EINVAL); 1132daeec1f0STony Prisk if (!prop->value) 1133daeec1f0STony Prisk return ERR_PTR(-ENODATA); 1134daeec1f0STony Prisk if (len > prop->length) 1135daeec1f0STony Prisk return ERR_PTR(-EOVERFLOW); 1136daeec1f0STony Prisk 1137daeec1f0STony Prisk return prop->value; 1138daeec1f0STony Prisk } 1139daeec1f0STony Prisk 1140daeec1f0STony Prisk /** 11413daf3726STony Prisk * of_property_read_u32_index - Find and read a u32 from a multi-value property. 11423daf3726STony Prisk * 11433daf3726STony Prisk * @np: device node from which the property value is to be read. 11443daf3726STony Prisk * @propname: name of the property to be searched. 11453daf3726STony Prisk * @index: index of the u32 in the list of values 11463daf3726STony Prisk * @out_value: pointer to return value, modified only if no error. 11473daf3726STony Prisk * 11483daf3726STony Prisk * Search for a property in a device node and read nth 32-bit value from 11493daf3726STony Prisk * it. Returns 0 on success, -EINVAL if the property does not exist, 11503daf3726STony Prisk * -ENODATA if property does not have a value, and -EOVERFLOW if the 11513daf3726STony Prisk * property data isn't large enough. 11523daf3726STony Prisk * 11533daf3726STony Prisk * The out_value is modified only if a valid u32 value can be decoded. 11543daf3726STony Prisk */ 11553daf3726STony Prisk int of_property_read_u32_index(const struct device_node *np, 11563daf3726STony Prisk const char *propname, 11573daf3726STony Prisk u32 index, u32 *out_value) 11583daf3726STony Prisk { 1159daeec1f0STony Prisk const u32 *val = of_find_property_value_of_size(np, propname, 1160daeec1f0STony Prisk ((index + 1) * sizeof(*out_value))); 11613daf3726STony Prisk 1162daeec1f0STony Prisk if (IS_ERR(val)) 1163daeec1f0STony Prisk return PTR_ERR(val); 11643daf3726STony Prisk 1165daeec1f0STony Prisk *out_value = be32_to_cpup(((__be32 *)val) + index); 11663daf3726STony Prisk return 0; 11673daf3726STony Prisk } 11683daf3726STony Prisk EXPORT_SYMBOL_GPL(of_property_read_u32_index); 11693daf3726STony Prisk 11703daf3726STony Prisk /** 1171be193249SViresh Kumar * of_property_read_u8_array - Find and read an array of u8 from a property. 1172be193249SViresh Kumar * 1173be193249SViresh Kumar * @np: device node from which the property value is to be read. 1174be193249SViresh Kumar * @propname: name of the property to be searched. 1175792efb84SLad, Prabhakar * @out_values: pointer to return value, modified only if return value is 0. 1176be193249SViresh Kumar * @sz: number of array elements to read 1177be193249SViresh Kumar * 1178be193249SViresh Kumar * Search for a property in a device node and read 8-bit value(s) from 1179be193249SViresh Kumar * it. Returns 0 on success, -EINVAL if the property does not exist, 1180be193249SViresh Kumar * -ENODATA if property does not have a value, and -EOVERFLOW if the 1181be193249SViresh Kumar * property data isn't large enough. 1182be193249SViresh Kumar * 1183be193249SViresh Kumar * dts entry of array should be like: 1184be193249SViresh Kumar * property = /bits/ 8 <0x50 0x60 0x70>; 1185be193249SViresh Kumar * 1186792efb84SLad, Prabhakar * The out_values is modified only if a valid u8 value can be decoded. 1187be193249SViresh Kumar */ 1188be193249SViresh Kumar int of_property_read_u8_array(const struct device_node *np, 1189be193249SViresh Kumar const char *propname, u8 *out_values, size_t sz) 1190be193249SViresh Kumar { 1191daeec1f0STony Prisk const u8 *val = of_find_property_value_of_size(np, propname, 1192daeec1f0STony Prisk (sz * sizeof(*out_values))); 1193be193249SViresh Kumar 1194daeec1f0STony Prisk if (IS_ERR(val)) 1195daeec1f0STony Prisk return PTR_ERR(val); 1196be193249SViresh Kumar 1197be193249SViresh Kumar while (sz--) 1198be193249SViresh Kumar *out_values++ = *val++; 1199be193249SViresh Kumar return 0; 1200be193249SViresh Kumar } 1201be193249SViresh Kumar EXPORT_SYMBOL_GPL(of_property_read_u8_array); 1202be193249SViresh Kumar 1203be193249SViresh Kumar /** 1204be193249SViresh Kumar * of_property_read_u16_array - Find and read an array of u16 from a property. 1205be193249SViresh Kumar * 1206be193249SViresh Kumar * @np: device node from which the property value is to be read. 1207be193249SViresh Kumar * @propname: name of the property to be searched. 1208792efb84SLad, Prabhakar * @out_values: pointer to return value, modified only if return value is 0. 1209be193249SViresh Kumar * @sz: number of array elements to read 1210be193249SViresh Kumar * 1211be193249SViresh Kumar * Search for a property in a device node and read 16-bit value(s) from 1212be193249SViresh Kumar * it. Returns 0 on success, -EINVAL if the property does not exist, 1213be193249SViresh Kumar * -ENODATA if property does not have a value, and -EOVERFLOW if the 1214be193249SViresh Kumar * property data isn't large enough. 1215be193249SViresh Kumar * 1216be193249SViresh Kumar * dts entry of array should be like: 1217be193249SViresh Kumar * property = /bits/ 16 <0x5000 0x6000 0x7000>; 1218be193249SViresh Kumar * 1219792efb84SLad, Prabhakar * The out_values is modified only if a valid u16 value can be decoded. 1220be193249SViresh Kumar */ 1221be193249SViresh Kumar int of_property_read_u16_array(const struct device_node *np, 1222be193249SViresh Kumar const char *propname, u16 *out_values, size_t sz) 1223be193249SViresh Kumar { 1224daeec1f0STony Prisk const __be16 *val = of_find_property_value_of_size(np, propname, 1225daeec1f0STony Prisk (sz * sizeof(*out_values))); 1226be193249SViresh Kumar 1227daeec1f0STony Prisk if (IS_ERR(val)) 1228daeec1f0STony Prisk return PTR_ERR(val); 1229be193249SViresh Kumar 1230be193249SViresh Kumar while (sz--) 1231be193249SViresh Kumar *out_values++ = be16_to_cpup(val++); 1232be193249SViresh Kumar return 0; 1233be193249SViresh Kumar } 1234be193249SViresh Kumar EXPORT_SYMBOL_GPL(of_property_read_u16_array); 1235be193249SViresh Kumar 1236be193249SViresh Kumar /** 12370e373639SRob Herring * of_property_read_u32_array - Find and read an array of 32 bit integers 12380e373639SRob Herring * from a property. 12390e373639SRob Herring * 1240a3b85363SThomas Abraham * @np: device node from which the property value is to be read. 1241a3b85363SThomas Abraham * @propname: name of the property to be searched. 1242792efb84SLad, Prabhakar * @out_values: pointer to return value, modified only if return value is 0. 1243be193249SViresh Kumar * @sz: number of array elements to read 1244a3b85363SThomas Abraham * 12450e373639SRob Herring * Search for a property in a device node and read 32-bit value(s) from 1246a3b85363SThomas Abraham * it. Returns 0 on success, -EINVAL if the property does not exist, 1247a3b85363SThomas Abraham * -ENODATA if property does not have a value, and -EOVERFLOW if the 1248a3b85363SThomas Abraham * property data isn't large enough. 1249a3b85363SThomas Abraham * 1250792efb84SLad, Prabhakar * The out_values is modified only if a valid u32 value can be decoded. 1251a3b85363SThomas Abraham */ 1252aac285c6SJamie Iles int of_property_read_u32_array(const struct device_node *np, 1253aac285c6SJamie Iles const char *propname, u32 *out_values, 1254aac285c6SJamie Iles size_t sz) 1255a3b85363SThomas Abraham { 1256daeec1f0STony Prisk const __be32 *val = of_find_property_value_of_size(np, propname, 1257daeec1f0STony Prisk (sz * sizeof(*out_values))); 1258a3b85363SThomas Abraham 1259daeec1f0STony Prisk if (IS_ERR(val)) 1260daeec1f0STony Prisk return PTR_ERR(val); 12610e373639SRob Herring 12620e373639SRob Herring while (sz--) 12630e373639SRob Herring *out_values++ = be32_to_cpup(val++); 1264a3b85363SThomas Abraham return 0; 1265a3b85363SThomas Abraham } 12660e373639SRob Herring EXPORT_SYMBOL_GPL(of_property_read_u32_array); 1267a3b85363SThomas Abraham 1268a3b85363SThomas Abraham /** 12694cd7f7a3SJamie Iles * of_property_read_u64 - Find and read a 64 bit integer from a property 12704cd7f7a3SJamie Iles * @np: device node from which the property value is to be read. 12714cd7f7a3SJamie Iles * @propname: name of the property to be searched. 12724cd7f7a3SJamie Iles * @out_value: pointer to return value, modified only if return value is 0. 12734cd7f7a3SJamie Iles * 12744cd7f7a3SJamie Iles * Search for a property in a device node and read a 64-bit value from 12754cd7f7a3SJamie Iles * it. Returns 0 on success, -EINVAL if the property does not exist, 12764cd7f7a3SJamie Iles * -ENODATA if property does not have a value, and -EOVERFLOW if the 12774cd7f7a3SJamie Iles * property data isn't large enough. 12784cd7f7a3SJamie Iles * 12794cd7f7a3SJamie Iles * The out_value is modified only if a valid u64 value can be decoded. 12804cd7f7a3SJamie Iles */ 12814cd7f7a3SJamie Iles int of_property_read_u64(const struct device_node *np, const char *propname, 12824cd7f7a3SJamie Iles u64 *out_value) 12834cd7f7a3SJamie Iles { 1284daeec1f0STony Prisk const __be32 *val = of_find_property_value_of_size(np, propname, 1285daeec1f0STony Prisk sizeof(*out_value)); 12864cd7f7a3SJamie Iles 1287daeec1f0STony Prisk if (IS_ERR(val)) 1288daeec1f0STony Prisk return PTR_ERR(val); 1289daeec1f0STony Prisk 1290daeec1f0STony Prisk *out_value = of_read_number(val, 2); 12914cd7f7a3SJamie Iles return 0; 12924cd7f7a3SJamie Iles } 12934cd7f7a3SJamie Iles EXPORT_SYMBOL_GPL(of_property_read_u64); 12944cd7f7a3SJamie Iles 12954cd7f7a3SJamie Iles /** 1296b31384faSRafael J. Wysocki * of_property_read_u64_array - Find and read an array of 64 bit integers 1297b31384faSRafael J. Wysocki * from a property. 1298b31384faSRafael J. Wysocki * 1299b31384faSRafael J. Wysocki * @np: device node from which the property value is to be read. 1300b31384faSRafael J. Wysocki * @propname: name of the property to be searched. 1301b31384faSRafael J. Wysocki * @out_values: pointer to return value, modified only if return value is 0. 1302b31384faSRafael J. Wysocki * @sz: number of array elements to read 1303b31384faSRafael J. Wysocki * 1304b31384faSRafael J. Wysocki * Search for a property in a device node and read 64-bit value(s) from 1305b31384faSRafael J. Wysocki * it. Returns 0 on success, -EINVAL if the property does not exist, 1306b31384faSRafael J. Wysocki * -ENODATA if property does not have a value, and -EOVERFLOW if the 1307b31384faSRafael J. Wysocki * property data isn't large enough. 1308b31384faSRafael J. Wysocki * 1309b31384faSRafael J. Wysocki * The out_values is modified only if a valid u64 value can be decoded. 1310b31384faSRafael J. Wysocki */ 1311b31384faSRafael J. Wysocki int of_property_read_u64_array(const struct device_node *np, 1312b31384faSRafael J. Wysocki const char *propname, u64 *out_values, 1313b31384faSRafael J. Wysocki size_t sz) 1314b31384faSRafael J. Wysocki { 1315b31384faSRafael J. Wysocki const __be32 *val = of_find_property_value_of_size(np, propname, 1316b31384faSRafael J. Wysocki (sz * sizeof(*out_values))); 1317b31384faSRafael J. Wysocki 1318b31384faSRafael J. Wysocki if (IS_ERR(val)) 1319b31384faSRafael J. Wysocki return PTR_ERR(val); 1320b31384faSRafael J. Wysocki 1321b31384faSRafael J. Wysocki while (sz--) { 1322b31384faSRafael J. Wysocki *out_values++ = of_read_number(val, 2); 1323b31384faSRafael J. Wysocki val += 2; 1324b31384faSRafael J. Wysocki } 1325b31384faSRafael J. Wysocki return 0; 1326b31384faSRafael J. Wysocki } 13272d4c0aefSSakari Ailus EXPORT_SYMBOL_GPL(of_property_read_u64_array); 1328b31384faSRafael J. Wysocki 1329b31384faSRafael J. Wysocki /** 1330a3b85363SThomas Abraham * of_property_read_string - Find and read a string from a property 1331a3b85363SThomas Abraham * @np: device node from which the property value is to be read. 1332a3b85363SThomas Abraham * @propname: name of the property to be searched. 1333a3b85363SThomas Abraham * @out_string: pointer to null terminated return string, modified only if 1334a3b85363SThomas Abraham * return value is 0. 1335a3b85363SThomas Abraham * 1336a3b85363SThomas Abraham * Search for a property in a device tree node and retrieve a null 1337a3b85363SThomas Abraham * terminated string value (pointer to data, not a copy). Returns 0 on 1338a3b85363SThomas Abraham * success, -EINVAL if the property does not exist, -ENODATA if property 1339a3b85363SThomas Abraham * does not have a value, and -EILSEQ if the string is not null-terminated 1340a3b85363SThomas Abraham * within the length of the property data. 1341a3b85363SThomas Abraham * 1342a3b85363SThomas Abraham * The out_string pointer is modified only if a valid string can be decoded. 1343a3b85363SThomas Abraham */ 1344aac285c6SJamie Iles int of_property_read_string(struct device_node *np, const char *propname, 1345f09bc831SShawn Guo const char **out_string) 1346a3b85363SThomas Abraham { 1347a3b85363SThomas Abraham struct property *prop = of_find_property(np, propname, NULL); 1348a3b85363SThomas Abraham if (!prop) 1349a3b85363SThomas Abraham return -EINVAL; 1350a3b85363SThomas Abraham if (!prop->value) 1351a3b85363SThomas Abraham return -ENODATA; 1352a3b85363SThomas Abraham if (strnlen(prop->value, prop->length) >= prop->length) 1353a3b85363SThomas Abraham return -EILSEQ; 1354a3b85363SThomas Abraham *out_string = prop->value; 1355a3b85363SThomas Abraham return 0; 1356a3b85363SThomas Abraham } 1357a3b85363SThomas Abraham EXPORT_SYMBOL_GPL(of_property_read_string); 1358a3b85363SThomas Abraham 1359a3b85363SThomas Abraham /** 13607aff0fe3SGrant Likely * of_property_match_string() - Find string in a list and return index 13617aff0fe3SGrant Likely * @np: pointer to node containing string list property 13627aff0fe3SGrant Likely * @propname: string list property name 13637aff0fe3SGrant Likely * @string: pointer to string to search for in string list 13647aff0fe3SGrant Likely * 13657aff0fe3SGrant Likely * This function searches a string list property and returns the index 13667aff0fe3SGrant Likely * of a specific string value. 13677aff0fe3SGrant Likely */ 13687aff0fe3SGrant Likely int of_property_match_string(struct device_node *np, const char *propname, 13697aff0fe3SGrant Likely const char *string) 13707aff0fe3SGrant Likely { 13717aff0fe3SGrant Likely struct property *prop = of_find_property(np, propname, NULL); 13727aff0fe3SGrant Likely size_t l; 13737aff0fe3SGrant Likely int i; 13747aff0fe3SGrant Likely const char *p, *end; 13757aff0fe3SGrant Likely 13767aff0fe3SGrant Likely if (!prop) 13777aff0fe3SGrant Likely return -EINVAL; 13787aff0fe3SGrant Likely if (!prop->value) 13797aff0fe3SGrant Likely return -ENODATA; 13807aff0fe3SGrant Likely 13817aff0fe3SGrant Likely p = prop->value; 13827aff0fe3SGrant Likely end = p + prop->length; 13837aff0fe3SGrant Likely 13847aff0fe3SGrant Likely for (i = 0; p < end; i++, p += l) { 1385a87fa1d8SGrant Likely l = strnlen(p, end - p) + 1; 13867aff0fe3SGrant Likely if (p + l > end) 13877aff0fe3SGrant Likely return -EILSEQ; 13887aff0fe3SGrant Likely pr_debug("comparing %s with %s\n", string, p); 13897aff0fe3SGrant Likely if (strcmp(string, p) == 0) 13907aff0fe3SGrant Likely return i; /* Found it; return index */ 13917aff0fe3SGrant Likely } 13927aff0fe3SGrant Likely return -ENODATA; 13937aff0fe3SGrant Likely } 13947aff0fe3SGrant Likely EXPORT_SYMBOL_GPL(of_property_match_string); 13954fcd15a0SBenoit Cousson 13964fcd15a0SBenoit Cousson /** 1397e99010edSJiri Slaby * of_property_read_string_helper() - Utility helper for parsing string properties 13984fcd15a0SBenoit Cousson * @np: device node from which the property value is to be read. 13994fcd15a0SBenoit Cousson * @propname: name of the property to be searched. 1400a87fa1d8SGrant Likely * @out_strs: output array of string pointers. 1401a87fa1d8SGrant Likely * @sz: number of array elements to read. 1402a87fa1d8SGrant Likely * @skip: Number of strings to skip over at beginning of list. 14034fcd15a0SBenoit Cousson * 1404a87fa1d8SGrant Likely * Don't call this function directly. It is a utility helper for the 1405a87fa1d8SGrant Likely * of_property_read_string*() family of functions. 14064fcd15a0SBenoit Cousson */ 1407a87fa1d8SGrant Likely int of_property_read_string_helper(struct device_node *np, const char *propname, 1408a87fa1d8SGrant Likely const char **out_strs, size_t sz, int skip) 14094fcd15a0SBenoit Cousson { 14104fcd15a0SBenoit Cousson struct property *prop = of_find_property(np, propname, NULL); 1411a87fa1d8SGrant Likely int l = 0, i = 0; 1412a87fa1d8SGrant Likely const char *p, *end; 14134fcd15a0SBenoit Cousson 14144fcd15a0SBenoit Cousson if (!prop) 14154fcd15a0SBenoit Cousson return -EINVAL; 14164fcd15a0SBenoit Cousson if (!prop->value) 14174fcd15a0SBenoit Cousson return -ENODATA; 14184fcd15a0SBenoit Cousson p = prop->value; 1419a87fa1d8SGrant Likely end = p + prop->length; 14204fcd15a0SBenoit Cousson 1421a87fa1d8SGrant Likely for (i = 0; p < end && (!out_strs || i < skip + sz); i++, p += l) { 1422a87fa1d8SGrant Likely l = strnlen(p, end - p) + 1; 1423a87fa1d8SGrant Likely if (p + l > end) 1424a87fa1d8SGrant Likely return -EILSEQ; 1425a87fa1d8SGrant Likely if (out_strs && i >= skip) 1426a87fa1d8SGrant Likely *out_strs++ = p; 14274fcd15a0SBenoit Cousson } 1428a87fa1d8SGrant Likely i -= skip; 1429a87fa1d8SGrant Likely return i <= 0 ? -ENODATA : i; 1430a87fa1d8SGrant Likely } 1431a87fa1d8SGrant Likely EXPORT_SYMBOL_GPL(of_property_read_string_helper); 14324fcd15a0SBenoit Cousson 1433624cfca5SGrant Likely void of_print_phandle_args(const char *msg, const struct of_phandle_args *args) 1434624cfca5SGrant Likely { 1435624cfca5SGrant Likely int i; 1436624cfca5SGrant Likely printk("%s %s", msg, of_node_full_name(args->np)); 1437624cfca5SGrant Likely for (i = 0; i < args->args_count; i++) 1438624cfca5SGrant Likely printk(i ? ",%08x" : ":%08x", args->args[i]); 1439624cfca5SGrant Likely printk("\n"); 1440624cfca5SGrant Likely } 1441624cfca5SGrant Likely 1442bd69f73fSGrant Likely static int __of_parse_phandle_with_args(const struct device_node *np, 1443bd69f73fSGrant Likely const char *list_name, 1444035fd948SStephen Warren const char *cells_name, 1445035fd948SStephen Warren int cell_count, int index, 144615c9a0acSGrant Likely struct of_phandle_args *out_args) 144764b60e09SAnton Vorontsov { 144815c9a0acSGrant Likely const __be32 *list, *list_end; 144923ce04c0SGrant Likely int rc = 0, size, cur_index = 0; 145015c9a0acSGrant Likely uint32_t count = 0; 145164b60e09SAnton Vorontsov struct device_node *node = NULL; 14529a6b2e58SGrant Likely phandle phandle; 145364b60e09SAnton Vorontsov 145415c9a0acSGrant Likely /* Retrieve the phandle list property */ 145515c9a0acSGrant Likely list = of_get_property(np, list_name, &size); 145615c9a0acSGrant Likely if (!list) 14571af4c7f1SAlexandre Courbot return -ENOENT; 145815c9a0acSGrant Likely list_end = list + size / sizeof(*list); 145915c9a0acSGrant Likely 146015c9a0acSGrant Likely /* Loop over the phandles until all the requested entry is found */ 146115c9a0acSGrant Likely while (list < list_end) { 146223ce04c0SGrant Likely rc = -EINVAL; 146315c9a0acSGrant Likely count = 0; 146415c9a0acSGrant Likely 146515c9a0acSGrant Likely /* 146615c9a0acSGrant Likely * If phandle is 0, then it is an empty entry with no 146715c9a0acSGrant Likely * arguments. Skip forward to the next entry. 146815c9a0acSGrant Likely */ 14699a6b2e58SGrant Likely phandle = be32_to_cpup(list++); 147015c9a0acSGrant Likely if (phandle) { 147115c9a0acSGrant Likely /* 147215c9a0acSGrant Likely * Find the provider node and parse the #*-cells 147391d9942cSStephen Warren * property to determine the argument length. 147491d9942cSStephen Warren * 147591d9942cSStephen Warren * This is not needed if the cell count is hard-coded 147691d9942cSStephen Warren * (i.e. cells_name not set, but cell_count is set), 147791d9942cSStephen Warren * except when we're going to return the found node 147891d9942cSStephen Warren * below. 147915c9a0acSGrant Likely */ 148091d9942cSStephen Warren if (cells_name || cur_index == index) { 14819a6b2e58SGrant Likely node = of_find_node_by_phandle(phandle); 148264b60e09SAnton Vorontsov if (!node) { 148315c9a0acSGrant Likely pr_err("%s: could not find phandle\n", 148464b60e09SAnton Vorontsov np->full_name); 148523ce04c0SGrant Likely goto err; 148615c9a0acSGrant Likely } 148791d9942cSStephen Warren } 1488035fd948SStephen Warren 1489035fd948SStephen Warren if (cells_name) { 1490035fd948SStephen Warren if (of_property_read_u32(node, cells_name, 1491035fd948SStephen Warren &count)) { 149215c9a0acSGrant Likely pr_err("%s: could not get %s for %s\n", 149315c9a0acSGrant Likely np->full_name, cells_name, 149415c9a0acSGrant Likely node->full_name); 149523ce04c0SGrant Likely goto err; 149615c9a0acSGrant Likely } 1497035fd948SStephen Warren } else { 1498035fd948SStephen Warren count = cell_count; 1499035fd948SStephen Warren } 150015c9a0acSGrant Likely 150115c9a0acSGrant Likely /* 150215c9a0acSGrant Likely * Make sure that the arguments actually fit in the 150315c9a0acSGrant Likely * remaining property data length 150415c9a0acSGrant Likely */ 150515c9a0acSGrant Likely if (list + count > list_end) { 150615c9a0acSGrant Likely pr_err("%s: arguments longer than property\n", 150715c9a0acSGrant Likely np->full_name); 150823ce04c0SGrant Likely goto err; 150915c9a0acSGrant Likely } 151015c9a0acSGrant Likely } 151115c9a0acSGrant Likely 151215c9a0acSGrant Likely /* 151315c9a0acSGrant Likely * All of the error cases above bail out of the loop, so at 151415c9a0acSGrant Likely * this point, the parsing is successful. If the requested 151515c9a0acSGrant Likely * index matches, then fill the out_args structure and return, 151615c9a0acSGrant Likely * or return -ENOENT for an empty entry. 151715c9a0acSGrant Likely */ 151823ce04c0SGrant Likely rc = -ENOENT; 151915c9a0acSGrant Likely if (cur_index == index) { 152015c9a0acSGrant Likely if (!phandle) 152123ce04c0SGrant Likely goto err; 152215c9a0acSGrant Likely 152315c9a0acSGrant Likely if (out_args) { 152415c9a0acSGrant Likely int i; 152515c9a0acSGrant Likely if (WARN_ON(count > MAX_PHANDLE_ARGS)) 152615c9a0acSGrant Likely count = MAX_PHANDLE_ARGS; 152715c9a0acSGrant Likely out_args->np = node; 152815c9a0acSGrant Likely out_args->args_count = count; 152915c9a0acSGrant Likely for (i = 0; i < count; i++) 153015c9a0acSGrant Likely out_args->args[i] = be32_to_cpup(list++); 1531b855f16bSTang Yuantian } else { 1532b855f16bSTang Yuantian of_node_put(node); 153315c9a0acSGrant Likely } 153423ce04c0SGrant Likely 153523ce04c0SGrant Likely /* Found it! return success */ 153615c9a0acSGrant Likely return 0; 153715c9a0acSGrant Likely } 153864b60e09SAnton Vorontsov 153964b60e09SAnton Vorontsov of_node_put(node); 154064b60e09SAnton Vorontsov node = NULL; 154115c9a0acSGrant Likely list += count; 154264b60e09SAnton Vorontsov cur_index++; 154364b60e09SAnton Vorontsov } 154464b60e09SAnton Vorontsov 154523ce04c0SGrant Likely /* 154623ce04c0SGrant Likely * Unlock node before returning result; will be one of: 154723ce04c0SGrant Likely * -ENOENT : index is for empty phandle 154823ce04c0SGrant Likely * -EINVAL : parsing error on data 1549bd69f73fSGrant Likely * [1..n] : Number of phandle (count mode; when index = -1) 155023ce04c0SGrant Likely */ 1551bd69f73fSGrant Likely rc = index < 0 ? cur_index : -ENOENT; 155223ce04c0SGrant Likely err: 155315c9a0acSGrant Likely if (node) 155464b60e09SAnton Vorontsov of_node_put(node); 155523ce04c0SGrant Likely return rc; 155664b60e09SAnton Vorontsov } 1557bd69f73fSGrant Likely 1558eded9dd4SStephen Warren /** 15595fba49e3SStephen Warren * of_parse_phandle - Resolve a phandle property to a device_node pointer 15605fba49e3SStephen Warren * @np: Pointer to device node holding phandle property 15615fba49e3SStephen Warren * @phandle_name: Name of property holding a phandle value 15625fba49e3SStephen Warren * @index: For properties holding a table of phandles, this is the index into 15635fba49e3SStephen Warren * the table 15645fba49e3SStephen Warren * 15655fba49e3SStephen Warren * Returns the device_node pointer with refcount incremented. Use 15665fba49e3SStephen Warren * of_node_put() on it when done. 15675fba49e3SStephen Warren */ 15685fba49e3SStephen Warren struct device_node *of_parse_phandle(const struct device_node *np, 15695fba49e3SStephen Warren const char *phandle_name, int index) 15705fba49e3SStephen Warren { 157191d9942cSStephen Warren struct of_phandle_args args; 15725fba49e3SStephen Warren 157391d9942cSStephen Warren if (index < 0) 15745fba49e3SStephen Warren return NULL; 15755fba49e3SStephen Warren 157691d9942cSStephen Warren if (__of_parse_phandle_with_args(np, phandle_name, NULL, 0, 157791d9942cSStephen Warren index, &args)) 157891d9942cSStephen Warren return NULL; 157991d9942cSStephen Warren 158091d9942cSStephen Warren return args.np; 15815fba49e3SStephen Warren } 15825fba49e3SStephen Warren EXPORT_SYMBOL(of_parse_phandle); 15835fba49e3SStephen Warren 15845fba49e3SStephen Warren /** 1585eded9dd4SStephen Warren * of_parse_phandle_with_args() - Find a node pointed by phandle in a list 1586eded9dd4SStephen Warren * @np: pointer to a device tree node containing a list 1587eded9dd4SStephen Warren * @list_name: property name that contains a list 1588eded9dd4SStephen Warren * @cells_name: property name that specifies phandles' arguments count 1589eded9dd4SStephen Warren * @index: index of a phandle to parse out 1590eded9dd4SStephen Warren * @out_args: optional pointer to output arguments structure (will be filled) 1591eded9dd4SStephen Warren * 1592eded9dd4SStephen Warren * This function is useful to parse lists of phandles and their arguments. 1593eded9dd4SStephen Warren * Returns 0 on success and fills out_args, on error returns appropriate 1594eded9dd4SStephen Warren * errno value. 1595eded9dd4SStephen Warren * 1596d94a75c1SGeert Uytterhoeven * Caller is responsible to call of_node_put() on the returned out_args->np 1597eded9dd4SStephen Warren * pointer. 1598eded9dd4SStephen Warren * 1599eded9dd4SStephen Warren * Example: 1600eded9dd4SStephen Warren * 1601eded9dd4SStephen Warren * phandle1: node1 { 1602eded9dd4SStephen Warren * #list-cells = <2>; 1603eded9dd4SStephen Warren * } 1604eded9dd4SStephen Warren * 1605eded9dd4SStephen Warren * phandle2: node2 { 1606eded9dd4SStephen Warren * #list-cells = <1>; 1607eded9dd4SStephen Warren * } 1608eded9dd4SStephen Warren * 1609eded9dd4SStephen Warren * node3 { 1610eded9dd4SStephen Warren * list = <&phandle1 1 2 &phandle2 3>; 1611eded9dd4SStephen Warren * } 1612eded9dd4SStephen Warren * 1613eded9dd4SStephen Warren * To get a device_node of the `node2' node you may call this: 1614eded9dd4SStephen Warren * of_parse_phandle_with_args(node3, "list", "#list-cells", 1, &args); 1615eded9dd4SStephen Warren */ 1616bd69f73fSGrant Likely int of_parse_phandle_with_args(const struct device_node *np, const char *list_name, 1617bd69f73fSGrant Likely const char *cells_name, int index, 1618bd69f73fSGrant Likely struct of_phandle_args *out_args) 1619bd69f73fSGrant Likely { 1620bd69f73fSGrant Likely if (index < 0) 1621bd69f73fSGrant Likely return -EINVAL; 1622035fd948SStephen Warren return __of_parse_phandle_with_args(np, list_name, cells_name, 0, 1623035fd948SStephen Warren index, out_args); 1624bd69f73fSGrant Likely } 162515c9a0acSGrant Likely EXPORT_SYMBOL(of_parse_phandle_with_args); 162602af11b0SGrant Likely 1627bd69f73fSGrant Likely /** 1628035fd948SStephen Warren * of_parse_phandle_with_fixed_args() - Find a node pointed by phandle in a list 1629035fd948SStephen Warren * @np: pointer to a device tree node containing a list 1630035fd948SStephen Warren * @list_name: property name that contains a list 1631035fd948SStephen Warren * @cell_count: number of argument cells following the phandle 1632035fd948SStephen Warren * @index: index of a phandle to parse out 1633035fd948SStephen Warren * @out_args: optional pointer to output arguments structure (will be filled) 1634035fd948SStephen Warren * 1635035fd948SStephen Warren * This function is useful to parse lists of phandles and their arguments. 1636035fd948SStephen Warren * Returns 0 on success and fills out_args, on error returns appropriate 1637035fd948SStephen Warren * errno value. 1638035fd948SStephen Warren * 1639d94a75c1SGeert Uytterhoeven * Caller is responsible to call of_node_put() on the returned out_args->np 1640035fd948SStephen Warren * pointer. 1641035fd948SStephen Warren * 1642035fd948SStephen Warren * Example: 1643035fd948SStephen Warren * 1644035fd948SStephen Warren * phandle1: node1 { 1645035fd948SStephen Warren * } 1646035fd948SStephen Warren * 1647035fd948SStephen Warren * phandle2: node2 { 1648035fd948SStephen Warren * } 1649035fd948SStephen Warren * 1650035fd948SStephen Warren * node3 { 1651035fd948SStephen Warren * list = <&phandle1 0 2 &phandle2 2 3>; 1652035fd948SStephen Warren * } 1653035fd948SStephen Warren * 1654035fd948SStephen Warren * To get a device_node of the `node2' node you may call this: 1655035fd948SStephen Warren * of_parse_phandle_with_fixed_args(node3, "list", 2, 1, &args); 1656035fd948SStephen Warren */ 1657035fd948SStephen Warren int of_parse_phandle_with_fixed_args(const struct device_node *np, 1658035fd948SStephen Warren const char *list_name, int cell_count, 1659035fd948SStephen Warren int index, struct of_phandle_args *out_args) 1660035fd948SStephen Warren { 1661035fd948SStephen Warren if (index < 0) 1662035fd948SStephen Warren return -EINVAL; 1663035fd948SStephen Warren return __of_parse_phandle_with_args(np, list_name, NULL, cell_count, 1664035fd948SStephen Warren index, out_args); 1665035fd948SStephen Warren } 1666035fd948SStephen Warren EXPORT_SYMBOL(of_parse_phandle_with_fixed_args); 1667035fd948SStephen Warren 1668035fd948SStephen Warren /** 1669bd69f73fSGrant Likely * of_count_phandle_with_args() - Find the number of phandles references in a property 1670bd69f73fSGrant Likely * @np: pointer to a device tree node containing a list 1671bd69f73fSGrant Likely * @list_name: property name that contains a list 1672bd69f73fSGrant Likely * @cells_name: property name that specifies phandles' arguments count 1673bd69f73fSGrant Likely * 1674bd69f73fSGrant Likely * Returns the number of phandle + argument tuples within a property. It 1675bd69f73fSGrant Likely * is a typical pattern to encode a list of phandle and variable 1676bd69f73fSGrant Likely * arguments into a single property. The number of arguments is encoded 1677bd69f73fSGrant Likely * by a property in the phandle-target node. For example, a gpios 1678bd69f73fSGrant Likely * property would contain a list of GPIO specifies consisting of a 1679bd69f73fSGrant Likely * phandle and 1 or more arguments. The number of arguments are 1680bd69f73fSGrant Likely * determined by the #gpio-cells property in the node pointed to by the 1681bd69f73fSGrant Likely * phandle. 1682bd69f73fSGrant Likely */ 1683bd69f73fSGrant Likely int of_count_phandle_with_args(const struct device_node *np, const char *list_name, 1684bd69f73fSGrant Likely const char *cells_name) 1685bd69f73fSGrant Likely { 1686035fd948SStephen Warren return __of_parse_phandle_with_args(np, list_name, cells_name, 0, -1, 1687035fd948SStephen Warren NULL); 1688bd69f73fSGrant Likely } 1689bd69f73fSGrant Likely EXPORT_SYMBOL(of_count_phandle_with_args); 1690bd69f73fSGrant Likely 169102af11b0SGrant Likely /** 169262664f67SXiubo Li * __of_add_property - Add a property to a node without lock operations 169362664f67SXiubo Li */ 1694d8c50088SPantelis Antoniou int __of_add_property(struct device_node *np, struct property *prop) 169562664f67SXiubo Li { 169662664f67SXiubo Li struct property **next; 169762664f67SXiubo Li 169862664f67SXiubo Li prop->next = NULL; 169962664f67SXiubo Li next = &np->properties; 170062664f67SXiubo Li while (*next) { 170162664f67SXiubo Li if (strcmp(prop->name, (*next)->name) == 0) 170262664f67SXiubo Li /* duplicate ! don't insert it */ 170362664f67SXiubo Li return -EEXIST; 170462664f67SXiubo Li 170562664f67SXiubo Li next = &(*next)->next; 170662664f67SXiubo Li } 170762664f67SXiubo Li *next = prop; 170862664f67SXiubo Li 170962664f67SXiubo Li return 0; 171062664f67SXiubo Li } 171162664f67SXiubo Li 171262664f67SXiubo Li /** 171379d1c712SNathan Fontenot * of_add_property - Add a property to a node 171402af11b0SGrant Likely */ 171579d1c712SNathan Fontenot int of_add_property(struct device_node *np, struct property *prop) 171602af11b0SGrant Likely { 171702af11b0SGrant Likely unsigned long flags; 17181cf3d8b3SNathan Fontenot int rc; 17191cf3d8b3SNathan Fontenot 17208a2b22a2SGrant Likely mutex_lock(&of_mutex); 172102af11b0SGrant Likely 1722d6d3c4e6SThomas Gleixner raw_spin_lock_irqsave(&devtree_lock, flags); 172362664f67SXiubo Li rc = __of_add_property(np, prop); 1724d6d3c4e6SThomas Gleixner raw_spin_unlock_irqrestore(&devtree_lock, flags); 172502af11b0SGrant Likely 17268a2b22a2SGrant Likely if (!rc) 172775b57ecfSGrant Likely __of_add_property_sysfs(np, prop); 172802af11b0SGrant Likely 17298a2b22a2SGrant Likely mutex_unlock(&of_mutex); 17308a2b22a2SGrant Likely 1731259092a3SGrant Likely if (!rc) 1732259092a3SGrant Likely of_property_notify(OF_RECONFIG_ADD_PROPERTY, np, prop, NULL); 1733259092a3SGrant Likely 173462664f67SXiubo Li return rc; 173502af11b0SGrant Likely } 173602af11b0SGrant Likely 1737d8c50088SPantelis Antoniou int __of_remove_property(struct device_node *np, struct property *prop) 1738d8c50088SPantelis Antoniou { 1739d8c50088SPantelis Antoniou struct property **next; 1740d8c50088SPantelis Antoniou 1741d8c50088SPantelis Antoniou for (next = &np->properties; *next; next = &(*next)->next) { 1742d8c50088SPantelis Antoniou if (*next == prop) 1743d8c50088SPantelis Antoniou break; 1744d8c50088SPantelis Antoniou } 1745d8c50088SPantelis Antoniou if (*next == NULL) 1746d8c50088SPantelis Antoniou return -ENODEV; 1747d8c50088SPantelis Antoniou 1748d8c50088SPantelis Antoniou /* found the node */ 1749d8c50088SPantelis Antoniou *next = prop->next; 1750d8c50088SPantelis Antoniou prop->next = np->deadprops; 1751d8c50088SPantelis Antoniou np->deadprops = prop; 1752d8c50088SPantelis Antoniou 1753d8c50088SPantelis Antoniou return 0; 1754d8c50088SPantelis Antoniou } 1755d8c50088SPantelis Antoniou 17568a2b22a2SGrant Likely void __of_remove_property_sysfs(struct device_node *np, struct property *prop) 17578a2b22a2SGrant Likely { 1758ef69d740SGaurav Minocha if (!IS_ENABLED(CONFIG_SYSFS)) 1759ef69d740SGaurav Minocha return; 1760ef69d740SGaurav Minocha 17618a2b22a2SGrant Likely /* at early boot, bail here and defer setup to of_init() */ 17628a2b22a2SGrant Likely if (of_kset && of_node_is_attached(np)) 17638a2b22a2SGrant Likely sysfs_remove_bin_file(&np->kobj, &prop->attr); 17648a2b22a2SGrant Likely } 17658a2b22a2SGrant Likely 176602af11b0SGrant Likely /** 176779d1c712SNathan Fontenot * of_remove_property - Remove a property from a node. 176802af11b0SGrant Likely * 176902af11b0SGrant Likely * Note that we don't actually remove it, since we have given out 177002af11b0SGrant Likely * who-knows-how-many pointers to the data using get-property. 177102af11b0SGrant Likely * Instead we just move the property to the "dead properties" 177202af11b0SGrant Likely * list, so it won't be found any more. 177302af11b0SGrant Likely */ 177479d1c712SNathan Fontenot int of_remove_property(struct device_node *np, struct property *prop) 177502af11b0SGrant Likely { 177602af11b0SGrant Likely unsigned long flags; 17771cf3d8b3SNathan Fontenot int rc; 17781cf3d8b3SNathan Fontenot 17798a2b22a2SGrant Likely mutex_lock(&of_mutex); 178002af11b0SGrant Likely 1781d6d3c4e6SThomas Gleixner raw_spin_lock_irqsave(&devtree_lock, flags); 1782d8c50088SPantelis Antoniou rc = __of_remove_property(np, prop); 1783d6d3c4e6SThomas Gleixner raw_spin_unlock_irqrestore(&devtree_lock, flags); 178402af11b0SGrant Likely 17858a2b22a2SGrant Likely if (!rc) 17868a2b22a2SGrant Likely __of_remove_property_sysfs(np, prop); 178702af11b0SGrant Likely 17888a2b22a2SGrant Likely mutex_unlock(&of_mutex); 17898a2b22a2SGrant Likely 1790259092a3SGrant Likely if (!rc) 1791259092a3SGrant Likely of_property_notify(OF_RECONFIG_REMOVE_PROPERTY, np, prop, NULL); 1792259092a3SGrant Likely 1793d8c50088SPantelis Antoniou return rc; 179402af11b0SGrant Likely } 179502af11b0SGrant Likely 1796d8c50088SPantelis Antoniou int __of_update_property(struct device_node *np, struct property *newprop, 1797d8c50088SPantelis Antoniou struct property **oldpropp) 1798d8c50088SPantelis Antoniou { 1799d8c50088SPantelis Antoniou struct property **next, *oldprop; 1800d8c50088SPantelis Antoniou 1801d8c50088SPantelis Antoniou for (next = &np->properties; *next; next = &(*next)->next) { 1802d8c50088SPantelis Antoniou if (of_prop_cmp((*next)->name, newprop->name) == 0) 1803d8c50088SPantelis Antoniou break; 1804d8c50088SPantelis Antoniou } 1805d8c50088SPantelis Antoniou *oldpropp = oldprop = *next; 1806d8c50088SPantelis Antoniou 1807d8c50088SPantelis Antoniou if (oldprop) { 1808d8c50088SPantelis Antoniou /* replace the node */ 1809d8c50088SPantelis Antoniou newprop->next = oldprop->next; 1810d8c50088SPantelis Antoniou *next = newprop; 1811d8c50088SPantelis Antoniou oldprop->next = np->deadprops; 1812d8c50088SPantelis Antoniou np->deadprops = oldprop; 1813d8c50088SPantelis Antoniou } else { 1814d8c50088SPantelis Antoniou /* new node */ 1815d8c50088SPantelis Antoniou newprop->next = NULL; 1816d8c50088SPantelis Antoniou *next = newprop; 1817d8c50088SPantelis Antoniou } 1818d8c50088SPantelis Antoniou 1819d8c50088SPantelis Antoniou return 0; 1820d8c50088SPantelis Antoniou } 1821d8c50088SPantelis Antoniou 18228a2b22a2SGrant Likely void __of_update_property_sysfs(struct device_node *np, struct property *newprop, 18238a2b22a2SGrant Likely struct property *oldprop) 18248a2b22a2SGrant Likely { 1825ef69d740SGaurav Minocha if (!IS_ENABLED(CONFIG_SYSFS)) 1826ef69d740SGaurav Minocha return; 1827ef69d740SGaurav Minocha 18288a2b22a2SGrant Likely /* At early boot, bail out and defer setup to of_init() */ 182902af11b0SGrant Likely if (!of_kset) 18308a2b22a2SGrant Likely return; 183102af11b0SGrant Likely 18328a2b22a2SGrant Likely if (oldprop) 18338a2b22a2SGrant Likely sysfs_remove_bin_file(&np->kobj, &oldprop->attr); 18348a2b22a2SGrant Likely __of_add_property_sysfs(np, newprop); 183502af11b0SGrant Likely } 183602af11b0SGrant Likely 183702af11b0SGrant Likely /* 183879d1c712SNathan Fontenot * of_update_property - Update a property in a node, if the property does 1839475d0094SDong Aisheng * not exist, add it. 184002af11b0SGrant Likely * 184102af11b0SGrant Likely * Note that we don't actually remove it, since we have given out 184202af11b0SGrant Likely * who-knows-how-many pointers to the data using get-property. 184302af11b0SGrant Likely * Instead we just move the property to the "dead properties" list, 184402af11b0SGrant Likely * and add the new property to the property list 184502af11b0SGrant Likely */ 184679d1c712SNathan Fontenot int of_update_property(struct device_node *np, struct property *newprop) 184702af11b0SGrant Likely { 1848d8c50088SPantelis Antoniou struct property *oldprop; 184902af11b0SGrant Likely unsigned long flags; 1850947fdaadSXiubo Li int rc; 18511cf3d8b3SNathan Fontenot 1852475d0094SDong Aisheng if (!newprop->name) 1853475d0094SDong Aisheng return -EINVAL; 1854475d0094SDong Aisheng 18558a2b22a2SGrant Likely mutex_lock(&of_mutex); 1856fcdeb7feSGrant Likely 1857d6d3c4e6SThomas Gleixner raw_spin_lock_irqsave(&devtree_lock, flags); 1858d8c50088SPantelis Antoniou rc = __of_update_property(np, newprop, &oldprop); 1859d6d3c4e6SThomas Gleixner raw_spin_unlock_irqrestore(&devtree_lock, flags); 1860e81b3295SNathan Fontenot 18618a2b22a2SGrant Likely if (!rc) 18628a2b22a2SGrant Likely __of_update_property_sysfs(np, newprop, oldprop); 1863fcdeb7feSGrant Likely 18648a2b22a2SGrant Likely mutex_unlock(&of_mutex); 18651cf3d8b3SNathan Fontenot 1866259092a3SGrant Likely if (!rc) 1867259092a3SGrant Likely of_property_notify(OF_RECONFIG_UPDATE_PROPERTY, np, newprop, oldprop); 1868fcdeb7feSGrant Likely 18691cf3d8b3SNathan Fontenot return rc; 1870e81b3295SNathan Fontenot } 1871e81b3295SNathan Fontenot 1872611cad72SShawn Guo static void of_alias_add(struct alias_prop *ap, struct device_node *np, 1873611cad72SShawn Guo int id, const char *stem, int stem_len) 1874611cad72SShawn Guo { 1875611cad72SShawn Guo ap->np = np; 1876611cad72SShawn Guo ap->id = id; 1877611cad72SShawn Guo strncpy(ap->stem, stem, stem_len); 1878611cad72SShawn Guo ap->stem[stem_len] = 0; 1879611cad72SShawn Guo list_add_tail(&ap->link, &aliases_lookup); 1880611cad72SShawn Guo pr_debug("adding DT alias:%s: stem=%s id=%i node=%s\n", 188174a7f084SGrant Likely ap->alias, ap->stem, ap->id, of_node_full_name(np)); 1882611cad72SShawn Guo } 1883611cad72SShawn Guo 1884611cad72SShawn Guo /** 18851821dda4SGeert Uytterhoeven * of_alias_scan - Scan all properties of the 'aliases' node 1886611cad72SShawn Guo * 18871821dda4SGeert Uytterhoeven * The function scans all the properties of the 'aliases' node and populates 18881821dda4SGeert Uytterhoeven * the global lookup table with the properties. It returns the 18891821dda4SGeert Uytterhoeven * number of alias properties found, or an error code in case of failure. 1890611cad72SShawn Guo * 1891611cad72SShawn Guo * @dt_alloc: An allocator that provides a virtual address to memory 18921821dda4SGeert Uytterhoeven * for storing the resulting tree 1893611cad72SShawn Guo */ 1894611cad72SShawn Guo void of_alias_scan(void * (*dt_alloc)(u64 size, u64 align)) 1895611cad72SShawn Guo { 1896611cad72SShawn Guo struct property *pp; 1897611cad72SShawn Guo 18987dbe5849SLaurentiu Tudor of_aliases = of_find_node_by_path("/aliases"); 1899611cad72SShawn Guo of_chosen = of_find_node_by_path("/chosen"); 1900611cad72SShawn Guo if (of_chosen == NULL) 1901611cad72SShawn Guo of_chosen = of_find_node_by_path("/chosen@0"); 19025c19e952SSascha Hauer 19035c19e952SSascha Hauer if (of_chosen) { 1904a752ee56SGrant Likely /* linux,stdout-path and /aliases/stdout are for legacy compatibility */ 1905676e1b2fSGrant Likely const char *name = of_get_property(of_chosen, "stdout-path", NULL); 1906676e1b2fSGrant Likely if (!name) 19075c19e952SSascha Hauer name = of_get_property(of_chosen, "linux,stdout-path", NULL); 1908a752ee56SGrant Likely if (IS_ENABLED(CONFIG_PPC) && !name) 1909a752ee56SGrant Likely name = of_get_property(of_aliases, "stdout", NULL); 1910f64255b5SPeter Hurley if (name) 19117914a7c5SLeif Lindholm of_stdout = of_find_node_opts_by_path(name, &of_stdout_options); 19125c19e952SSascha Hauer } 19135c19e952SSascha Hauer 1914611cad72SShawn Guo if (!of_aliases) 1915611cad72SShawn Guo return; 1916611cad72SShawn Guo 19178af0da93SDong Aisheng for_each_property_of_node(of_aliases, pp) { 1918611cad72SShawn Guo const char *start = pp->name; 1919611cad72SShawn Guo const char *end = start + strlen(start); 1920611cad72SShawn Guo struct device_node *np; 1921611cad72SShawn Guo struct alias_prop *ap; 1922611cad72SShawn Guo int id, len; 1923611cad72SShawn Guo 1924611cad72SShawn Guo /* Skip those we do not want to proceed */ 1925611cad72SShawn Guo if (!strcmp(pp->name, "name") || 1926611cad72SShawn Guo !strcmp(pp->name, "phandle") || 1927611cad72SShawn Guo !strcmp(pp->name, "linux,phandle")) 1928611cad72SShawn Guo continue; 1929611cad72SShawn Guo 1930611cad72SShawn Guo np = of_find_node_by_path(pp->value); 1931611cad72SShawn Guo if (!np) 1932611cad72SShawn Guo continue; 1933611cad72SShawn Guo 1934611cad72SShawn Guo /* walk the alias backwards to extract the id and work out 1935611cad72SShawn Guo * the 'stem' string */ 1936611cad72SShawn Guo while (isdigit(*(end-1)) && end > start) 1937611cad72SShawn Guo end--; 1938611cad72SShawn Guo len = end - start; 1939611cad72SShawn Guo 1940611cad72SShawn Guo if (kstrtoint(end, 10, &id) < 0) 1941611cad72SShawn Guo continue; 1942611cad72SShawn Guo 1943611cad72SShawn Guo /* Allocate an alias_prop with enough space for the stem */ 1944611cad72SShawn Guo ap = dt_alloc(sizeof(*ap) + len + 1, 4); 1945611cad72SShawn Guo if (!ap) 1946611cad72SShawn Guo continue; 19470640332eSGrant Likely memset(ap, 0, sizeof(*ap) + len + 1); 1948611cad72SShawn Guo ap->alias = start; 1949611cad72SShawn Guo of_alias_add(ap, np, id, start, len); 1950611cad72SShawn Guo } 1951611cad72SShawn Guo } 1952611cad72SShawn Guo 1953611cad72SShawn Guo /** 1954611cad72SShawn Guo * of_alias_get_id - Get alias id for the given device_node 1955611cad72SShawn Guo * @np: Pointer to the given device_node 1956611cad72SShawn Guo * @stem: Alias stem of the given device_node 1957611cad72SShawn Guo * 19585a53a07fSGeert Uytterhoeven * The function travels the lookup table to get the alias id for the given 19595a53a07fSGeert Uytterhoeven * device_node and alias stem. It returns the alias id if found. 1960611cad72SShawn Guo */ 1961611cad72SShawn Guo int of_alias_get_id(struct device_node *np, const char *stem) 1962611cad72SShawn Guo { 1963611cad72SShawn Guo struct alias_prop *app; 1964611cad72SShawn Guo int id = -ENODEV; 1965611cad72SShawn Guo 1966c05aba2bSPantelis Antoniou mutex_lock(&of_mutex); 1967611cad72SShawn Guo list_for_each_entry(app, &aliases_lookup, link) { 1968611cad72SShawn Guo if (strcmp(app->stem, stem) != 0) 1969611cad72SShawn Guo continue; 1970611cad72SShawn Guo 1971611cad72SShawn Guo if (np == app->np) { 1972611cad72SShawn Guo id = app->id; 1973611cad72SShawn Guo break; 1974611cad72SShawn Guo } 1975611cad72SShawn Guo } 1976c05aba2bSPantelis Antoniou mutex_unlock(&of_mutex); 1977611cad72SShawn Guo 1978611cad72SShawn Guo return id; 1979611cad72SShawn Guo } 1980611cad72SShawn Guo EXPORT_SYMBOL_GPL(of_alias_get_id); 1981c541adc6SStephen Warren 1982351d224fSWolfram Sang /** 1983351d224fSWolfram Sang * of_alias_get_highest_id - Get highest alias id for the given stem 1984351d224fSWolfram Sang * @stem: Alias stem to be examined 1985351d224fSWolfram Sang * 1986351d224fSWolfram Sang * The function travels the lookup table to get the highest alias id for the 1987351d224fSWolfram Sang * given alias stem. It returns the alias id if found. 1988351d224fSWolfram Sang */ 1989351d224fSWolfram Sang int of_alias_get_highest_id(const char *stem) 1990351d224fSWolfram Sang { 1991351d224fSWolfram Sang struct alias_prop *app; 1992351d224fSWolfram Sang int id = -ENODEV; 1993351d224fSWolfram Sang 1994351d224fSWolfram Sang mutex_lock(&of_mutex); 1995351d224fSWolfram Sang list_for_each_entry(app, &aliases_lookup, link) { 1996351d224fSWolfram Sang if (strcmp(app->stem, stem) != 0) 1997351d224fSWolfram Sang continue; 1998351d224fSWolfram Sang 1999351d224fSWolfram Sang if (app->id > id) 2000351d224fSWolfram Sang id = app->id; 2001351d224fSWolfram Sang } 2002351d224fSWolfram Sang mutex_unlock(&of_mutex); 2003351d224fSWolfram Sang 2004351d224fSWolfram Sang return id; 2005351d224fSWolfram Sang } 2006351d224fSWolfram Sang EXPORT_SYMBOL_GPL(of_alias_get_highest_id); 2007351d224fSWolfram Sang 2008c541adc6SStephen Warren const __be32 *of_prop_next_u32(struct property *prop, const __be32 *cur, 2009c541adc6SStephen Warren u32 *pu) 2010c541adc6SStephen Warren { 2011c541adc6SStephen Warren const void *curv = cur; 2012c541adc6SStephen Warren 2013c541adc6SStephen Warren if (!prop) 2014c541adc6SStephen Warren return NULL; 2015c541adc6SStephen Warren 2016c541adc6SStephen Warren if (!cur) { 2017c541adc6SStephen Warren curv = prop->value; 2018c541adc6SStephen Warren goto out_val; 2019c541adc6SStephen Warren } 2020c541adc6SStephen Warren 2021c541adc6SStephen Warren curv += sizeof(*cur); 2022c541adc6SStephen Warren if (curv >= prop->value + prop->length) 2023c541adc6SStephen Warren return NULL; 2024c541adc6SStephen Warren 2025c541adc6SStephen Warren out_val: 2026c541adc6SStephen Warren *pu = be32_to_cpup(curv); 2027c541adc6SStephen Warren return curv; 2028c541adc6SStephen Warren } 2029c541adc6SStephen Warren EXPORT_SYMBOL_GPL(of_prop_next_u32); 2030c541adc6SStephen Warren 2031c541adc6SStephen Warren const char *of_prop_next_string(struct property *prop, const char *cur) 2032c541adc6SStephen Warren { 2033c541adc6SStephen Warren const void *curv = cur; 2034c541adc6SStephen Warren 2035c541adc6SStephen Warren if (!prop) 2036c541adc6SStephen Warren return NULL; 2037c541adc6SStephen Warren 2038c541adc6SStephen Warren if (!cur) 2039c541adc6SStephen Warren return prop->value; 2040c541adc6SStephen Warren 2041c541adc6SStephen Warren curv += strlen(cur) + 1; 2042c541adc6SStephen Warren if (curv >= prop->value + prop->length) 2043c541adc6SStephen Warren return NULL; 2044c541adc6SStephen Warren 2045c541adc6SStephen Warren return curv; 2046c541adc6SStephen Warren } 2047c541adc6SStephen Warren EXPORT_SYMBOL_GPL(of_prop_next_string); 20485c19e952SSascha Hauer 20495c19e952SSascha Hauer /** 20503482f2c5SGrant Likely * of_console_check() - Test and setup console for DT setup 20513482f2c5SGrant Likely * @dn - Pointer to device node 20523482f2c5SGrant Likely * @name - Name to use for preferred console without index. ex. "ttyS" 20533482f2c5SGrant Likely * @index - Index to use for preferred console. 20545c19e952SSascha Hauer * 20553482f2c5SGrant Likely * Check if the given device node matches the stdout-path property in the 20563482f2c5SGrant Likely * /chosen node. If it does then register it as the preferred console and return 20573482f2c5SGrant Likely * TRUE. Otherwise return FALSE. 20585c19e952SSascha Hauer */ 20593482f2c5SGrant Likely bool of_console_check(struct device_node *dn, char *name, int index) 20605c19e952SSascha Hauer { 20613482f2c5SGrant Likely if (!dn || dn != of_stdout || console_set_on_cmdline) 20625c19e952SSascha Hauer return false; 20637914a7c5SLeif Lindholm return !add_preferred_console(name, index, 20647914a7c5SLeif Lindholm kstrdup(of_stdout_options, GFP_KERNEL)); 20655c19e952SSascha Hauer } 20663482f2c5SGrant Likely EXPORT_SYMBOL_GPL(of_console_check); 2067a3e31b45SSudeep KarkadaNagesha 2068a3e31b45SSudeep KarkadaNagesha /** 2069a3e31b45SSudeep KarkadaNagesha * of_find_next_cache_node - Find a node's subsidiary cache 2070a3e31b45SSudeep KarkadaNagesha * @np: node of type "cpu" or "cache" 2071a3e31b45SSudeep KarkadaNagesha * 2072a3e31b45SSudeep KarkadaNagesha * Returns a node pointer with refcount incremented, use 2073a3e31b45SSudeep KarkadaNagesha * of_node_put() on it when done. Caller should hold a reference 2074a3e31b45SSudeep KarkadaNagesha * to np. 2075a3e31b45SSudeep KarkadaNagesha */ 2076a3e31b45SSudeep KarkadaNagesha struct device_node *of_find_next_cache_node(const struct device_node *np) 2077a3e31b45SSudeep KarkadaNagesha { 2078a3e31b45SSudeep KarkadaNagesha struct device_node *child; 2079a3e31b45SSudeep KarkadaNagesha const phandle *handle; 2080a3e31b45SSudeep KarkadaNagesha 2081a3e31b45SSudeep KarkadaNagesha handle = of_get_property(np, "l2-cache", NULL); 2082a3e31b45SSudeep KarkadaNagesha if (!handle) 2083a3e31b45SSudeep KarkadaNagesha handle = of_get_property(np, "next-level-cache", NULL); 2084a3e31b45SSudeep KarkadaNagesha 2085a3e31b45SSudeep KarkadaNagesha if (handle) 2086a3e31b45SSudeep KarkadaNagesha return of_find_node_by_phandle(be32_to_cpup(handle)); 2087a3e31b45SSudeep KarkadaNagesha 2088a3e31b45SSudeep KarkadaNagesha /* OF on pmac has nodes instead of properties named "l2-cache" 2089a3e31b45SSudeep KarkadaNagesha * beneath CPU nodes. 2090a3e31b45SSudeep KarkadaNagesha */ 2091a3e31b45SSudeep KarkadaNagesha if (!strcmp(np->type, "cpu")) 2092a3e31b45SSudeep KarkadaNagesha for_each_child_of_node(np, child) 2093a3e31b45SSudeep KarkadaNagesha if (!strcmp(child->type, "cache")) 2094a3e31b45SSudeep KarkadaNagesha return child; 2095a3e31b45SSudeep KarkadaNagesha 2096a3e31b45SSudeep KarkadaNagesha return NULL; 2097a3e31b45SSudeep KarkadaNagesha } 2098fd9fdb78SPhilipp Zabel 2099fd9fdb78SPhilipp Zabel /** 2100f2a575f6SPhilipp Zabel * of_graph_parse_endpoint() - parse common endpoint node properties 2101f2a575f6SPhilipp Zabel * @node: pointer to endpoint device_node 2102f2a575f6SPhilipp Zabel * @endpoint: pointer to the OF endpoint data structure 2103f2a575f6SPhilipp Zabel * 2104f2a575f6SPhilipp Zabel * The caller should hold a reference to @node. 2105f2a575f6SPhilipp Zabel */ 2106f2a575f6SPhilipp Zabel int of_graph_parse_endpoint(const struct device_node *node, 2107f2a575f6SPhilipp Zabel struct of_endpoint *endpoint) 2108f2a575f6SPhilipp Zabel { 2109f2a575f6SPhilipp Zabel struct device_node *port_node = of_get_parent(node); 2110f2a575f6SPhilipp Zabel 2111d484700aSPhilipp Zabel WARN_ONCE(!port_node, "%s(): endpoint %s has no parent node\n", 2112d484700aSPhilipp Zabel __func__, node->full_name); 2113d484700aSPhilipp Zabel 2114f2a575f6SPhilipp Zabel memset(endpoint, 0, sizeof(*endpoint)); 2115f2a575f6SPhilipp Zabel 2116f2a575f6SPhilipp Zabel endpoint->local_node = node; 2117f2a575f6SPhilipp Zabel /* 2118f2a575f6SPhilipp Zabel * It doesn't matter whether the two calls below succeed. 2119f2a575f6SPhilipp Zabel * If they don't then the default value 0 is used. 2120f2a575f6SPhilipp Zabel */ 2121f2a575f6SPhilipp Zabel of_property_read_u32(port_node, "reg", &endpoint->port); 2122f2a575f6SPhilipp Zabel of_property_read_u32(node, "reg", &endpoint->id); 2123f2a575f6SPhilipp Zabel 2124f2a575f6SPhilipp Zabel of_node_put(port_node); 2125f2a575f6SPhilipp Zabel 2126f2a575f6SPhilipp Zabel return 0; 2127f2a575f6SPhilipp Zabel } 2128f2a575f6SPhilipp Zabel EXPORT_SYMBOL(of_graph_parse_endpoint); 2129f2a575f6SPhilipp Zabel 2130f2a575f6SPhilipp Zabel /** 2131bfe446e3SPhilipp Zabel * of_graph_get_port_by_id() - get the port matching a given id 2132bfe446e3SPhilipp Zabel * @parent: pointer to the parent device node 2133bfe446e3SPhilipp Zabel * @id: id of the port 2134bfe446e3SPhilipp Zabel * 2135bfe446e3SPhilipp Zabel * Return: A 'port' node pointer with refcount incremented. The caller 2136bfe446e3SPhilipp Zabel * has to use of_node_put() on it when done. 2137bfe446e3SPhilipp Zabel */ 2138bfe446e3SPhilipp Zabel struct device_node *of_graph_get_port_by_id(struct device_node *parent, u32 id) 2139bfe446e3SPhilipp Zabel { 2140bfe446e3SPhilipp Zabel struct device_node *node, *port; 2141bfe446e3SPhilipp Zabel 2142bfe446e3SPhilipp Zabel node = of_get_child_by_name(parent, "ports"); 2143bfe446e3SPhilipp Zabel if (node) 2144bfe446e3SPhilipp Zabel parent = node; 2145bfe446e3SPhilipp Zabel 2146bfe446e3SPhilipp Zabel for_each_child_of_node(parent, port) { 2147bfe446e3SPhilipp Zabel u32 port_id = 0; 2148bfe446e3SPhilipp Zabel 2149bfe446e3SPhilipp Zabel if (of_node_cmp(port->name, "port") != 0) 2150bfe446e3SPhilipp Zabel continue; 2151bfe446e3SPhilipp Zabel of_property_read_u32(port, "reg", &port_id); 2152bfe446e3SPhilipp Zabel if (id == port_id) 2153bfe446e3SPhilipp Zabel break; 2154bfe446e3SPhilipp Zabel } 2155bfe446e3SPhilipp Zabel 2156bfe446e3SPhilipp Zabel of_node_put(node); 2157bfe446e3SPhilipp Zabel 2158bfe446e3SPhilipp Zabel return port; 2159bfe446e3SPhilipp Zabel } 2160bfe446e3SPhilipp Zabel EXPORT_SYMBOL(of_graph_get_port_by_id); 2161bfe446e3SPhilipp Zabel 2162bfe446e3SPhilipp Zabel /** 2163fd9fdb78SPhilipp Zabel * of_graph_get_next_endpoint() - get next endpoint node 2164fd9fdb78SPhilipp Zabel * @parent: pointer to the parent device node 2165fd9fdb78SPhilipp Zabel * @prev: previous endpoint node, or NULL to get first 2166fd9fdb78SPhilipp Zabel * 2167fd9fdb78SPhilipp Zabel * Return: An 'endpoint' node pointer with refcount incremented. Refcount 2168f033c0bcSPhilipp Zabel * of the passed @prev node is decremented. 2169fd9fdb78SPhilipp Zabel */ 2170fd9fdb78SPhilipp Zabel struct device_node *of_graph_get_next_endpoint(const struct device_node *parent, 2171fd9fdb78SPhilipp Zabel struct device_node *prev) 2172fd9fdb78SPhilipp Zabel { 2173fd9fdb78SPhilipp Zabel struct device_node *endpoint; 21743c83e61eSLinus Torvalds struct device_node *port; 2175fd9fdb78SPhilipp Zabel 2176fd9fdb78SPhilipp Zabel if (!parent) 2177fd9fdb78SPhilipp Zabel return NULL; 2178fd9fdb78SPhilipp Zabel 21793c83e61eSLinus Torvalds /* 21803c83e61eSLinus Torvalds * Start by locating the port node. If no previous endpoint is specified 21813c83e61eSLinus Torvalds * search for the first port node, otherwise get the previous endpoint 21823c83e61eSLinus Torvalds * parent port node. 21833c83e61eSLinus Torvalds */ 2184fd9fdb78SPhilipp Zabel if (!prev) { 2185fd9fdb78SPhilipp Zabel struct device_node *node; 21863c83e61eSLinus Torvalds 2187fd9fdb78SPhilipp Zabel node = of_get_child_by_name(parent, "ports"); 2188fd9fdb78SPhilipp Zabel if (node) 2189fd9fdb78SPhilipp Zabel parent = node; 2190fd9fdb78SPhilipp Zabel 2191fd9fdb78SPhilipp Zabel port = of_get_child_by_name(parent, "port"); 2192fd9fdb78SPhilipp Zabel of_node_put(node); 21934329b93bSPhilipp Zabel 21943c83e61eSLinus Torvalds if (!port) { 21953c83e61eSLinus Torvalds pr_err("%s(): no port node found in %s\n", 21963c83e61eSLinus Torvalds __func__, parent->full_name); 21973c83e61eSLinus Torvalds return NULL; 21984329b93bSPhilipp Zabel } 21993c83e61eSLinus Torvalds } else { 2200fd9fdb78SPhilipp Zabel port = of_get_parent(prev); 22016ff60d39SPhilipp Zabel if (WARN_ONCE(!port, "%s(): endpoint %s has no parent node\n", 22026ff60d39SPhilipp Zabel __func__, prev->full_name)) 2203fd9fdb78SPhilipp Zabel return NULL; 22043c83e61eSLinus Torvalds } 22053c83e61eSLinus Torvalds 22063c83e61eSLinus Torvalds while (1) { 22073c83e61eSLinus Torvalds /* 22083c83e61eSLinus Torvalds * Now that we have a port node, get the next endpoint by 22093c83e61eSLinus Torvalds * getting the next child. If the previous endpoint is NULL this 22103c83e61eSLinus Torvalds * will return the first child. 22113c83e61eSLinus Torvalds */ 2212fd9fdb78SPhilipp Zabel endpoint = of_get_next_child(port, prev); 2213fd9fdb78SPhilipp Zabel if (endpoint) { 2214fd9fdb78SPhilipp Zabel of_node_put(port); 2215fd9fdb78SPhilipp Zabel return endpoint; 2216fd9fdb78SPhilipp Zabel } 2217fd9fdb78SPhilipp Zabel 2218fd9fdb78SPhilipp Zabel /* No more endpoints under this port, try the next one. */ 22193c83e61eSLinus Torvalds prev = NULL; 22203c83e61eSLinus Torvalds 2221fd9fdb78SPhilipp Zabel do { 2222fd9fdb78SPhilipp Zabel port = of_get_next_child(parent, port); 2223fd9fdb78SPhilipp Zabel if (!port) 2224fd9fdb78SPhilipp Zabel return NULL; 2225fd9fdb78SPhilipp Zabel } while (of_node_cmp(port->name, "port")); 22263c83e61eSLinus Torvalds } 2227fd9fdb78SPhilipp Zabel } 2228fd9fdb78SPhilipp Zabel EXPORT_SYMBOL(of_graph_get_next_endpoint); 2229fd9fdb78SPhilipp Zabel 2230fd9fdb78SPhilipp Zabel /** 22318ccd0d0cSHyungwon Hwang * of_graph_get_endpoint_by_regs() - get endpoint node of specific identifiers 22328ccd0d0cSHyungwon Hwang * @parent: pointer to the parent device node 22338ccd0d0cSHyungwon Hwang * @port_reg: identifier (value of reg property) of the parent port node 22348ccd0d0cSHyungwon Hwang * @reg: identifier (value of reg property) of the endpoint node 22358ccd0d0cSHyungwon Hwang * 22368ccd0d0cSHyungwon Hwang * Return: An 'endpoint' node pointer which is identified by reg and at the same 22378ccd0d0cSHyungwon Hwang * is the child of a port node identified by port_reg. reg and port_reg are 22388ccd0d0cSHyungwon Hwang * ignored when they are -1. 22398ccd0d0cSHyungwon Hwang */ 22408ccd0d0cSHyungwon Hwang struct device_node *of_graph_get_endpoint_by_regs( 22418ccd0d0cSHyungwon Hwang const struct device_node *parent, int port_reg, int reg) 22428ccd0d0cSHyungwon Hwang { 22438ccd0d0cSHyungwon Hwang struct of_endpoint endpoint; 22448ccd0d0cSHyungwon Hwang struct device_node *node, *prev_node = NULL; 22458ccd0d0cSHyungwon Hwang 22468ccd0d0cSHyungwon Hwang while (1) { 22478ccd0d0cSHyungwon Hwang node = of_graph_get_next_endpoint(parent, prev_node); 22488ccd0d0cSHyungwon Hwang of_node_put(prev_node); 22498ccd0d0cSHyungwon Hwang if (!node) 22508ccd0d0cSHyungwon Hwang break; 22518ccd0d0cSHyungwon Hwang 22528ccd0d0cSHyungwon Hwang of_graph_parse_endpoint(node, &endpoint); 22538ccd0d0cSHyungwon Hwang if (((port_reg == -1) || (endpoint.port == port_reg)) && 22548ccd0d0cSHyungwon Hwang ((reg == -1) || (endpoint.id == reg))) 22558ccd0d0cSHyungwon Hwang return node; 22568ccd0d0cSHyungwon Hwang 22578ccd0d0cSHyungwon Hwang prev_node = node; 22588ccd0d0cSHyungwon Hwang } 22598ccd0d0cSHyungwon Hwang 22608ccd0d0cSHyungwon Hwang return NULL; 22618ccd0d0cSHyungwon Hwang } 22628ffaa903SDave Airlie EXPORT_SYMBOL(of_graph_get_endpoint_by_regs); 22638ccd0d0cSHyungwon Hwang 22648ccd0d0cSHyungwon Hwang /** 2265fd9fdb78SPhilipp Zabel * of_graph_get_remote_port_parent() - get remote port's parent node 2266fd9fdb78SPhilipp Zabel * @node: pointer to a local endpoint device_node 2267fd9fdb78SPhilipp Zabel * 2268fd9fdb78SPhilipp Zabel * Return: Remote device node associated with remote endpoint node linked 2269fd9fdb78SPhilipp Zabel * to @node. Use of_node_put() on it when done. 2270fd9fdb78SPhilipp Zabel */ 2271fd9fdb78SPhilipp Zabel struct device_node *of_graph_get_remote_port_parent( 2272fd9fdb78SPhilipp Zabel const struct device_node *node) 2273fd9fdb78SPhilipp Zabel { 2274fd9fdb78SPhilipp Zabel struct device_node *np; 2275fd9fdb78SPhilipp Zabel unsigned int depth; 2276fd9fdb78SPhilipp Zabel 2277fd9fdb78SPhilipp Zabel /* Get remote endpoint node. */ 2278fd9fdb78SPhilipp Zabel np = of_parse_phandle(node, "remote-endpoint", 0); 2279fd9fdb78SPhilipp Zabel 2280fd9fdb78SPhilipp Zabel /* Walk 3 levels up only if there is 'ports' node. */ 2281fd9fdb78SPhilipp Zabel for (depth = 3; depth && np; depth--) { 2282fd9fdb78SPhilipp Zabel np = of_get_next_parent(np); 2283fd9fdb78SPhilipp Zabel if (depth == 2 && of_node_cmp(np->name, "ports")) 2284fd9fdb78SPhilipp Zabel break; 2285fd9fdb78SPhilipp Zabel } 2286fd9fdb78SPhilipp Zabel return np; 2287fd9fdb78SPhilipp Zabel } 2288fd9fdb78SPhilipp Zabel EXPORT_SYMBOL(of_graph_get_remote_port_parent); 2289fd9fdb78SPhilipp Zabel 2290fd9fdb78SPhilipp Zabel /** 2291fd9fdb78SPhilipp Zabel * of_graph_get_remote_port() - get remote port node 2292fd9fdb78SPhilipp Zabel * @node: pointer to a local endpoint device_node 2293fd9fdb78SPhilipp Zabel * 2294fd9fdb78SPhilipp Zabel * Return: Remote port node associated with remote endpoint node linked 2295fd9fdb78SPhilipp Zabel * to @node. Use of_node_put() on it when done. 2296fd9fdb78SPhilipp Zabel */ 2297fd9fdb78SPhilipp Zabel struct device_node *of_graph_get_remote_port(const struct device_node *node) 2298fd9fdb78SPhilipp Zabel { 2299fd9fdb78SPhilipp Zabel struct device_node *np; 2300fd9fdb78SPhilipp Zabel 2301fd9fdb78SPhilipp Zabel /* Get remote endpoint node. */ 2302fd9fdb78SPhilipp Zabel np = of_parse_phandle(node, "remote-endpoint", 0); 2303fd9fdb78SPhilipp Zabel if (!np) 2304fd9fdb78SPhilipp Zabel return NULL; 2305fd9fdb78SPhilipp Zabel return of_get_next_parent(np); 2306fd9fdb78SPhilipp Zabel } 2307fd9fdb78SPhilipp Zabel EXPORT_SYMBOL(of_graph_get_remote_port); 2308