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 { 920c3f061cSRob Herring return numa_node_id(); 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 19275b57ecfSGrant Likely static int __init of_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); 20175b57ecfSGrant Likely return -ENOMEM; 20275b57ecfSGrant Likely } 20375b57ecfSGrant Likely for_each_of_allnodes(np) 2048a2b22a2SGrant Likely __of_attach_node_sysfs(np); 205c05aba2bSPantelis Antoniou mutex_unlock(&of_mutex); 20675b57ecfSGrant Likely 2078357041aSGrant Likely /* Symlink in /proc as required by userspace ABI */ 2085063e25aSGrant Likely if (of_root) 20975b57ecfSGrant Likely proc_symlink("device-tree", NULL, "/sys/firmware/devicetree/base"); 21075b57ecfSGrant Likely 21175b57ecfSGrant Likely return 0; 21275b57ecfSGrant Likely } 21375b57ecfSGrant Likely core_initcall(of_init); 21475b57ecfSGrant Likely 21528d0e36bSThomas Gleixner static struct property *__of_find_property(const struct device_node *np, 21628d0e36bSThomas Gleixner const char *name, int *lenp) 217581b605aSStephen Rothwell { 218581b605aSStephen Rothwell struct property *pp; 219581b605aSStephen Rothwell 22064e4566fSTimur Tabi if (!np) 22164e4566fSTimur Tabi return NULL; 22264e4566fSTimur Tabi 223a3a7cab1SSachin Kamat for (pp = np->properties; pp; pp = pp->next) { 224581b605aSStephen Rothwell if (of_prop_cmp(pp->name, name) == 0) { 225a3a7cab1SSachin Kamat if (lenp) 226581b605aSStephen Rothwell *lenp = pp->length; 227581b605aSStephen Rothwell break; 228581b605aSStephen Rothwell } 229581b605aSStephen Rothwell } 23028d0e36bSThomas Gleixner 23128d0e36bSThomas Gleixner return pp; 23228d0e36bSThomas Gleixner } 23328d0e36bSThomas Gleixner 23428d0e36bSThomas Gleixner struct property *of_find_property(const struct device_node *np, 23528d0e36bSThomas Gleixner const char *name, 23628d0e36bSThomas Gleixner int *lenp) 23728d0e36bSThomas Gleixner { 23828d0e36bSThomas Gleixner struct property *pp; 239d6d3c4e6SThomas Gleixner unsigned long flags; 24028d0e36bSThomas Gleixner 241d6d3c4e6SThomas Gleixner raw_spin_lock_irqsave(&devtree_lock, flags); 24228d0e36bSThomas Gleixner pp = __of_find_property(np, name, lenp); 243d6d3c4e6SThomas Gleixner raw_spin_unlock_irqrestore(&devtree_lock, flags); 244581b605aSStephen Rothwell 245581b605aSStephen Rothwell return pp; 246581b605aSStephen Rothwell } 247581b605aSStephen Rothwell EXPORT_SYMBOL(of_find_property); 248581b605aSStephen Rothwell 2495063e25aSGrant Likely struct device_node *__of_find_all_nodes(struct device_node *prev) 2505063e25aSGrant Likely { 2515063e25aSGrant Likely struct device_node *np; 2525063e25aSGrant Likely if (!prev) { 2535063e25aSGrant Likely np = of_root; 2545063e25aSGrant Likely } else if (prev->child) { 2555063e25aSGrant Likely np = prev->child; 2565063e25aSGrant Likely } else { 2575063e25aSGrant Likely /* Walk back up looking for a sibling, or the end of the structure */ 2585063e25aSGrant Likely np = prev; 2595063e25aSGrant Likely while (np->parent && !np->sibling) 2605063e25aSGrant Likely np = np->parent; 2615063e25aSGrant Likely np = np->sibling; /* Might be null at the end of the tree */ 2625063e25aSGrant Likely } 2635063e25aSGrant Likely return np; 2645063e25aSGrant Likely } 2655063e25aSGrant Likely 266e91edcf5SGrant Likely /** 267e91edcf5SGrant Likely * of_find_all_nodes - Get next node in global list 268e91edcf5SGrant Likely * @prev: Previous node or NULL to start iteration 269e91edcf5SGrant Likely * of_node_put() will be called on it 270e91edcf5SGrant Likely * 271e91edcf5SGrant Likely * Returns a node pointer with refcount incremented, use 272e91edcf5SGrant Likely * of_node_put() on it when done. 273e91edcf5SGrant Likely */ 274e91edcf5SGrant Likely struct device_node *of_find_all_nodes(struct device_node *prev) 275e91edcf5SGrant Likely { 276e91edcf5SGrant Likely struct device_node *np; 277d25d8694SBenjamin Herrenschmidt unsigned long flags; 278e91edcf5SGrant Likely 279d25d8694SBenjamin Herrenschmidt raw_spin_lock_irqsave(&devtree_lock, flags); 2805063e25aSGrant Likely np = __of_find_all_nodes(prev); 2815063e25aSGrant Likely of_node_get(np); 282e91edcf5SGrant Likely of_node_put(prev); 283d25d8694SBenjamin Herrenschmidt raw_spin_unlock_irqrestore(&devtree_lock, flags); 284e91edcf5SGrant Likely return np; 285e91edcf5SGrant Likely } 286e91edcf5SGrant Likely EXPORT_SYMBOL(of_find_all_nodes); 287e91edcf5SGrant Likely 28897e873e5SStephen Rothwell /* 28997e873e5SStephen Rothwell * Find a property with a given name for a given node 29097e873e5SStephen Rothwell * and return the value. 29197e873e5SStephen Rothwell */ 292a25095d4SGrant Likely const void *__of_get_property(const struct device_node *np, 29328d0e36bSThomas Gleixner const char *name, int *lenp) 29428d0e36bSThomas Gleixner { 29528d0e36bSThomas Gleixner struct property *pp = __of_find_property(np, name, lenp); 29628d0e36bSThomas Gleixner 29728d0e36bSThomas Gleixner return pp ? pp->value : NULL; 29828d0e36bSThomas Gleixner } 29928d0e36bSThomas Gleixner 30028d0e36bSThomas Gleixner /* 30128d0e36bSThomas Gleixner * Find a property with a given name for a given node 30228d0e36bSThomas Gleixner * and return the value. 30328d0e36bSThomas Gleixner */ 30497e873e5SStephen Rothwell const void *of_get_property(const struct device_node *np, const char *name, 30597e873e5SStephen Rothwell int *lenp) 30697e873e5SStephen Rothwell { 30797e873e5SStephen Rothwell struct property *pp = of_find_property(np, name, lenp); 30897e873e5SStephen Rothwell 30997e873e5SStephen Rothwell return pp ? pp->value : NULL; 31097e873e5SStephen Rothwell } 31197e873e5SStephen Rothwell EXPORT_SYMBOL(of_get_property); 3120081cbc3SStephen Rothwell 313183912d3SSudeep KarkadaNagesha /* 314183912d3SSudeep KarkadaNagesha * arch_match_cpu_phys_id - Match the given logical CPU and physical id 315183912d3SSudeep KarkadaNagesha * 316183912d3SSudeep KarkadaNagesha * @cpu: logical cpu index of a core/thread 317183912d3SSudeep KarkadaNagesha * @phys_id: physical identifier of a core/thread 318183912d3SSudeep KarkadaNagesha * 319183912d3SSudeep KarkadaNagesha * CPU logical to physical index mapping is architecture specific. 320183912d3SSudeep KarkadaNagesha * However this __weak function provides a default match of physical 321183912d3SSudeep KarkadaNagesha * id to logical cpu index. phys_id provided here is usually values read 322183912d3SSudeep KarkadaNagesha * from the device tree which must match the hardware internal registers. 323183912d3SSudeep KarkadaNagesha * 324183912d3SSudeep KarkadaNagesha * Returns true if the physical identifier and the logical cpu index 325183912d3SSudeep KarkadaNagesha * correspond to the same core/thread, false otherwise. 326183912d3SSudeep KarkadaNagesha */ 327183912d3SSudeep KarkadaNagesha bool __weak arch_match_cpu_phys_id(int cpu, u64 phys_id) 328183912d3SSudeep KarkadaNagesha { 329183912d3SSudeep KarkadaNagesha return (u32)phys_id == cpu; 330183912d3SSudeep KarkadaNagesha } 331183912d3SSudeep KarkadaNagesha 332183912d3SSudeep KarkadaNagesha /** 333183912d3SSudeep KarkadaNagesha * Checks if the given "prop_name" property holds the physical id of the 334183912d3SSudeep KarkadaNagesha * core/thread corresponding to the logical cpu 'cpu'. If 'thread' is not 335183912d3SSudeep KarkadaNagesha * NULL, local thread number within the core is returned in it. 336183912d3SSudeep KarkadaNagesha */ 337183912d3SSudeep KarkadaNagesha static bool __of_find_n_match_cpu_property(struct device_node *cpun, 338183912d3SSudeep KarkadaNagesha const char *prop_name, int cpu, unsigned int *thread) 339183912d3SSudeep KarkadaNagesha { 340183912d3SSudeep KarkadaNagesha const __be32 *cell; 341183912d3SSudeep KarkadaNagesha int ac, prop_len, tid; 342183912d3SSudeep KarkadaNagesha u64 hwid; 343183912d3SSudeep KarkadaNagesha 344183912d3SSudeep KarkadaNagesha ac = of_n_addr_cells(cpun); 345183912d3SSudeep KarkadaNagesha cell = of_get_property(cpun, prop_name, &prop_len); 346f3cea45aSGrant Likely if (!cell || !ac) 347183912d3SSudeep KarkadaNagesha return false; 348f3cea45aSGrant Likely prop_len /= sizeof(*cell) * ac; 349183912d3SSudeep KarkadaNagesha for (tid = 0; tid < prop_len; tid++) { 350183912d3SSudeep KarkadaNagesha hwid = of_read_number(cell, ac); 351183912d3SSudeep KarkadaNagesha if (arch_match_cpu_phys_id(cpu, hwid)) { 352183912d3SSudeep KarkadaNagesha if (thread) 353183912d3SSudeep KarkadaNagesha *thread = tid; 354183912d3SSudeep KarkadaNagesha return true; 355183912d3SSudeep KarkadaNagesha } 356183912d3SSudeep KarkadaNagesha cell += ac; 357183912d3SSudeep KarkadaNagesha } 358183912d3SSudeep KarkadaNagesha return false; 359183912d3SSudeep KarkadaNagesha } 360183912d3SSudeep KarkadaNagesha 361d1cb9d1aSDavid Miller /* 362d1cb9d1aSDavid Miller * arch_find_n_match_cpu_physical_id - See if the given device node is 363d1cb9d1aSDavid Miller * for the cpu corresponding to logical cpu 'cpu'. Return true if so, 364d1cb9d1aSDavid Miller * else false. If 'thread' is non-NULL, the local thread number within the 365d1cb9d1aSDavid Miller * core is returned in it. 366d1cb9d1aSDavid Miller */ 367d1cb9d1aSDavid Miller bool __weak arch_find_n_match_cpu_physical_id(struct device_node *cpun, 368d1cb9d1aSDavid Miller int cpu, unsigned int *thread) 369d1cb9d1aSDavid Miller { 370d1cb9d1aSDavid Miller /* Check for non-standard "ibm,ppc-interrupt-server#s" property 371d1cb9d1aSDavid Miller * for thread ids on PowerPC. If it doesn't exist fallback to 372d1cb9d1aSDavid Miller * standard "reg" property. 373d1cb9d1aSDavid Miller */ 374d1cb9d1aSDavid Miller if (IS_ENABLED(CONFIG_PPC) && 375d1cb9d1aSDavid Miller __of_find_n_match_cpu_property(cpun, 376d1cb9d1aSDavid Miller "ibm,ppc-interrupt-server#s", 377d1cb9d1aSDavid Miller cpu, thread)) 378d1cb9d1aSDavid Miller return true; 379d1cb9d1aSDavid Miller 380d1cb9d1aSDavid Miller if (__of_find_n_match_cpu_property(cpun, "reg", cpu, thread)) 381d1cb9d1aSDavid Miller return true; 382d1cb9d1aSDavid Miller 383d1cb9d1aSDavid Miller return false; 384d1cb9d1aSDavid Miller } 385d1cb9d1aSDavid Miller 386183912d3SSudeep KarkadaNagesha /** 387183912d3SSudeep KarkadaNagesha * of_get_cpu_node - Get device node associated with the given logical CPU 388183912d3SSudeep KarkadaNagesha * 389183912d3SSudeep KarkadaNagesha * @cpu: CPU number(logical index) for which device node is required 390183912d3SSudeep KarkadaNagesha * @thread: if not NULL, local thread number within the physical core is 391183912d3SSudeep KarkadaNagesha * returned 392183912d3SSudeep KarkadaNagesha * 393183912d3SSudeep KarkadaNagesha * The main purpose of this function is to retrieve the device node for the 394183912d3SSudeep KarkadaNagesha * given logical CPU index. It should be used to initialize the of_node in 395183912d3SSudeep KarkadaNagesha * cpu device. Once of_node in cpu device is populated, all the further 396183912d3SSudeep KarkadaNagesha * references can use that instead. 397183912d3SSudeep KarkadaNagesha * 398183912d3SSudeep KarkadaNagesha * CPU logical to physical index mapping is architecture specific and is built 399183912d3SSudeep KarkadaNagesha * before booting secondary cores. This function uses arch_match_cpu_phys_id 400183912d3SSudeep KarkadaNagesha * which can be overridden by architecture specific implementation. 401183912d3SSudeep KarkadaNagesha * 402183912d3SSudeep KarkadaNagesha * Returns a node pointer for the logical cpu if found, else NULL. 403183912d3SSudeep KarkadaNagesha */ 404183912d3SSudeep KarkadaNagesha struct device_node *of_get_cpu_node(int cpu, unsigned int *thread) 405183912d3SSudeep KarkadaNagesha { 406d1cb9d1aSDavid Miller struct device_node *cpun; 407183912d3SSudeep KarkadaNagesha 408d1cb9d1aSDavid Miller for_each_node_by_type(cpun, "cpu") { 409d1cb9d1aSDavid Miller if (arch_find_n_match_cpu_physical_id(cpun, cpu, thread)) 410183912d3SSudeep KarkadaNagesha return cpun; 411183912d3SSudeep KarkadaNagesha } 412183912d3SSudeep KarkadaNagesha return NULL; 413183912d3SSudeep KarkadaNagesha } 414183912d3SSudeep KarkadaNagesha EXPORT_SYMBOL(of_get_cpu_node); 415183912d3SSudeep KarkadaNagesha 416215a14cfSKevin Hao /** 417215a14cfSKevin Hao * __of_device_is_compatible() - Check if the node matches given constraints 418215a14cfSKevin Hao * @device: pointer to node 419215a14cfSKevin Hao * @compat: required compatible string, NULL or "" for any match 420215a14cfSKevin Hao * @type: required device_type value, NULL or "" for any match 421215a14cfSKevin Hao * @name: required node name, NULL or "" for any match 422215a14cfSKevin Hao * 423215a14cfSKevin Hao * Checks if the given @compat, @type and @name strings match the 424215a14cfSKevin Hao * properties of the given @device. A constraints can be skipped by 425215a14cfSKevin Hao * passing NULL or an empty string as the constraint. 426215a14cfSKevin Hao * 427215a14cfSKevin Hao * Returns 0 for no match, and a positive integer on match. The return 428215a14cfSKevin Hao * value is a relative score with larger values indicating better 429215a14cfSKevin Hao * matches. The score is weighted for the most specific compatible value 430215a14cfSKevin Hao * to get the highest score. Matching type is next, followed by matching 431215a14cfSKevin Hao * name. Practically speaking, this results in the following priority 432215a14cfSKevin Hao * order for matches: 433215a14cfSKevin Hao * 434215a14cfSKevin Hao * 1. specific compatible && type && name 435215a14cfSKevin Hao * 2. specific compatible && type 436215a14cfSKevin Hao * 3. specific compatible && name 437215a14cfSKevin Hao * 4. specific compatible 438215a14cfSKevin Hao * 5. general compatible && type && name 439215a14cfSKevin Hao * 6. general compatible && type 440215a14cfSKevin Hao * 7. general compatible && name 441215a14cfSKevin Hao * 8. general compatible 442215a14cfSKevin Hao * 9. type && name 443215a14cfSKevin Hao * 10. type 444215a14cfSKevin Hao * 11. name 4450081cbc3SStephen Rothwell */ 44628d0e36bSThomas Gleixner static int __of_device_is_compatible(const struct device_node *device, 447215a14cfSKevin Hao const char *compat, const char *type, const char *name) 4480081cbc3SStephen Rothwell { 449215a14cfSKevin Hao struct property *prop; 4500081cbc3SStephen Rothwell const char *cp; 451215a14cfSKevin Hao int index = 0, score = 0; 4520081cbc3SStephen Rothwell 453215a14cfSKevin Hao /* Compatible match has highest priority */ 454215a14cfSKevin Hao if (compat && compat[0]) { 455215a14cfSKevin Hao prop = __of_find_property(device, "compatible", NULL); 456215a14cfSKevin Hao for (cp = of_prop_next_string(prop, NULL); cp; 457215a14cfSKevin Hao cp = of_prop_next_string(prop, cp), index++) { 458215a14cfSKevin Hao if (of_compat_cmp(cp, compat, strlen(compat)) == 0) { 459215a14cfSKevin Hao score = INT_MAX/2 - (index << 2); 460215a14cfSKevin Hao break; 461215a14cfSKevin Hao } 462215a14cfSKevin Hao } 463215a14cfSKevin Hao if (!score) 4640081cbc3SStephen Rothwell return 0; 4650081cbc3SStephen Rothwell } 4660081cbc3SStephen Rothwell 467215a14cfSKevin Hao /* Matching type is better than matching name */ 468215a14cfSKevin Hao if (type && type[0]) { 469215a14cfSKevin Hao if (!device->type || of_node_cmp(type, device->type)) 4700081cbc3SStephen Rothwell return 0; 471215a14cfSKevin Hao score += 2; 472215a14cfSKevin Hao } 473215a14cfSKevin Hao 474215a14cfSKevin Hao /* Matching name is a bit better than not */ 475215a14cfSKevin Hao if (name && name[0]) { 476215a14cfSKevin Hao if (!device->name || of_node_cmp(name, device->name)) 477215a14cfSKevin Hao return 0; 478215a14cfSKevin Hao score++; 479215a14cfSKevin Hao } 480215a14cfSKevin Hao 481215a14cfSKevin Hao return score; 4820081cbc3SStephen Rothwell } 48328d0e36bSThomas Gleixner 48428d0e36bSThomas Gleixner /** Checks if the given "compat" string matches one of the strings in 48528d0e36bSThomas Gleixner * the device's "compatible" property 48628d0e36bSThomas Gleixner */ 48728d0e36bSThomas Gleixner int of_device_is_compatible(const struct device_node *device, 48828d0e36bSThomas Gleixner const char *compat) 48928d0e36bSThomas Gleixner { 490d6d3c4e6SThomas Gleixner unsigned long flags; 49128d0e36bSThomas Gleixner int res; 49228d0e36bSThomas Gleixner 493d6d3c4e6SThomas Gleixner raw_spin_lock_irqsave(&devtree_lock, flags); 494215a14cfSKevin Hao res = __of_device_is_compatible(device, compat, NULL, NULL); 495d6d3c4e6SThomas Gleixner raw_spin_unlock_irqrestore(&devtree_lock, flags); 49628d0e36bSThomas Gleixner return res; 49728d0e36bSThomas Gleixner } 4980081cbc3SStephen Rothwell EXPORT_SYMBOL(of_device_is_compatible); 499e679c5f4SStephen Rothwell 500e679c5f4SStephen Rothwell /** 50171a157e8SGrant Likely * of_machine_is_compatible - Test root of device tree for a given compatible value 5021f43cfb9SGrant Likely * @compat: compatible string to look for in root node's compatible property. 5031f43cfb9SGrant Likely * 50425c7a1deSKevin Cernekee * Returns a positive integer if the root node has the given value in its 5051f43cfb9SGrant Likely * compatible property. 5061f43cfb9SGrant Likely */ 50771a157e8SGrant Likely int of_machine_is_compatible(const char *compat) 5081f43cfb9SGrant Likely { 5091f43cfb9SGrant Likely struct device_node *root; 5101f43cfb9SGrant Likely int rc = 0; 5111f43cfb9SGrant Likely 5121f43cfb9SGrant Likely root = of_find_node_by_path("/"); 5131f43cfb9SGrant Likely if (root) { 5141f43cfb9SGrant Likely rc = of_device_is_compatible(root, compat); 5151f43cfb9SGrant Likely of_node_put(root); 5161f43cfb9SGrant Likely } 5171f43cfb9SGrant Likely return rc; 5181f43cfb9SGrant Likely } 51971a157e8SGrant Likely EXPORT_SYMBOL(of_machine_is_compatible); 5201f43cfb9SGrant Likely 5211f43cfb9SGrant Likely /** 522c31a0c05SStephen Warren * __of_device_is_available - check if a device is available for use 523834d97d4SJosh Boyer * 524c31a0c05SStephen Warren * @device: Node to check for availability, with locks already held 525834d97d4SJosh Boyer * 52653a4ab96SKevin Cernekee * Returns true if the status property is absent or set to "okay" or "ok", 52753a4ab96SKevin Cernekee * false otherwise 528834d97d4SJosh Boyer */ 52953a4ab96SKevin Cernekee static bool __of_device_is_available(const struct device_node *device) 530834d97d4SJosh Boyer { 531834d97d4SJosh Boyer const char *status; 532834d97d4SJosh Boyer int statlen; 533834d97d4SJosh Boyer 53442ccd781SXiubo Li if (!device) 53553a4ab96SKevin Cernekee return false; 53642ccd781SXiubo Li 537c31a0c05SStephen Warren status = __of_get_property(device, "status", &statlen); 538834d97d4SJosh Boyer if (status == NULL) 53953a4ab96SKevin Cernekee return true; 540834d97d4SJosh Boyer 541834d97d4SJosh Boyer if (statlen > 0) { 542834d97d4SJosh Boyer if (!strcmp(status, "okay") || !strcmp(status, "ok")) 54353a4ab96SKevin Cernekee return true; 544834d97d4SJosh Boyer } 545834d97d4SJosh Boyer 54653a4ab96SKevin Cernekee return false; 547834d97d4SJosh Boyer } 548c31a0c05SStephen Warren 549c31a0c05SStephen Warren /** 550c31a0c05SStephen Warren * of_device_is_available - check if a device is available for use 551c31a0c05SStephen Warren * 552c31a0c05SStephen Warren * @device: Node to check for availability 553c31a0c05SStephen Warren * 55453a4ab96SKevin Cernekee * Returns true if the status property is absent or set to "okay" or "ok", 55553a4ab96SKevin Cernekee * false otherwise 556c31a0c05SStephen Warren */ 55753a4ab96SKevin Cernekee bool of_device_is_available(const struct device_node *device) 558c31a0c05SStephen Warren { 559c31a0c05SStephen Warren unsigned long flags; 56053a4ab96SKevin Cernekee bool res; 561c31a0c05SStephen Warren 562c31a0c05SStephen Warren raw_spin_lock_irqsave(&devtree_lock, flags); 563c31a0c05SStephen Warren res = __of_device_is_available(device); 564c31a0c05SStephen Warren raw_spin_unlock_irqrestore(&devtree_lock, flags); 565c31a0c05SStephen Warren return res; 566c31a0c05SStephen Warren 567c31a0c05SStephen Warren } 568834d97d4SJosh Boyer EXPORT_SYMBOL(of_device_is_available); 569834d97d4SJosh Boyer 570834d97d4SJosh Boyer /** 571e679c5f4SStephen Rothwell * of_get_parent - Get a node's parent if any 572e679c5f4SStephen Rothwell * @node: Node to get parent 573e679c5f4SStephen Rothwell * 574e679c5f4SStephen Rothwell * Returns a node pointer with refcount incremented, use 575e679c5f4SStephen Rothwell * of_node_put() on it when done. 576e679c5f4SStephen Rothwell */ 577e679c5f4SStephen Rothwell struct device_node *of_get_parent(const struct device_node *node) 578e679c5f4SStephen Rothwell { 579e679c5f4SStephen Rothwell struct device_node *np; 580d6d3c4e6SThomas Gleixner unsigned long flags; 581e679c5f4SStephen Rothwell 582e679c5f4SStephen Rothwell if (!node) 583e679c5f4SStephen Rothwell return NULL; 584e679c5f4SStephen Rothwell 585d6d3c4e6SThomas Gleixner raw_spin_lock_irqsave(&devtree_lock, flags); 586e679c5f4SStephen Rothwell np = of_node_get(node->parent); 587d6d3c4e6SThomas Gleixner raw_spin_unlock_irqrestore(&devtree_lock, flags); 588e679c5f4SStephen Rothwell return np; 589e679c5f4SStephen Rothwell } 590e679c5f4SStephen Rothwell EXPORT_SYMBOL(of_get_parent); 591d1cd355aSStephen Rothwell 592d1cd355aSStephen Rothwell /** 593f4eb0107SMichael Ellerman * of_get_next_parent - Iterate to a node's parent 594f4eb0107SMichael Ellerman * @node: Node to get parent of 595f4eb0107SMichael Ellerman * 596f4eb0107SMichael Ellerman * This is like of_get_parent() except that it drops the 597f4eb0107SMichael Ellerman * refcount on the passed node, making it suitable for iterating 598f4eb0107SMichael Ellerman * through a node's parents. 599f4eb0107SMichael Ellerman * 600f4eb0107SMichael Ellerman * Returns a node pointer with refcount incremented, use 601f4eb0107SMichael Ellerman * of_node_put() on it when done. 602f4eb0107SMichael Ellerman */ 603f4eb0107SMichael Ellerman struct device_node *of_get_next_parent(struct device_node *node) 604f4eb0107SMichael Ellerman { 605f4eb0107SMichael Ellerman struct device_node *parent; 606d6d3c4e6SThomas Gleixner unsigned long flags; 607f4eb0107SMichael Ellerman 608f4eb0107SMichael Ellerman if (!node) 609f4eb0107SMichael Ellerman return NULL; 610f4eb0107SMichael Ellerman 611d6d3c4e6SThomas Gleixner raw_spin_lock_irqsave(&devtree_lock, flags); 612f4eb0107SMichael Ellerman parent = of_node_get(node->parent); 613f4eb0107SMichael Ellerman of_node_put(node); 614d6d3c4e6SThomas Gleixner raw_spin_unlock_irqrestore(&devtree_lock, flags); 615f4eb0107SMichael Ellerman return parent; 616f4eb0107SMichael Ellerman } 6176695be68SGuennadi Liakhovetski EXPORT_SYMBOL(of_get_next_parent); 618f4eb0107SMichael Ellerman 6190d0e02d6SGrant Likely static struct device_node *__of_get_next_child(const struct device_node *node, 6200d0e02d6SGrant Likely struct device_node *prev) 6210d0e02d6SGrant Likely { 6220d0e02d6SGrant Likely struct device_node *next; 6230d0e02d6SGrant Likely 62443cb4367SFlorian Fainelli if (!node) 62543cb4367SFlorian Fainelli return NULL; 62643cb4367SFlorian Fainelli 6270d0e02d6SGrant Likely next = prev ? prev->sibling : node->child; 6280d0e02d6SGrant Likely for (; next; next = next->sibling) 6290d0e02d6SGrant Likely if (of_node_get(next)) 6300d0e02d6SGrant Likely break; 6310d0e02d6SGrant Likely of_node_put(prev); 6320d0e02d6SGrant Likely return next; 6330d0e02d6SGrant Likely } 6340d0e02d6SGrant Likely #define __for_each_child_of_node(parent, child) \ 6350d0e02d6SGrant Likely for (child = __of_get_next_child(parent, NULL); child != NULL; \ 6360d0e02d6SGrant Likely child = __of_get_next_child(parent, child)) 6370d0e02d6SGrant Likely 638f4eb0107SMichael Ellerman /** 639d1cd355aSStephen Rothwell * of_get_next_child - Iterate a node childs 640d1cd355aSStephen Rothwell * @node: parent node 641d1cd355aSStephen Rothwell * @prev: previous child of the parent node, or NULL to get first 642d1cd355aSStephen Rothwell * 643d1cd355aSStephen Rothwell * Returns a node pointer with refcount incremented, use 644d1cd355aSStephen Rothwell * of_node_put() on it when done. 645d1cd355aSStephen Rothwell */ 646d1cd355aSStephen Rothwell struct device_node *of_get_next_child(const struct device_node *node, 647d1cd355aSStephen Rothwell struct device_node *prev) 648d1cd355aSStephen Rothwell { 649d1cd355aSStephen Rothwell struct device_node *next; 650d6d3c4e6SThomas Gleixner unsigned long flags; 651d1cd355aSStephen Rothwell 652d6d3c4e6SThomas Gleixner raw_spin_lock_irqsave(&devtree_lock, flags); 6530d0e02d6SGrant Likely next = __of_get_next_child(node, prev); 654d6d3c4e6SThomas Gleixner raw_spin_unlock_irqrestore(&devtree_lock, flags); 655d1cd355aSStephen Rothwell return next; 656d1cd355aSStephen Rothwell } 657d1cd355aSStephen Rothwell EXPORT_SYMBOL(of_get_next_child); 6581ef4d424SStephen Rothwell 6591ef4d424SStephen Rothwell /** 6603296193dSTimur Tabi * of_get_next_available_child - Find the next available child node 6613296193dSTimur Tabi * @node: parent node 6623296193dSTimur Tabi * @prev: previous child of the parent node, or NULL to get first 6633296193dSTimur Tabi * 6643296193dSTimur Tabi * This function is like of_get_next_child(), except that it 6653296193dSTimur Tabi * automatically skips any disabled nodes (i.e. status = "disabled"). 6663296193dSTimur Tabi */ 6673296193dSTimur Tabi struct device_node *of_get_next_available_child(const struct device_node *node, 6683296193dSTimur Tabi struct device_node *prev) 6693296193dSTimur Tabi { 6703296193dSTimur Tabi struct device_node *next; 671d25d8694SBenjamin Herrenschmidt unsigned long flags; 6723296193dSTimur Tabi 67343cb4367SFlorian Fainelli if (!node) 67443cb4367SFlorian Fainelli return NULL; 67543cb4367SFlorian Fainelli 676d25d8694SBenjamin Herrenschmidt raw_spin_lock_irqsave(&devtree_lock, flags); 6773296193dSTimur Tabi next = prev ? prev->sibling : node->child; 6783296193dSTimur Tabi for (; next; next = next->sibling) { 679c31a0c05SStephen Warren if (!__of_device_is_available(next)) 6803296193dSTimur Tabi continue; 6813296193dSTimur Tabi if (of_node_get(next)) 6823296193dSTimur Tabi break; 6833296193dSTimur Tabi } 6843296193dSTimur Tabi of_node_put(prev); 685d25d8694SBenjamin Herrenschmidt raw_spin_unlock_irqrestore(&devtree_lock, flags); 6863296193dSTimur Tabi return next; 6873296193dSTimur Tabi } 6883296193dSTimur Tabi EXPORT_SYMBOL(of_get_next_available_child); 6893296193dSTimur Tabi 6903296193dSTimur Tabi /** 6919c19761aSSrinivas Kandagatla * of_get_child_by_name - Find the child node by name for a given parent 6929c19761aSSrinivas Kandagatla * @node: parent node 6939c19761aSSrinivas Kandagatla * @name: child name to look for. 6949c19761aSSrinivas Kandagatla * 6959c19761aSSrinivas Kandagatla * This function looks for child node for given matching name 6969c19761aSSrinivas Kandagatla * 6979c19761aSSrinivas Kandagatla * Returns a node pointer if found, with refcount incremented, use 6989c19761aSSrinivas Kandagatla * of_node_put() on it when done. 6999c19761aSSrinivas Kandagatla * Returns NULL if node is not found. 7009c19761aSSrinivas Kandagatla */ 7019c19761aSSrinivas Kandagatla struct device_node *of_get_child_by_name(const struct device_node *node, 7029c19761aSSrinivas Kandagatla const char *name) 7039c19761aSSrinivas Kandagatla { 7049c19761aSSrinivas Kandagatla struct device_node *child; 7059c19761aSSrinivas Kandagatla 7069c19761aSSrinivas Kandagatla for_each_child_of_node(node, child) 7079c19761aSSrinivas Kandagatla if (child->name && (of_node_cmp(child->name, name) == 0)) 7089c19761aSSrinivas Kandagatla break; 7099c19761aSSrinivas Kandagatla return child; 7109c19761aSSrinivas Kandagatla } 7119c19761aSSrinivas Kandagatla EXPORT_SYMBOL(of_get_child_by_name); 7129c19761aSSrinivas Kandagatla 713c22e650eSGrant Likely static struct device_node *__of_find_node_by_path(struct device_node *parent, 714c22e650eSGrant Likely const char *path) 715c22e650eSGrant Likely { 716c22e650eSGrant Likely struct device_node *child; 717c22e650eSGrant Likely int len = strchrnul(path, '/') - path; 71875c28c09SLeif Lindholm int term; 719c22e650eSGrant Likely 720c22e650eSGrant Likely if (!len) 721c22e650eSGrant Likely return NULL; 722c22e650eSGrant Likely 72375c28c09SLeif Lindholm term = strchrnul(path, ':') - path; 72475c28c09SLeif Lindholm if (term < len) 72575c28c09SLeif Lindholm len = term; 72675c28c09SLeif Lindholm 727c22e650eSGrant Likely __for_each_child_of_node(parent, child) { 728c22e650eSGrant Likely const char *name = strrchr(child->full_name, '/'); 729c22e650eSGrant Likely if (WARN(!name, "malformed device_node %s\n", child->full_name)) 730c22e650eSGrant Likely continue; 731c22e650eSGrant Likely name++; 732c22e650eSGrant Likely if (strncmp(path, name, len) == 0 && (strlen(name) == len)) 733c22e650eSGrant Likely return child; 734c22e650eSGrant Likely } 735c22e650eSGrant Likely return NULL; 736c22e650eSGrant Likely } 737c22e650eSGrant Likely 7389c19761aSSrinivas Kandagatla /** 73975c28c09SLeif Lindholm * of_find_node_opts_by_path - Find a node matching a full OF path 740c22e650eSGrant Likely * @path: Either the full path to match, or if the path does not 741c22e650eSGrant Likely * start with '/', the name of a property of the /aliases 742c22e650eSGrant Likely * node (an alias). In the case of an alias, the node 743c22e650eSGrant Likely * matching the alias' value will be returned. 74475c28c09SLeif Lindholm * @opts: Address of a pointer into which to store the start of 74575c28c09SLeif Lindholm * an options string appended to the end of the path with 74675c28c09SLeif Lindholm * a ':' separator. 747c22e650eSGrant Likely * 748c22e650eSGrant Likely * Valid paths: 749c22e650eSGrant Likely * /foo/bar Full path 750c22e650eSGrant Likely * foo Valid alias 751c22e650eSGrant Likely * foo/bar Valid alias + relative path 7521ef4d424SStephen Rothwell * 7531ef4d424SStephen Rothwell * Returns a node pointer with refcount incremented, use 7541ef4d424SStephen Rothwell * of_node_put() on it when done. 7551ef4d424SStephen Rothwell */ 75675c28c09SLeif Lindholm struct device_node *of_find_node_opts_by_path(const char *path, const char **opts) 7571ef4d424SStephen Rothwell { 758c22e650eSGrant Likely struct device_node *np = NULL; 759c22e650eSGrant Likely struct property *pp; 760d6d3c4e6SThomas Gleixner unsigned long flags; 76175c28c09SLeif Lindholm const char *separator = strchr(path, ':'); 76275c28c09SLeif Lindholm 76375c28c09SLeif Lindholm if (opts) 76475c28c09SLeif Lindholm *opts = separator ? separator + 1 : NULL; 7651ef4d424SStephen Rothwell 766c22e650eSGrant Likely if (strcmp(path, "/") == 0) 7675063e25aSGrant Likely return of_node_get(of_root); 768c22e650eSGrant Likely 769c22e650eSGrant Likely /* The path could begin with an alias */ 770c22e650eSGrant Likely if (*path != '/') { 771c22e650eSGrant Likely char *p = strchrnul(path, '/'); 77275c28c09SLeif Lindholm int len = separator ? separator - path : p - path; 773c22e650eSGrant Likely 774c22e650eSGrant Likely /* of_aliases must not be NULL */ 775c22e650eSGrant Likely if (!of_aliases) 776c22e650eSGrant Likely return NULL; 777c22e650eSGrant Likely 778c22e650eSGrant Likely for_each_property_of_node(of_aliases, pp) { 779c22e650eSGrant Likely if (strlen(pp->name) == len && !strncmp(pp->name, path, len)) { 780c22e650eSGrant Likely np = of_find_node_by_path(pp->value); 7811ef4d424SStephen Rothwell break; 7821ef4d424SStephen Rothwell } 783c22e650eSGrant Likely } 784c22e650eSGrant Likely if (!np) 785c22e650eSGrant Likely return NULL; 786c22e650eSGrant Likely path = p; 787c22e650eSGrant Likely } 788c22e650eSGrant Likely 789c22e650eSGrant Likely /* Step down the tree matching path components */ 790c22e650eSGrant Likely raw_spin_lock_irqsave(&devtree_lock, flags); 791c22e650eSGrant Likely if (!np) 7925063e25aSGrant Likely np = of_node_get(of_root); 793c22e650eSGrant Likely while (np && *path == '/') { 794c22e650eSGrant Likely path++; /* Increment past '/' delimiter */ 795c22e650eSGrant Likely np = __of_find_node_by_path(np, path); 796c22e650eSGrant Likely path = strchrnul(path, '/'); 797c22e650eSGrant Likely } 798d6d3c4e6SThomas Gleixner raw_spin_unlock_irqrestore(&devtree_lock, flags); 7991ef4d424SStephen Rothwell return np; 8001ef4d424SStephen Rothwell } 80175c28c09SLeif Lindholm EXPORT_SYMBOL(of_find_node_opts_by_path); 8021ef4d424SStephen Rothwell 8031ef4d424SStephen Rothwell /** 8041ef4d424SStephen Rothwell * of_find_node_by_name - Find a node by its "name" property 8051ef4d424SStephen Rothwell * @from: The node to start searching from or NULL, the node 8061ef4d424SStephen Rothwell * you pass will not be searched, only the next one 8071ef4d424SStephen Rothwell * will; typically, you pass what the previous call 8081ef4d424SStephen Rothwell * returned. of_node_put() will be called on it 8091ef4d424SStephen Rothwell * @name: The name string to match against 8101ef4d424SStephen Rothwell * 8111ef4d424SStephen Rothwell * Returns a node pointer with refcount incremented, use 8121ef4d424SStephen Rothwell * of_node_put() on it when done. 8131ef4d424SStephen Rothwell */ 8141ef4d424SStephen Rothwell struct device_node *of_find_node_by_name(struct device_node *from, 8151ef4d424SStephen Rothwell const char *name) 8161ef4d424SStephen Rothwell { 8171ef4d424SStephen Rothwell struct device_node *np; 818d6d3c4e6SThomas Gleixner unsigned long flags; 8191ef4d424SStephen Rothwell 820d6d3c4e6SThomas Gleixner raw_spin_lock_irqsave(&devtree_lock, flags); 8215063e25aSGrant Likely for_each_of_allnodes_from(from, np) 8221ef4d424SStephen Rothwell if (np->name && (of_node_cmp(np->name, name) == 0) 8231ef4d424SStephen Rothwell && of_node_get(np)) 8241ef4d424SStephen Rothwell break; 8251ef4d424SStephen Rothwell of_node_put(from); 826d6d3c4e6SThomas Gleixner raw_spin_unlock_irqrestore(&devtree_lock, flags); 8271ef4d424SStephen Rothwell return np; 8281ef4d424SStephen Rothwell } 8291ef4d424SStephen Rothwell EXPORT_SYMBOL(of_find_node_by_name); 8301ef4d424SStephen Rothwell 8311ef4d424SStephen Rothwell /** 8321ef4d424SStephen Rothwell * of_find_node_by_type - Find a node by its "device_type" property 8331ef4d424SStephen Rothwell * @from: The node to start searching from, or NULL to start searching 8341ef4d424SStephen Rothwell * the entire device tree. The node you pass will not be 8351ef4d424SStephen Rothwell * searched, only the next one will; typically, you pass 8361ef4d424SStephen Rothwell * what the previous call returned. of_node_put() will be 8371ef4d424SStephen Rothwell * called on from for you. 8381ef4d424SStephen Rothwell * @type: The type string to match against 8391ef4d424SStephen Rothwell * 8401ef4d424SStephen Rothwell * Returns a node pointer with refcount incremented, use 8411ef4d424SStephen Rothwell * of_node_put() on it when done. 8421ef4d424SStephen Rothwell */ 8431ef4d424SStephen Rothwell struct device_node *of_find_node_by_type(struct device_node *from, 8441ef4d424SStephen Rothwell const char *type) 8451ef4d424SStephen Rothwell { 8461ef4d424SStephen Rothwell struct device_node *np; 847d6d3c4e6SThomas Gleixner unsigned long flags; 8481ef4d424SStephen Rothwell 849d6d3c4e6SThomas Gleixner raw_spin_lock_irqsave(&devtree_lock, flags); 8505063e25aSGrant Likely for_each_of_allnodes_from(from, np) 8511ef4d424SStephen Rothwell if (np->type && (of_node_cmp(np->type, type) == 0) 8521ef4d424SStephen Rothwell && of_node_get(np)) 8531ef4d424SStephen Rothwell break; 8541ef4d424SStephen Rothwell of_node_put(from); 855d6d3c4e6SThomas Gleixner raw_spin_unlock_irqrestore(&devtree_lock, flags); 8561ef4d424SStephen Rothwell return np; 8571ef4d424SStephen Rothwell } 8581ef4d424SStephen Rothwell EXPORT_SYMBOL(of_find_node_by_type); 8591ef4d424SStephen Rothwell 8601ef4d424SStephen Rothwell /** 8611ef4d424SStephen Rothwell * of_find_compatible_node - Find a node based on type and one of the 8621ef4d424SStephen Rothwell * tokens in its "compatible" property 8631ef4d424SStephen Rothwell * @from: The node to start searching from or NULL, the node 8641ef4d424SStephen Rothwell * you pass will not be searched, only the next one 8651ef4d424SStephen Rothwell * will; typically, you pass what the previous call 8661ef4d424SStephen Rothwell * returned. of_node_put() will be called on it 8671ef4d424SStephen Rothwell * @type: The type string to match "device_type" or NULL to ignore 8681ef4d424SStephen Rothwell * @compatible: The string to match to one of the tokens in the device 8691ef4d424SStephen Rothwell * "compatible" list. 8701ef4d424SStephen Rothwell * 8711ef4d424SStephen Rothwell * Returns a node pointer with refcount incremented, use 8721ef4d424SStephen Rothwell * of_node_put() on it when done. 8731ef4d424SStephen Rothwell */ 8741ef4d424SStephen Rothwell struct device_node *of_find_compatible_node(struct device_node *from, 8751ef4d424SStephen Rothwell const char *type, const char *compatible) 8761ef4d424SStephen Rothwell { 8771ef4d424SStephen Rothwell struct device_node *np; 878d6d3c4e6SThomas Gleixner unsigned long flags; 8791ef4d424SStephen Rothwell 880d6d3c4e6SThomas Gleixner raw_spin_lock_irqsave(&devtree_lock, flags); 8815063e25aSGrant Likely for_each_of_allnodes_from(from, np) 882215a14cfSKevin Hao if (__of_device_is_compatible(np, compatible, type, NULL) && 88328d0e36bSThomas Gleixner of_node_get(np)) 8841ef4d424SStephen Rothwell break; 8851ef4d424SStephen Rothwell of_node_put(from); 886d6d3c4e6SThomas Gleixner raw_spin_unlock_irqrestore(&devtree_lock, flags); 8871ef4d424SStephen Rothwell return np; 8881ef4d424SStephen Rothwell } 8891ef4d424SStephen Rothwell EXPORT_SYMBOL(of_find_compatible_node); 890283029d1SGrant Likely 891283029d1SGrant Likely /** 8921e291b14SMichael Ellerman * of_find_node_with_property - Find a node which has a property with 8931e291b14SMichael Ellerman * the given name. 8941e291b14SMichael Ellerman * @from: The node to start searching from or NULL, the node 8951e291b14SMichael Ellerman * you pass will not be searched, only the next one 8961e291b14SMichael Ellerman * will; typically, you pass what the previous call 8971e291b14SMichael Ellerman * returned. of_node_put() will be called on it 8981e291b14SMichael Ellerman * @prop_name: The name of the property to look for. 8991e291b14SMichael Ellerman * 9001e291b14SMichael Ellerman * Returns a node pointer with refcount incremented, use 9011e291b14SMichael Ellerman * of_node_put() on it when done. 9021e291b14SMichael Ellerman */ 9031e291b14SMichael Ellerman struct device_node *of_find_node_with_property(struct device_node *from, 9041e291b14SMichael Ellerman const char *prop_name) 9051e291b14SMichael Ellerman { 9061e291b14SMichael Ellerman struct device_node *np; 9071e291b14SMichael Ellerman struct property *pp; 908d6d3c4e6SThomas Gleixner unsigned long flags; 9091e291b14SMichael Ellerman 910d6d3c4e6SThomas Gleixner raw_spin_lock_irqsave(&devtree_lock, flags); 9115063e25aSGrant Likely for_each_of_allnodes_from(from, np) { 912a3a7cab1SSachin Kamat for (pp = np->properties; pp; pp = pp->next) { 9131e291b14SMichael Ellerman if (of_prop_cmp(pp->name, prop_name) == 0) { 9141e291b14SMichael Ellerman of_node_get(np); 9151e291b14SMichael Ellerman goto out; 9161e291b14SMichael Ellerman } 9171e291b14SMichael Ellerman } 9181e291b14SMichael Ellerman } 9191e291b14SMichael Ellerman out: 9201e291b14SMichael Ellerman of_node_put(from); 921d6d3c4e6SThomas Gleixner raw_spin_unlock_irqrestore(&devtree_lock, flags); 9221e291b14SMichael Ellerman return np; 9231e291b14SMichael Ellerman } 9241e291b14SMichael Ellerman EXPORT_SYMBOL(of_find_node_with_property); 9251e291b14SMichael Ellerman 92628d0e36bSThomas Gleixner static 92728d0e36bSThomas Gleixner const struct of_device_id *__of_match_node(const struct of_device_id *matches, 928283029d1SGrant Likely const struct device_node *node) 929283029d1SGrant Likely { 930215a14cfSKevin Hao const struct of_device_id *best_match = NULL; 931215a14cfSKevin Hao int score, best_score = 0; 932215a14cfSKevin Hao 933a52f07ecSGrant Likely if (!matches) 934a52f07ecSGrant Likely return NULL; 935a52f07ecSGrant Likely 936215a14cfSKevin Hao for (; matches->name[0] || matches->type[0] || matches->compatible[0]; matches++) { 937215a14cfSKevin Hao score = __of_device_is_compatible(node, matches->compatible, 938215a14cfSKevin Hao matches->type, matches->name); 939215a14cfSKevin Hao if (score > best_score) { 940215a14cfSKevin Hao best_match = matches; 941215a14cfSKevin Hao best_score = score; 942283029d1SGrant Likely } 943215a14cfSKevin Hao } 944215a14cfSKevin Hao 945215a14cfSKevin Hao return best_match; 946283029d1SGrant Likely } 94728d0e36bSThomas Gleixner 94828d0e36bSThomas Gleixner /** 949c50949d3SGeert Uytterhoeven * of_match_node - Tell if a device_node has a matching of_match structure 95028d0e36bSThomas Gleixner * @matches: array of of device match structures to search in 95128d0e36bSThomas Gleixner * @node: the of device structure to match against 95228d0e36bSThomas Gleixner * 95371c5498eSKevin Hao * Low level utility function used by device matching. 95428d0e36bSThomas Gleixner */ 95528d0e36bSThomas Gleixner const struct of_device_id *of_match_node(const struct of_device_id *matches, 95628d0e36bSThomas Gleixner const struct device_node *node) 95728d0e36bSThomas Gleixner { 95828d0e36bSThomas Gleixner const struct of_device_id *match; 959d6d3c4e6SThomas Gleixner unsigned long flags; 96028d0e36bSThomas Gleixner 961d6d3c4e6SThomas Gleixner raw_spin_lock_irqsave(&devtree_lock, flags); 96228d0e36bSThomas Gleixner match = __of_match_node(matches, node); 963d6d3c4e6SThomas Gleixner raw_spin_unlock_irqrestore(&devtree_lock, flags); 96428d0e36bSThomas Gleixner return match; 96528d0e36bSThomas Gleixner } 966283029d1SGrant Likely EXPORT_SYMBOL(of_match_node); 967283029d1SGrant Likely 968283029d1SGrant Likely /** 96950c8af4cSStephen Warren * of_find_matching_node_and_match - Find a node based on an of_device_id 97050c8af4cSStephen Warren * match table. 971283029d1SGrant Likely * @from: The node to start searching from or NULL, the node 972283029d1SGrant Likely * you pass will not be searched, only the next one 973283029d1SGrant Likely * will; typically, you pass what the previous call 974283029d1SGrant Likely * returned. of_node_put() will be called on it 975283029d1SGrant Likely * @matches: array of of device match structures to search in 97650c8af4cSStephen Warren * @match Updated to point at the matches entry which matched 977283029d1SGrant Likely * 978283029d1SGrant Likely * Returns a node pointer with refcount incremented, use 979283029d1SGrant Likely * of_node_put() on it when done. 980283029d1SGrant Likely */ 98150c8af4cSStephen Warren struct device_node *of_find_matching_node_and_match(struct device_node *from, 98250c8af4cSStephen Warren const struct of_device_id *matches, 98350c8af4cSStephen Warren const struct of_device_id **match) 984283029d1SGrant Likely { 985283029d1SGrant Likely struct device_node *np; 986dc71bcf1SThomas Abraham const struct of_device_id *m; 987d6d3c4e6SThomas Gleixner unsigned long flags; 988283029d1SGrant Likely 98950c8af4cSStephen Warren if (match) 99050c8af4cSStephen Warren *match = NULL; 99150c8af4cSStephen Warren 992d6d3c4e6SThomas Gleixner raw_spin_lock_irqsave(&devtree_lock, flags); 9935063e25aSGrant Likely for_each_of_allnodes_from(from, np) { 99428d0e36bSThomas Gleixner m = __of_match_node(matches, np); 995dc71bcf1SThomas Abraham if (m && of_node_get(np)) { 99650c8af4cSStephen Warren if (match) 997dc71bcf1SThomas Abraham *match = m; 998283029d1SGrant Likely break; 999283029d1SGrant Likely } 100050c8af4cSStephen Warren } 1001283029d1SGrant Likely of_node_put(from); 1002d6d3c4e6SThomas Gleixner raw_spin_unlock_irqrestore(&devtree_lock, flags); 1003283029d1SGrant Likely return np; 1004283029d1SGrant Likely } 100580c2022eSGrant Likely EXPORT_SYMBOL(of_find_matching_node_and_match); 10063f07af49SGrant Likely 10073f07af49SGrant Likely /** 10083f07af49SGrant Likely * of_modalias_node - Lookup appropriate modalias for a device node 10093f07af49SGrant Likely * @node: pointer to a device tree node 10103f07af49SGrant Likely * @modalias: Pointer to buffer that modalias value will be copied into 10113f07af49SGrant Likely * @len: Length of modalias value 10123f07af49SGrant Likely * 10132ffe8c5fSGrant Likely * Based on the value of the compatible property, this routine will attempt 10142ffe8c5fSGrant Likely * to choose an appropriate modalias value for a particular device tree node. 10152ffe8c5fSGrant Likely * It does this by stripping the manufacturer prefix (as delimited by a ',') 10162ffe8c5fSGrant Likely * from the first entry in the compatible list property. 10173f07af49SGrant Likely * 10182ffe8c5fSGrant Likely * This routine returns 0 on success, <0 on failure. 10193f07af49SGrant Likely */ 10203f07af49SGrant Likely int of_modalias_node(struct device_node *node, char *modalias, int len) 10213f07af49SGrant Likely { 10222ffe8c5fSGrant Likely const char *compatible, *p; 10232ffe8c5fSGrant Likely int cplen; 10243f07af49SGrant Likely 10253f07af49SGrant Likely compatible = of_get_property(node, "compatible", &cplen); 10262ffe8c5fSGrant Likely if (!compatible || strlen(compatible) > cplen) 10273f07af49SGrant Likely return -ENODEV; 10283f07af49SGrant Likely p = strchr(compatible, ','); 10292ffe8c5fSGrant Likely strlcpy(modalias, p ? p + 1 : compatible, len); 10303f07af49SGrant Likely return 0; 10313f07af49SGrant Likely } 10323f07af49SGrant Likely EXPORT_SYMBOL_GPL(of_modalias_node); 10333f07af49SGrant Likely 103464b60e09SAnton Vorontsov /** 103589751a7cSJeremy Kerr * of_find_node_by_phandle - Find a node given a phandle 103689751a7cSJeremy Kerr * @handle: phandle of the node to find 103789751a7cSJeremy Kerr * 103889751a7cSJeremy Kerr * Returns a node pointer with refcount incremented, use 103989751a7cSJeremy Kerr * of_node_put() on it when done. 104089751a7cSJeremy Kerr */ 104189751a7cSJeremy Kerr struct device_node *of_find_node_by_phandle(phandle handle) 104289751a7cSJeremy Kerr { 104389751a7cSJeremy Kerr struct device_node *np; 1044d25d8694SBenjamin Herrenschmidt unsigned long flags; 104589751a7cSJeremy Kerr 1046fc59b447SGrant Likely if (!handle) 1047fc59b447SGrant Likely return NULL; 1048fc59b447SGrant Likely 1049d25d8694SBenjamin Herrenschmidt raw_spin_lock_irqsave(&devtree_lock, flags); 10505063e25aSGrant Likely for_each_of_allnodes(np) 105189751a7cSJeremy Kerr if (np->phandle == handle) 105289751a7cSJeremy Kerr break; 105389751a7cSJeremy Kerr of_node_get(np); 1054d25d8694SBenjamin Herrenschmidt raw_spin_unlock_irqrestore(&devtree_lock, flags); 105589751a7cSJeremy Kerr return np; 105689751a7cSJeremy Kerr } 105789751a7cSJeremy Kerr EXPORT_SYMBOL(of_find_node_by_phandle); 105889751a7cSJeremy Kerr 105989751a7cSJeremy Kerr /** 1060ad54a0cfSHeiko Stuebner * of_property_count_elems_of_size - Count the number of elements in a property 1061ad54a0cfSHeiko Stuebner * 1062ad54a0cfSHeiko Stuebner * @np: device node from which the property value is to be read. 1063ad54a0cfSHeiko Stuebner * @propname: name of the property to be searched. 1064ad54a0cfSHeiko Stuebner * @elem_size: size of the individual element 1065ad54a0cfSHeiko Stuebner * 1066ad54a0cfSHeiko Stuebner * Search for a property in a device node and count the number of elements of 1067ad54a0cfSHeiko Stuebner * size elem_size in it. Returns number of elements on sucess, -EINVAL if the 1068ad54a0cfSHeiko Stuebner * property does not exist or its length does not match a multiple of elem_size 1069ad54a0cfSHeiko Stuebner * and -ENODATA if the property does not have a value. 1070ad54a0cfSHeiko Stuebner */ 1071ad54a0cfSHeiko Stuebner int of_property_count_elems_of_size(const struct device_node *np, 1072ad54a0cfSHeiko Stuebner const char *propname, int elem_size) 1073ad54a0cfSHeiko Stuebner { 1074ad54a0cfSHeiko Stuebner struct property *prop = of_find_property(np, propname, NULL); 1075ad54a0cfSHeiko Stuebner 1076ad54a0cfSHeiko Stuebner if (!prop) 1077ad54a0cfSHeiko Stuebner return -EINVAL; 1078ad54a0cfSHeiko Stuebner if (!prop->value) 1079ad54a0cfSHeiko Stuebner return -ENODATA; 1080ad54a0cfSHeiko Stuebner 1081ad54a0cfSHeiko Stuebner if (prop->length % elem_size != 0) { 1082ad54a0cfSHeiko Stuebner pr_err("size of %s in node %s is not a multiple of %d\n", 1083ad54a0cfSHeiko Stuebner propname, np->full_name, elem_size); 1084ad54a0cfSHeiko Stuebner return -EINVAL; 1085ad54a0cfSHeiko Stuebner } 1086ad54a0cfSHeiko Stuebner 1087ad54a0cfSHeiko Stuebner return prop->length / elem_size; 1088ad54a0cfSHeiko Stuebner } 1089ad54a0cfSHeiko Stuebner EXPORT_SYMBOL_GPL(of_property_count_elems_of_size); 1090ad54a0cfSHeiko Stuebner 1091ad54a0cfSHeiko Stuebner /** 1092daeec1f0STony Prisk * of_find_property_value_of_size 1093daeec1f0STony Prisk * 1094daeec1f0STony Prisk * @np: device node from which the property value is to be read. 1095daeec1f0STony Prisk * @propname: name of the property to be searched. 1096daeec1f0STony Prisk * @len: requested length of property value 1097daeec1f0STony Prisk * 1098daeec1f0STony Prisk * Search for a property in a device node and valid the requested size. 1099daeec1f0STony Prisk * Returns the property value on success, -EINVAL if the property does not 1100daeec1f0STony Prisk * exist, -ENODATA if property does not have a value, and -EOVERFLOW if the 1101daeec1f0STony Prisk * property data isn't large enough. 1102daeec1f0STony Prisk * 1103daeec1f0STony Prisk */ 1104daeec1f0STony Prisk static void *of_find_property_value_of_size(const struct device_node *np, 1105daeec1f0STony Prisk const char *propname, u32 len) 1106daeec1f0STony Prisk { 1107daeec1f0STony Prisk struct property *prop = of_find_property(np, propname, NULL); 1108daeec1f0STony Prisk 1109daeec1f0STony Prisk if (!prop) 1110daeec1f0STony Prisk return ERR_PTR(-EINVAL); 1111daeec1f0STony Prisk if (!prop->value) 1112daeec1f0STony Prisk return ERR_PTR(-ENODATA); 1113daeec1f0STony Prisk if (len > prop->length) 1114daeec1f0STony Prisk return ERR_PTR(-EOVERFLOW); 1115daeec1f0STony Prisk 1116daeec1f0STony Prisk return prop->value; 1117daeec1f0STony Prisk } 1118daeec1f0STony Prisk 1119daeec1f0STony Prisk /** 11203daf3726STony Prisk * of_property_read_u32_index - Find and read a u32 from a multi-value property. 11213daf3726STony Prisk * 11223daf3726STony Prisk * @np: device node from which the property value is to be read. 11233daf3726STony Prisk * @propname: name of the property to be searched. 11243daf3726STony Prisk * @index: index of the u32 in the list of values 11253daf3726STony Prisk * @out_value: pointer to return value, modified only if no error. 11263daf3726STony Prisk * 11273daf3726STony Prisk * Search for a property in a device node and read nth 32-bit value from 11283daf3726STony Prisk * it. Returns 0 on success, -EINVAL if the property does not exist, 11293daf3726STony Prisk * -ENODATA if property does not have a value, and -EOVERFLOW if the 11303daf3726STony Prisk * property data isn't large enough. 11313daf3726STony Prisk * 11323daf3726STony Prisk * The out_value is modified only if a valid u32 value can be decoded. 11333daf3726STony Prisk */ 11343daf3726STony Prisk int of_property_read_u32_index(const struct device_node *np, 11353daf3726STony Prisk const char *propname, 11363daf3726STony Prisk u32 index, u32 *out_value) 11373daf3726STony Prisk { 1138daeec1f0STony Prisk const u32 *val = of_find_property_value_of_size(np, propname, 1139daeec1f0STony Prisk ((index + 1) * sizeof(*out_value))); 11403daf3726STony Prisk 1141daeec1f0STony Prisk if (IS_ERR(val)) 1142daeec1f0STony Prisk return PTR_ERR(val); 11433daf3726STony Prisk 1144daeec1f0STony Prisk *out_value = be32_to_cpup(((__be32 *)val) + index); 11453daf3726STony Prisk return 0; 11463daf3726STony Prisk } 11473daf3726STony Prisk EXPORT_SYMBOL_GPL(of_property_read_u32_index); 11483daf3726STony Prisk 11493daf3726STony Prisk /** 1150be193249SViresh Kumar * of_property_read_u8_array - Find and read an array of u8 from a property. 1151be193249SViresh Kumar * 1152be193249SViresh Kumar * @np: device node from which the property value is to be read. 1153be193249SViresh Kumar * @propname: name of the property to be searched. 1154792efb84SLad, Prabhakar * @out_values: pointer to return value, modified only if return value is 0. 1155be193249SViresh Kumar * @sz: number of array elements to read 1156be193249SViresh Kumar * 1157be193249SViresh Kumar * Search for a property in a device node and read 8-bit value(s) from 1158be193249SViresh Kumar * it. Returns 0 on success, -EINVAL if the property does not exist, 1159be193249SViresh Kumar * -ENODATA if property does not have a value, and -EOVERFLOW if the 1160be193249SViresh Kumar * property data isn't large enough. 1161be193249SViresh Kumar * 1162be193249SViresh Kumar * dts entry of array should be like: 1163be193249SViresh Kumar * property = /bits/ 8 <0x50 0x60 0x70>; 1164be193249SViresh Kumar * 1165792efb84SLad, Prabhakar * The out_values is modified only if a valid u8 value can be decoded. 1166be193249SViresh Kumar */ 1167be193249SViresh Kumar int of_property_read_u8_array(const struct device_node *np, 1168be193249SViresh Kumar const char *propname, u8 *out_values, size_t sz) 1169be193249SViresh Kumar { 1170daeec1f0STony Prisk const u8 *val = of_find_property_value_of_size(np, propname, 1171daeec1f0STony Prisk (sz * sizeof(*out_values))); 1172be193249SViresh Kumar 1173daeec1f0STony Prisk if (IS_ERR(val)) 1174daeec1f0STony Prisk return PTR_ERR(val); 1175be193249SViresh Kumar 1176be193249SViresh Kumar while (sz--) 1177be193249SViresh Kumar *out_values++ = *val++; 1178be193249SViresh Kumar return 0; 1179be193249SViresh Kumar } 1180be193249SViresh Kumar EXPORT_SYMBOL_GPL(of_property_read_u8_array); 1181be193249SViresh Kumar 1182be193249SViresh Kumar /** 1183be193249SViresh Kumar * of_property_read_u16_array - Find and read an array of u16 from a property. 1184be193249SViresh Kumar * 1185be193249SViresh Kumar * @np: device node from which the property value is to be read. 1186be193249SViresh Kumar * @propname: name of the property to be searched. 1187792efb84SLad, Prabhakar * @out_values: pointer to return value, modified only if return value is 0. 1188be193249SViresh Kumar * @sz: number of array elements to read 1189be193249SViresh Kumar * 1190be193249SViresh Kumar * Search for a property in a device node and read 16-bit value(s) from 1191be193249SViresh Kumar * it. Returns 0 on success, -EINVAL if the property does not exist, 1192be193249SViresh Kumar * -ENODATA if property does not have a value, and -EOVERFLOW if the 1193be193249SViresh Kumar * property data isn't large enough. 1194be193249SViresh Kumar * 1195be193249SViresh Kumar * dts entry of array should be like: 1196be193249SViresh Kumar * property = /bits/ 16 <0x5000 0x6000 0x7000>; 1197be193249SViresh Kumar * 1198792efb84SLad, Prabhakar * The out_values is modified only if a valid u16 value can be decoded. 1199be193249SViresh Kumar */ 1200be193249SViresh Kumar int of_property_read_u16_array(const struct device_node *np, 1201be193249SViresh Kumar const char *propname, u16 *out_values, size_t sz) 1202be193249SViresh Kumar { 1203daeec1f0STony Prisk const __be16 *val = of_find_property_value_of_size(np, propname, 1204daeec1f0STony Prisk (sz * sizeof(*out_values))); 1205be193249SViresh Kumar 1206daeec1f0STony Prisk if (IS_ERR(val)) 1207daeec1f0STony Prisk return PTR_ERR(val); 1208be193249SViresh Kumar 1209be193249SViresh Kumar while (sz--) 1210be193249SViresh Kumar *out_values++ = be16_to_cpup(val++); 1211be193249SViresh Kumar return 0; 1212be193249SViresh Kumar } 1213be193249SViresh Kumar EXPORT_SYMBOL_GPL(of_property_read_u16_array); 1214be193249SViresh Kumar 1215be193249SViresh Kumar /** 12160e373639SRob Herring * of_property_read_u32_array - Find and read an array of 32 bit integers 12170e373639SRob Herring * from a property. 12180e373639SRob Herring * 1219a3b85363SThomas Abraham * @np: device node from which the property value is to be read. 1220a3b85363SThomas Abraham * @propname: name of the property to be searched. 1221792efb84SLad, Prabhakar * @out_values: pointer to return value, modified only if return value is 0. 1222be193249SViresh Kumar * @sz: number of array elements to read 1223a3b85363SThomas Abraham * 12240e373639SRob Herring * Search for a property in a device node and read 32-bit value(s) from 1225a3b85363SThomas Abraham * it. Returns 0 on success, -EINVAL if the property does not exist, 1226a3b85363SThomas Abraham * -ENODATA if property does not have a value, and -EOVERFLOW if the 1227a3b85363SThomas Abraham * property data isn't large enough. 1228a3b85363SThomas Abraham * 1229792efb84SLad, Prabhakar * The out_values is modified only if a valid u32 value can be decoded. 1230a3b85363SThomas Abraham */ 1231aac285c6SJamie Iles int of_property_read_u32_array(const struct device_node *np, 1232aac285c6SJamie Iles const char *propname, u32 *out_values, 1233aac285c6SJamie Iles size_t sz) 1234a3b85363SThomas Abraham { 1235daeec1f0STony Prisk const __be32 *val = of_find_property_value_of_size(np, propname, 1236daeec1f0STony Prisk (sz * sizeof(*out_values))); 1237a3b85363SThomas Abraham 1238daeec1f0STony Prisk if (IS_ERR(val)) 1239daeec1f0STony Prisk return PTR_ERR(val); 12400e373639SRob Herring 12410e373639SRob Herring while (sz--) 12420e373639SRob Herring *out_values++ = be32_to_cpup(val++); 1243a3b85363SThomas Abraham return 0; 1244a3b85363SThomas Abraham } 12450e373639SRob Herring EXPORT_SYMBOL_GPL(of_property_read_u32_array); 1246a3b85363SThomas Abraham 1247a3b85363SThomas Abraham /** 12484cd7f7a3SJamie Iles * of_property_read_u64 - Find and read a 64 bit integer from a property 12494cd7f7a3SJamie Iles * @np: device node from which the property value is to be read. 12504cd7f7a3SJamie Iles * @propname: name of the property to be searched. 12514cd7f7a3SJamie Iles * @out_value: pointer to return value, modified only if return value is 0. 12524cd7f7a3SJamie Iles * 12534cd7f7a3SJamie Iles * Search for a property in a device node and read a 64-bit value from 12544cd7f7a3SJamie Iles * it. Returns 0 on success, -EINVAL if the property does not exist, 12554cd7f7a3SJamie Iles * -ENODATA if property does not have a value, and -EOVERFLOW if the 12564cd7f7a3SJamie Iles * property data isn't large enough. 12574cd7f7a3SJamie Iles * 12584cd7f7a3SJamie Iles * The out_value is modified only if a valid u64 value can be decoded. 12594cd7f7a3SJamie Iles */ 12604cd7f7a3SJamie Iles int of_property_read_u64(const struct device_node *np, const char *propname, 12614cd7f7a3SJamie Iles u64 *out_value) 12624cd7f7a3SJamie Iles { 1263daeec1f0STony Prisk const __be32 *val = of_find_property_value_of_size(np, propname, 1264daeec1f0STony Prisk sizeof(*out_value)); 12654cd7f7a3SJamie Iles 1266daeec1f0STony Prisk if (IS_ERR(val)) 1267daeec1f0STony Prisk return PTR_ERR(val); 1268daeec1f0STony Prisk 1269daeec1f0STony Prisk *out_value = of_read_number(val, 2); 12704cd7f7a3SJamie Iles return 0; 12714cd7f7a3SJamie Iles } 12724cd7f7a3SJamie Iles EXPORT_SYMBOL_GPL(of_property_read_u64); 12734cd7f7a3SJamie Iles 12744cd7f7a3SJamie Iles /** 1275b31384faSRafael J. Wysocki * of_property_read_u64_array - Find and read an array of 64 bit integers 1276b31384faSRafael J. Wysocki * from a property. 1277b31384faSRafael J. Wysocki * 1278b31384faSRafael J. Wysocki * @np: device node from which the property value is to be read. 1279b31384faSRafael J. Wysocki * @propname: name of the property to be searched. 1280b31384faSRafael J. Wysocki * @out_values: pointer to return value, modified only if return value is 0. 1281b31384faSRafael J. Wysocki * @sz: number of array elements to read 1282b31384faSRafael J. Wysocki * 1283b31384faSRafael J. Wysocki * Search for a property in a device node and read 64-bit value(s) from 1284b31384faSRafael J. Wysocki * it. Returns 0 on success, -EINVAL if the property does not exist, 1285b31384faSRafael J. Wysocki * -ENODATA if property does not have a value, and -EOVERFLOW if the 1286b31384faSRafael J. Wysocki * property data isn't large enough. 1287b31384faSRafael J. Wysocki * 1288b31384faSRafael J. Wysocki * The out_values is modified only if a valid u64 value can be decoded. 1289b31384faSRafael J. Wysocki */ 1290b31384faSRafael J. Wysocki int of_property_read_u64_array(const struct device_node *np, 1291b31384faSRafael J. Wysocki const char *propname, u64 *out_values, 1292b31384faSRafael J. Wysocki size_t sz) 1293b31384faSRafael J. Wysocki { 1294b31384faSRafael J. Wysocki const __be32 *val = of_find_property_value_of_size(np, propname, 1295b31384faSRafael J. Wysocki (sz * sizeof(*out_values))); 1296b31384faSRafael J. Wysocki 1297b31384faSRafael J. Wysocki if (IS_ERR(val)) 1298b31384faSRafael J. Wysocki return PTR_ERR(val); 1299b31384faSRafael J. Wysocki 1300b31384faSRafael J. Wysocki while (sz--) { 1301b31384faSRafael J. Wysocki *out_values++ = of_read_number(val, 2); 1302b31384faSRafael J. Wysocki val += 2; 1303b31384faSRafael J. Wysocki } 1304b31384faSRafael J. Wysocki return 0; 1305b31384faSRafael J. Wysocki } 13062d4c0aefSSakari Ailus EXPORT_SYMBOL_GPL(of_property_read_u64_array); 1307b31384faSRafael J. Wysocki 1308b31384faSRafael J. Wysocki /** 1309a3b85363SThomas Abraham * of_property_read_string - Find and read a string from a property 1310a3b85363SThomas Abraham * @np: device node from which the property value is to be read. 1311a3b85363SThomas Abraham * @propname: name of the property to be searched. 1312a3b85363SThomas Abraham * @out_string: pointer to null terminated return string, modified only if 1313a3b85363SThomas Abraham * return value is 0. 1314a3b85363SThomas Abraham * 1315a3b85363SThomas Abraham * Search for a property in a device tree node and retrieve a null 1316a3b85363SThomas Abraham * terminated string value (pointer to data, not a copy). Returns 0 on 1317a3b85363SThomas Abraham * success, -EINVAL if the property does not exist, -ENODATA if property 1318a3b85363SThomas Abraham * does not have a value, and -EILSEQ if the string is not null-terminated 1319a3b85363SThomas Abraham * within the length of the property data. 1320a3b85363SThomas Abraham * 1321a3b85363SThomas Abraham * The out_string pointer is modified only if a valid string can be decoded. 1322a3b85363SThomas Abraham */ 1323aac285c6SJamie Iles int of_property_read_string(struct device_node *np, const char *propname, 1324f09bc831SShawn Guo const char **out_string) 1325a3b85363SThomas Abraham { 1326a3b85363SThomas Abraham struct property *prop = of_find_property(np, propname, NULL); 1327a3b85363SThomas Abraham if (!prop) 1328a3b85363SThomas Abraham return -EINVAL; 1329a3b85363SThomas Abraham if (!prop->value) 1330a3b85363SThomas Abraham return -ENODATA; 1331a3b85363SThomas Abraham if (strnlen(prop->value, prop->length) >= prop->length) 1332a3b85363SThomas Abraham return -EILSEQ; 1333a3b85363SThomas Abraham *out_string = prop->value; 1334a3b85363SThomas Abraham return 0; 1335a3b85363SThomas Abraham } 1336a3b85363SThomas Abraham EXPORT_SYMBOL_GPL(of_property_read_string); 1337a3b85363SThomas Abraham 1338a3b85363SThomas Abraham /** 13397aff0fe3SGrant Likely * of_property_match_string() - Find string in a list and return index 13407aff0fe3SGrant Likely * @np: pointer to node containing string list property 13417aff0fe3SGrant Likely * @propname: string list property name 13427aff0fe3SGrant Likely * @string: pointer to string to search for in string list 13437aff0fe3SGrant Likely * 13447aff0fe3SGrant Likely * This function searches a string list property and returns the index 13457aff0fe3SGrant Likely * of a specific string value. 13467aff0fe3SGrant Likely */ 13477aff0fe3SGrant Likely int of_property_match_string(struct device_node *np, const char *propname, 13487aff0fe3SGrant Likely const char *string) 13497aff0fe3SGrant Likely { 13507aff0fe3SGrant Likely struct property *prop = of_find_property(np, propname, NULL); 13517aff0fe3SGrant Likely size_t l; 13527aff0fe3SGrant Likely int i; 13537aff0fe3SGrant Likely const char *p, *end; 13547aff0fe3SGrant Likely 13557aff0fe3SGrant Likely if (!prop) 13567aff0fe3SGrant Likely return -EINVAL; 13577aff0fe3SGrant Likely if (!prop->value) 13587aff0fe3SGrant Likely return -ENODATA; 13597aff0fe3SGrant Likely 13607aff0fe3SGrant Likely p = prop->value; 13617aff0fe3SGrant Likely end = p + prop->length; 13627aff0fe3SGrant Likely 13637aff0fe3SGrant Likely for (i = 0; p < end; i++, p += l) { 1364a87fa1d8SGrant Likely l = strnlen(p, end - p) + 1; 13657aff0fe3SGrant Likely if (p + l > end) 13667aff0fe3SGrant Likely return -EILSEQ; 13677aff0fe3SGrant Likely pr_debug("comparing %s with %s\n", string, p); 13687aff0fe3SGrant Likely if (strcmp(string, p) == 0) 13697aff0fe3SGrant Likely return i; /* Found it; return index */ 13707aff0fe3SGrant Likely } 13717aff0fe3SGrant Likely return -ENODATA; 13727aff0fe3SGrant Likely } 13737aff0fe3SGrant Likely EXPORT_SYMBOL_GPL(of_property_match_string); 13744fcd15a0SBenoit Cousson 13754fcd15a0SBenoit Cousson /** 1376e99010edSJiri Slaby * of_property_read_string_helper() - Utility helper for parsing string properties 13774fcd15a0SBenoit Cousson * @np: device node from which the property value is to be read. 13784fcd15a0SBenoit Cousson * @propname: name of the property to be searched. 1379a87fa1d8SGrant Likely * @out_strs: output array of string pointers. 1380a87fa1d8SGrant Likely * @sz: number of array elements to read. 1381a87fa1d8SGrant Likely * @skip: Number of strings to skip over at beginning of list. 13824fcd15a0SBenoit Cousson * 1383a87fa1d8SGrant Likely * Don't call this function directly. It is a utility helper for the 1384a87fa1d8SGrant Likely * of_property_read_string*() family of functions. 13854fcd15a0SBenoit Cousson */ 1386a87fa1d8SGrant Likely int of_property_read_string_helper(struct device_node *np, const char *propname, 1387a87fa1d8SGrant Likely const char **out_strs, size_t sz, int skip) 13884fcd15a0SBenoit Cousson { 13894fcd15a0SBenoit Cousson struct property *prop = of_find_property(np, propname, NULL); 1390a87fa1d8SGrant Likely int l = 0, i = 0; 1391a87fa1d8SGrant Likely const char *p, *end; 13924fcd15a0SBenoit Cousson 13934fcd15a0SBenoit Cousson if (!prop) 13944fcd15a0SBenoit Cousson return -EINVAL; 13954fcd15a0SBenoit Cousson if (!prop->value) 13964fcd15a0SBenoit Cousson return -ENODATA; 13974fcd15a0SBenoit Cousson p = prop->value; 1398a87fa1d8SGrant Likely end = p + prop->length; 13994fcd15a0SBenoit Cousson 1400a87fa1d8SGrant Likely for (i = 0; p < end && (!out_strs || i < skip + sz); i++, p += l) { 1401a87fa1d8SGrant Likely l = strnlen(p, end - p) + 1; 1402a87fa1d8SGrant Likely if (p + l > end) 1403a87fa1d8SGrant Likely return -EILSEQ; 1404a87fa1d8SGrant Likely if (out_strs && i >= skip) 1405a87fa1d8SGrant Likely *out_strs++ = p; 14064fcd15a0SBenoit Cousson } 1407a87fa1d8SGrant Likely i -= skip; 1408a87fa1d8SGrant Likely return i <= 0 ? -ENODATA : i; 1409a87fa1d8SGrant Likely } 1410a87fa1d8SGrant Likely EXPORT_SYMBOL_GPL(of_property_read_string_helper); 14114fcd15a0SBenoit Cousson 1412624cfca5SGrant Likely void of_print_phandle_args(const char *msg, const struct of_phandle_args *args) 1413624cfca5SGrant Likely { 1414624cfca5SGrant Likely int i; 1415624cfca5SGrant Likely printk("%s %s", msg, of_node_full_name(args->np)); 1416624cfca5SGrant Likely for (i = 0; i < args->args_count; i++) 1417624cfca5SGrant Likely printk(i ? ",%08x" : ":%08x", args->args[i]); 1418624cfca5SGrant Likely printk("\n"); 1419624cfca5SGrant Likely } 1420624cfca5SGrant Likely 1421bd69f73fSGrant Likely static int __of_parse_phandle_with_args(const struct device_node *np, 1422bd69f73fSGrant Likely const char *list_name, 1423035fd948SStephen Warren const char *cells_name, 1424035fd948SStephen Warren int cell_count, int index, 142515c9a0acSGrant Likely struct of_phandle_args *out_args) 142664b60e09SAnton Vorontsov { 142715c9a0acSGrant Likely const __be32 *list, *list_end; 142823ce04c0SGrant Likely int rc = 0, size, cur_index = 0; 142915c9a0acSGrant Likely uint32_t count = 0; 143064b60e09SAnton Vorontsov struct device_node *node = NULL; 14319a6b2e58SGrant Likely phandle phandle; 143264b60e09SAnton Vorontsov 143315c9a0acSGrant Likely /* Retrieve the phandle list property */ 143415c9a0acSGrant Likely list = of_get_property(np, list_name, &size); 143515c9a0acSGrant Likely if (!list) 14361af4c7f1SAlexandre Courbot return -ENOENT; 143715c9a0acSGrant Likely list_end = list + size / sizeof(*list); 143815c9a0acSGrant Likely 143915c9a0acSGrant Likely /* Loop over the phandles until all the requested entry is found */ 144015c9a0acSGrant Likely while (list < list_end) { 144123ce04c0SGrant Likely rc = -EINVAL; 144215c9a0acSGrant Likely count = 0; 144315c9a0acSGrant Likely 144415c9a0acSGrant Likely /* 144515c9a0acSGrant Likely * If phandle is 0, then it is an empty entry with no 144615c9a0acSGrant Likely * arguments. Skip forward to the next entry. 144715c9a0acSGrant Likely */ 14489a6b2e58SGrant Likely phandle = be32_to_cpup(list++); 144915c9a0acSGrant Likely if (phandle) { 145015c9a0acSGrant Likely /* 145115c9a0acSGrant Likely * Find the provider node and parse the #*-cells 145291d9942cSStephen Warren * property to determine the argument length. 145391d9942cSStephen Warren * 145491d9942cSStephen Warren * This is not needed if the cell count is hard-coded 145591d9942cSStephen Warren * (i.e. cells_name not set, but cell_count is set), 145691d9942cSStephen Warren * except when we're going to return the found node 145791d9942cSStephen Warren * below. 145815c9a0acSGrant Likely */ 145991d9942cSStephen Warren if (cells_name || cur_index == index) { 14609a6b2e58SGrant Likely node = of_find_node_by_phandle(phandle); 146164b60e09SAnton Vorontsov if (!node) { 146215c9a0acSGrant Likely pr_err("%s: could not find phandle\n", 146364b60e09SAnton Vorontsov np->full_name); 146423ce04c0SGrant Likely goto err; 146515c9a0acSGrant Likely } 146691d9942cSStephen Warren } 1467035fd948SStephen Warren 1468035fd948SStephen Warren if (cells_name) { 1469035fd948SStephen Warren if (of_property_read_u32(node, cells_name, 1470035fd948SStephen Warren &count)) { 147115c9a0acSGrant Likely pr_err("%s: could not get %s for %s\n", 147215c9a0acSGrant Likely np->full_name, cells_name, 147315c9a0acSGrant Likely node->full_name); 147423ce04c0SGrant Likely goto err; 147515c9a0acSGrant Likely } 1476035fd948SStephen Warren } else { 1477035fd948SStephen Warren count = cell_count; 1478035fd948SStephen Warren } 147915c9a0acSGrant Likely 148015c9a0acSGrant Likely /* 148115c9a0acSGrant Likely * Make sure that the arguments actually fit in the 148215c9a0acSGrant Likely * remaining property data length 148315c9a0acSGrant Likely */ 148415c9a0acSGrant Likely if (list + count > list_end) { 148515c9a0acSGrant Likely pr_err("%s: arguments longer than property\n", 148615c9a0acSGrant Likely np->full_name); 148723ce04c0SGrant Likely goto err; 148815c9a0acSGrant Likely } 148915c9a0acSGrant Likely } 149015c9a0acSGrant Likely 149115c9a0acSGrant Likely /* 149215c9a0acSGrant Likely * All of the error cases above bail out of the loop, so at 149315c9a0acSGrant Likely * this point, the parsing is successful. If the requested 149415c9a0acSGrant Likely * index matches, then fill the out_args structure and return, 149515c9a0acSGrant Likely * or return -ENOENT for an empty entry. 149615c9a0acSGrant Likely */ 149723ce04c0SGrant Likely rc = -ENOENT; 149815c9a0acSGrant Likely if (cur_index == index) { 149915c9a0acSGrant Likely if (!phandle) 150023ce04c0SGrant Likely goto err; 150115c9a0acSGrant Likely 150215c9a0acSGrant Likely if (out_args) { 150315c9a0acSGrant Likely int i; 150415c9a0acSGrant Likely if (WARN_ON(count > MAX_PHANDLE_ARGS)) 150515c9a0acSGrant Likely count = MAX_PHANDLE_ARGS; 150615c9a0acSGrant Likely out_args->np = node; 150715c9a0acSGrant Likely out_args->args_count = count; 150815c9a0acSGrant Likely for (i = 0; i < count; i++) 150915c9a0acSGrant Likely out_args->args[i] = be32_to_cpup(list++); 1510b855f16bSTang Yuantian } else { 1511b855f16bSTang Yuantian of_node_put(node); 151215c9a0acSGrant Likely } 151323ce04c0SGrant Likely 151423ce04c0SGrant Likely /* Found it! return success */ 151515c9a0acSGrant Likely return 0; 151615c9a0acSGrant Likely } 151764b60e09SAnton Vorontsov 151864b60e09SAnton Vorontsov of_node_put(node); 151964b60e09SAnton Vorontsov node = NULL; 152015c9a0acSGrant Likely list += count; 152164b60e09SAnton Vorontsov cur_index++; 152264b60e09SAnton Vorontsov } 152364b60e09SAnton Vorontsov 152423ce04c0SGrant Likely /* 152523ce04c0SGrant Likely * Unlock node before returning result; will be one of: 152623ce04c0SGrant Likely * -ENOENT : index is for empty phandle 152723ce04c0SGrant Likely * -EINVAL : parsing error on data 1528bd69f73fSGrant Likely * [1..n] : Number of phandle (count mode; when index = -1) 152923ce04c0SGrant Likely */ 1530bd69f73fSGrant Likely rc = index < 0 ? cur_index : -ENOENT; 153123ce04c0SGrant Likely err: 153215c9a0acSGrant Likely if (node) 153364b60e09SAnton Vorontsov of_node_put(node); 153423ce04c0SGrant Likely return rc; 153564b60e09SAnton Vorontsov } 1536bd69f73fSGrant Likely 1537eded9dd4SStephen Warren /** 15385fba49e3SStephen Warren * of_parse_phandle - Resolve a phandle property to a device_node pointer 15395fba49e3SStephen Warren * @np: Pointer to device node holding phandle property 15405fba49e3SStephen Warren * @phandle_name: Name of property holding a phandle value 15415fba49e3SStephen Warren * @index: For properties holding a table of phandles, this is the index into 15425fba49e3SStephen Warren * the table 15435fba49e3SStephen Warren * 15445fba49e3SStephen Warren * Returns the device_node pointer with refcount incremented. Use 15455fba49e3SStephen Warren * of_node_put() on it when done. 15465fba49e3SStephen Warren */ 15475fba49e3SStephen Warren struct device_node *of_parse_phandle(const struct device_node *np, 15485fba49e3SStephen Warren const char *phandle_name, int index) 15495fba49e3SStephen Warren { 155091d9942cSStephen Warren struct of_phandle_args args; 15515fba49e3SStephen Warren 155291d9942cSStephen Warren if (index < 0) 15535fba49e3SStephen Warren return NULL; 15545fba49e3SStephen Warren 155591d9942cSStephen Warren if (__of_parse_phandle_with_args(np, phandle_name, NULL, 0, 155691d9942cSStephen Warren index, &args)) 155791d9942cSStephen Warren return NULL; 155891d9942cSStephen Warren 155991d9942cSStephen Warren return args.np; 15605fba49e3SStephen Warren } 15615fba49e3SStephen Warren EXPORT_SYMBOL(of_parse_phandle); 15625fba49e3SStephen Warren 15635fba49e3SStephen Warren /** 1564eded9dd4SStephen Warren * of_parse_phandle_with_args() - Find a node pointed by phandle in a list 1565eded9dd4SStephen Warren * @np: pointer to a device tree node containing a list 1566eded9dd4SStephen Warren * @list_name: property name that contains a list 1567eded9dd4SStephen Warren * @cells_name: property name that specifies phandles' arguments count 1568eded9dd4SStephen Warren * @index: index of a phandle to parse out 1569eded9dd4SStephen Warren * @out_args: optional pointer to output arguments structure (will be filled) 1570eded9dd4SStephen Warren * 1571eded9dd4SStephen Warren * This function is useful to parse lists of phandles and their arguments. 1572eded9dd4SStephen Warren * Returns 0 on success and fills out_args, on error returns appropriate 1573eded9dd4SStephen Warren * errno value. 1574eded9dd4SStephen Warren * 1575d94a75c1SGeert Uytterhoeven * Caller is responsible to call of_node_put() on the returned out_args->np 1576eded9dd4SStephen Warren * pointer. 1577eded9dd4SStephen Warren * 1578eded9dd4SStephen Warren * Example: 1579eded9dd4SStephen Warren * 1580eded9dd4SStephen Warren * phandle1: node1 { 1581eded9dd4SStephen Warren * #list-cells = <2>; 1582eded9dd4SStephen Warren * } 1583eded9dd4SStephen Warren * 1584eded9dd4SStephen Warren * phandle2: node2 { 1585eded9dd4SStephen Warren * #list-cells = <1>; 1586eded9dd4SStephen Warren * } 1587eded9dd4SStephen Warren * 1588eded9dd4SStephen Warren * node3 { 1589eded9dd4SStephen Warren * list = <&phandle1 1 2 &phandle2 3>; 1590eded9dd4SStephen Warren * } 1591eded9dd4SStephen Warren * 1592eded9dd4SStephen Warren * To get a device_node of the `node2' node you may call this: 1593eded9dd4SStephen Warren * of_parse_phandle_with_args(node3, "list", "#list-cells", 1, &args); 1594eded9dd4SStephen Warren */ 1595bd69f73fSGrant Likely int of_parse_phandle_with_args(const struct device_node *np, const char *list_name, 1596bd69f73fSGrant Likely const char *cells_name, int index, 1597bd69f73fSGrant Likely struct of_phandle_args *out_args) 1598bd69f73fSGrant Likely { 1599bd69f73fSGrant Likely if (index < 0) 1600bd69f73fSGrant Likely return -EINVAL; 1601035fd948SStephen Warren return __of_parse_phandle_with_args(np, list_name, cells_name, 0, 1602035fd948SStephen Warren index, out_args); 1603bd69f73fSGrant Likely } 160415c9a0acSGrant Likely EXPORT_SYMBOL(of_parse_phandle_with_args); 160502af11b0SGrant Likely 1606bd69f73fSGrant Likely /** 1607035fd948SStephen Warren * of_parse_phandle_with_fixed_args() - Find a node pointed by phandle in a list 1608035fd948SStephen Warren * @np: pointer to a device tree node containing a list 1609035fd948SStephen Warren * @list_name: property name that contains a list 1610035fd948SStephen Warren * @cell_count: number of argument cells following the phandle 1611035fd948SStephen Warren * @index: index of a phandle to parse out 1612035fd948SStephen Warren * @out_args: optional pointer to output arguments structure (will be filled) 1613035fd948SStephen Warren * 1614035fd948SStephen Warren * This function is useful to parse lists of phandles and their arguments. 1615035fd948SStephen Warren * Returns 0 on success and fills out_args, on error returns appropriate 1616035fd948SStephen Warren * errno value. 1617035fd948SStephen Warren * 1618d94a75c1SGeert Uytterhoeven * Caller is responsible to call of_node_put() on the returned out_args->np 1619035fd948SStephen Warren * pointer. 1620035fd948SStephen Warren * 1621035fd948SStephen Warren * Example: 1622035fd948SStephen Warren * 1623035fd948SStephen Warren * phandle1: node1 { 1624035fd948SStephen Warren * } 1625035fd948SStephen Warren * 1626035fd948SStephen Warren * phandle2: node2 { 1627035fd948SStephen Warren * } 1628035fd948SStephen Warren * 1629035fd948SStephen Warren * node3 { 1630035fd948SStephen Warren * list = <&phandle1 0 2 &phandle2 2 3>; 1631035fd948SStephen Warren * } 1632035fd948SStephen Warren * 1633035fd948SStephen Warren * To get a device_node of the `node2' node you may call this: 1634035fd948SStephen Warren * of_parse_phandle_with_fixed_args(node3, "list", 2, 1, &args); 1635035fd948SStephen Warren */ 1636035fd948SStephen Warren int of_parse_phandle_with_fixed_args(const struct device_node *np, 1637035fd948SStephen Warren const char *list_name, int cell_count, 1638035fd948SStephen Warren int index, struct of_phandle_args *out_args) 1639035fd948SStephen Warren { 1640035fd948SStephen Warren if (index < 0) 1641035fd948SStephen Warren return -EINVAL; 1642035fd948SStephen Warren return __of_parse_phandle_with_args(np, list_name, NULL, cell_count, 1643035fd948SStephen Warren index, out_args); 1644035fd948SStephen Warren } 1645035fd948SStephen Warren EXPORT_SYMBOL(of_parse_phandle_with_fixed_args); 1646035fd948SStephen Warren 1647035fd948SStephen Warren /** 1648bd69f73fSGrant Likely * of_count_phandle_with_args() - Find the number of phandles references in a property 1649bd69f73fSGrant Likely * @np: pointer to a device tree node containing a list 1650bd69f73fSGrant Likely * @list_name: property name that contains a list 1651bd69f73fSGrant Likely * @cells_name: property name that specifies phandles' arguments count 1652bd69f73fSGrant Likely * 1653bd69f73fSGrant Likely * Returns the number of phandle + argument tuples within a property. It 1654bd69f73fSGrant Likely * is a typical pattern to encode a list of phandle and variable 1655bd69f73fSGrant Likely * arguments into a single property. The number of arguments is encoded 1656bd69f73fSGrant Likely * by a property in the phandle-target node. For example, a gpios 1657bd69f73fSGrant Likely * property would contain a list of GPIO specifies consisting of a 1658bd69f73fSGrant Likely * phandle and 1 or more arguments. The number of arguments are 1659bd69f73fSGrant Likely * determined by the #gpio-cells property in the node pointed to by the 1660bd69f73fSGrant Likely * phandle. 1661bd69f73fSGrant Likely */ 1662bd69f73fSGrant Likely int of_count_phandle_with_args(const struct device_node *np, const char *list_name, 1663bd69f73fSGrant Likely const char *cells_name) 1664bd69f73fSGrant Likely { 1665035fd948SStephen Warren return __of_parse_phandle_with_args(np, list_name, cells_name, 0, -1, 1666035fd948SStephen Warren NULL); 1667bd69f73fSGrant Likely } 1668bd69f73fSGrant Likely EXPORT_SYMBOL(of_count_phandle_with_args); 1669bd69f73fSGrant Likely 167002af11b0SGrant Likely /** 167162664f67SXiubo Li * __of_add_property - Add a property to a node without lock operations 167262664f67SXiubo Li */ 1673d8c50088SPantelis Antoniou int __of_add_property(struct device_node *np, struct property *prop) 167462664f67SXiubo Li { 167562664f67SXiubo Li struct property **next; 167662664f67SXiubo Li 167762664f67SXiubo Li prop->next = NULL; 167862664f67SXiubo Li next = &np->properties; 167962664f67SXiubo Li while (*next) { 168062664f67SXiubo Li if (strcmp(prop->name, (*next)->name) == 0) 168162664f67SXiubo Li /* duplicate ! don't insert it */ 168262664f67SXiubo Li return -EEXIST; 168362664f67SXiubo Li 168462664f67SXiubo Li next = &(*next)->next; 168562664f67SXiubo Li } 168662664f67SXiubo Li *next = prop; 168762664f67SXiubo Li 168862664f67SXiubo Li return 0; 168962664f67SXiubo Li } 169062664f67SXiubo Li 169162664f67SXiubo Li /** 169279d1c712SNathan Fontenot * of_add_property - Add a property to a node 169302af11b0SGrant Likely */ 169479d1c712SNathan Fontenot int of_add_property(struct device_node *np, struct property *prop) 169502af11b0SGrant Likely { 169602af11b0SGrant Likely unsigned long flags; 16971cf3d8b3SNathan Fontenot int rc; 16981cf3d8b3SNathan Fontenot 16998a2b22a2SGrant Likely mutex_lock(&of_mutex); 170002af11b0SGrant Likely 1701d6d3c4e6SThomas Gleixner raw_spin_lock_irqsave(&devtree_lock, flags); 170262664f67SXiubo Li rc = __of_add_property(np, prop); 1703d6d3c4e6SThomas Gleixner raw_spin_unlock_irqrestore(&devtree_lock, flags); 170402af11b0SGrant Likely 17058a2b22a2SGrant Likely if (!rc) 170675b57ecfSGrant Likely __of_add_property_sysfs(np, prop); 170702af11b0SGrant Likely 17088a2b22a2SGrant Likely mutex_unlock(&of_mutex); 17098a2b22a2SGrant Likely 1710259092a3SGrant Likely if (!rc) 1711259092a3SGrant Likely of_property_notify(OF_RECONFIG_ADD_PROPERTY, np, prop, NULL); 1712259092a3SGrant Likely 171362664f67SXiubo Li return rc; 171402af11b0SGrant Likely } 171502af11b0SGrant Likely 1716d8c50088SPantelis Antoniou int __of_remove_property(struct device_node *np, struct property *prop) 1717d8c50088SPantelis Antoniou { 1718d8c50088SPantelis Antoniou struct property **next; 1719d8c50088SPantelis Antoniou 1720d8c50088SPantelis Antoniou for (next = &np->properties; *next; next = &(*next)->next) { 1721d8c50088SPantelis Antoniou if (*next == prop) 1722d8c50088SPantelis Antoniou break; 1723d8c50088SPantelis Antoniou } 1724d8c50088SPantelis Antoniou if (*next == NULL) 1725d8c50088SPantelis Antoniou return -ENODEV; 1726d8c50088SPantelis Antoniou 1727d8c50088SPantelis Antoniou /* found the node */ 1728d8c50088SPantelis Antoniou *next = prop->next; 1729d8c50088SPantelis Antoniou prop->next = np->deadprops; 1730d8c50088SPantelis Antoniou np->deadprops = prop; 1731d8c50088SPantelis Antoniou 1732d8c50088SPantelis Antoniou return 0; 1733d8c50088SPantelis Antoniou } 1734d8c50088SPantelis Antoniou 17358a2b22a2SGrant Likely void __of_remove_property_sysfs(struct device_node *np, struct property *prop) 17368a2b22a2SGrant Likely { 1737ef69d740SGaurav Minocha if (!IS_ENABLED(CONFIG_SYSFS)) 1738ef69d740SGaurav Minocha return; 1739ef69d740SGaurav Minocha 17408a2b22a2SGrant Likely /* at early boot, bail here and defer setup to of_init() */ 17418a2b22a2SGrant Likely if (of_kset && of_node_is_attached(np)) 17428a2b22a2SGrant Likely sysfs_remove_bin_file(&np->kobj, &prop->attr); 17438a2b22a2SGrant Likely } 17448a2b22a2SGrant Likely 174502af11b0SGrant Likely /** 174679d1c712SNathan Fontenot * of_remove_property - Remove a property from a node. 174702af11b0SGrant Likely * 174802af11b0SGrant Likely * Note that we don't actually remove it, since we have given out 174902af11b0SGrant Likely * who-knows-how-many pointers to the data using get-property. 175002af11b0SGrant Likely * Instead we just move the property to the "dead properties" 175102af11b0SGrant Likely * list, so it won't be found any more. 175202af11b0SGrant Likely */ 175379d1c712SNathan Fontenot int of_remove_property(struct device_node *np, struct property *prop) 175402af11b0SGrant Likely { 175502af11b0SGrant Likely unsigned long flags; 17561cf3d8b3SNathan Fontenot int rc; 17571cf3d8b3SNathan Fontenot 17588a2b22a2SGrant Likely mutex_lock(&of_mutex); 175902af11b0SGrant Likely 1760d6d3c4e6SThomas Gleixner raw_spin_lock_irqsave(&devtree_lock, flags); 1761d8c50088SPantelis Antoniou rc = __of_remove_property(np, prop); 1762d6d3c4e6SThomas Gleixner raw_spin_unlock_irqrestore(&devtree_lock, flags); 176302af11b0SGrant Likely 17648a2b22a2SGrant Likely if (!rc) 17658a2b22a2SGrant Likely __of_remove_property_sysfs(np, prop); 176602af11b0SGrant Likely 17678a2b22a2SGrant Likely mutex_unlock(&of_mutex); 17688a2b22a2SGrant Likely 1769259092a3SGrant Likely if (!rc) 1770259092a3SGrant Likely of_property_notify(OF_RECONFIG_REMOVE_PROPERTY, np, prop, NULL); 1771259092a3SGrant Likely 1772d8c50088SPantelis Antoniou return rc; 177302af11b0SGrant Likely } 177402af11b0SGrant Likely 1775d8c50088SPantelis Antoniou int __of_update_property(struct device_node *np, struct property *newprop, 1776d8c50088SPantelis Antoniou struct property **oldpropp) 1777d8c50088SPantelis Antoniou { 1778d8c50088SPantelis Antoniou struct property **next, *oldprop; 1779d8c50088SPantelis Antoniou 1780d8c50088SPantelis Antoniou for (next = &np->properties; *next; next = &(*next)->next) { 1781d8c50088SPantelis Antoniou if (of_prop_cmp((*next)->name, newprop->name) == 0) 1782d8c50088SPantelis Antoniou break; 1783d8c50088SPantelis Antoniou } 1784d8c50088SPantelis Antoniou *oldpropp = oldprop = *next; 1785d8c50088SPantelis Antoniou 1786d8c50088SPantelis Antoniou if (oldprop) { 1787d8c50088SPantelis Antoniou /* replace the node */ 1788d8c50088SPantelis Antoniou newprop->next = oldprop->next; 1789d8c50088SPantelis Antoniou *next = newprop; 1790d8c50088SPantelis Antoniou oldprop->next = np->deadprops; 1791d8c50088SPantelis Antoniou np->deadprops = oldprop; 1792d8c50088SPantelis Antoniou } else { 1793d8c50088SPantelis Antoniou /* new node */ 1794d8c50088SPantelis Antoniou newprop->next = NULL; 1795d8c50088SPantelis Antoniou *next = newprop; 1796d8c50088SPantelis Antoniou } 1797d8c50088SPantelis Antoniou 1798d8c50088SPantelis Antoniou return 0; 1799d8c50088SPantelis Antoniou } 1800d8c50088SPantelis Antoniou 18018a2b22a2SGrant Likely void __of_update_property_sysfs(struct device_node *np, struct property *newprop, 18028a2b22a2SGrant Likely struct property *oldprop) 18038a2b22a2SGrant Likely { 1804ef69d740SGaurav Minocha if (!IS_ENABLED(CONFIG_SYSFS)) 1805ef69d740SGaurav Minocha return; 1806ef69d740SGaurav Minocha 18078a2b22a2SGrant Likely /* At early boot, bail out and defer setup to of_init() */ 180802af11b0SGrant Likely if (!of_kset) 18098a2b22a2SGrant Likely return; 181002af11b0SGrant Likely 18118a2b22a2SGrant Likely if (oldprop) 18128a2b22a2SGrant Likely sysfs_remove_bin_file(&np->kobj, &oldprop->attr); 18138a2b22a2SGrant Likely __of_add_property_sysfs(np, newprop); 181402af11b0SGrant Likely } 181502af11b0SGrant Likely 181602af11b0SGrant Likely /* 181779d1c712SNathan Fontenot * of_update_property - Update a property in a node, if the property does 1818475d0094SDong Aisheng * not exist, add it. 181902af11b0SGrant Likely * 182002af11b0SGrant Likely * Note that we don't actually remove it, since we have given out 182102af11b0SGrant Likely * who-knows-how-many pointers to the data using get-property. 182202af11b0SGrant Likely * Instead we just move the property to the "dead properties" list, 182302af11b0SGrant Likely * and add the new property to the property list 182402af11b0SGrant Likely */ 182579d1c712SNathan Fontenot int of_update_property(struct device_node *np, struct property *newprop) 182602af11b0SGrant Likely { 1827d8c50088SPantelis Antoniou struct property *oldprop; 182802af11b0SGrant Likely unsigned long flags; 1829947fdaadSXiubo Li int rc; 18301cf3d8b3SNathan Fontenot 1831475d0094SDong Aisheng if (!newprop->name) 1832475d0094SDong Aisheng return -EINVAL; 1833475d0094SDong Aisheng 18348a2b22a2SGrant Likely mutex_lock(&of_mutex); 1835fcdeb7feSGrant Likely 1836d6d3c4e6SThomas Gleixner raw_spin_lock_irqsave(&devtree_lock, flags); 1837d8c50088SPantelis Antoniou rc = __of_update_property(np, newprop, &oldprop); 1838d6d3c4e6SThomas Gleixner raw_spin_unlock_irqrestore(&devtree_lock, flags); 1839e81b3295SNathan Fontenot 18408a2b22a2SGrant Likely if (!rc) 18418a2b22a2SGrant Likely __of_update_property_sysfs(np, newprop, oldprop); 1842fcdeb7feSGrant Likely 18438a2b22a2SGrant Likely mutex_unlock(&of_mutex); 18441cf3d8b3SNathan Fontenot 1845259092a3SGrant Likely if (!rc) 1846259092a3SGrant Likely of_property_notify(OF_RECONFIG_UPDATE_PROPERTY, np, newprop, oldprop); 1847fcdeb7feSGrant Likely 18481cf3d8b3SNathan Fontenot return rc; 1849e81b3295SNathan Fontenot } 1850e81b3295SNathan Fontenot 1851611cad72SShawn Guo static void of_alias_add(struct alias_prop *ap, struct device_node *np, 1852611cad72SShawn Guo int id, const char *stem, int stem_len) 1853611cad72SShawn Guo { 1854611cad72SShawn Guo ap->np = np; 1855611cad72SShawn Guo ap->id = id; 1856611cad72SShawn Guo strncpy(ap->stem, stem, stem_len); 1857611cad72SShawn Guo ap->stem[stem_len] = 0; 1858611cad72SShawn Guo list_add_tail(&ap->link, &aliases_lookup); 1859611cad72SShawn Guo pr_debug("adding DT alias:%s: stem=%s id=%i node=%s\n", 186074a7f084SGrant Likely ap->alias, ap->stem, ap->id, of_node_full_name(np)); 1861611cad72SShawn Guo } 1862611cad72SShawn Guo 1863611cad72SShawn Guo /** 18641821dda4SGeert Uytterhoeven * of_alias_scan - Scan all properties of the 'aliases' node 1865611cad72SShawn Guo * 18661821dda4SGeert Uytterhoeven * The function scans all the properties of the 'aliases' node and populates 18671821dda4SGeert Uytterhoeven * the global lookup table with the properties. It returns the 18681821dda4SGeert Uytterhoeven * number of alias properties found, or an error code in case of failure. 1869611cad72SShawn Guo * 1870611cad72SShawn Guo * @dt_alloc: An allocator that provides a virtual address to memory 18711821dda4SGeert Uytterhoeven * for storing the resulting tree 1872611cad72SShawn Guo */ 1873611cad72SShawn Guo void of_alias_scan(void * (*dt_alloc)(u64 size, u64 align)) 1874611cad72SShawn Guo { 1875611cad72SShawn Guo struct property *pp; 1876611cad72SShawn Guo 18777dbe5849SLaurentiu Tudor of_aliases = of_find_node_by_path("/aliases"); 1878611cad72SShawn Guo of_chosen = of_find_node_by_path("/chosen"); 1879611cad72SShawn Guo if (of_chosen == NULL) 1880611cad72SShawn Guo of_chosen = of_find_node_by_path("/chosen@0"); 18815c19e952SSascha Hauer 18825c19e952SSascha Hauer if (of_chosen) { 1883a752ee56SGrant Likely /* linux,stdout-path and /aliases/stdout are for legacy compatibility */ 1884676e1b2fSGrant Likely const char *name = of_get_property(of_chosen, "stdout-path", NULL); 1885676e1b2fSGrant Likely if (!name) 18865c19e952SSascha Hauer name = of_get_property(of_chosen, "linux,stdout-path", NULL); 1887a752ee56SGrant Likely if (IS_ENABLED(CONFIG_PPC) && !name) 1888a752ee56SGrant Likely name = of_get_property(of_aliases, "stdout", NULL); 18895c19e952SSascha Hauer if (name) 18907914a7c5SLeif Lindholm of_stdout = of_find_node_opts_by_path(name, &of_stdout_options); 18915c19e952SSascha Hauer } 18925c19e952SSascha Hauer 1893611cad72SShawn Guo if (!of_aliases) 1894611cad72SShawn Guo return; 1895611cad72SShawn Guo 18968af0da93SDong Aisheng for_each_property_of_node(of_aliases, pp) { 1897611cad72SShawn Guo const char *start = pp->name; 1898611cad72SShawn Guo const char *end = start + strlen(start); 1899611cad72SShawn Guo struct device_node *np; 1900611cad72SShawn Guo struct alias_prop *ap; 1901611cad72SShawn Guo int id, len; 1902611cad72SShawn Guo 1903611cad72SShawn Guo /* Skip those we do not want to proceed */ 1904611cad72SShawn Guo if (!strcmp(pp->name, "name") || 1905611cad72SShawn Guo !strcmp(pp->name, "phandle") || 1906611cad72SShawn Guo !strcmp(pp->name, "linux,phandle")) 1907611cad72SShawn Guo continue; 1908611cad72SShawn Guo 1909611cad72SShawn Guo np = of_find_node_by_path(pp->value); 1910611cad72SShawn Guo if (!np) 1911611cad72SShawn Guo continue; 1912611cad72SShawn Guo 1913611cad72SShawn Guo /* walk the alias backwards to extract the id and work out 1914611cad72SShawn Guo * the 'stem' string */ 1915611cad72SShawn Guo while (isdigit(*(end-1)) && end > start) 1916611cad72SShawn Guo end--; 1917611cad72SShawn Guo len = end - start; 1918611cad72SShawn Guo 1919611cad72SShawn Guo if (kstrtoint(end, 10, &id) < 0) 1920611cad72SShawn Guo continue; 1921611cad72SShawn Guo 1922611cad72SShawn Guo /* Allocate an alias_prop with enough space for the stem */ 1923611cad72SShawn Guo ap = dt_alloc(sizeof(*ap) + len + 1, 4); 1924611cad72SShawn Guo if (!ap) 1925611cad72SShawn Guo continue; 19260640332eSGrant Likely memset(ap, 0, sizeof(*ap) + len + 1); 1927611cad72SShawn Guo ap->alias = start; 1928611cad72SShawn Guo of_alias_add(ap, np, id, start, len); 1929611cad72SShawn Guo } 1930611cad72SShawn Guo } 1931611cad72SShawn Guo 1932611cad72SShawn Guo /** 1933611cad72SShawn Guo * of_alias_get_id - Get alias id for the given device_node 1934611cad72SShawn Guo * @np: Pointer to the given device_node 1935611cad72SShawn Guo * @stem: Alias stem of the given device_node 1936611cad72SShawn Guo * 19375a53a07fSGeert Uytterhoeven * The function travels the lookup table to get the alias id for the given 19385a53a07fSGeert Uytterhoeven * device_node and alias stem. It returns the alias id if found. 1939611cad72SShawn Guo */ 1940611cad72SShawn Guo int of_alias_get_id(struct device_node *np, const char *stem) 1941611cad72SShawn Guo { 1942611cad72SShawn Guo struct alias_prop *app; 1943611cad72SShawn Guo int id = -ENODEV; 1944611cad72SShawn Guo 1945c05aba2bSPantelis Antoniou mutex_lock(&of_mutex); 1946611cad72SShawn Guo list_for_each_entry(app, &aliases_lookup, link) { 1947611cad72SShawn Guo if (strcmp(app->stem, stem) != 0) 1948611cad72SShawn Guo continue; 1949611cad72SShawn Guo 1950611cad72SShawn Guo if (np == app->np) { 1951611cad72SShawn Guo id = app->id; 1952611cad72SShawn Guo break; 1953611cad72SShawn Guo } 1954611cad72SShawn Guo } 1955c05aba2bSPantelis Antoniou mutex_unlock(&of_mutex); 1956611cad72SShawn Guo 1957611cad72SShawn Guo return id; 1958611cad72SShawn Guo } 1959611cad72SShawn Guo EXPORT_SYMBOL_GPL(of_alias_get_id); 1960c541adc6SStephen Warren 1961c541adc6SStephen Warren const __be32 *of_prop_next_u32(struct property *prop, const __be32 *cur, 1962c541adc6SStephen Warren u32 *pu) 1963c541adc6SStephen Warren { 1964c541adc6SStephen Warren const void *curv = cur; 1965c541adc6SStephen Warren 1966c541adc6SStephen Warren if (!prop) 1967c541adc6SStephen Warren return NULL; 1968c541adc6SStephen Warren 1969c541adc6SStephen Warren if (!cur) { 1970c541adc6SStephen Warren curv = prop->value; 1971c541adc6SStephen Warren goto out_val; 1972c541adc6SStephen Warren } 1973c541adc6SStephen Warren 1974c541adc6SStephen Warren curv += sizeof(*cur); 1975c541adc6SStephen Warren if (curv >= prop->value + prop->length) 1976c541adc6SStephen Warren return NULL; 1977c541adc6SStephen Warren 1978c541adc6SStephen Warren out_val: 1979c541adc6SStephen Warren *pu = be32_to_cpup(curv); 1980c541adc6SStephen Warren return curv; 1981c541adc6SStephen Warren } 1982c541adc6SStephen Warren EXPORT_SYMBOL_GPL(of_prop_next_u32); 1983c541adc6SStephen Warren 1984c541adc6SStephen Warren const char *of_prop_next_string(struct property *prop, const char *cur) 1985c541adc6SStephen Warren { 1986c541adc6SStephen Warren const void *curv = cur; 1987c541adc6SStephen Warren 1988c541adc6SStephen Warren if (!prop) 1989c541adc6SStephen Warren return NULL; 1990c541adc6SStephen Warren 1991c541adc6SStephen Warren if (!cur) 1992c541adc6SStephen Warren return prop->value; 1993c541adc6SStephen Warren 1994c541adc6SStephen Warren curv += strlen(cur) + 1; 1995c541adc6SStephen Warren if (curv >= prop->value + prop->length) 1996c541adc6SStephen Warren return NULL; 1997c541adc6SStephen Warren 1998c541adc6SStephen Warren return curv; 1999c541adc6SStephen Warren } 2000c541adc6SStephen Warren EXPORT_SYMBOL_GPL(of_prop_next_string); 20015c19e952SSascha Hauer 20025c19e952SSascha Hauer /** 20033482f2c5SGrant Likely * of_console_check() - Test and setup console for DT setup 20043482f2c5SGrant Likely * @dn - Pointer to device node 20053482f2c5SGrant Likely * @name - Name to use for preferred console without index. ex. "ttyS" 20063482f2c5SGrant Likely * @index - Index to use for preferred console. 20075c19e952SSascha Hauer * 20083482f2c5SGrant Likely * Check if the given device node matches the stdout-path property in the 20093482f2c5SGrant Likely * /chosen node. If it does then register it as the preferred console and return 20103482f2c5SGrant Likely * TRUE. Otherwise return FALSE. 20115c19e952SSascha Hauer */ 20123482f2c5SGrant Likely bool of_console_check(struct device_node *dn, char *name, int index) 20135c19e952SSascha Hauer { 20143482f2c5SGrant Likely if (!dn || dn != of_stdout || console_set_on_cmdline) 20155c19e952SSascha Hauer return false; 20167914a7c5SLeif Lindholm return !add_preferred_console(name, index, 20177914a7c5SLeif Lindholm kstrdup(of_stdout_options, GFP_KERNEL)); 20185c19e952SSascha Hauer } 20193482f2c5SGrant Likely EXPORT_SYMBOL_GPL(of_console_check); 2020a3e31b45SSudeep KarkadaNagesha 2021a3e31b45SSudeep KarkadaNagesha /** 2022a3e31b45SSudeep KarkadaNagesha * of_find_next_cache_node - Find a node's subsidiary cache 2023a3e31b45SSudeep KarkadaNagesha * @np: node of type "cpu" or "cache" 2024a3e31b45SSudeep KarkadaNagesha * 2025a3e31b45SSudeep KarkadaNagesha * Returns a node pointer with refcount incremented, use 2026a3e31b45SSudeep KarkadaNagesha * of_node_put() on it when done. Caller should hold a reference 2027a3e31b45SSudeep KarkadaNagesha * to np. 2028a3e31b45SSudeep KarkadaNagesha */ 2029a3e31b45SSudeep KarkadaNagesha struct device_node *of_find_next_cache_node(const struct device_node *np) 2030a3e31b45SSudeep KarkadaNagesha { 2031a3e31b45SSudeep KarkadaNagesha struct device_node *child; 2032a3e31b45SSudeep KarkadaNagesha const phandle *handle; 2033a3e31b45SSudeep KarkadaNagesha 2034a3e31b45SSudeep KarkadaNagesha handle = of_get_property(np, "l2-cache", NULL); 2035a3e31b45SSudeep KarkadaNagesha if (!handle) 2036a3e31b45SSudeep KarkadaNagesha handle = of_get_property(np, "next-level-cache", NULL); 2037a3e31b45SSudeep KarkadaNagesha 2038a3e31b45SSudeep KarkadaNagesha if (handle) 2039a3e31b45SSudeep KarkadaNagesha return of_find_node_by_phandle(be32_to_cpup(handle)); 2040a3e31b45SSudeep KarkadaNagesha 2041a3e31b45SSudeep KarkadaNagesha /* OF on pmac has nodes instead of properties named "l2-cache" 2042a3e31b45SSudeep KarkadaNagesha * beneath CPU nodes. 2043a3e31b45SSudeep KarkadaNagesha */ 2044a3e31b45SSudeep KarkadaNagesha if (!strcmp(np->type, "cpu")) 2045a3e31b45SSudeep KarkadaNagesha for_each_child_of_node(np, child) 2046a3e31b45SSudeep KarkadaNagesha if (!strcmp(child->type, "cache")) 2047a3e31b45SSudeep KarkadaNagesha return child; 2048a3e31b45SSudeep KarkadaNagesha 2049a3e31b45SSudeep KarkadaNagesha return NULL; 2050a3e31b45SSudeep KarkadaNagesha } 2051fd9fdb78SPhilipp Zabel 2052fd9fdb78SPhilipp Zabel /** 2053f2a575f6SPhilipp Zabel * of_graph_parse_endpoint() - parse common endpoint node properties 2054f2a575f6SPhilipp Zabel * @node: pointer to endpoint device_node 2055f2a575f6SPhilipp Zabel * @endpoint: pointer to the OF endpoint data structure 2056f2a575f6SPhilipp Zabel * 2057f2a575f6SPhilipp Zabel * The caller should hold a reference to @node. 2058f2a575f6SPhilipp Zabel */ 2059f2a575f6SPhilipp Zabel int of_graph_parse_endpoint(const struct device_node *node, 2060f2a575f6SPhilipp Zabel struct of_endpoint *endpoint) 2061f2a575f6SPhilipp Zabel { 2062f2a575f6SPhilipp Zabel struct device_node *port_node = of_get_parent(node); 2063f2a575f6SPhilipp Zabel 2064d484700aSPhilipp Zabel WARN_ONCE(!port_node, "%s(): endpoint %s has no parent node\n", 2065d484700aSPhilipp Zabel __func__, node->full_name); 2066d484700aSPhilipp Zabel 2067f2a575f6SPhilipp Zabel memset(endpoint, 0, sizeof(*endpoint)); 2068f2a575f6SPhilipp Zabel 2069f2a575f6SPhilipp Zabel endpoint->local_node = node; 2070f2a575f6SPhilipp Zabel /* 2071f2a575f6SPhilipp Zabel * It doesn't matter whether the two calls below succeed. 2072f2a575f6SPhilipp Zabel * If they don't then the default value 0 is used. 2073f2a575f6SPhilipp Zabel */ 2074f2a575f6SPhilipp Zabel of_property_read_u32(port_node, "reg", &endpoint->port); 2075f2a575f6SPhilipp Zabel of_property_read_u32(node, "reg", &endpoint->id); 2076f2a575f6SPhilipp Zabel 2077f2a575f6SPhilipp Zabel of_node_put(port_node); 2078f2a575f6SPhilipp Zabel 2079f2a575f6SPhilipp Zabel return 0; 2080f2a575f6SPhilipp Zabel } 2081f2a575f6SPhilipp Zabel EXPORT_SYMBOL(of_graph_parse_endpoint); 2082f2a575f6SPhilipp Zabel 2083f2a575f6SPhilipp Zabel /** 2084fd9fdb78SPhilipp Zabel * of_graph_get_next_endpoint() - get next endpoint node 2085fd9fdb78SPhilipp Zabel * @parent: pointer to the parent device node 2086fd9fdb78SPhilipp Zabel * @prev: previous endpoint node, or NULL to get first 2087fd9fdb78SPhilipp Zabel * 2088fd9fdb78SPhilipp Zabel * Return: An 'endpoint' node pointer with refcount incremented. Refcount 2089fd9fdb78SPhilipp Zabel * of the passed @prev node is not decremented, the caller have to use 2090fd9fdb78SPhilipp Zabel * of_node_put() on it when done. 2091fd9fdb78SPhilipp Zabel */ 2092fd9fdb78SPhilipp Zabel struct device_node *of_graph_get_next_endpoint(const struct device_node *parent, 2093fd9fdb78SPhilipp Zabel struct device_node *prev) 2094fd9fdb78SPhilipp Zabel { 2095fd9fdb78SPhilipp Zabel struct device_node *endpoint; 20963c83e61eSLinus Torvalds struct device_node *port; 2097fd9fdb78SPhilipp Zabel 2098fd9fdb78SPhilipp Zabel if (!parent) 2099fd9fdb78SPhilipp Zabel return NULL; 2100fd9fdb78SPhilipp Zabel 21013c83e61eSLinus Torvalds /* 21023c83e61eSLinus Torvalds * Start by locating the port node. If no previous endpoint is specified 21033c83e61eSLinus Torvalds * search for the first port node, otherwise get the previous endpoint 21043c83e61eSLinus Torvalds * parent port node. 21053c83e61eSLinus Torvalds */ 2106fd9fdb78SPhilipp Zabel if (!prev) { 2107fd9fdb78SPhilipp Zabel struct device_node *node; 21083c83e61eSLinus Torvalds 2109fd9fdb78SPhilipp Zabel node = of_get_child_by_name(parent, "ports"); 2110fd9fdb78SPhilipp Zabel if (node) 2111fd9fdb78SPhilipp Zabel parent = node; 2112fd9fdb78SPhilipp Zabel 2113fd9fdb78SPhilipp Zabel port = of_get_child_by_name(parent, "port"); 2114fd9fdb78SPhilipp Zabel of_node_put(node); 21154329b93bSPhilipp Zabel 21163c83e61eSLinus Torvalds if (!port) { 21173c83e61eSLinus Torvalds pr_err("%s(): no port node found in %s\n", 21183c83e61eSLinus Torvalds __func__, parent->full_name); 21193c83e61eSLinus Torvalds return NULL; 21204329b93bSPhilipp Zabel } 21213c83e61eSLinus Torvalds } else { 2122fd9fdb78SPhilipp Zabel port = of_get_parent(prev); 21236ff60d39SPhilipp Zabel if (WARN_ONCE(!port, "%s(): endpoint %s has no parent node\n", 21246ff60d39SPhilipp Zabel __func__, prev->full_name)) 2125fd9fdb78SPhilipp Zabel return NULL; 2126fd9fdb78SPhilipp Zabel 21273c83e61eSLinus Torvalds /* 21283c83e61eSLinus Torvalds * Avoid dropping prev node refcount to 0 when getting the next 21293c83e61eSLinus Torvalds * child below. 21303c83e61eSLinus Torvalds */ 2131fd9fdb78SPhilipp Zabel of_node_get(prev); 21323c83e61eSLinus Torvalds } 21333c83e61eSLinus Torvalds 21343c83e61eSLinus Torvalds while (1) { 21353c83e61eSLinus Torvalds /* 21363c83e61eSLinus Torvalds * Now that we have a port node, get the next endpoint by 21373c83e61eSLinus Torvalds * getting the next child. If the previous endpoint is NULL this 21383c83e61eSLinus Torvalds * will return the first child. 21393c83e61eSLinus Torvalds */ 2140fd9fdb78SPhilipp Zabel endpoint = of_get_next_child(port, prev); 2141fd9fdb78SPhilipp Zabel if (endpoint) { 2142fd9fdb78SPhilipp Zabel of_node_put(port); 2143fd9fdb78SPhilipp Zabel return endpoint; 2144fd9fdb78SPhilipp Zabel } 2145fd9fdb78SPhilipp Zabel 2146fd9fdb78SPhilipp Zabel /* No more endpoints under this port, try the next one. */ 21473c83e61eSLinus Torvalds prev = NULL; 21483c83e61eSLinus Torvalds 2149fd9fdb78SPhilipp Zabel do { 2150fd9fdb78SPhilipp Zabel port = of_get_next_child(parent, port); 2151fd9fdb78SPhilipp Zabel if (!port) 2152fd9fdb78SPhilipp Zabel return NULL; 2153fd9fdb78SPhilipp Zabel } while (of_node_cmp(port->name, "port")); 21543c83e61eSLinus Torvalds } 2155fd9fdb78SPhilipp Zabel } 2156fd9fdb78SPhilipp Zabel EXPORT_SYMBOL(of_graph_get_next_endpoint); 2157fd9fdb78SPhilipp Zabel 2158fd9fdb78SPhilipp Zabel /** 2159fd9fdb78SPhilipp Zabel * of_graph_get_remote_port_parent() - get remote port's parent node 2160fd9fdb78SPhilipp Zabel * @node: pointer to a local endpoint device_node 2161fd9fdb78SPhilipp Zabel * 2162fd9fdb78SPhilipp Zabel * Return: Remote device node associated with remote endpoint node linked 2163fd9fdb78SPhilipp Zabel * to @node. Use of_node_put() on it when done. 2164fd9fdb78SPhilipp Zabel */ 2165fd9fdb78SPhilipp Zabel struct device_node *of_graph_get_remote_port_parent( 2166fd9fdb78SPhilipp Zabel const struct device_node *node) 2167fd9fdb78SPhilipp Zabel { 2168fd9fdb78SPhilipp Zabel struct device_node *np; 2169fd9fdb78SPhilipp Zabel unsigned int depth; 2170fd9fdb78SPhilipp Zabel 2171fd9fdb78SPhilipp Zabel /* Get remote endpoint node. */ 2172fd9fdb78SPhilipp Zabel np = of_parse_phandle(node, "remote-endpoint", 0); 2173fd9fdb78SPhilipp Zabel 2174fd9fdb78SPhilipp Zabel /* Walk 3 levels up only if there is 'ports' node. */ 2175fd9fdb78SPhilipp Zabel for (depth = 3; depth && np; depth--) { 2176fd9fdb78SPhilipp Zabel np = of_get_next_parent(np); 2177fd9fdb78SPhilipp Zabel if (depth == 2 && of_node_cmp(np->name, "ports")) 2178fd9fdb78SPhilipp Zabel break; 2179fd9fdb78SPhilipp Zabel } 2180fd9fdb78SPhilipp Zabel return np; 2181fd9fdb78SPhilipp Zabel } 2182fd9fdb78SPhilipp Zabel EXPORT_SYMBOL(of_graph_get_remote_port_parent); 2183fd9fdb78SPhilipp Zabel 2184fd9fdb78SPhilipp Zabel /** 2185fd9fdb78SPhilipp Zabel * of_graph_get_remote_port() - get remote port node 2186fd9fdb78SPhilipp Zabel * @node: pointer to a local endpoint device_node 2187fd9fdb78SPhilipp Zabel * 2188fd9fdb78SPhilipp Zabel * Return: Remote port node associated with remote endpoint node linked 2189fd9fdb78SPhilipp Zabel * to @node. Use of_node_put() on it when done. 2190fd9fdb78SPhilipp Zabel */ 2191fd9fdb78SPhilipp Zabel struct device_node *of_graph_get_remote_port(const struct device_node *node) 2192fd9fdb78SPhilipp Zabel { 2193fd9fdb78SPhilipp Zabel struct device_node *np; 2194fd9fdb78SPhilipp Zabel 2195fd9fdb78SPhilipp Zabel /* Get remote endpoint node. */ 2196fd9fdb78SPhilipp Zabel np = of_parse_phandle(node, "remote-endpoint", 0); 2197fd9fdb78SPhilipp Zabel if (!np) 2198fd9fdb78SPhilipp Zabel return NULL; 2199fd9fdb78SPhilipp Zabel return of_get_next_parent(np); 2200fd9fdb78SPhilipp Zabel } 2201fd9fdb78SPhilipp Zabel EXPORT_SYMBOL(of_graph_get_remote_port); 2202