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