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 */ 20611cad72SShawn Guo #include <linux/ctype.h> 21183912d3SSudeep KarkadaNagesha #include <linux/cpu.h> 2297e873e5SStephen Rothwell #include <linux/module.h> 2397e873e5SStephen Rothwell #include <linux/of.h> 24581b605aSStephen Rothwell #include <linux/spinlock.h> 255a0e3ad6STejun Heo #include <linux/slab.h> 26a9f2f63aSJeremy Kerr #include <linux/proc_fs.h> 27581b605aSStephen Rothwell 28ced4eec9SStepan Moskovchenko #include "of_private.h" 29611cad72SShawn Guo 30ced4eec9SStepan Moskovchenko LIST_HEAD(aliases_lookup); 31611cad72SShawn Guo 32465aac6dSRandy Dunlap struct device_node *of_allnodes; 33465aac6dSRandy Dunlap EXPORT_SYMBOL(of_allnodes); 34fc0bdae4SGrant Likely struct device_node *of_chosen; 35611cad72SShawn Guo struct device_node *of_aliases; 365c19e952SSascha Hauer static struct device_node *of_stdout; 37611cad72SShawn Guo 38ced4eec9SStepan Moskovchenko DEFINE_MUTEX(of_aliases_mutex); 391ef4d424SStephen Rothwell 40581b605aSStephen Rothwell /* use when traversing tree through the allnext, child, sibling, 41581b605aSStephen Rothwell * or parent members of struct device_node. 42581b605aSStephen Rothwell */ 43d6d3c4e6SThomas Gleixner DEFINE_RAW_SPINLOCK(devtree_lock); 4497e873e5SStephen Rothwell 4597e873e5SStephen Rothwell int of_n_addr_cells(struct device_node *np) 4697e873e5SStephen Rothwell { 47a9fadeefSJeremy Kerr const __be32 *ip; 4897e873e5SStephen Rothwell 4997e873e5SStephen Rothwell do { 5097e873e5SStephen Rothwell if (np->parent) 5197e873e5SStephen Rothwell np = np->parent; 5297e873e5SStephen Rothwell ip = of_get_property(np, "#address-cells", NULL); 5397e873e5SStephen Rothwell if (ip) 5433714881SJeremy Kerr return be32_to_cpup(ip); 5597e873e5SStephen Rothwell } while (np->parent); 5697e873e5SStephen Rothwell /* No #address-cells property for the root node */ 5797e873e5SStephen Rothwell return OF_ROOT_NODE_ADDR_CELLS_DEFAULT; 5897e873e5SStephen Rothwell } 5997e873e5SStephen Rothwell EXPORT_SYMBOL(of_n_addr_cells); 6097e873e5SStephen Rothwell 6197e873e5SStephen Rothwell int of_n_size_cells(struct device_node *np) 6297e873e5SStephen Rothwell { 63a9fadeefSJeremy Kerr const __be32 *ip; 6497e873e5SStephen Rothwell 6597e873e5SStephen Rothwell do { 6697e873e5SStephen Rothwell if (np->parent) 6797e873e5SStephen Rothwell np = np->parent; 6897e873e5SStephen Rothwell ip = of_get_property(np, "#size-cells", NULL); 6997e873e5SStephen Rothwell if (ip) 7033714881SJeremy Kerr return be32_to_cpup(ip); 7197e873e5SStephen Rothwell } while (np->parent); 7297e873e5SStephen Rothwell /* No #size-cells property for the root node */ 7397e873e5SStephen Rothwell return OF_ROOT_NODE_SIZE_CELLS_DEFAULT; 7497e873e5SStephen Rothwell } 7597e873e5SStephen Rothwell EXPORT_SYMBOL(of_n_size_cells); 7697e873e5SStephen Rothwell 770f22dd39SGrant Likely #if defined(CONFIG_OF_DYNAMIC) 78923f7e30SGrant Likely /** 79923f7e30SGrant Likely * of_node_get - Increment refcount of a node 80923f7e30SGrant Likely * @node: Node to inc refcount, NULL is supported to 81923f7e30SGrant Likely * simplify writing of callers 82923f7e30SGrant Likely * 83923f7e30SGrant Likely * Returns node. 84923f7e30SGrant Likely */ 85923f7e30SGrant Likely struct device_node *of_node_get(struct device_node *node) 86923f7e30SGrant Likely { 87923f7e30SGrant Likely if (node) 88923f7e30SGrant Likely kref_get(&node->kref); 89923f7e30SGrant Likely return node; 90923f7e30SGrant Likely } 91923f7e30SGrant Likely EXPORT_SYMBOL(of_node_get); 92923f7e30SGrant Likely 93923f7e30SGrant Likely static inline struct device_node *kref_to_device_node(struct kref *kref) 94923f7e30SGrant Likely { 95923f7e30SGrant Likely return container_of(kref, struct device_node, kref); 96923f7e30SGrant Likely } 97923f7e30SGrant Likely 98923f7e30SGrant Likely /** 99923f7e30SGrant Likely * of_node_release - release a dynamically allocated node 100923f7e30SGrant Likely * @kref: kref element of the node to be released 101923f7e30SGrant Likely * 102923f7e30SGrant Likely * In of_node_put() this function is passed to kref_put() 103923f7e30SGrant Likely * as the destructor. 104923f7e30SGrant Likely */ 105923f7e30SGrant Likely static void of_node_release(struct kref *kref) 106923f7e30SGrant Likely { 107923f7e30SGrant Likely struct device_node *node = kref_to_device_node(kref); 108923f7e30SGrant Likely struct property *prop = node->properties; 109923f7e30SGrant Likely 110923f7e30SGrant Likely /* We should never be releasing nodes that haven't been detached. */ 111923f7e30SGrant Likely if (!of_node_check_flag(node, OF_DETACHED)) { 112923f7e30SGrant Likely pr_err("ERROR: Bad of_node_put() on %s\n", node->full_name); 113923f7e30SGrant Likely dump_stack(); 114923f7e30SGrant Likely kref_init(&node->kref); 115923f7e30SGrant Likely return; 116923f7e30SGrant Likely } 117923f7e30SGrant Likely 118923f7e30SGrant Likely if (!of_node_check_flag(node, OF_DYNAMIC)) 119923f7e30SGrant Likely return; 120923f7e30SGrant Likely 121923f7e30SGrant Likely while (prop) { 122923f7e30SGrant Likely struct property *next = prop->next; 123923f7e30SGrant Likely kfree(prop->name); 124923f7e30SGrant Likely kfree(prop->value); 125923f7e30SGrant Likely kfree(prop); 126923f7e30SGrant Likely prop = next; 127923f7e30SGrant Likely 128923f7e30SGrant Likely if (!prop) { 129923f7e30SGrant Likely prop = node->deadprops; 130923f7e30SGrant Likely node->deadprops = NULL; 131923f7e30SGrant Likely } 132923f7e30SGrant Likely } 133923f7e30SGrant Likely kfree(node->full_name); 134923f7e30SGrant Likely kfree(node->data); 135923f7e30SGrant Likely kfree(node); 136923f7e30SGrant Likely } 137923f7e30SGrant Likely 138923f7e30SGrant Likely /** 139923f7e30SGrant Likely * of_node_put - Decrement refcount of a node 140923f7e30SGrant Likely * @node: Node to dec refcount, NULL is supported to 141923f7e30SGrant Likely * simplify writing of callers 142923f7e30SGrant Likely * 143923f7e30SGrant Likely */ 144923f7e30SGrant Likely void of_node_put(struct device_node *node) 145923f7e30SGrant Likely { 146923f7e30SGrant Likely if (node) 147923f7e30SGrant Likely kref_put(&node->kref, of_node_release); 148923f7e30SGrant Likely } 149923f7e30SGrant Likely EXPORT_SYMBOL(of_node_put); 1500f22dd39SGrant Likely #endif /* CONFIG_OF_DYNAMIC */ 151923f7e30SGrant Likely 15228d0e36bSThomas Gleixner static struct property *__of_find_property(const struct device_node *np, 15328d0e36bSThomas Gleixner const char *name, int *lenp) 154581b605aSStephen Rothwell { 155581b605aSStephen Rothwell struct property *pp; 156581b605aSStephen Rothwell 15764e4566fSTimur Tabi if (!np) 15864e4566fSTimur Tabi return NULL; 15964e4566fSTimur Tabi 160a3a7cab1SSachin Kamat for (pp = np->properties; pp; pp = pp->next) { 161581b605aSStephen Rothwell if (of_prop_cmp(pp->name, name) == 0) { 162a3a7cab1SSachin Kamat if (lenp) 163581b605aSStephen Rothwell *lenp = pp->length; 164581b605aSStephen Rothwell break; 165581b605aSStephen Rothwell } 166581b605aSStephen Rothwell } 16728d0e36bSThomas Gleixner 16828d0e36bSThomas Gleixner return pp; 16928d0e36bSThomas Gleixner } 17028d0e36bSThomas Gleixner 17128d0e36bSThomas Gleixner struct property *of_find_property(const struct device_node *np, 17228d0e36bSThomas Gleixner const char *name, 17328d0e36bSThomas Gleixner int *lenp) 17428d0e36bSThomas Gleixner { 17528d0e36bSThomas Gleixner struct property *pp; 176d6d3c4e6SThomas Gleixner unsigned long flags; 17728d0e36bSThomas Gleixner 178d6d3c4e6SThomas Gleixner raw_spin_lock_irqsave(&devtree_lock, flags); 17928d0e36bSThomas Gleixner pp = __of_find_property(np, name, lenp); 180d6d3c4e6SThomas Gleixner raw_spin_unlock_irqrestore(&devtree_lock, flags); 181581b605aSStephen Rothwell 182581b605aSStephen Rothwell return pp; 183581b605aSStephen Rothwell } 184581b605aSStephen Rothwell EXPORT_SYMBOL(of_find_property); 185581b605aSStephen Rothwell 186e91edcf5SGrant Likely /** 187e91edcf5SGrant Likely * of_find_all_nodes - Get next node in global list 188e91edcf5SGrant Likely * @prev: Previous node or NULL to start iteration 189e91edcf5SGrant Likely * of_node_put() will be called on it 190e91edcf5SGrant Likely * 191e91edcf5SGrant Likely * Returns a node pointer with refcount incremented, use 192e91edcf5SGrant Likely * of_node_put() on it when done. 193e91edcf5SGrant Likely */ 194e91edcf5SGrant Likely struct device_node *of_find_all_nodes(struct device_node *prev) 195e91edcf5SGrant Likely { 196e91edcf5SGrant Likely struct device_node *np; 197d25d8694SBenjamin Herrenschmidt unsigned long flags; 198e91edcf5SGrant Likely 199d25d8694SBenjamin Herrenschmidt raw_spin_lock_irqsave(&devtree_lock, flags); 200465aac6dSRandy Dunlap np = prev ? prev->allnext : of_allnodes; 201e91edcf5SGrant Likely for (; np != NULL; np = np->allnext) 202e91edcf5SGrant Likely if (of_node_get(np)) 203e91edcf5SGrant Likely break; 204e91edcf5SGrant Likely of_node_put(prev); 205d25d8694SBenjamin Herrenschmidt raw_spin_unlock_irqrestore(&devtree_lock, flags); 206e91edcf5SGrant Likely return np; 207e91edcf5SGrant Likely } 208e91edcf5SGrant Likely EXPORT_SYMBOL(of_find_all_nodes); 209e91edcf5SGrant Likely 21097e873e5SStephen Rothwell /* 21197e873e5SStephen Rothwell * Find a property with a given name for a given node 21297e873e5SStephen Rothwell * and return the value. 21397e873e5SStephen Rothwell */ 21428d0e36bSThomas Gleixner static const void *__of_get_property(const struct device_node *np, 21528d0e36bSThomas Gleixner const char *name, int *lenp) 21628d0e36bSThomas Gleixner { 21728d0e36bSThomas Gleixner struct property *pp = __of_find_property(np, name, lenp); 21828d0e36bSThomas Gleixner 21928d0e36bSThomas Gleixner return pp ? pp->value : NULL; 22028d0e36bSThomas Gleixner } 22128d0e36bSThomas Gleixner 22228d0e36bSThomas Gleixner /* 22328d0e36bSThomas Gleixner * Find a property with a given name for a given node 22428d0e36bSThomas Gleixner * and return the value. 22528d0e36bSThomas Gleixner */ 22697e873e5SStephen Rothwell const void *of_get_property(const struct device_node *np, const char *name, 22797e873e5SStephen Rothwell int *lenp) 22897e873e5SStephen Rothwell { 22997e873e5SStephen Rothwell struct property *pp = of_find_property(np, name, lenp); 23097e873e5SStephen Rothwell 23197e873e5SStephen Rothwell return pp ? pp->value : NULL; 23297e873e5SStephen Rothwell } 23397e873e5SStephen Rothwell EXPORT_SYMBOL(of_get_property); 2340081cbc3SStephen Rothwell 235183912d3SSudeep KarkadaNagesha /* 236183912d3SSudeep KarkadaNagesha * arch_match_cpu_phys_id - Match the given logical CPU and physical id 237183912d3SSudeep KarkadaNagesha * 238183912d3SSudeep KarkadaNagesha * @cpu: logical cpu index of a core/thread 239183912d3SSudeep KarkadaNagesha * @phys_id: physical identifier of a core/thread 240183912d3SSudeep KarkadaNagesha * 241183912d3SSudeep KarkadaNagesha * CPU logical to physical index mapping is architecture specific. 242183912d3SSudeep KarkadaNagesha * However this __weak function provides a default match of physical 243183912d3SSudeep KarkadaNagesha * id to logical cpu index. phys_id provided here is usually values read 244183912d3SSudeep KarkadaNagesha * from the device tree which must match the hardware internal registers. 245183912d3SSudeep KarkadaNagesha * 246183912d3SSudeep KarkadaNagesha * Returns true if the physical identifier and the logical cpu index 247183912d3SSudeep KarkadaNagesha * correspond to the same core/thread, false otherwise. 248183912d3SSudeep KarkadaNagesha */ 249183912d3SSudeep KarkadaNagesha bool __weak arch_match_cpu_phys_id(int cpu, u64 phys_id) 250183912d3SSudeep KarkadaNagesha { 251183912d3SSudeep KarkadaNagesha return (u32)phys_id == cpu; 252183912d3SSudeep KarkadaNagesha } 253183912d3SSudeep KarkadaNagesha 254183912d3SSudeep KarkadaNagesha /** 255183912d3SSudeep KarkadaNagesha * Checks if the given "prop_name" property holds the physical id of the 256183912d3SSudeep KarkadaNagesha * core/thread corresponding to the logical cpu 'cpu'. If 'thread' is not 257183912d3SSudeep KarkadaNagesha * NULL, local thread number within the core is returned in it. 258183912d3SSudeep KarkadaNagesha */ 259183912d3SSudeep KarkadaNagesha static bool __of_find_n_match_cpu_property(struct device_node *cpun, 260183912d3SSudeep KarkadaNagesha const char *prop_name, int cpu, unsigned int *thread) 261183912d3SSudeep KarkadaNagesha { 262183912d3SSudeep KarkadaNagesha const __be32 *cell; 263183912d3SSudeep KarkadaNagesha int ac, prop_len, tid; 264183912d3SSudeep KarkadaNagesha u64 hwid; 265183912d3SSudeep KarkadaNagesha 266183912d3SSudeep KarkadaNagesha ac = of_n_addr_cells(cpun); 267183912d3SSudeep KarkadaNagesha cell = of_get_property(cpun, prop_name, &prop_len); 268f3cea45aSGrant Likely if (!cell || !ac) 269183912d3SSudeep KarkadaNagesha return false; 270f3cea45aSGrant Likely prop_len /= sizeof(*cell) * ac; 271183912d3SSudeep KarkadaNagesha for (tid = 0; tid < prop_len; tid++) { 272183912d3SSudeep KarkadaNagesha hwid = of_read_number(cell, ac); 273183912d3SSudeep KarkadaNagesha if (arch_match_cpu_phys_id(cpu, hwid)) { 274183912d3SSudeep KarkadaNagesha if (thread) 275183912d3SSudeep KarkadaNagesha *thread = tid; 276183912d3SSudeep KarkadaNagesha return true; 277183912d3SSudeep KarkadaNagesha } 278183912d3SSudeep KarkadaNagesha cell += ac; 279183912d3SSudeep KarkadaNagesha } 280183912d3SSudeep KarkadaNagesha return false; 281183912d3SSudeep KarkadaNagesha } 282183912d3SSudeep KarkadaNagesha 283d1cb9d1aSDavid Miller /* 284d1cb9d1aSDavid Miller * arch_find_n_match_cpu_physical_id - See if the given device node is 285d1cb9d1aSDavid Miller * for the cpu corresponding to logical cpu 'cpu'. Return true if so, 286d1cb9d1aSDavid Miller * else false. If 'thread' is non-NULL, the local thread number within the 287d1cb9d1aSDavid Miller * core is returned in it. 288d1cb9d1aSDavid Miller */ 289d1cb9d1aSDavid Miller bool __weak arch_find_n_match_cpu_physical_id(struct device_node *cpun, 290d1cb9d1aSDavid Miller int cpu, unsigned int *thread) 291d1cb9d1aSDavid Miller { 292d1cb9d1aSDavid Miller /* Check for non-standard "ibm,ppc-interrupt-server#s" property 293d1cb9d1aSDavid Miller * for thread ids on PowerPC. If it doesn't exist fallback to 294d1cb9d1aSDavid Miller * standard "reg" property. 295d1cb9d1aSDavid Miller */ 296d1cb9d1aSDavid Miller if (IS_ENABLED(CONFIG_PPC) && 297d1cb9d1aSDavid Miller __of_find_n_match_cpu_property(cpun, 298d1cb9d1aSDavid Miller "ibm,ppc-interrupt-server#s", 299d1cb9d1aSDavid Miller cpu, thread)) 300d1cb9d1aSDavid Miller return true; 301d1cb9d1aSDavid Miller 302d1cb9d1aSDavid Miller if (__of_find_n_match_cpu_property(cpun, "reg", cpu, thread)) 303d1cb9d1aSDavid Miller return true; 304d1cb9d1aSDavid Miller 305d1cb9d1aSDavid Miller return false; 306d1cb9d1aSDavid Miller } 307d1cb9d1aSDavid Miller 308183912d3SSudeep KarkadaNagesha /** 309183912d3SSudeep KarkadaNagesha * of_get_cpu_node - Get device node associated with the given logical CPU 310183912d3SSudeep KarkadaNagesha * 311183912d3SSudeep KarkadaNagesha * @cpu: CPU number(logical index) for which device node is required 312183912d3SSudeep KarkadaNagesha * @thread: if not NULL, local thread number within the physical core is 313183912d3SSudeep KarkadaNagesha * returned 314183912d3SSudeep KarkadaNagesha * 315183912d3SSudeep KarkadaNagesha * The main purpose of this function is to retrieve the device node for the 316183912d3SSudeep KarkadaNagesha * given logical CPU index. It should be used to initialize the of_node in 317183912d3SSudeep KarkadaNagesha * cpu device. Once of_node in cpu device is populated, all the further 318183912d3SSudeep KarkadaNagesha * references can use that instead. 319183912d3SSudeep KarkadaNagesha * 320183912d3SSudeep KarkadaNagesha * CPU logical to physical index mapping is architecture specific and is built 321183912d3SSudeep KarkadaNagesha * before booting secondary cores. This function uses arch_match_cpu_phys_id 322183912d3SSudeep KarkadaNagesha * which can be overridden by architecture specific implementation. 323183912d3SSudeep KarkadaNagesha * 324183912d3SSudeep KarkadaNagesha * Returns a node pointer for the logical cpu if found, else NULL. 325183912d3SSudeep KarkadaNagesha */ 326183912d3SSudeep KarkadaNagesha struct device_node *of_get_cpu_node(int cpu, unsigned int *thread) 327183912d3SSudeep KarkadaNagesha { 328d1cb9d1aSDavid Miller struct device_node *cpun; 329183912d3SSudeep KarkadaNagesha 330d1cb9d1aSDavid Miller for_each_node_by_type(cpun, "cpu") { 331d1cb9d1aSDavid Miller if (arch_find_n_match_cpu_physical_id(cpun, cpu, thread)) 332183912d3SSudeep KarkadaNagesha return cpun; 333183912d3SSudeep KarkadaNagesha } 334183912d3SSudeep KarkadaNagesha return NULL; 335183912d3SSudeep KarkadaNagesha } 336183912d3SSudeep KarkadaNagesha EXPORT_SYMBOL(of_get_cpu_node); 337183912d3SSudeep KarkadaNagesha 3380081cbc3SStephen Rothwell /** Checks if the given "compat" string matches one of the strings in 3390081cbc3SStephen Rothwell * the device's "compatible" property 3400081cbc3SStephen Rothwell */ 34128d0e36bSThomas Gleixner static int __of_device_is_compatible(const struct device_node *device, 3420081cbc3SStephen Rothwell const char *compat) 3430081cbc3SStephen Rothwell { 3440081cbc3SStephen Rothwell const char* cp; 3450081cbc3SStephen Rothwell int cplen, l; 3460081cbc3SStephen Rothwell 34728d0e36bSThomas Gleixner cp = __of_get_property(device, "compatible", &cplen); 3480081cbc3SStephen Rothwell if (cp == NULL) 3490081cbc3SStephen Rothwell return 0; 3500081cbc3SStephen Rothwell while (cplen > 0) { 3510081cbc3SStephen Rothwell if (of_compat_cmp(cp, compat, strlen(compat)) == 0) 3520081cbc3SStephen Rothwell return 1; 3530081cbc3SStephen Rothwell l = strlen(cp) + 1; 3540081cbc3SStephen Rothwell cp += l; 3550081cbc3SStephen Rothwell cplen -= l; 3560081cbc3SStephen Rothwell } 3570081cbc3SStephen Rothwell 3580081cbc3SStephen Rothwell return 0; 3590081cbc3SStephen Rothwell } 36028d0e36bSThomas Gleixner 36128d0e36bSThomas Gleixner /** Checks if the given "compat" string matches one of the strings in 36228d0e36bSThomas Gleixner * the device's "compatible" property 36328d0e36bSThomas Gleixner */ 36428d0e36bSThomas Gleixner int of_device_is_compatible(const struct device_node *device, 36528d0e36bSThomas Gleixner const char *compat) 36628d0e36bSThomas Gleixner { 367d6d3c4e6SThomas Gleixner unsigned long flags; 36828d0e36bSThomas Gleixner int res; 36928d0e36bSThomas Gleixner 370d6d3c4e6SThomas Gleixner raw_spin_lock_irqsave(&devtree_lock, flags); 37128d0e36bSThomas Gleixner res = __of_device_is_compatible(device, compat); 372d6d3c4e6SThomas Gleixner raw_spin_unlock_irqrestore(&devtree_lock, flags); 37328d0e36bSThomas Gleixner return res; 37428d0e36bSThomas Gleixner } 3750081cbc3SStephen Rothwell EXPORT_SYMBOL(of_device_is_compatible); 376e679c5f4SStephen Rothwell 377e679c5f4SStephen Rothwell /** 37871a157e8SGrant Likely * of_machine_is_compatible - Test root of device tree for a given compatible value 3791f43cfb9SGrant Likely * @compat: compatible string to look for in root node's compatible property. 3801f43cfb9SGrant Likely * 3811f43cfb9SGrant Likely * Returns true if the root node has the given value in its 3821f43cfb9SGrant Likely * compatible property. 3831f43cfb9SGrant Likely */ 38471a157e8SGrant Likely int of_machine_is_compatible(const char *compat) 3851f43cfb9SGrant Likely { 3861f43cfb9SGrant Likely struct device_node *root; 3871f43cfb9SGrant Likely int rc = 0; 3881f43cfb9SGrant Likely 3891f43cfb9SGrant Likely root = of_find_node_by_path("/"); 3901f43cfb9SGrant Likely if (root) { 3911f43cfb9SGrant Likely rc = of_device_is_compatible(root, compat); 3921f43cfb9SGrant Likely of_node_put(root); 3931f43cfb9SGrant Likely } 3941f43cfb9SGrant Likely return rc; 3951f43cfb9SGrant Likely } 39671a157e8SGrant Likely EXPORT_SYMBOL(of_machine_is_compatible); 3971f43cfb9SGrant Likely 3981f43cfb9SGrant Likely /** 399c31a0c05SStephen Warren * __of_device_is_available - check if a device is available for use 400834d97d4SJosh Boyer * 401c31a0c05SStephen Warren * @device: Node to check for availability, with locks already held 402834d97d4SJosh Boyer * 403834d97d4SJosh Boyer * Returns 1 if the status property is absent or set to "okay" or "ok", 404834d97d4SJosh Boyer * 0 otherwise 405834d97d4SJosh Boyer */ 406c31a0c05SStephen Warren static int __of_device_is_available(const struct device_node *device) 407834d97d4SJosh Boyer { 408834d97d4SJosh Boyer const char *status; 409834d97d4SJosh Boyer int statlen; 410834d97d4SJosh Boyer 411c31a0c05SStephen Warren status = __of_get_property(device, "status", &statlen); 412834d97d4SJosh Boyer if (status == NULL) 413834d97d4SJosh Boyer return 1; 414834d97d4SJosh Boyer 415834d97d4SJosh Boyer if (statlen > 0) { 416834d97d4SJosh Boyer if (!strcmp(status, "okay") || !strcmp(status, "ok")) 417834d97d4SJosh Boyer return 1; 418834d97d4SJosh Boyer } 419834d97d4SJosh Boyer 420834d97d4SJosh Boyer return 0; 421834d97d4SJosh Boyer } 422c31a0c05SStephen Warren 423c31a0c05SStephen Warren /** 424c31a0c05SStephen Warren * of_device_is_available - check if a device is available for use 425c31a0c05SStephen Warren * 426c31a0c05SStephen Warren * @device: Node to check for availability 427c31a0c05SStephen Warren * 428c31a0c05SStephen Warren * Returns 1 if the status property is absent or set to "okay" or "ok", 429c31a0c05SStephen Warren * 0 otherwise 430c31a0c05SStephen Warren */ 431c31a0c05SStephen Warren int of_device_is_available(const struct device_node *device) 432c31a0c05SStephen Warren { 433c31a0c05SStephen Warren unsigned long flags; 434c31a0c05SStephen Warren int res; 435c31a0c05SStephen Warren 436c31a0c05SStephen Warren raw_spin_lock_irqsave(&devtree_lock, flags); 437c31a0c05SStephen Warren res = __of_device_is_available(device); 438c31a0c05SStephen Warren raw_spin_unlock_irqrestore(&devtree_lock, flags); 439c31a0c05SStephen Warren return res; 440c31a0c05SStephen Warren 441c31a0c05SStephen Warren } 442834d97d4SJosh Boyer EXPORT_SYMBOL(of_device_is_available); 443834d97d4SJosh Boyer 444834d97d4SJosh Boyer /** 445e679c5f4SStephen Rothwell * of_get_parent - Get a node's parent if any 446e679c5f4SStephen Rothwell * @node: Node to get parent 447e679c5f4SStephen Rothwell * 448e679c5f4SStephen Rothwell * Returns a node pointer with refcount incremented, use 449e679c5f4SStephen Rothwell * of_node_put() on it when done. 450e679c5f4SStephen Rothwell */ 451e679c5f4SStephen Rothwell struct device_node *of_get_parent(const struct device_node *node) 452e679c5f4SStephen Rothwell { 453e679c5f4SStephen Rothwell struct device_node *np; 454d6d3c4e6SThomas Gleixner unsigned long flags; 455e679c5f4SStephen Rothwell 456e679c5f4SStephen Rothwell if (!node) 457e679c5f4SStephen Rothwell return NULL; 458e679c5f4SStephen Rothwell 459d6d3c4e6SThomas Gleixner raw_spin_lock_irqsave(&devtree_lock, flags); 460e679c5f4SStephen Rothwell np = of_node_get(node->parent); 461d6d3c4e6SThomas Gleixner raw_spin_unlock_irqrestore(&devtree_lock, flags); 462e679c5f4SStephen Rothwell return np; 463e679c5f4SStephen Rothwell } 464e679c5f4SStephen Rothwell EXPORT_SYMBOL(of_get_parent); 465d1cd355aSStephen Rothwell 466d1cd355aSStephen Rothwell /** 467f4eb0107SMichael Ellerman * of_get_next_parent - Iterate to a node's parent 468f4eb0107SMichael Ellerman * @node: Node to get parent of 469f4eb0107SMichael Ellerman * 470f4eb0107SMichael Ellerman * This is like of_get_parent() except that it drops the 471f4eb0107SMichael Ellerman * refcount on the passed node, making it suitable for iterating 472f4eb0107SMichael Ellerman * through a node's parents. 473f4eb0107SMichael Ellerman * 474f4eb0107SMichael Ellerman * Returns a node pointer with refcount incremented, use 475f4eb0107SMichael Ellerman * of_node_put() on it when done. 476f4eb0107SMichael Ellerman */ 477f4eb0107SMichael Ellerman struct device_node *of_get_next_parent(struct device_node *node) 478f4eb0107SMichael Ellerman { 479f4eb0107SMichael Ellerman struct device_node *parent; 480d6d3c4e6SThomas Gleixner unsigned long flags; 481f4eb0107SMichael Ellerman 482f4eb0107SMichael Ellerman if (!node) 483f4eb0107SMichael Ellerman return NULL; 484f4eb0107SMichael Ellerman 485d6d3c4e6SThomas Gleixner raw_spin_lock_irqsave(&devtree_lock, flags); 486f4eb0107SMichael Ellerman parent = of_node_get(node->parent); 487f4eb0107SMichael Ellerman of_node_put(node); 488d6d3c4e6SThomas Gleixner raw_spin_unlock_irqrestore(&devtree_lock, flags); 489f4eb0107SMichael Ellerman return parent; 490f4eb0107SMichael Ellerman } 4916695be68SGuennadi Liakhovetski EXPORT_SYMBOL(of_get_next_parent); 492f4eb0107SMichael Ellerman 493f4eb0107SMichael Ellerman /** 494d1cd355aSStephen Rothwell * of_get_next_child - Iterate a node childs 495d1cd355aSStephen Rothwell * @node: parent node 496d1cd355aSStephen Rothwell * @prev: previous child of the parent node, or NULL to get first 497d1cd355aSStephen Rothwell * 498d1cd355aSStephen Rothwell * Returns a node pointer with refcount incremented, use 499d1cd355aSStephen Rothwell * of_node_put() on it when done. 500d1cd355aSStephen Rothwell */ 501d1cd355aSStephen Rothwell struct device_node *of_get_next_child(const struct device_node *node, 502d1cd355aSStephen Rothwell struct device_node *prev) 503d1cd355aSStephen Rothwell { 504d1cd355aSStephen Rothwell struct device_node *next; 505d6d3c4e6SThomas Gleixner unsigned long flags; 506d1cd355aSStephen Rothwell 507d6d3c4e6SThomas Gleixner raw_spin_lock_irqsave(&devtree_lock, flags); 508d1cd355aSStephen Rothwell next = prev ? prev->sibling : node->child; 509d1cd355aSStephen Rothwell for (; next; next = next->sibling) 510d1cd355aSStephen Rothwell if (of_node_get(next)) 511d1cd355aSStephen Rothwell break; 512d1cd355aSStephen Rothwell of_node_put(prev); 513d6d3c4e6SThomas Gleixner raw_spin_unlock_irqrestore(&devtree_lock, flags); 514d1cd355aSStephen Rothwell return next; 515d1cd355aSStephen Rothwell } 516d1cd355aSStephen Rothwell EXPORT_SYMBOL(of_get_next_child); 5171ef4d424SStephen Rothwell 5181ef4d424SStephen Rothwell /** 5193296193dSTimur Tabi * of_get_next_available_child - Find the next available child node 5203296193dSTimur Tabi * @node: parent node 5213296193dSTimur Tabi * @prev: previous child of the parent node, or NULL to get first 5223296193dSTimur Tabi * 5233296193dSTimur Tabi * This function is like of_get_next_child(), except that it 5243296193dSTimur Tabi * automatically skips any disabled nodes (i.e. status = "disabled"). 5253296193dSTimur Tabi */ 5263296193dSTimur Tabi struct device_node *of_get_next_available_child(const struct device_node *node, 5273296193dSTimur Tabi struct device_node *prev) 5283296193dSTimur Tabi { 5293296193dSTimur Tabi struct device_node *next; 530d25d8694SBenjamin Herrenschmidt unsigned long flags; 5313296193dSTimur Tabi 532d25d8694SBenjamin Herrenschmidt raw_spin_lock_irqsave(&devtree_lock, flags); 5333296193dSTimur Tabi next = prev ? prev->sibling : node->child; 5343296193dSTimur Tabi for (; next; next = next->sibling) { 535c31a0c05SStephen Warren if (!__of_device_is_available(next)) 5363296193dSTimur Tabi continue; 5373296193dSTimur Tabi if (of_node_get(next)) 5383296193dSTimur Tabi break; 5393296193dSTimur Tabi } 5403296193dSTimur Tabi of_node_put(prev); 541d25d8694SBenjamin Herrenschmidt raw_spin_unlock_irqrestore(&devtree_lock, flags); 5423296193dSTimur Tabi return next; 5433296193dSTimur Tabi } 5443296193dSTimur Tabi EXPORT_SYMBOL(of_get_next_available_child); 5453296193dSTimur Tabi 5463296193dSTimur Tabi /** 5479c19761aSSrinivas Kandagatla * of_get_child_by_name - Find the child node by name for a given parent 5489c19761aSSrinivas Kandagatla * @node: parent node 5499c19761aSSrinivas Kandagatla * @name: child name to look for. 5509c19761aSSrinivas Kandagatla * 5519c19761aSSrinivas Kandagatla * This function looks for child node for given matching name 5529c19761aSSrinivas Kandagatla * 5539c19761aSSrinivas Kandagatla * Returns a node pointer if found, with refcount incremented, use 5549c19761aSSrinivas Kandagatla * of_node_put() on it when done. 5559c19761aSSrinivas Kandagatla * Returns NULL if node is not found. 5569c19761aSSrinivas Kandagatla */ 5579c19761aSSrinivas Kandagatla struct device_node *of_get_child_by_name(const struct device_node *node, 5589c19761aSSrinivas Kandagatla const char *name) 5599c19761aSSrinivas Kandagatla { 5609c19761aSSrinivas Kandagatla struct device_node *child; 5619c19761aSSrinivas Kandagatla 5629c19761aSSrinivas Kandagatla for_each_child_of_node(node, child) 5639c19761aSSrinivas Kandagatla if (child->name && (of_node_cmp(child->name, name) == 0)) 5649c19761aSSrinivas Kandagatla break; 5659c19761aSSrinivas Kandagatla return child; 5669c19761aSSrinivas Kandagatla } 5679c19761aSSrinivas Kandagatla EXPORT_SYMBOL(of_get_child_by_name); 5689c19761aSSrinivas Kandagatla 5699c19761aSSrinivas Kandagatla /** 5701ef4d424SStephen Rothwell * of_find_node_by_path - Find a node matching a full OF path 5711ef4d424SStephen Rothwell * @path: The full path to match 5721ef4d424SStephen Rothwell * 5731ef4d424SStephen Rothwell * Returns a node pointer with refcount incremented, use 5741ef4d424SStephen Rothwell * of_node_put() on it when done. 5751ef4d424SStephen Rothwell */ 5761ef4d424SStephen Rothwell struct device_node *of_find_node_by_path(const char *path) 5771ef4d424SStephen Rothwell { 578465aac6dSRandy Dunlap struct device_node *np = of_allnodes; 579d6d3c4e6SThomas Gleixner unsigned long flags; 5801ef4d424SStephen Rothwell 581d6d3c4e6SThomas Gleixner raw_spin_lock_irqsave(&devtree_lock, flags); 5821ef4d424SStephen Rothwell for (; np; np = np->allnext) { 5831ef4d424SStephen Rothwell if (np->full_name && (of_node_cmp(np->full_name, path) == 0) 5841ef4d424SStephen Rothwell && of_node_get(np)) 5851ef4d424SStephen Rothwell break; 5861ef4d424SStephen Rothwell } 587d6d3c4e6SThomas Gleixner raw_spin_unlock_irqrestore(&devtree_lock, flags); 5881ef4d424SStephen Rothwell return np; 5891ef4d424SStephen Rothwell } 5901ef4d424SStephen Rothwell EXPORT_SYMBOL(of_find_node_by_path); 5911ef4d424SStephen Rothwell 5921ef4d424SStephen Rothwell /** 5931ef4d424SStephen Rothwell * of_find_node_by_name - Find a node by its "name" property 5941ef4d424SStephen Rothwell * @from: The node to start searching from or NULL, the node 5951ef4d424SStephen Rothwell * you pass will not be searched, only the next one 5961ef4d424SStephen Rothwell * will; typically, you pass what the previous call 5971ef4d424SStephen Rothwell * returned. of_node_put() will be called on it 5981ef4d424SStephen Rothwell * @name: The name string to match against 5991ef4d424SStephen Rothwell * 6001ef4d424SStephen Rothwell * Returns a node pointer with refcount incremented, use 6011ef4d424SStephen Rothwell * of_node_put() on it when done. 6021ef4d424SStephen Rothwell */ 6031ef4d424SStephen Rothwell struct device_node *of_find_node_by_name(struct device_node *from, 6041ef4d424SStephen Rothwell const char *name) 6051ef4d424SStephen Rothwell { 6061ef4d424SStephen Rothwell struct device_node *np; 607d6d3c4e6SThomas Gleixner unsigned long flags; 6081ef4d424SStephen Rothwell 609d6d3c4e6SThomas Gleixner raw_spin_lock_irqsave(&devtree_lock, flags); 610465aac6dSRandy Dunlap np = from ? from->allnext : of_allnodes; 6111ef4d424SStephen Rothwell for (; np; np = np->allnext) 6121ef4d424SStephen Rothwell if (np->name && (of_node_cmp(np->name, name) == 0) 6131ef4d424SStephen Rothwell && of_node_get(np)) 6141ef4d424SStephen Rothwell break; 6151ef4d424SStephen Rothwell of_node_put(from); 616d6d3c4e6SThomas Gleixner raw_spin_unlock_irqrestore(&devtree_lock, flags); 6171ef4d424SStephen Rothwell return np; 6181ef4d424SStephen Rothwell } 6191ef4d424SStephen Rothwell EXPORT_SYMBOL(of_find_node_by_name); 6201ef4d424SStephen Rothwell 6211ef4d424SStephen Rothwell /** 6221ef4d424SStephen Rothwell * of_find_node_by_type - Find a node by its "device_type" property 6231ef4d424SStephen Rothwell * @from: The node to start searching from, or NULL to start searching 6241ef4d424SStephen Rothwell * the entire device tree. The node you pass will not be 6251ef4d424SStephen Rothwell * searched, only the next one will; typically, you pass 6261ef4d424SStephen Rothwell * what the previous call returned. of_node_put() will be 6271ef4d424SStephen Rothwell * called on from for you. 6281ef4d424SStephen Rothwell * @type: The type string to match against 6291ef4d424SStephen Rothwell * 6301ef4d424SStephen Rothwell * Returns a node pointer with refcount incremented, use 6311ef4d424SStephen Rothwell * of_node_put() on it when done. 6321ef4d424SStephen Rothwell */ 6331ef4d424SStephen Rothwell struct device_node *of_find_node_by_type(struct device_node *from, 6341ef4d424SStephen Rothwell const char *type) 6351ef4d424SStephen Rothwell { 6361ef4d424SStephen Rothwell struct device_node *np; 637d6d3c4e6SThomas Gleixner unsigned long flags; 6381ef4d424SStephen Rothwell 639d6d3c4e6SThomas Gleixner raw_spin_lock_irqsave(&devtree_lock, flags); 640465aac6dSRandy Dunlap np = from ? from->allnext : of_allnodes; 6411ef4d424SStephen Rothwell for (; np; np = np->allnext) 6421ef4d424SStephen Rothwell if (np->type && (of_node_cmp(np->type, type) == 0) 6431ef4d424SStephen Rothwell && of_node_get(np)) 6441ef4d424SStephen Rothwell break; 6451ef4d424SStephen Rothwell of_node_put(from); 646d6d3c4e6SThomas Gleixner raw_spin_unlock_irqrestore(&devtree_lock, flags); 6471ef4d424SStephen Rothwell return np; 6481ef4d424SStephen Rothwell } 6491ef4d424SStephen Rothwell EXPORT_SYMBOL(of_find_node_by_type); 6501ef4d424SStephen Rothwell 6511ef4d424SStephen Rothwell /** 6521ef4d424SStephen Rothwell * of_find_compatible_node - Find a node based on type and one of the 6531ef4d424SStephen Rothwell * tokens in its "compatible" property 6541ef4d424SStephen Rothwell * @from: The node to start searching from or NULL, the node 6551ef4d424SStephen Rothwell * you pass will not be searched, only the next one 6561ef4d424SStephen Rothwell * will; typically, you pass what the previous call 6571ef4d424SStephen Rothwell * returned. of_node_put() will be called on it 6581ef4d424SStephen Rothwell * @type: The type string to match "device_type" or NULL to ignore 6591ef4d424SStephen Rothwell * @compatible: The string to match to one of the tokens in the device 6601ef4d424SStephen Rothwell * "compatible" list. 6611ef4d424SStephen Rothwell * 6621ef4d424SStephen Rothwell * Returns a node pointer with refcount incremented, use 6631ef4d424SStephen Rothwell * of_node_put() on it when done. 6641ef4d424SStephen Rothwell */ 6651ef4d424SStephen Rothwell struct device_node *of_find_compatible_node(struct device_node *from, 6661ef4d424SStephen Rothwell const char *type, const char *compatible) 6671ef4d424SStephen Rothwell { 6681ef4d424SStephen Rothwell struct device_node *np; 669d6d3c4e6SThomas Gleixner unsigned long flags; 6701ef4d424SStephen Rothwell 671d6d3c4e6SThomas Gleixner raw_spin_lock_irqsave(&devtree_lock, flags); 672465aac6dSRandy Dunlap np = from ? from->allnext : of_allnodes; 6731ef4d424SStephen Rothwell for (; np; np = np->allnext) { 6741ef4d424SStephen Rothwell if (type 6751ef4d424SStephen Rothwell && !(np->type && (of_node_cmp(np->type, type) == 0))) 6761ef4d424SStephen Rothwell continue; 67728d0e36bSThomas Gleixner if (__of_device_is_compatible(np, compatible) && 67828d0e36bSThomas Gleixner of_node_get(np)) 6791ef4d424SStephen Rothwell break; 6801ef4d424SStephen Rothwell } 6811ef4d424SStephen Rothwell of_node_put(from); 682d6d3c4e6SThomas Gleixner raw_spin_unlock_irqrestore(&devtree_lock, flags); 6831ef4d424SStephen Rothwell return np; 6841ef4d424SStephen Rothwell } 6851ef4d424SStephen Rothwell EXPORT_SYMBOL(of_find_compatible_node); 686283029d1SGrant Likely 687283029d1SGrant Likely /** 6881e291b14SMichael Ellerman * of_find_node_with_property - Find a node which has a property with 6891e291b14SMichael Ellerman * the given name. 6901e291b14SMichael Ellerman * @from: The node to start searching from or NULL, the node 6911e291b14SMichael Ellerman * you pass will not be searched, only the next one 6921e291b14SMichael Ellerman * will; typically, you pass what the previous call 6931e291b14SMichael Ellerman * returned. of_node_put() will be called on it 6941e291b14SMichael Ellerman * @prop_name: The name of the property to look for. 6951e291b14SMichael Ellerman * 6961e291b14SMichael Ellerman * Returns a node pointer with refcount incremented, use 6971e291b14SMichael Ellerman * of_node_put() on it when done. 6981e291b14SMichael Ellerman */ 6991e291b14SMichael Ellerman struct device_node *of_find_node_with_property(struct device_node *from, 7001e291b14SMichael Ellerman const char *prop_name) 7011e291b14SMichael Ellerman { 7021e291b14SMichael Ellerman struct device_node *np; 7031e291b14SMichael Ellerman struct property *pp; 704d6d3c4e6SThomas Gleixner unsigned long flags; 7051e291b14SMichael Ellerman 706d6d3c4e6SThomas Gleixner raw_spin_lock_irqsave(&devtree_lock, flags); 707465aac6dSRandy Dunlap np = from ? from->allnext : of_allnodes; 7081e291b14SMichael Ellerman for (; np; np = np->allnext) { 709a3a7cab1SSachin Kamat for (pp = np->properties; pp; pp = pp->next) { 7101e291b14SMichael Ellerman if (of_prop_cmp(pp->name, prop_name) == 0) { 7111e291b14SMichael Ellerman of_node_get(np); 7121e291b14SMichael Ellerman goto out; 7131e291b14SMichael Ellerman } 7141e291b14SMichael Ellerman } 7151e291b14SMichael Ellerman } 7161e291b14SMichael Ellerman out: 7171e291b14SMichael Ellerman of_node_put(from); 718d6d3c4e6SThomas Gleixner raw_spin_unlock_irqrestore(&devtree_lock, flags); 7191e291b14SMichael Ellerman return np; 7201e291b14SMichael Ellerman } 7211e291b14SMichael Ellerman EXPORT_SYMBOL(of_find_node_with_property); 7221e291b14SMichael Ellerman 72328d0e36bSThomas Gleixner static 72428d0e36bSThomas Gleixner const struct of_device_id *__of_match_node(const struct of_device_id *matches, 725283029d1SGrant Likely const struct device_node *node) 726283029d1SGrant Likely { 727a52f07ecSGrant Likely if (!matches) 728a52f07ecSGrant Likely return NULL; 729a52f07ecSGrant Likely 730283029d1SGrant Likely while (matches->name[0] || matches->type[0] || matches->compatible[0]) { 731283029d1SGrant Likely int match = 1; 732283029d1SGrant Likely if (matches->name[0]) 733283029d1SGrant Likely match &= node->name 734283029d1SGrant Likely && !strcmp(matches->name, node->name); 735283029d1SGrant Likely if (matches->type[0]) 736283029d1SGrant Likely match &= node->type 737283029d1SGrant Likely && !strcmp(matches->type, node->type); 738bc51b0c2SLinus Torvalds if (matches->compatible[0]) 73928d0e36bSThomas Gleixner match &= __of_device_is_compatible(node, 740bc51b0c2SLinus Torvalds matches->compatible); 741bc51b0c2SLinus Torvalds if (match) 742283029d1SGrant Likely return matches; 743283029d1SGrant Likely matches++; 744283029d1SGrant Likely } 745283029d1SGrant Likely return NULL; 746283029d1SGrant Likely } 74728d0e36bSThomas Gleixner 74828d0e36bSThomas Gleixner /** 74928d0e36bSThomas Gleixner * of_match_node - Tell if an device_node has a matching of_match structure 75028d0e36bSThomas Gleixner * @matches: array of of device match structures to search in 75128d0e36bSThomas Gleixner * @node: the of device structure to match against 75228d0e36bSThomas Gleixner * 75328d0e36bSThomas Gleixner * Low level utility function used by device matching. 75428d0e36bSThomas Gleixner */ 75528d0e36bSThomas Gleixner const struct of_device_id *of_match_node(const struct of_device_id *matches, 75628d0e36bSThomas Gleixner const struct device_node *node) 75728d0e36bSThomas Gleixner { 75828d0e36bSThomas Gleixner const struct of_device_id *match; 759d6d3c4e6SThomas Gleixner unsigned long flags; 76028d0e36bSThomas Gleixner 761d6d3c4e6SThomas Gleixner raw_spin_lock_irqsave(&devtree_lock, flags); 76228d0e36bSThomas Gleixner match = __of_match_node(matches, node); 763d6d3c4e6SThomas Gleixner raw_spin_unlock_irqrestore(&devtree_lock, flags); 76428d0e36bSThomas Gleixner return match; 76528d0e36bSThomas Gleixner } 766283029d1SGrant Likely EXPORT_SYMBOL(of_match_node); 767283029d1SGrant Likely 768283029d1SGrant Likely /** 76950c8af4cSStephen Warren * of_find_matching_node_and_match - Find a node based on an of_device_id 77050c8af4cSStephen Warren * match table. 771283029d1SGrant Likely * @from: The node to start searching from or NULL, the node 772283029d1SGrant Likely * you pass will not be searched, only the next one 773283029d1SGrant Likely * will; typically, you pass what the previous call 774283029d1SGrant Likely * returned. of_node_put() will be called on it 775283029d1SGrant Likely * @matches: array of of device match structures to search in 77650c8af4cSStephen Warren * @match Updated to point at the matches entry which matched 777283029d1SGrant Likely * 778283029d1SGrant Likely * Returns a node pointer with refcount incremented, use 779283029d1SGrant Likely * of_node_put() on it when done. 780283029d1SGrant Likely */ 78150c8af4cSStephen Warren struct device_node *of_find_matching_node_and_match(struct device_node *from, 78250c8af4cSStephen Warren const struct of_device_id *matches, 78350c8af4cSStephen Warren const struct of_device_id **match) 784283029d1SGrant Likely { 785283029d1SGrant Likely struct device_node *np; 786dc71bcf1SThomas Abraham const struct of_device_id *m; 787d6d3c4e6SThomas Gleixner unsigned long flags; 788283029d1SGrant Likely 78950c8af4cSStephen Warren if (match) 79050c8af4cSStephen Warren *match = NULL; 79150c8af4cSStephen Warren 792d6d3c4e6SThomas Gleixner raw_spin_lock_irqsave(&devtree_lock, flags); 793465aac6dSRandy Dunlap np = from ? from->allnext : of_allnodes; 794283029d1SGrant Likely for (; np; np = np->allnext) { 79528d0e36bSThomas Gleixner m = __of_match_node(matches, np); 796dc71bcf1SThomas Abraham if (m && of_node_get(np)) { 79750c8af4cSStephen Warren if (match) 798dc71bcf1SThomas Abraham *match = m; 799283029d1SGrant Likely break; 800283029d1SGrant Likely } 80150c8af4cSStephen Warren } 802283029d1SGrant Likely of_node_put(from); 803d6d3c4e6SThomas Gleixner raw_spin_unlock_irqrestore(&devtree_lock, flags); 804283029d1SGrant Likely return np; 805283029d1SGrant Likely } 80680c2022eSGrant Likely EXPORT_SYMBOL(of_find_matching_node_and_match); 8073f07af49SGrant Likely 8083f07af49SGrant Likely /** 8093f07af49SGrant Likely * of_modalias_node - Lookup appropriate modalias for a device node 8103f07af49SGrant Likely * @node: pointer to a device tree node 8113f07af49SGrant Likely * @modalias: Pointer to buffer that modalias value will be copied into 8123f07af49SGrant Likely * @len: Length of modalias value 8133f07af49SGrant Likely * 8142ffe8c5fSGrant Likely * Based on the value of the compatible property, this routine will attempt 8152ffe8c5fSGrant Likely * to choose an appropriate modalias value for a particular device tree node. 8162ffe8c5fSGrant Likely * It does this by stripping the manufacturer prefix (as delimited by a ',') 8172ffe8c5fSGrant Likely * from the first entry in the compatible list property. 8183f07af49SGrant Likely * 8192ffe8c5fSGrant Likely * This routine returns 0 on success, <0 on failure. 8203f07af49SGrant Likely */ 8213f07af49SGrant Likely int of_modalias_node(struct device_node *node, char *modalias, int len) 8223f07af49SGrant Likely { 8232ffe8c5fSGrant Likely const char *compatible, *p; 8242ffe8c5fSGrant Likely int cplen; 8253f07af49SGrant Likely 8263f07af49SGrant Likely compatible = of_get_property(node, "compatible", &cplen); 8272ffe8c5fSGrant Likely if (!compatible || strlen(compatible) > cplen) 8283f07af49SGrant Likely return -ENODEV; 8293f07af49SGrant Likely p = strchr(compatible, ','); 8302ffe8c5fSGrant Likely strlcpy(modalias, p ? p + 1 : compatible, len); 8313f07af49SGrant Likely return 0; 8323f07af49SGrant Likely } 8333f07af49SGrant Likely EXPORT_SYMBOL_GPL(of_modalias_node); 8343f07af49SGrant Likely 83564b60e09SAnton Vorontsov /** 83689751a7cSJeremy Kerr * of_find_node_by_phandle - Find a node given a phandle 83789751a7cSJeremy Kerr * @handle: phandle of the node to find 83889751a7cSJeremy Kerr * 83989751a7cSJeremy Kerr * Returns a node pointer with refcount incremented, use 84089751a7cSJeremy Kerr * of_node_put() on it when done. 84189751a7cSJeremy Kerr */ 84289751a7cSJeremy Kerr struct device_node *of_find_node_by_phandle(phandle handle) 84389751a7cSJeremy Kerr { 84489751a7cSJeremy Kerr struct device_node *np; 845d25d8694SBenjamin Herrenschmidt unsigned long flags; 84689751a7cSJeremy Kerr 847d25d8694SBenjamin Herrenschmidt raw_spin_lock_irqsave(&devtree_lock, flags); 848465aac6dSRandy Dunlap for (np = of_allnodes; np; np = np->allnext) 84989751a7cSJeremy Kerr if (np->phandle == handle) 85089751a7cSJeremy Kerr break; 85189751a7cSJeremy Kerr of_node_get(np); 852d25d8694SBenjamin Herrenschmidt raw_spin_unlock_irqrestore(&devtree_lock, flags); 85389751a7cSJeremy Kerr return np; 85489751a7cSJeremy Kerr } 85589751a7cSJeremy Kerr EXPORT_SYMBOL(of_find_node_by_phandle); 85689751a7cSJeremy Kerr 85789751a7cSJeremy Kerr /** 858daeec1f0STony Prisk * of_find_property_value_of_size 859daeec1f0STony Prisk * 860daeec1f0STony Prisk * @np: device node from which the property value is to be read. 861daeec1f0STony Prisk * @propname: name of the property to be searched. 862daeec1f0STony Prisk * @len: requested length of property value 863daeec1f0STony Prisk * 864daeec1f0STony Prisk * Search for a property in a device node and valid the requested size. 865daeec1f0STony Prisk * Returns the property value on success, -EINVAL if the property does not 866daeec1f0STony Prisk * exist, -ENODATA if property does not have a value, and -EOVERFLOW if the 867daeec1f0STony Prisk * property data isn't large enough. 868daeec1f0STony Prisk * 869daeec1f0STony Prisk */ 870daeec1f0STony Prisk static void *of_find_property_value_of_size(const struct device_node *np, 871daeec1f0STony Prisk const char *propname, u32 len) 872daeec1f0STony Prisk { 873daeec1f0STony Prisk struct property *prop = of_find_property(np, propname, NULL); 874daeec1f0STony Prisk 875daeec1f0STony Prisk if (!prop) 876daeec1f0STony Prisk return ERR_PTR(-EINVAL); 877daeec1f0STony Prisk if (!prop->value) 878daeec1f0STony Prisk return ERR_PTR(-ENODATA); 879daeec1f0STony Prisk if (len > prop->length) 880daeec1f0STony Prisk return ERR_PTR(-EOVERFLOW); 881daeec1f0STony Prisk 882daeec1f0STony Prisk return prop->value; 883daeec1f0STony Prisk } 884daeec1f0STony Prisk 885daeec1f0STony Prisk /** 8863daf3726STony Prisk * of_property_read_u32_index - Find and read a u32 from a multi-value property. 8873daf3726STony Prisk * 8883daf3726STony Prisk * @np: device node from which the property value is to be read. 8893daf3726STony Prisk * @propname: name of the property to be searched. 8903daf3726STony Prisk * @index: index of the u32 in the list of values 8913daf3726STony Prisk * @out_value: pointer to return value, modified only if no error. 8923daf3726STony Prisk * 8933daf3726STony Prisk * Search for a property in a device node and read nth 32-bit value from 8943daf3726STony Prisk * it. Returns 0 on success, -EINVAL if the property does not exist, 8953daf3726STony Prisk * -ENODATA if property does not have a value, and -EOVERFLOW if the 8963daf3726STony Prisk * property data isn't large enough. 8973daf3726STony Prisk * 8983daf3726STony Prisk * The out_value is modified only if a valid u32 value can be decoded. 8993daf3726STony Prisk */ 9003daf3726STony Prisk int of_property_read_u32_index(const struct device_node *np, 9013daf3726STony Prisk const char *propname, 9023daf3726STony Prisk u32 index, u32 *out_value) 9033daf3726STony Prisk { 904daeec1f0STony Prisk const u32 *val = of_find_property_value_of_size(np, propname, 905daeec1f0STony Prisk ((index + 1) * sizeof(*out_value))); 9063daf3726STony Prisk 907daeec1f0STony Prisk if (IS_ERR(val)) 908daeec1f0STony Prisk return PTR_ERR(val); 9093daf3726STony Prisk 910daeec1f0STony Prisk *out_value = be32_to_cpup(((__be32 *)val) + index); 9113daf3726STony Prisk return 0; 9123daf3726STony Prisk } 9133daf3726STony Prisk EXPORT_SYMBOL_GPL(of_property_read_u32_index); 9143daf3726STony Prisk 9153daf3726STony Prisk /** 916be193249SViresh Kumar * of_property_read_u8_array - Find and read an array of u8 from a property. 917be193249SViresh Kumar * 918be193249SViresh Kumar * @np: device node from which the property value is to be read. 919be193249SViresh Kumar * @propname: name of the property to be searched. 920792efb84SLad, Prabhakar * @out_values: pointer to return value, modified only if return value is 0. 921be193249SViresh Kumar * @sz: number of array elements to read 922be193249SViresh Kumar * 923be193249SViresh Kumar * Search for a property in a device node and read 8-bit value(s) from 924be193249SViresh Kumar * it. Returns 0 on success, -EINVAL if the property does not exist, 925be193249SViresh Kumar * -ENODATA if property does not have a value, and -EOVERFLOW if the 926be193249SViresh Kumar * property data isn't large enough. 927be193249SViresh Kumar * 928be193249SViresh Kumar * dts entry of array should be like: 929be193249SViresh Kumar * property = /bits/ 8 <0x50 0x60 0x70>; 930be193249SViresh Kumar * 931792efb84SLad, Prabhakar * The out_values is modified only if a valid u8 value can be decoded. 932be193249SViresh Kumar */ 933be193249SViresh Kumar int of_property_read_u8_array(const struct device_node *np, 934be193249SViresh Kumar const char *propname, u8 *out_values, size_t sz) 935be193249SViresh Kumar { 936daeec1f0STony Prisk const u8 *val = of_find_property_value_of_size(np, propname, 937daeec1f0STony Prisk (sz * sizeof(*out_values))); 938be193249SViresh Kumar 939daeec1f0STony Prisk if (IS_ERR(val)) 940daeec1f0STony Prisk return PTR_ERR(val); 941be193249SViresh Kumar 942be193249SViresh Kumar while (sz--) 943be193249SViresh Kumar *out_values++ = *val++; 944be193249SViresh Kumar return 0; 945be193249SViresh Kumar } 946be193249SViresh Kumar EXPORT_SYMBOL_GPL(of_property_read_u8_array); 947be193249SViresh Kumar 948be193249SViresh Kumar /** 949be193249SViresh Kumar * of_property_read_u16_array - Find and read an array of u16 from a property. 950be193249SViresh Kumar * 951be193249SViresh Kumar * @np: device node from which the property value is to be read. 952be193249SViresh Kumar * @propname: name of the property to be searched. 953792efb84SLad, Prabhakar * @out_values: pointer to return value, modified only if return value is 0. 954be193249SViresh Kumar * @sz: number of array elements to read 955be193249SViresh Kumar * 956be193249SViresh Kumar * Search for a property in a device node and read 16-bit value(s) from 957be193249SViresh Kumar * it. Returns 0 on success, -EINVAL if the property does not exist, 958be193249SViresh Kumar * -ENODATA if property does not have a value, and -EOVERFLOW if the 959be193249SViresh Kumar * property data isn't large enough. 960be193249SViresh Kumar * 961be193249SViresh Kumar * dts entry of array should be like: 962be193249SViresh Kumar * property = /bits/ 16 <0x5000 0x6000 0x7000>; 963be193249SViresh Kumar * 964792efb84SLad, Prabhakar * The out_values is modified only if a valid u16 value can be decoded. 965be193249SViresh Kumar */ 966be193249SViresh Kumar int of_property_read_u16_array(const struct device_node *np, 967be193249SViresh Kumar const char *propname, u16 *out_values, size_t sz) 968be193249SViresh Kumar { 969daeec1f0STony Prisk const __be16 *val = of_find_property_value_of_size(np, propname, 970daeec1f0STony Prisk (sz * sizeof(*out_values))); 971be193249SViresh Kumar 972daeec1f0STony Prisk if (IS_ERR(val)) 973daeec1f0STony Prisk return PTR_ERR(val); 974be193249SViresh Kumar 975be193249SViresh Kumar while (sz--) 976be193249SViresh Kumar *out_values++ = be16_to_cpup(val++); 977be193249SViresh Kumar return 0; 978be193249SViresh Kumar } 979be193249SViresh Kumar EXPORT_SYMBOL_GPL(of_property_read_u16_array); 980be193249SViresh Kumar 981be193249SViresh Kumar /** 9820e373639SRob Herring * of_property_read_u32_array - Find and read an array of 32 bit integers 9830e373639SRob Herring * from a property. 9840e373639SRob Herring * 985a3b85363SThomas Abraham * @np: device node from which the property value is to be read. 986a3b85363SThomas Abraham * @propname: name of the property to be searched. 987792efb84SLad, Prabhakar * @out_values: pointer to return value, modified only if return value is 0. 988be193249SViresh Kumar * @sz: number of array elements to read 989a3b85363SThomas Abraham * 9900e373639SRob Herring * Search for a property in a device node and read 32-bit value(s) from 991a3b85363SThomas Abraham * it. Returns 0 on success, -EINVAL if the property does not exist, 992a3b85363SThomas Abraham * -ENODATA if property does not have a value, and -EOVERFLOW if the 993a3b85363SThomas Abraham * property data isn't large enough. 994a3b85363SThomas Abraham * 995792efb84SLad, Prabhakar * The out_values is modified only if a valid u32 value can be decoded. 996a3b85363SThomas Abraham */ 997aac285c6SJamie Iles int of_property_read_u32_array(const struct device_node *np, 998aac285c6SJamie Iles const char *propname, u32 *out_values, 999aac285c6SJamie Iles size_t sz) 1000a3b85363SThomas Abraham { 1001daeec1f0STony Prisk const __be32 *val = of_find_property_value_of_size(np, propname, 1002daeec1f0STony Prisk (sz * sizeof(*out_values))); 1003a3b85363SThomas Abraham 1004daeec1f0STony Prisk if (IS_ERR(val)) 1005daeec1f0STony Prisk return PTR_ERR(val); 10060e373639SRob Herring 10070e373639SRob Herring while (sz--) 10080e373639SRob Herring *out_values++ = be32_to_cpup(val++); 1009a3b85363SThomas Abraham return 0; 1010a3b85363SThomas Abraham } 10110e373639SRob Herring EXPORT_SYMBOL_GPL(of_property_read_u32_array); 1012a3b85363SThomas Abraham 1013a3b85363SThomas Abraham /** 10144cd7f7a3SJamie Iles * of_property_read_u64 - Find and read a 64 bit integer from a property 10154cd7f7a3SJamie Iles * @np: device node from which the property value is to be read. 10164cd7f7a3SJamie Iles * @propname: name of the property to be searched. 10174cd7f7a3SJamie Iles * @out_value: pointer to return value, modified only if return value is 0. 10184cd7f7a3SJamie Iles * 10194cd7f7a3SJamie Iles * Search for a property in a device node and read a 64-bit value from 10204cd7f7a3SJamie Iles * it. Returns 0 on success, -EINVAL if the property does not exist, 10214cd7f7a3SJamie Iles * -ENODATA if property does not have a value, and -EOVERFLOW if the 10224cd7f7a3SJamie Iles * property data isn't large enough. 10234cd7f7a3SJamie Iles * 10244cd7f7a3SJamie Iles * The out_value is modified only if a valid u64 value can be decoded. 10254cd7f7a3SJamie Iles */ 10264cd7f7a3SJamie Iles int of_property_read_u64(const struct device_node *np, const char *propname, 10274cd7f7a3SJamie Iles u64 *out_value) 10284cd7f7a3SJamie Iles { 1029daeec1f0STony Prisk const __be32 *val = of_find_property_value_of_size(np, propname, 1030daeec1f0STony Prisk sizeof(*out_value)); 10314cd7f7a3SJamie Iles 1032daeec1f0STony Prisk if (IS_ERR(val)) 1033daeec1f0STony Prisk return PTR_ERR(val); 1034daeec1f0STony Prisk 1035daeec1f0STony Prisk *out_value = of_read_number(val, 2); 10364cd7f7a3SJamie Iles return 0; 10374cd7f7a3SJamie Iles } 10384cd7f7a3SJamie Iles EXPORT_SYMBOL_GPL(of_property_read_u64); 10394cd7f7a3SJamie Iles 10404cd7f7a3SJamie Iles /** 1041a3b85363SThomas Abraham * of_property_read_string - Find and read a string from a property 1042a3b85363SThomas Abraham * @np: device node from which the property value is to be read. 1043a3b85363SThomas Abraham * @propname: name of the property to be searched. 1044a3b85363SThomas Abraham * @out_string: pointer to null terminated return string, modified only if 1045a3b85363SThomas Abraham * return value is 0. 1046a3b85363SThomas Abraham * 1047a3b85363SThomas Abraham * Search for a property in a device tree node and retrieve a null 1048a3b85363SThomas Abraham * terminated string value (pointer to data, not a copy). Returns 0 on 1049a3b85363SThomas Abraham * success, -EINVAL if the property does not exist, -ENODATA if property 1050a3b85363SThomas Abraham * does not have a value, and -EILSEQ if the string is not null-terminated 1051a3b85363SThomas Abraham * within the length of the property data. 1052a3b85363SThomas Abraham * 1053a3b85363SThomas Abraham * The out_string pointer is modified only if a valid string can be decoded. 1054a3b85363SThomas Abraham */ 1055aac285c6SJamie Iles int of_property_read_string(struct device_node *np, const char *propname, 1056f09bc831SShawn Guo const char **out_string) 1057a3b85363SThomas Abraham { 1058a3b85363SThomas Abraham struct property *prop = of_find_property(np, propname, NULL); 1059a3b85363SThomas Abraham if (!prop) 1060a3b85363SThomas Abraham return -EINVAL; 1061a3b85363SThomas Abraham if (!prop->value) 1062a3b85363SThomas Abraham return -ENODATA; 1063a3b85363SThomas Abraham if (strnlen(prop->value, prop->length) >= prop->length) 1064a3b85363SThomas Abraham return -EILSEQ; 1065a3b85363SThomas Abraham *out_string = prop->value; 1066a3b85363SThomas Abraham return 0; 1067a3b85363SThomas Abraham } 1068a3b85363SThomas Abraham EXPORT_SYMBOL_GPL(of_property_read_string); 1069a3b85363SThomas Abraham 1070a3b85363SThomas Abraham /** 10714fcd15a0SBenoit Cousson * of_property_read_string_index - Find and read a string from a multiple 10724fcd15a0SBenoit Cousson * strings property. 10734fcd15a0SBenoit Cousson * @np: device node from which the property value is to be read. 10744fcd15a0SBenoit Cousson * @propname: name of the property to be searched. 10754fcd15a0SBenoit Cousson * @index: index of the string in the list of strings 10764fcd15a0SBenoit Cousson * @out_string: pointer to null terminated return string, modified only if 10774fcd15a0SBenoit Cousson * return value is 0. 10784fcd15a0SBenoit Cousson * 10794fcd15a0SBenoit Cousson * Search for a property in a device tree node and retrieve a null 10804fcd15a0SBenoit Cousson * terminated string value (pointer to data, not a copy) in the list of strings 10814fcd15a0SBenoit Cousson * contained in that property. 10824fcd15a0SBenoit Cousson * Returns 0 on success, -EINVAL if the property does not exist, -ENODATA if 10834fcd15a0SBenoit Cousson * property does not have a value, and -EILSEQ if the string is not 10844fcd15a0SBenoit Cousson * null-terminated within the length of the property data. 10854fcd15a0SBenoit Cousson * 10864fcd15a0SBenoit Cousson * The out_string pointer is modified only if a valid string can be decoded. 10874fcd15a0SBenoit Cousson */ 10884fcd15a0SBenoit Cousson int of_property_read_string_index(struct device_node *np, const char *propname, 10894fcd15a0SBenoit Cousson int index, const char **output) 10904fcd15a0SBenoit Cousson { 10914fcd15a0SBenoit Cousson struct property *prop = of_find_property(np, propname, NULL); 10924fcd15a0SBenoit Cousson int i = 0; 10934fcd15a0SBenoit Cousson size_t l = 0, total = 0; 10944fcd15a0SBenoit Cousson const char *p; 10954fcd15a0SBenoit Cousson 10964fcd15a0SBenoit Cousson if (!prop) 10974fcd15a0SBenoit Cousson return -EINVAL; 10984fcd15a0SBenoit Cousson if (!prop->value) 10994fcd15a0SBenoit Cousson return -ENODATA; 11004fcd15a0SBenoit Cousson if (strnlen(prop->value, prop->length) >= prop->length) 11014fcd15a0SBenoit Cousson return -EILSEQ; 11024fcd15a0SBenoit Cousson 11034fcd15a0SBenoit Cousson p = prop->value; 11044fcd15a0SBenoit Cousson 11054fcd15a0SBenoit Cousson for (i = 0; total < prop->length; total += l, p += l) { 11064fcd15a0SBenoit Cousson l = strlen(p) + 1; 110788af7f58SBenoit Cousson if (i++ == index) { 11084fcd15a0SBenoit Cousson *output = p; 11094fcd15a0SBenoit Cousson return 0; 11104fcd15a0SBenoit Cousson } 11114fcd15a0SBenoit Cousson } 11124fcd15a0SBenoit Cousson return -ENODATA; 11134fcd15a0SBenoit Cousson } 11144fcd15a0SBenoit Cousson EXPORT_SYMBOL_GPL(of_property_read_string_index); 11154fcd15a0SBenoit Cousson 11167aff0fe3SGrant Likely /** 11177aff0fe3SGrant Likely * of_property_match_string() - Find string in a list and return index 11187aff0fe3SGrant Likely * @np: pointer to node containing string list property 11197aff0fe3SGrant Likely * @propname: string list property name 11207aff0fe3SGrant Likely * @string: pointer to string to search for in string list 11217aff0fe3SGrant Likely * 11227aff0fe3SGrant Likely * This function searches a string list property and returns the index 11237aff0fe3SGrant Likely * of a specific string value. 11247aff0fe3SGrant Likely */ 11257aff0fe3SGrant Likely int of_property_match_string(struct device_node *np, const char *propname, 11267aff0fe3SGrant Likely const char *string) 11277aff0fe3SGrant Likely { 11287aff0fe3SGrant Likely struct property *prop = of_find_property(np, propname, NULL); 11297aff0fe3SGrant Likely size_t l; 11307aff0fe3SGrant Likely int i; 11317aff0fe3SGrant Likely const char *p, *end; 11327aff0fe3SGrant Likely 11337aff0fe3SGrant Likely if (!prop) 11347aff0fe3SGrant Likely return -EINVAL; 11357aff0fe3SGrant Likely if (!prop->value) 11367aff0fe3SGrant Likely return -ENODATA; 11377aff0fe3SGrant Likely 11387aff0fe3SGrant Likely p = prop->value; 11397aff0fe3SGrant Likely end = p + prop->length; 11407aff0fe3SGrant Likely 11417aff0fe3SGrant Likely for (i = 0; p < end; i++, p += l) { 11427aff0fe3SGrant Likely l = strlen(p) + 1; 11437aff0fe3SGrant Likely if (p + l > end) 11447aff0fe3SGrant Likely return -EILSEQ; 11457aff0fe3SGrant Likely pr_debug("comparing %s with %s\n", string, p); 11467aff0fe3SGrant Likely if (strcmp(string, p) == 0) 11477aff0fe3SGrant Likely return i; /* Found it; return index */ 11487aff0fe3SGrant Likely } 11497aff0fe3SGrant Likely return -ENODATA; 11507aff0fe3SGrant Likely } 11517aff0fe3SGrant Likely EXPORT_SYMBOL_GPL(of_property_match_string); 11524fcd15a0SBenoit Cousson 11534fcd15a0SBenoit Cousson /** 11544fcd15a0SBenoit Cousson * of_property_count_strings - Find and return the number of strings from a 11554fcd15a0SBenoit Cousson * multiple strings property. 11564fcd15a0SBenoit Cousson * @np: device node from which the property value is to be read. 11574fcd15a0SBenoit Cousson * @propname: name of the property to be searched. 11584fcd15a0SBenoit Cousson * 11594fcd15a0SBenoit Cousson * Search for a property in a device tree node and retrieve the number of null 11604fcd15a0SBenoit Cousson * terminated string contain in it. Returns the number of strings on 11614fcd15a0SBenoit Cousson * success, -EINVAL if the property does not exist, -ENODATA if property 11624fcd15a0SBenoit Cousson * does not have a value, and -EILSEQ if the string is not null-terminated 11634fcd15a0SBenoit Cousson * within the length of the property data. 11644fcd15a0SBenoit Cousson */ 11654fcd15a0SBenoit Cousson int of_property_count_strings(struct device_node *np, const char *propname) 11664fcd15a0SBenoit Cousson { 11674fcd15a0SBenoit Cousson struct property *prop = of_find_property(np, propname, NULL); 11684fcd15a0SBenoit Cousson int i = 0; 11694fcd15a0SBenoit Cousson size_t l = 0, total = 0; 11704fcd15a0SBenoit Cousson const char *p; 11714fcd15a0SBenoit Cousson 11724fcd15a0SBenoit Cousson if (!prop) 11734fcd15a0SBenoit Cousson return -EINVAL; 11744fcd15a0SBenoit Cousson if (!prop->value) 11754fcd15a0SBenoit Cousson return -ENODATA; 11764fcd15a0SBenoit Cousson if (strnlen(prop->value, prop->length) >= prop->length) 11774fcd15a0SBenoit Cousson return -EILSEQ; 11784fcd15a0SBenoit Cousson 11794fcd15a0SBenoit Cousson p = prop->value; 11804fcd15a0SBenoit Cousson 118188af7f58SBenoit Cousson for (i = 0; total < prop->length; total += l, p += l, i++) 11824fcd15a0SBenoit Cousson l = strlen(p) + 1; 118388af7f58SBenoit Cousson 11844fcd15a0SBenoit Cousson return i; 11854fcd15a0SBenoit Cousson } 11864fcd15a0SBenoit Cousson EXPORT_SYMBOL_GPL(of_property_count_strings); 11874fcd15a0SBenoit Cousson 1188bd69f73fSGrant Likely static int __of_parse_phandle_with_args(const struct device_node *np, 1189bd69f73fSGrant Likely const char *list_name, 1190035fd948SStephen Warren const char *cells_name, 1191035fd948SStephen Warren int cell_count, int index, 119215c9a0acSGrant Likely struct of_phandle_args *out_args) 119364b60e09SAnton Vorontsov { 119415c9a0acSGrant Likely const __be32 *list, *list_end; 119523ce04c0SGrant Likely int rc = 0, size, cur_index = 0; 119615c9a0acSGrant Likely uint32_t count = 0; 119764b60e09SAnton Vorontsov struct device_node *node = NULL; 11989a6b2e58SGrant Likely phandle phandle; 119964b60e09SAnton Vorontsov 120015c9a0acSGrant Likely /* Retrieve the phandle list property */ 120115c9a0acSGrant Likely list = of_get_property(np, list_name, &size); 120215c9a0acSGrant Likely if (!list) 12031af4c7f1SAlexandre Courbot return -ENOENT; 120415c9a0acSGrant Likely list_end = list + size / sizeof(*list); 120515c9a0acSGrant Likely 120615c9a0acSGrant Likely /* Loop over the phandles until all the requested entry is found */ 120715c9a0acSGrant Likely while (list < list_end) { 120823ce04c0SGrant Likely rc = -EINVAL; 120915c9a0acSGrant Likely count = 0; 121015c9a0acSGrant Likely 121115c9a0acSGrant Likely /* 121215c9a0acSGrant Likely * If phandle is 0, then it is an empty entry with no 121315c9a0acSGrant Likely * arguments. Skip forward to the next entry. 121415c9a0acSGrant Likely */ 12159a6b2e58SGrant Likely phandle = be32_to_cpup(list++); 121615c9a0acSGrant Likely if (phandle) { 121715c9a0acSGrant Likely /* 121815c9a0acSGrant Likely * Find the provider node and parse the #*-cells 121991d9942cSStephen Warren * property to determine the argument length. 122091d9942cSStephen Warren * 122191d9942cSStephen Warren * This is not needed if the cell count is hard-coded 122291d9942cSStephen Warren * (i.e. cells_name not set, but cell_count is set), 122391d9942cSStephen Warren * except when we're going to return the found node 122491d9942cSStephen Warren * below. 122515c9a0acSGrant Likely */ 122691d9942cSStephen Warren if (cells_name || cur_index == index) { 12279a6b2e58SGrant Likely node = of_find_node_by_phandle(phandle); 122864b60e09SAnton Vorontsov if (!node) { 122915c9a0acSGrant Likely pr_err("%s: could not find phandle\n", 123064b60e09SAnton Vorontsov np->full_name); 123123ce04c0SGrant Likely goto err; 123215c9a0acSGrant Likely } 123391d9942cSStephen Warren } 1234035fd948SStephen Warren 1235035fd948SStephen Warren if (cells_name) { 1236035fd948SStephen Warren if (of_property_read_u32(node, cells_name, 1237035fd948SStephen Warren &count)) { 123815c9a0acSGrant Likely pr_err("%s: could not get %s for %s\n", 123915c9a0acSGrant Likely np->full_name, cells_name, 124015c9a0acSGrant Likely node->full_name); 124123ce04c0SGrant Likely goto err; 124215c9a0acSGrant Likely } 1243035fd948SStephen Warren } else { 1244035fd948SStephen Warren count = cell_count; 1245035fd948SStephen Warren } 124615c9a0acSGrant Likely 124715c9a0acSGrant Likely /* 124815c9a0acSGrant Likely * Make sure that the arguments actually fit in the 124915c9a0acSGrant Likely * remaining property data length 125015c9a0acSGrant Likely */ 125115c9a0acSGrant Likely if (list + count > list_end) { 125215c9a0acSGrant Likely pr_err("%s: arguments longer than property\n", 125315c9a0acSGrant Likely np->full_name); 125423ce04c0SGrant Likely goto err; 125515c9a0acSGrant Likely } 125615c9a0acSGrant Likely } 125715c9a0acSGrant Likely 125815c9a0acSGrant Likely /* 125915c9a0acSGrant Likely * All of the error cases above bail out of the loop, so at 126015c9a0acSGrant Likely * this point, the parsing is successful. If the requested 126115c9a0acSGrant Likely * index matches, then fill the out_args structure and return, 126215c9a0acSGrant Likely * or return -ENOENT for an empty entry. 126315c9a0acSGrant Likely */ 126423ce04c0SGrant Likely rc = -ENOENT; 126515c9a0acSGrant Likely if (cur_index == index) { 126615c9a0acSGrant Likely if (!phandle) 126723ce04c0SGrant Likely goto err; 126815c9a0acSGrant Likely 126915c9a0acSGrant Likely if (out_args) { 127015c9a0acSGrant Likely int i; 127115c9a0acSGrant Likely if (WARN_ON(count > MAX_PHANDLE_ARGS)) 127215c9a0acSGrant Likely count = MAX_PHANDLE_ARGS; 127315c9a0acSGrant Likely out_args->np = node; 127415c9a0acSGrant Likely out_args->args_count = count; 127515c9a0acSGrant Likely for (i = 0; i < count; i++) 127615c9a0acSGrant Likely out_args->args[i] = be32_to_cpup(list++); 1277b855f16bSTang Yuantian } else { 1278b855f16bSTang Yuantian of_node_put(node); 127915c9a0acSGrant Likely } 128023ce04c0SGrant Likely 128123ce04c0SGrant Likely /* Found it! return success */ 128215c9a0acSGrant Likely return 0; 128315c9a0acSGrant Likely } 128464b60e09SAnton Vorontsov 128564b60e09SAnton Vorontsov of_node_put(node); 128664b60e09SAnton Vorontsov node = NULL; 128715c9a0acSGrant Likely list += count; 128864b60e09SAnton Vorontsov cur_index++; 128964b60e09SAnton Vorontsov } 129064b60e09SAnton Vorontsov 129123ce04c0SGrant Likely /* 129223ce04c0SGrant Likely * Unlock node before returning result; will be one of: 129323ce04c0SGrant Likely * -ENOENT : index is for empty phandle 129423ce04c0SGrant Likely * -EINVAL : parsing error on data 1295bd69f73fSGrant Likely * [1..n] : Number of phandle (count mode; when index = -1) 129623ce04c0SGrant Likely */ 1297bd69f73fSGrant Likely rc = index < 0 ? cur_index : -ENOENT; 129823ce04c0SGrant Likely err: 129915c9a0acSGrant Likely if (node) 130064b60e09SAnton Vorontsov of_node_put(node); 130123ce04c0SGrant Likely return rc; 130264b60e09SAnton Vorontsov } 1303bd69f73fSGrant Likely 1304eded9dd4SStephen Warren /** 13055fba49e3SStephen Warren * of_parse_phandle - Resolve a phandle property to a device_node pointer 13065fba49e3SStephen Warren * @np: Pointer to device node holding phandle property 13075fba49e3SStephen Warren * @phandle_name: Name of property holding a phandle value 13085fba49e3SStephen Warren * @index: For properties holding a table of phandles, this is the index into 13095fba49e3SStephen Warren * the table 13105fba49e3SStephen Warren * 13115fba49e3SStephen Warren * Returns the device_node pointer with refcount incremented. Use 13125fba49e3SStephen Warren * of_node_put() on it when done. 13135fba49e3SStephen Warren */ 13145fba49e3SStephen Warren struct device_node *of_parse_phandle(const struct device_node *np, 13155fba49e3SStephen Warren const char *phandle_name, int index) 13165fba49e3SStephen Warren { 131791d9942cSStephen Warren struct of_phandle_args args; 13185fba49e3SStephen Warren 131991d9942cSStephen Warren if (index < 0) 13205fba49e3SStephen Warren return NULL; 13215fba49e3SStephen Warren 132291d9942cSStephen Warren if (__of_parse_phandle_with_args(np, phandle_name, NULL, 0, 132391d9942cSStephen Warren index, &args)) 132491d9942cSStephen Warren return NULL; 132591d9942cSStephen Warren 132691d9942cSStephen Warren return args.np; 13275fba49e3SStephen Warren } 13285fba49e3SStephen Warren EXPORT_SYMBOL(of_parse_phandle); 13295fba49e3SStephen Warren 13305fba49e3SStephen Warren /** 1331eded9dd4SStephen Warren * of_parse_phandle_with_args() - Find a node pointed by phandle in a list 1332eded9dd4SStephen Warren * @np: pointer to a device tree node containing a list 1333eded9dd4SStephen Warren * @list_name: property name that contains a list 1334eded9dd4SStephen Warren * @cells_name: property name that specifies phandles' arguments count 1335eded9dd4SStephen Warren * @index: index of a phandle to parse out 1336eded9dd4SStephen Warren * @out_args: optional pointer to output arguments structure (will be filled) 1337eded9dd4SStephen Warren * 1338eded9dd4SStephen Warren * This function is useful to parse lists of phandles and their arguments. 1339eded9dd4SStephen Warren * Returns 0 on success and fills out_args, on error returns appropriate 1340eded9dd4SStephen Warren * errno value. 1341eded9dd4SStephen Warren * 1342eded9dd4SStephen Warren * Caller is responsible to call of_node_put() on the returned out_args->node 1343eded9dd4SStephen Warren * pointer. 1344eded9dd4SStephen Warren * 1345eded9dd4SStephen Warren * Example: 1346eded9dd4SStephen Warren * 1347eded9dd4SStephen Warren * phandle1: node1 { 1348eded9dd4SStephen Warren * #list-cells = <2>; 1349eded9dd4SStephen Warren * } 1350eded9dd4SStephen Warren * 1351eded9dd4SStephen Warren * phandle2: node2 { 1352eded9dd4SStephen Warren * #list-cells = <1>; 1353eded9dd4SStephen Warren * } 1354eded9dd4SStephen Warren * 1355eded9dd4SStephen Warren * node3 { 1356eded9dd4SStephen Warren * list = <&phandle1 1 2 &phandle2 3>; 1357eded9dd4SStephen Warren * } 1358eded9dd4SStephen Warren * 1359eded9dd4SStephen Warren * To get a device_node of the `node2' node you may call this: 1360eded9dd4SStephen Warren * of_parse_phandle_with_args(node3, "list", "#list-cells", 1, &args); 1361eded9dd4SStephen Warren */ 1362bd69f73fSGrant Likely int of_parse_phandle_with_args(const struct device_node *np, const char *list_name, 1363bd69f73fSGrant Likely const char *cells_name, int index, 1364bd69f73fSGrant Likely struct of_phandle_args *out_args) 1365bd69f73fSGrant Likely { 1366bd69f73fSGrant Likely if (index < 0) 1367bd69f73fSGrant Likely return -EINVAL; 1368035fd948SStephen Warren return __of_parse_phandle_with_args(np, list_name, cells_name, 0, 1369035fd948SStephen Warren index, out_args); 1370bd69f73fSGrant Likely } 137115c9a0acSGrant Likely EXPORT_SYMBOL(of_parse_phandle_with_args); 137202af11b0SGrant Likely 1373bd69f73fSGrant Likely /** 1374035fd948SStephen Warren * of_parse_phandle_with_fixed_args() - Find a node pointed by phandle in a list 1375035fd948SStephen Warren * @np: pointer to a device tree node containing a list 1376035fd948SStephen Warren * @list_name: property name that contains a list 1377035fd948SStephen Warren * @cell_count: number of argument cells following the phandle 1378035fd948SStephen Warren * @index: index of a phandle to parse out 1379035fd948SStephen Warren * @out_args: optional pointer to output arguments structure (will be filled) 1380035fd948SStephen Warren * 1381035fd948SStephen Warren * This function is useful to parse lists of phandles and their arguments. 1382035fd948SStephen Warren * Returns 0 on success and fills out_args, on error returns appropriate 1383035fd948SStephen Warren * errno value. 1384035fd948SStephen Warren * 1385035fd948SStephen Warren * Caller is responsible to call of_node_put() on the returned out_args->node 1386035fd948SStephen Warren * pointer. 1387035fd948SStephen Warren * 1388035fd948SStephen Warren * Example: 1389035fd948SStephen Warren * 1390035fd948SStephen Warren * phandle1: node1 { 1391035fd948SStephen Warren * } 1392035fd948SStephen Warren * 1393035fd948SStephen Warren * phandle2: node2 { 1394035fd948SStephen Warren * } 1395035fd948SStephen Warren * 1396035fd948SStephen Warren * node3 { 1397035fd948SStephen Warren * list = <&phandle1 0 2 &phandle2 2 3>; 1398035fd948SStephen Warren * } 1399035fd948SStephen Warren * 1400035fd948SStephen Warren * To get a device_node of the `node2' node you may call this: 1401035fd948SStephen Warren * of_parse_phandle_with_fixed_args(node3, "list", 2, 1, &args); 1402035fd948SStephen Warren */ 1403035fd948SStephen Warren int of_parse_phandle_with_fixed_args(const struct device_node *np, 1404035fd948SStephen Warren const char *list_name, int cell_count, 1405035fd948SStephen Warren int index, struct of_phandle_args *out_args) 1406035fd948SStephen Warren { 1407035fd948SStephen Warren if (index < 0) 1408035fd948SStephen Warren return -EINVAL; 1409035fd948SStephen Warren return __of_parse_phandle_with_args(np, list_name, NULL, cell_count, 1410035fd948SStephen Warren index, out_args); 1411035fd948SStephen Warren } 1412035fd948SStephen Warren EXPORT_SYMBOL(of_parse_phandle_with_fixed_args); 1413035fd948SStephen Warren 1414035fd948SStephen Warren /** 1415bd69f73fSGrant Likely * of_count_phandle_with_args() - Find the number of phandles references in a property 1416bd69f73fSGrant Likely * @np: pointer to a device tree node containing a list 1417bd69f73fSGrant Likely * @list_name: property name that contains a list 1418bd69f73fSGrant Likely * @cells_name: property name that specifies phandles' arguments count 1419bd69f73fSGrant Likely * 1420bd69f73fSGrant Likely * Returns the number of phandle + argument tuples within a property. It 1421bd69f73fSGrant Likely * is a typical pattern to encode a list of phandle and variable 1422bd69f73fSGrant Likely * arguments into a single property. The number of arguments is encoded 1423bd69f73fSGrant Likely * by a property in the phandle-target node. For example, a gpios 1424bd69f73fSGrant Likely * property would contain a list of GPIO specifies consisting of a 1425bd69f73fSGrant Likely * phandle and 1 or more arguments. The number of arguments are 1426bd69f73fSGrant Likely * determined by the #gpio-cells property in the node pointed to by the 1427bd69f73fSGrant Likely * phandle. 1428bd69f73fSGrant Likely */ 1429bd69f73fSGrant Likely int of_count_phandle_with_args(const struct device_node *np, const char *list_name, 1430bd69f73fSGrant Likely const char *cells_name) 1431bd69f73fSGrant Likely { 1432035fd948SStephen Warren return __of_parse_phandle_with_args(np, list_name, cells_name, 0, -1, 1433035fd948SStephen Warren NULL); 1434bd69f73fSGrant Likely } 1435bd69f73fSGrant Likely EXPORT_SYMBOL(of_count_phandle_with_args); 1436bd69f73fSGrant Likely 14371cf3d8b3SNathan Fontenot #if defined(CONFIG_OF_DYNAMIC) 14381cf3d8b3SNathan Fontenot static int of_property_notify(int action, struct device_node *np, 14391cf3d8b3SNathan Fontenot struct property *prop) 14401cf3d8b3SNathan Fontenot { 14411cf3d8b3SNathan Fontenot struct of_prop_reconfig pr; 14421cf3d8b3SNathan Fontenot 14431cf3d8b3SNathan Fontenot pr.dn = np; 14441cf3d8b3SNathan Fontenot pr.prop = prop; 14451cf3d8b3SNathan Fontenot return of_reconfig_notify(action, &pr); 14461cf3d8b3SNathan Fontenot } 14471cf3d8b3SNathan Fontenot #else 14481cf3d8b3SNathan Fontenot static int of_property_notify(int action, struct device_node *np, 14491cf3d8b3SNathan Fontenot struct property *prop) 14501cf3d8b3SNathan Fontenot { 14511cf3d8b3SNathan Fontenot return 0; 14521cf3d8b3SNathan Fontenot } 14531cf3d8b3SNathan Fontenot #endif 14541cf3d8b3SNathan Fontenot 145502af11b0SGrant Likely /** 145679d1c712SNathan Fontenot * of_add_property - Add a property to a node 145702af11b0SGrant Likely */ 145879d1c712SNathan Fontenot int of_add_property(struct device_node *np, struct property *prop) 145902af11b0SGrant Likely { 146002af11b0SGrant Likely struct property **next; 146102af11b0SGrant Likely unsigned long flags; 14621cf3d8b3SNathan Fontenot int rc; 14631cf3d8b3SNathan Fontenot 14641cf3d8b3SNathan Fontenot rc = of_property_notify(OF_RECONFIG_ADD_PROPERTY, np, prop); 14651cf3d8b3SNathan Fontenot if (rc) 14661cf3d8b3SNathan Fontenot return rc; 146702af11b0SGrant Likely 146802af11b0SGrant Likely prop->next = NULL; 1469d6d3c4e6SThomas Gleixner raw_spin_lock_irqsave(&devtree_lock, flags); 147002af11b0SGrant Likely next = &np->properties; 147102af11b0SGrant Likely while (*next) { 147202af11b0SGrant Likely if (strcmp(prop->name, (*next)->name) == 0) { 147302af11b0SGrant Likely /* duplicate ! don't insert it */ 1474d6d3c4e6SThomas Gleixner raw_spin_unlock_irqrestore(&devtree_lock, flags); 147502af11b0SGrant Likely return -1; 147602af11b0SGrant Likely } 147702af11b0SGrant Likely next = &(*next)->next; 147802af11b0SGrant Likely } 147902af11b0SGrant Likely *next = prop; 1480d6d3c4e6SThomas Gleixner raw_spin_unlock_irqrestore(&devtree_lock, flags); 148102af11b0SGrant Likely 148202af11b0SGrant Likely #ifdef CONFIG_PROC_DEVICETREE 148302af11b0SGrant Likely /* try to add to proc as well if it was initialized */ 148402af11b0SGrant Likely if (np->pde) 148502af11b0SGrant Likely proc_device_tree_add_prop(np->pde, prop); 148602af11b0SGrant Likely #endif /* CONFIG_PROC_DEVICETREE */ 148702af11b0SGrant Likely 148802af11b0SGrant Likely return 0; 148902af11b0SGrant Likely } 149002af11b0SGrant Likely 149102af11b0SGrant Likely /** 149279d1c712SNathan Fontenot * of_remove_property - Remove a property from a node. 149302af11b0SGrant Likely * 149402af11b0SGrant Likely * Note that we don't actually remove it, since we have given out 149502af11b0SGrant Likely * who-knows-how-many pointers to the data using get-property. 149602af11b0SGrant Likely * Instead we just move the property to the "dead properties" 149702af11b0SGrant Likely * list, so it won't be found any more. 149802af11b0SGrant Likely */ 149979d1c712SNathan Fontenot int of_remove_property(struct device_node *np, struct property *prop) 150002af11b0SGrant Likely { 150102af11b0SGrant Likely struct property **next; 150202af11b0SGrant Likely unsigned long flags; 150302af11b0SGrant Likely int found = 0; 15041cf3d8b3SNathan Fontenot int rc; 15051cf3d8b3SNathan Fontenot 15061cf3d8b3SNathan Fontenot rc = of_property_notify(OF_RECONFIG_REMOVE_PROPERTY, np, prop); 15071cf3d8b3SNathan Fontenot if (rc) 15081cf3d8b3SNathan Fontenot return rc; 150902af11b0SGrant Likely 1510d6d3c4e6SThomas Gleixner raw_spin_lock_irqsave(&devtree_lock, flags); 151102af11b0SGrant Likely next = &np->properties; 151202af11b0SGrant Likely while (*next) { 151302af11b0SGrant Likely if (*next == prop) { 151402af11b0SGrant Likely /* found the node */ 151502af11b0SGrant Likely *next = prop->next; 151602af11b0SGrant Likely prop->next = np->deadprops; 151702af11b0SGrant Likely np->deadprops = prop; 151802af11b0SGrant Likely found = 1; 151902af11b0SGrant Likely break; 152002af11b0SGrant Likely } 152102af11b0SGrant Likely next = &(*next)->next; 152202af11b0SGrant Likely } 1523d6d3c4e6SThomas Gleixner raw_spin_unlock_irqrestore(&devtree_lock, flags); 152402af11b0SGrant Likely 152502af11b0SGrant Likely if (!found) 152602af11b0SGrant Likely return -ENODEV; 152702af11b0SGrant Likely 152802af11b0SGrant Likely #ifdef CONFIG_PROC_DEVICETREE 152902af11b0SGrant Likely /* try to remove the proc node as well */ 153002af11b0SGrant Likely if (np->pde) 153102af11b0SGrant Likely proc_device_tree_remove_prop(np->pde, prop); 153202af11b0SGrant Likely #endif /* CONFIG_PROC_DEVICETREE */ 153302af11b0SGrant Likely 153402af11b0SGrant Likely return 0; 153502af11b0SGrant Likely } 153602af11b0SGrant Likely 153702af11b0SGrant Likely /* 153879d1c712SNathan Fontenot * of_update_property - Update a property in a node, if the property does 1539475d0094SDong Aisheng * not exist, add it. 154002af11b0SGrant Likely * 154102af11b0SGrant Likely * Note that we don't actually remove it, since we have given out 154202af11b0SGrant Likely * who-knows-how-many pointers to the data using get-property. 154302af11b0SGrant Likely * Instead we just move the property to the "dead properties" list, 154402af11b0SGrant Likely * and add the new property to the property list 154502af11b0SGrant Likely */ 154679d1c712SNathan Fontenot int of_update_property(struct device_node *np, struct property *newprop) 154702af11b0SGrant Likely { 1548475d0094SDong Aisheng struct property **next, *oldprop; 154902af11b0SGrant Likely unsigned long flags; 15501cf3d8b3SNathan Fontenot int rc, found = 0; 15511cf3d8b3SNathan Fontenot 15521cf3d8b3SNathan Fontenot rc = of_property_notify(OF_RECONFIG_UPDATE_PROPERTY, np, newprop); 15531cf3d8b3SNathan Fontenot if (rc) 15541cf3d8b3SNathan Fontenot return rc; 155502af11b0SGrant Likely 1556475d0094SDong Aisheng if (!newprop->name) 1557475d0094SDong Aisheng return -EINVAL; 1558475d0094SDong Aisheng 1559475d0094SDong Aisheng oldprop = of_find_property(np, newprop->name, NULL); 1560475d0094SDong Aisheng if (!oldprop) 156179d1c712SNathan Fontenot return of_add_property(np, newprop); 1562475d0094SDong Aisheng 1563d6d3c4e6SThomas Gleixner raw_spin_lock_irqsave(&devtree_lock, flags); 156402af11b0SGrant Likely next = &np->properties; 156502af11b0SGrant Likely while (*next) { 156602af11b0SGrant Likely if (*next == oldprop) { 156702af11b0SGrant Likely /* found the node */ 156802af11b0SGrant Likely newprop->next = oldprop->next; 156902af11b0SGrant Likely *next = newprop; 157002af11b0SGrant Likely oldprop->next = np->deadprops; 157102af11b0SGrant Likely np->deadprops = oldprop; 157202af11b0SGrant Likely found = 1; 157302af11b0SGrant Likely break; 157402af11b0SGrant Likely } 157502af11b0SGrant Likely next = &(*next)->next; 157602af11b0SGrant Likely } 1577d6d3c4e6SThomas Gleixner raw_spin_unlock_irqrestore(&devtree_lock, flags); 157802af11b0SGrant Likely 157902af11b0SGrant Likely if (!found) 158002af11b0SGrant Likely return -ENODEV; 158102af11b0SGrant Likely 158202af11b0SGrant Likely #ifdef CONFIG_PROC_DEVICETREE 158302af11b0SGrant Likely /* try to add to proc as well if it was initialized */ 158402af11b0SGrant Likely if (np->pde) 158502af11b0SGrant Likely proc_device_tree_update_prop(np->pde, newprop, oldprop); 158602af11b0SGrant Likely #endif /* CONFIG_PROC_DEVICETREE */ 158702af11b0SGrant Likely 158802af11b0SGrant Likely return 0; 158902af11b0SGrant Likely } 1590fcdeb7feSGrant Likely 1591fcdeb7feSGrant Likely #if defined(CONFIG_OF_DYNAMIC) 1592fcdeb7feSGrant Likely /* 1593fcdeb7feSGrant Likely * Support for dynamic device trees. 1594fcdeb7feSGrant Likely * 1595fcdeb7feSGrant Likely * On some platforms, the device tree can be manipulated at runtime. 1596fcdeb7feSGrant Likely * The routines in this section support adding, removing and changing 1597fcdeb7feSGrant Likely * device tree nodes. 1598fcdeb7feSGrant Likely */ 1599fcdeb7feSGrant Likely 16001cf3d8b3SNathan Fontenot static BLOCKING_NOTIFIER_HEAD(of_reconfig_chain); 16011cf3d8b3SNathan Fontenot 16021cf3d8b3SNathan Fontenot int of_reconfig_notifier_register(struct notifier_block *nb) 16031cf3d8b3SNathan Fontenot { 16041cf3d8b3SNathan Fontenot return blocking_notifier_chain_register(&of_reconfig_chain, nb); 16051cf3d8b3SNathan Fontenot } 16061a9bd454SNathan Fontenot EXPORT_SYMBOL_GPL(of_reconfig_notifier_register); 16071cf3d8b3SNathan Fontenot 16081cf3d8b3SNathan Fontenot int of_reconfig_notifier_unregister(struct notifier_block *nb) 16091cf3d8b3SNathan Fontenot { 16101cf3d8b3SNathan Fontenot return blocking_notifier_chain_unregister(&of_reconfig_chain, nb); 16111cf3d8b3SNathan Fontenot } 16121a9bd454SNathan Fontenot EXPORT_SYMBOL_GPL(of_reconfig_notifier_unregister); 16131cf3d8b3SNathan Fontenot 16141cf3d8b3SNathan Fontenot int of_reconfig_notify(unsigned long action, void *p) 16151cf3d8b3SNathan Fontenot { 16161cf3d8b3SNathan Fontenot int rc; 16171cf3d8b3SNathan Fontenot 16181cf3d8b3SNathan Fontenot rc = blocking_notifier_call_chain(&of_reconfig_chain, action, p); 16191cf3d8b3SNathan Fontenot return notifier_to_errno(rc); 16201cf3d8b3SNathan Fontenot } 16211cf3d8b3SNathan Fontenot 1622e81b3295SNathan Fontenot #ifdef CONFIG_PROC_DEVICETREE 1623e81b3295SNathan Fontenot static void of_add_proc_dt_entry(struct device_node *dn) 1624e81b3295SNathan Fontenot { 1625e81b3295SNathan Fontenot struct proc_dir_entry *ent; 1626e81b3295SNathan Fontenot 1627e81b3295SNathan Fontenot ent = proc_mkdir(strrchr(dn->full_name, '/') + 1, dn->parent->pde); 1628e81b3295SNathan Fontenot if (ent) 1629e81b3295SNathan Fontenot proc_device_tree_add_node(dn, ent); 1630e81b3295SNathan Fontenot } 1631e81b3295SNathan Fontenot #else 1632e81b3295SNathan Fontenot static void of_add_proc_dt_entry(struct device_node *dn) 1633e81b3295SNathan Fontenot { 1634e81b3295SNathan Fontenot return; 1635e81b3295SNathan Fontenot } 1636e81b3295SNathan Fontenot #endif 1637e81b3295SNathan Fontenot 1638fcdeb7feSGrant Likely /** 1639fcdeb7feSGrant Likely * of_attach_node - Plug a device node into the tree and global list. 1640fcdeb7feSGrant Likely */ 16411cf3d8b3SNathan Fontenot int of_attach_node(struct device_node *np) 1642fcdeb7feSGrant Likely { 1643fcdeb7feSGrant Likely unsigned long flags; 16441cf3d8b3SNathan Fontenot int rc; 16451cf3d8b3SNathan Fontenot 16461cf3d8b3SNathan Fontenot rc = of_reconfig_notify(OF_RECONFIG_ATTACH_NODE, np); 16471cf3d8b3SNathan Fontenot if (rc) 16481cf3d8b3SNathan Fontenot return rc; 1649fcdeb7feSGrant Likely 1650d6d3c4e6SThomas Gleixner raw_spin_lock_irqsave(&devtree_lock, flags); 1651fcdeb7feSGrant Likely np->sibling = np->parent->child; 1652465aac6dSRandy Dunlap np->allnext = of_allnodes; 1653fcdeb7feSGrant Likely np->parent->child = np; 1654465aac6dSRandy Dunlap of_allnodes = np; 1655d6d3c4e6SThomas Gleixner raw_spin_unlock_irqrestore(&devtree_lock, flags); 1656e81b3295SNathan Fontenot 1657e81b3295SNathan Fontenot of_add_proc_dt_entry(np); 16581cf3d8b3SNathan Fontenot return 0; 1659fcdeb7feSGrant Likely } 1660fcdeb7feSGrant Likely 1661e81b3295SNathan Fontenot #ifdef CONFIG_PROC_DEVICETREE 1662e81b3295SNathan Fontenot static void of_remove_proc_dt_entry(struct device_node *dn) 1663e81b3295SNathan Fontenot { 1664a8ca16eaSDavid Howells proc_remove(dn->pde); 1665e81b3295SNathan Fontenot } 1666e81b3295SNathan Fontenot #else 1667e81b3295SNathan Fontenot static void of_remove_proc_dt_entry(struct device_node *dn) 1668e81b3295SNathan Fontenot { 1669e81b3295SNathan Fontenot return; 1670e81b3295SNathan Fontenot } 1671e81b3295SNathan Fontenot #endif 1672e81b3295SNathan Fontenot 1673fcdeb7feSGrant Likely /** 1674fcdeb7feSGrant Likely * of_detach_node - "Unplug" a node from the device tree. 1675fcdeb7feSGrant Likely * 1676fcdeb7feSGrant Likely * The caller must hold a reference to the node. The memory associated with 1677fcdeb7feSGrant Likely * the node is not freed until its refcount goes to zero. 1678fcdeb7feSGrant Likely */ 16791cf3d8b3SNathan Fontenot int of_detach_node(struct device_node *np) 1680fcdeb7feSGrant Likely { 1681fcdeb7feSGrant Likely struct device_node *parent; 1682fcdeb7feSGrant Likely unsigned long flags; 16831cf3d8b3SNathan Fontenot int rc = 0; 16841cf3d8b3SNathan Fontenot 16851cf3d8b3SNathan Fontenot rc = of_reconfig_notify(OF_RECONFIG_DETACH_NODE, np); 16861cf3d8b3SNathan Fontenot if (rc) 16871cf3d8b3SNathan Fontenot return rc; 1688fcdeb7feSGrant Likely 1689d6d3c4e6SThomas Gleixner raw_spin_lock_irqsave(&devtree_lock, flags); 1690fcdeb7feSGrant Likely 1691e81b3295SNathan Fontenot if (of_node_check_flag(np, OF_DETACHED)) { 1692e81b3295SNathan Fontenot /* someone already detached it */ 1693d6d3c4e6SThomas Gleixner raw_spin_unlock_irqrestore(&devtree_lock, flags); 16941cf3d8b3SNathan Fontenot return rc; 1695e81b3295SNathan Fontenot } 1696e81b3295SNathan Fontenot 1697fcdeb7feSGrant Likely parent = np->parent; 1698e81b3295SNathan Fontenot if (!parent) { 1699d6d3c4e6SThomas Gleixner raw_spin_unlock_irqrestore(&devtree_lock, flags); 17001cf3d8b3SNathan Fontenot return rc; 1701e81b3295SNathan Fontenot } 1702fcdeb7feSGrant Likely 1703465aac6dSRandy Dunlap if (of_allnodes == np) 1704465aac6dSRandy Dunlap of_allnodes = np->allnext; 1705fcdeb7feSGrant Likely else { 1706fcdeb7feSGrant Likely struct device_node *prev; 1707465aac6dSRandy Dunlap for (prev = of_allnodes; 1708fcdeb7feSGrant Likely prev->allnext != np; 1709fcdeb7feSGrant Likely prev = prev->allnext) 1710fcdeb7feSGrant Likely ; 1711fcdeb7feSGrant Likely prev->allnext = np->allnext; 1712fcdeb7feSGrant Likely } 1713fcdeb7feSGrant Likely 1714fcdeb7feSGrant Likely if (parent->child == np) 1715fcdeb7feSGrant Likely parent->child = np->sibling; 1716fcdeb7feSGrant Likely else { 1717fcdeb7feSGrant Likely struct device_node *prevsib; 1718fcdeb7feSGrant Likely for (prevsib = np->parent->child; 1719fcdeb7feSGrant Likely prevsib->sibling != np; 1720fcdeb7feSGrant Likely prevsib = prevsib->sibling) 1721fcdeb7feSGrant Likely ; 1722fcdeb7feSGrant Likely prevsib->sibling = np->sibling; 1723fcdeb7feSGrant Likely } 1724fcdeb7feSGrant Likely 1725fcdeb7feSGrant Likely of_node_set_flag(np, OF_DETACHED); 1726d6d3c4e6SThomas Gleixner raw_spin_unlock_irqrestore(&devtree_lock, flags); 1727e81b3295SNathan Fontenot 1728e81b3295SNathan Fontenot of_remove_proc_dt_entry(np); 17291cf3d8b3SNathan Fontenot return rc; 1730fcdeb7feSGrant Likely } 1731fcdeb7feSGrant Likely #endif /* defined(CONFIG_OF_DYNAMIC) */ 1732fcdeb7feSGrant Likely 1733611cad72SShawn Guo static void of_alias_add(struct alias_prop *ap, struct device_node *np, 1734611cad72SShawn Guo int id, const char *stem, int stem_len) 1735611cad72SShawn Guo { 1736611cad72SShawn Guo ap->np = np; 1737611cad72SShawn Guo ap->id = id; 1738611cad72SShawn Guo strncpy(ap->stem, stem, stem_len); 1739611cad72SShawn Guo ap->stem[stem_len] = 0; 1740611cad72SShawn Guo list_add_tail(&ap->link, &aliases_lookup); 1741611cad72SShawn Guo pr_debug("adding DT alias:%s: stem=%s id=%i node=%s\n", 174274a7f084SGrant Likely ap->alias, ap->stem, ap->id, of_node_full_name(np)); 1743611cad72SShawn Guo } 1744611cad72SShawn Guo 1745611cad72SShawn Guo /** 1746611cad72SShawn Guo * of_alias_scan - Scan all properties of 'aliases' node 1747611cad72SShawn Guo * 1748611cad72SShawn Guo * The function scans all the properties of 'aliases' node and populate 1749611cad72SShawn Guo * the the global lookup table with the properties. It returns the 1750611cad72SShawn Guo * number of alias_prop found, or error code in error case. 1751611cad72SShawn Guo * 1752611cad72SShawn Guo * @dt_alloc: An allocator that provides a virtual address to memory 1753611cad72SShawn Guo * for the resulting tree 1754611cad72SShawn Guo */ 1755611cad72SShawn Guo void of_alias_scan(void * (*dt_alloc)(u64 size, u64 align)) 1756611cad72SShawn Guo { 1757611cad72SShawn Guo struct property *pp; 1758611cad72SShawn Guo 1759611cad72SShawn Guo of_chosen = of_find_node_by_path("/chosen"); 1760611cad72SShawn Guo if (of_chosen == NULL) 1761611cad72SShawn Guo of_chosen = of_find_node_by_path("/chosen@0"); 17625c19e952SSascha Hauer 17635c19e952SSascha Hauer if (of_chosen) { 17645c19e952SSascha Hauer const char *name; 17655c19e952SSascha Hauer 17665c19e952SSascha Hauer name = of_get_property(of_chosen, "linux,stdout-path", NULL); 17675c19e952SSascha Hauer if (name) 17685c19e952SSascha Hauer of_stdout = of_find_node_by_path(name); 17695c19e952SSascha Hauer } 17705c19e952SSascha Hauer 1771611cad72SShawn Guo of_aliases = of_find_node_by_path("/aliases"); 1772611cad72SShawn Guo if (!of_aliases) 1773611cad72SShawn Guo return; 1774611cad72SShawn Guo 17758af0da93SDong Aisheng for_each_property_of_node(of_aliases, pp) { 1776611cad72SShawn Guo const char *start = pp->name; 1777611cad72SShawn Guo const char *end = start + strlen(start); 1778611cad72SShawn Guo struct device_node *np; 1779611cad72SShawn Guo struct alias_prop *ap; 1780611cad72SShawn Guo int id, len; 1781611cad72SShawn Guo 1782611cad72SShawn Guo /* Skip those we do not want to proceed */ 1783611cad72SShawn Guo if (!strcmp(pp->name, "name") || 1784611cad72SShawn Guo !strcmp(pp->name, "phandle") || 1785611cad72SShawn Guo !strcmp(pp->name, "linux,phandle")) 1786611cad72SShawn Guo continue; 1787611cad72SShawn Guo 1788611cad72SShawn Guo np = of_find_node_by_path(pp->value); 1789611cad72SShawn Guo if (!np) 1790611cad72SShawn Guo continue; 1791611cad72SShawn Guo 1792611cad72SShawn Guo /* walk the alias backwards to extract the id and work out 1793611cad72SShawn Guo * the 'stem' string */ 1794611cad72SShawn Guo while (isdigit(*(end-1)) && end > start) 1795611cad72SShawn Guo end--; 1796611cad72SShawn Guo len = end - start; 1797611cad72SShawn Guo 1798611cad72SShawn Guo if (kstrtoint(end, 10, &id) < 0) 1799611cad72SShawn Guo continue; 1800611cad72SShawn Guo 1801611cad72SShawn Guo /* Allocate an alias_prop with enough space for the stem */ 1802611cad72SShawn Guo ap = dt_alloc(sizeof(*ap) + len + 1, 4); 1803611cad72SShawn Guo if (!ap) 1804611cad72SShawn Guo continue; 18050640332eSGrant Likely memset(ap, 0, sizeof(*ap) + len + 1); 1806611cad72SShawn Guo ap->alias = start; 1807611cad72SShawn Guo of_alias_add(ap, np, id, start, len); 1808611cad72SShawn Guo } 1809611cad72SShawn Guo } 1810611cad72SShawn Guo 1811611cad72SShawn Guo /** 1812611cad72SShawn Guo * of_alias_get_id - Get alias id for the given device_node 1813611cad72SShawn Guo * @np: Pointer to the given device_node 1814611cad72SShawn Guo * @stem: Alias stem of the given device_node 1815611cad72SShawn Guo * 1816611cad72SShawn Guo * The function travels the lookup table to get alias id for the given 1817611cad72SShawn Guo * device_node and alias stem. It returns the alias id if find it. 1818611cad72SShawn Guo */ 1819611cad72SShawn Guo int of_alias_get_id(struct device_node *np, const char *stem) 1820611cad72SShawn Guo { 1821611cad72SShawn Guo struct alias_prop *app; 1822611cad72SShawn Guo int id = -ENODEV; 1823611cad72SShawn Guo 1824611cad72SShawn Guo mutex_lock(&of_aliases_mutex); 1825611cad72SShawn Guo list_for_each_entry(app, &aliases_lookup, link) { 1826611cad72SShawn Guo if (strcmp(app->stem, stem) != 0) 1827611cad72SShawn Guo continue; 1828611cad72SShawn Guo 1829611cad72SShawn Guo if (np == app->np) { 1830611cad72SShawn Guo id = app->id; 1831611cad72SShawn Guo break; 1832611cad72SShawn Guo } 1833611cad72SShawn Guo } 1834611cad72SShawn Guo mutex_unlock(&of_aliases_mutex); 1835611cad72SShawn Guo 1836611cad72SShawn Guo return id; 1837611cad72SShawn Guo } 1838611cad72SShawn Guo EXPORT_SYMBOL_GPL(of_alias_get_id); 1839c541adc6SStephen Warren 1840c541adc6SStephen Warren const __be32 *of_prop_next_u32(struct property *prop, const __be32 *cur, 1841c541adc6SStephen Warren u32 *pu) 1842c541adc6SStephen Warren { 1843c541adc6SStephen Warren const void *curv = cur; 1844c541adc6SStephen Warren 1845c541adc6SStephen Warren if (!prop) 1846c541adc6SStephen Warren return NULL; 1847c541adc6SStephen Warren 1848c541adc6SStephen Warren if (!cur) { 1849c541adc6SStephen Warren curv = prop->value; 1850c541adc6SStephen Warren goto out_val; 1851c541adc6SStephen Warren } 1852c541adc6SStephen Warren 1853c541adc6SStephen Warren curv += sizeof(*cur); 1854c541adc6SStephen Warren if (curv >= prop->value + prop->length) 1855c541adc6SStephen Warren return NULL; 1856c541adc6SStephen Warren 1857c541adc6SStephen Warren out_val: 1858c541adc6SStephen Warren *pu = be32_to_cpup(curv); 1859c541adc6SStephen Warren return curv; 1860c541adc6SStephen Warren } 1861c541adc6SStephen Warren EXPORT_SYMBOL_GPL(of_prop_next_u32); 1862c541adc6SStephen Warren 1863c541adc6SStephen Warren const char *of_prop_next_string(struct property *prop, const char *cur) 1864c541adc6SStephen Warren { 1865c541adc6SStephen Warren const void *curv = cur; 1866c541adc6SStephen Warren 1867c541adc6SStephen Warren if (!prop) 1868c541adc6SStephen Warren return NULL; 1869c541adc6SStephen Warren 1870c541adc6SStephen Warren if (!cur) 1871c541adc6SStephen Warren return prop->value; 1872c541adc6SStephen Warren 1873c541adc6SStephen Warren curv += strlen(cur) + 1; 1874c541adc6SStephen Warren if (curv >= prop->value + prop->length) 1875c541adc6SStephen Warren return NULL; 1876c541adc6SStephen Warren 1877c541adc6SStephen Warren return curv; 1878c541adc6SStephen Warren } 1879c541adc6SStephen Warren EXPORT_SYMBOL_GPL(of_prop_next_string); 18805c19e952SSascha Hauer 18815c19e952SSascha Hauer /** 18825c19e952SSascha Hauer * of_device_is_stdout_path - check if a device node matches the 18835c19e952SSascha Hauer * linux,stdout-path property 18845c19e952SSascha Hauer * 18855c19e952SSascha Hauer * Check if this device node matches the linux,stdout-path property 18865c19e952SSascha Hauer * in the chosen node. return true if yes, false otherwise. 18875c19e952SSascha Hauer */ 18885c19e952SSascha Hauer int of_device_is_stdout_path(struct device_node *dn) 18895c19e952SSascha Hauer { 18905c19e952SSascha Hauer if (!of_stdout) 18915c19e952SSascha Hauer return false; 18925c19e952SSascha Hauer 18935c19e952SSascha Hauer return of_stdout == dn; 18945c19e952SSascha Hauer } 18955c19e952SSascha Hauer EXPORT_SYMBOL_GPL(of_device_is_stdout_path); 1896