1 /* 2 * Procedures for creating, accessing and interpreting the device tree. 3 * 4 * Paul Mackerras August 1996. 5 * Copyright (C) 1996-2005 Paul Mackerras. 6 * 7 * Adapted for 64bit PowerPC by Dave Engebretsen and Peter Bergner. 8 * {engebret|bergner}@us.ibm.com 9 * 10 * Adapted for sparc and sparc64 by David S. Miller davem@davemloft.net 11 * 12 * Reconsolidated from arch/x/kernel/prom.c by Stephen Rothwell. 13 * 14 * This program is free software; you can redistribute it and/or 15 * modify it under the terms of the GNU General Public License 16 * as published by the Free Software Foundation; either version 17 * 2 of the License, or (at your option) any later version. 18 */ 19 #include <linux/module.h> 20 #include <linux/of.h> 21 #include <linux/spinlock.h> 22 23 struct device_node *allnodes; 24 25 /* use when traversing tree through the allnext, child, sibling, 26 * or parent members of struct device_node. 27 */ 28 DEFINE_RWLOCK(devtree_lock); 29 30 int of_n_addr_cells(struct device_node *np) 31 { 32 const int *ip; 33 34 do { 35 if (np->parent) 36 np = np->parent; 37 ip = of_get_property(np, "#address-cells", NULL); 38 if (ip) 39 return *ip; 40 } while (np->parent); 41 /* No #address-cells property for the root node */ 42 return OF_ROOT_NODE_ADDR_CELLS_DEFAULT; 43 } 44 EXPORT_SYMBOL(of_n_addr_cells); 45 46 int of_n_size_cells(struct device_node *np) 47 { 48 const int *ip; 49 50 do { 51 if (np->parent) 52 np = np->parent; 53 ip = of_get_property(np, "#size-cells", NULL); 54 if (ip) 55 return *ip; 56 } while (np->parent); 57 /* No #size-cells property for the root node */ 58 return OF_ROOT_NODE_SIZE_CELLS_DEFAULT; 59 } 60 EXPORT_SYMBOL(of_n_size_cells); 61 62 struct property *of_find_property(const struct device_node *np, 63 const char *name, 64 int *lenp) 65 { 66 struct property *pp; 67 68 read_lock(&devtree_lock); 69 for (pp = np->properties; pp != 0; pp = pp->next) { 70 if (of_prop_cmp(pp->name, name) == 0) { 71 if (lenp != 0) 72 *lenp = pp->length; 73 break; 74 } 75 } 76 read_unlock(&devtree_lock); 77 78 return pp; 79 } 80 EXPORT_SYMBOL(of_find_property); 81 82 /* 83 * Find a property with a given name for a given node 84 * and return the value. 85 */ 86 const void *of_get_property(const struct device_node *np, const char *name, 87 int *lenp) 88 { 89 struct property *pp = of_find_property(np, name, lenp); 90 91 return pp ? pp->value : NULL; 92 } 93 EXPORT_SYMBOL(of_get_property); 94 95 /** Checks if the given "compat" string matches one of the strings in 96 * the device's "compatible" property 97 */ 98 int of_device_is_compatible(const struct device_node *device, 99 const char *compat) 100 { 101 const char* cp; 102 int cplen, l; 103 104 cp = of_get_property(device, "compatible", &cplen); 105 if (cp == NULL) 106 return 0; 107 while (cplen > 0) { 108 if (of_compat_cmp(cp, compat, strlen(compat)) == 0) 109 return 1; 110 l = strlen(cp) + 1; 111 cp += l; 112 cplen -= l; 113 } 114 115 return 0; 116 } 117 EXPORT_SYMBOL(of_device_is_compatible); 118 119 /** 120 * of_get_parent - Get a node's parent if any 121 * @node: Node to get parent 122 * 123 * Returns a node pointer with refcount incremented, use 124 * of_node_put() on it when done. 125 */ 126 struct device_node *of_get_parent(const struct device_node *node) 127 { 128 struct device_node *np; 129 130 if (!node) 131 return NULL; 132 133 read_lock(&devtree_lock); 134 np = of_node_get(node->parent); 135 read_unlock(&devtree_lock); 136 return np; 137 } 138 EXPORT_SYMBOL(of_get_parent); 139 140 /** 141 * of_get_next_child - Iterate a node childs 142 * @node: parent node 143 * @prev: previous child of the parent node, or NULL to get first 144 * 145 * Returns a node pointer with refcount incremented, use 146 * of_node_put() on it when done. 147 */ 148 struct device_node *of_get_next_child(const struct device_node *node, 149 struct device_node *prev) 150 { 151 struct device_node *next; 152 153 read_lock(&devtree_lock); 154 next = prev ? prev->sibling : node->child; 155 for (; next; next = next->sibling) 156 if (of_node_get(next)) 157 break; 158 of_node_put(prev); 159 read_unlock(&devtree_lock); 160 return next; 161 } 162 EXPORT_SYMBOL(of_get_next_child); 163 164 /** 165 * of_find_node_by_path - Find a node matching a full OF path 166 * @path: The full path to match 167 * 168 * Returns a node pointer with refcount incremented, use 169 * of_node_put() on it when done. 170 */ 171 struct device_node *of_find_node_by_path(const char *path) 172 { 173 struct device_node *np = allnodes; 174 175 read_lock(&devtree_lock); 176 for (; np; np = np->allnext) { 177 if (np->full_name && (of_node_cmp(np->full_name, path) == 0) 178 && of_node_get(np)) 179 break; 180 } 181 read_unlock(&devtree_lock); 182 return np; 183 } 184 EXPORT_SYMBOL(of_find_node_by_path); 185 186 /** 187 * of_find_node_by_name - Find a node by its "name" property 188 * @from: The node to start searching from or NULL, the node 189 * you pass will not be searched, only the next one 190 * will; typically, you pass what the previous call 191 * returned. of_node_put() will be called on it 192 * @name: The name string to match against 193 * 194 * Returns a node pointer with refcount incremented, use 195 * of_node_put() on it when done. 196 */ 197 struct device_node *of_find_node_by_name(struct device_node *from, 198 const char *name) 199 { 200 struct device_node *np; 201 202 read_lock(&devtree_lock); 203 np = from ? from->allnext : allnodes; 204 for (; np; np = np->allnext) 205 if (np->name && (of_node_cmp(np->name, name) == 0) 206 && of_node_get(np)) 207 break; 208 of_node_put(from); 209 read_unlock(&devtree_lock); 210 return np; 211 } 212 EXPORT_SYMBOL(of_find_node_by_name); 213 214 /** 215 * of_find_node_by_type - Find a node by its "device_type" property 216 * @from: The node to start searching from, or NULL to start searching 217 * the entire device tree. The node you pass will not be 218 * searched, only the next one will; typically, you pass 219 * what the previous call returned. of_node_put() will be 220 * called on from for you. 221 * @type: The type string to match against 222 * 223 * Returns a node pointer with refcount incremented, use 224 * of_node_put() on it when done. 225 */ 226 struct device_node *of_find_node_by_type(struct device_node *from, 227 const char *type) 228 { 229 struct device_node *np; 230 231 read_lock(&devtree_lock); 232 np = from ? from->allnext : allnodes; 233 for (; np; np = np->allnext) 234 if (np->type && (of_node_cmp(np->type, type) == 0) 235 && of_node_get(np)) 236 break; 237 of_node_put(from); 238 read_unlock(&devtree_lock); 239 return np; 240 } 241 EXPORT_SYMBOL(of_find_node_by_type); 242 243 /** 244 * of_find_compatible_node - Find a node based on type and one of the 245 * tokens in its "compatible" property 246 * @from: The node to start searching from or NULL, the node 247 * you pass will not be searched, only the next one 248 * will; typically, you pass what the previous call 249 * returned. of_node_put() will be called on it 250 * @type: The type string to match "device_type" or NULL to ignore 251 * @compatible: The string to match to one of the tokens in the device 252 * "compatible" list. 253 * 254 * Returns a node pointer with refcount incremented, use 255 * of_node_put() on it when done. 256 */ 257 struct device_node *of_find_compatible_node(struct device_node *from, 258 const char *type, const char *compatible) 259 { 260 struct device_node *np; 261 262 read_lock(&devtree_lock); 263 np = from ? from->allnext : allnodes; 264 for (; np; np = np->allnext) { 265 if (type 266 && !(np->type && (of_node_cmp(np->type, type) == 0))) 267 continue; 268 if (of_device_is_compatible(np, compatible) && of_node_get(np)) 269 break; 270 } 271 of_node_put(from); 272 read_unlock(&devtree_lock); 273 return np; 274 } 275 EXPORT_SYMBOL(of_find_compatible_node); 276 277 /** 278 * of_match_node - Tell if an device_node has a matching of_match structure 279 * @matches: array of of device match structures to search in 280 * @node: the of device structure to match against 281 * 282 * Low level utility function used by device matching. 283 */ 284 const struct of_device_id *of_match_node(const struct of_device_id *matches, 285 const struct device_node *node) 286 { 287 while (matches->name[0] || matches->type[0] || matches->compatible[0]) { 288 int match = 1; 289 if (matches->name[0]) 290 match &= node->name 291 && !strcmp(matches->name, node->name); 292 if (matches->type[0]) 293 match &= node->type 294 && !strcmp(matches->type, node->type); 295 if (matches->compatible[0]) 296 match &= of_device_is_compatible(node, 297 matches->compatible); 298 if (match) 299 return matches; 300 matches++; 301 } 302 return NULL; 303 } 304 EXPORT_SYMBOL(of_match_node); 305 306 /** 307 * of_find_matching_node - Find a node based on an of_device_id match 308 * table. 309 * @from: The node to start searching from or NULL, the node 310 * you pass will not be searched, only the next one 311 * will; typically, you pass what the previous call 312 * returned. of_node_put() will be called on it 313 * @matches: array of of device match structures to search in 314 * 315 * Returns a node pointer with refcount incremented, use 316 * of_node_put() on it when done. 317 */ 318 struct device_node *of_find_matching_node(struct device_node *from, 319 const struct of_device_id *matches) 320 { 321 struct device_node *np; 322 323 read_lock(&devtree_lock); 324 np = from ? from->allnext : allnodes; 325 for (; np; np = np->allnext) { 326 if (of_match_node(matches, np) && of_node_get(np)) 327 break; 328 } 329 of_node_put(from); 330 read_unlock(&devtree_lock); 331 return np; 332 } 333 EXPORT_SYMBOL(of_find_matching_node); 334