Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

at v2.6.26-rc3 721 lines 28 kB view raw
1#ifndef _LIBFDT_H 2#define _LIBFDT_H 3/* 4 * libfdt - Flat Device Tree manipulation 5 * Copyright (C) 2006 David Gibson, IBM Corporation. 6 * 7 * libfdt is dual licensed: you can use it either under the terms of 8 * the GPL, or the BSD license, at your option. 9 * 10 * a) This library is free software; you can redistribute it and/or 11 * modify it under the terms of the GNU General Public License as 12 * published by the Free Software Foundation; either version 2 of the 13 * License, or (at your option) any later version. 14 * 15 * This library is distributed in the hope that it will be useful, 16 * but WITHOUT ANY WARRANTY; without even the implied warranty of 17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 * GNU General Public License for more details. 19 * 20 * You should have received a copy of the GNU General Public 21 * License along with this library; if not, write to the Free 22 * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, 23 * MA 02110-1301 USA 24 * 25 * Alternatively, 26 * 27 * b) Redistribution and use in source and binary forms, with or 28 * without modification, are permitted provided that the following 29 * conditions are met: 30 * 31 * 1. Redistributions of source code must retain the above 32 * copyright notice, this list of conditions and the following 33 * disclaimer. 34 * 2. Redistributions in binary form must reproduce the above 35 * copyright notice, this list of conditions and the following 36 * disclaimer in the documentation and/or other materials 37 * provided with the distribution. 38 * 39 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND 40 * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, 41 * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 42 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 43 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR 44 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 45 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 46 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 47 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 48 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 49 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 50 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, 51 * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 52 */ 53 54#include <libfdt_env.h> 55#include <fdt.h> 56 57#define FDT_FIRST_SUPPORTED_VERSION 0x10 58#define FDT_LAST_SUPPORTED_VERSION 0x11 59 60/* Error codes: informative error codes */ 61#define FDT_ERR_NOTFOUND 1 62 /* FDT_ERR_NOTFOUND: The requested node or property does not exist */ 63#define FDT_ERR_EXISTS 2 64 /* FDT_ERR_EXISTS: Attemped to create a node or property which 65 * already exists */ 66#define FDT_ERR_NOSPACE 3 67 /* FDT_ERR_NOSPACE: Operation needed to expand the device 68 * tree, but its buffer did not have sufficient space to 69 * contain the expanded tree. Use fdt_open_into() to move the 70 * device tree to a buffer with more space. */ 71 72/* Error codes: codes for bad parameters */ 73#define FDT_ERR_BADOFFSET 4 74 /* FDT_ERR_BADOFFSET: Function was passed a structure block 75 * offset which is out-of-bounds, or which points to an 76 * unsuitable part of the structure for the operation. */ 77#define FDT_ERR_BADPATH 5 78 /* FDT_ERR_BADPATH: Function was passed a badly formatted path 79 * (e.g. missing a leading / for a function which requires an 80 * absolute path) */ 81#define FDT_ERR_BADPHANDLE 6 82 /* FDT_ERR_BADPHANDLE: Function was passed an invalid phandle 83 * value. phandle values of 0 and -1 are not permitted. */ 84#define FDT_ERR_BADSTATE 7 85 /* FDT_ERR_BADSTATE: Function was passed an incomplete device 86 * tree created by the sequential-write functions, which is 87 * not sufficiently complete for the requested operation. */ 88 89/* Error codes: codes for bad device tree blobs */ 90#define FDT_ERR_TRUNCATED 8 91 /* FDT_ERR_TRUNCATED: Structure block of the given device tree 92 * ends without an FDT_END tag. */ 93#define FDT_ERR_BADMAGIC 9 94 /* FDT_ERR_BADMAGIC: Given "device tree" appears not to be a 95 * device tree at all - it is missing the flattened device 96 * tree magic number. */ 97#define FDT_ERR_BADVERSION 10 98 /* FDT_ERR_BADVERSION: Given device tree has a version which 99 * can't be handled by the requested operation. For 100 * read-write functions, this may mean that fdt_open_into() is 101 * required to convert the tree to the expected version. */ 102#define FDT_ERR_BADSTRUCTURE 11 103 /* FDT_ERR_BADSTRUCTURE: Given device tree has a corrupt 104 * structure block or other serious error (e.g. misnested 105 * nodes, or subnodes preceding properties). */ 106#define FDT_ERR_BADLAYOUT 12 107 /* FDT_ERR_BADLAYOUT: For read-write functions, the given 108 * device tree has it's sub-blocks in an order that the 109 * function can't handle (memory reserve map, then structure, 110 * then strings). Use fdt_open_into() to reorganize the tree 111 * into a form suitable for the read-write operations. */ 112 113/* "Can't happen" error indicating a bug in libfdt */ 114#define FDT_ERR_INTERNAL 13 115 /* FDT_ERR_INTERNAL: libfdt has failed an internal assertion. 116 * Should never be returned, if it is, it indicates a bug in 117 * libfdt itself. */ 118 119#define FDT_ERR_MAX 13 120 121/**********************************************************************/ 122/* Low-level functions (you probably don't need these) */ 123/**********************************************************************/ 124 125const void *fdt_offset_ptr(const void *fdt, int offset, int checklen); 126static inline void *fdt_offset_ptr_w(void *fdt, int offset, int checklen) 127{ 128 return (void *)fdt_offset_ptr(fdt, offset, checklen); 129} 130 131uint32_t fdt_next_tag(const void *fdt, int offset, int *nextoffset); 132 133/**********************************************************************/ 134/* General functions */ 135/**********************************************************************/ 136 137#define fdt_get_header(fdt, field) \ 138 (fdt32_to_cpu(((const struct fdt_header *)(fdt))->field)) 139#define fdt_magic(fdt) (fdt_get_header(fdt, magic)) 140#define fdt_totalsize(fdt) (fdt_get_header(fdt, totalsize)) 141#define fdt_off_dt_struct(fdt) (fdt_get_header(fdt, off_dt_struct)) 142#define fdt_off_dt_strings(fdt) (fdt_get_header(fdt, off_dt_strings)) 143#define fdt_off_mem_rsvmap(fdt) (fdt_get_header(fdt, off_mem_rsvmap)) 144#define fdt_version(fdt) (fdt_get_header(fdt, version)) 145#define fdt_last_comp_version(fdt) (fdt_get_header(fdt, last_comp_version)) 146#define fdt_boot_cpuid_phys(fdt) (fdt_get_header(fdt, boot_cpuid_phys)) 147#define fdt_size_dt_strings(fdt) (fdt_get_header(fdt, size_dt_strings)) 148#define fdt_size_dt_struct(fdt) (fdt_get_header(fdt, size_dt_struct)) 149 150#define __fdt_set_hdr(name) \ 151 static inline void fdt_set_##name(void *fdt, uint32_t val) \ 152 { \ 153 struct fdt_header *fdth = fdt; \ 154 fdth->name = cpu_to_fdt32(val); \ 155 } 156__fdt_set_hdr(magic); 157__fdt_set_hdr(totalsize); 158__fdt_set_hdr(off_dt_struct); 159__fdt_set_hdr(off_dt_strings); 160__fdt_set_hdr(off_mem_rsvmap); 161__fdt_set_hdr(version); 162__fdt_set_hdr(last_comp_version); 163__fdt_set_hdr(boot_cpuid_phys); 164__fdt_set_hdr(size_dt_strings); 165__fdt_set_hdr(size_dt_struct); 166#undef __fdt_set_hdr 167 168/** 169 * fdt_check_header - sanity check a device tree or possible device tree 170 * @fdt: pointer to data which might be a flattened device tree 171 * 172 * fdt_check_header() checks that the given buffer contains what 173 * appears to be a flattened device tree with sane information in its 174 * header. 175 * 176 * returns: 177 * 0, if the buffer appears to contain a valid device tree 178 * -FDT_ERR_BADMAGIC, 179 * -FDT_ERR_BADVERSION, 180 * -FDT_ERR_BADSTATE, standard meanings, as above 181 */ 182int fdt_check_header(const void *fdt); 183 184/** 185 * fdt_move - move a device tree around in memory 186 * @fdt: pointer to the device tree to move 187 * @buf: pointer to memory where the device is to be moved 188 * @bufsize: size of the memory space at buf 189 * 190 * fdt_move() relocates, if possible, the device tree blob located at 191 * fdt to the buffer at buf of size bufsize. The buffer may overlap 192 * with the existing device tree blob at fdt. Therefore, 193 * fdt_move(fdt, fdt, fdt_totalsize(fdt)) 194 * should always succeed. 195 * 196 * returns: 197 * 0, on success 198 * -FDT_ERR_NOSPACE, bufsize is insufficient to contain the device tree 199 * -FDT_ERR_BADMAGIC, 200 * -FDT_ERR_BADVERSION, 201 * -FDT_ERR_BADSTATE, standard meanings 202 */ 203int fdt_move(const void *fdt, void *buf, int bufsize); 204 205/**********************************************************************/ 206/* Read-only functions */ 207/**********************************************************************/ 208 209/** 210 * fdt_string - retreive a string from the strings block of a device tree 211 * @fdt: pointer to the device tree blob 212 * @stroffset: offset of the string within the strings block (native endian) 213 * 214 * fdt_string() retrieves a pointer to a single string from the 215 * strings block of the device tree blob at fdt. 216 * 217 * returns: 218 * a pointer to the string, on success 219 * NULL, if stroffset is out of bounds 220 */ 221const char *fdt_string(const void *fdt, int stroffset); 222 223/** 224 * fdt_num_mem_rsv - retreive the number of memory reserve map entries 225 * @fdt: pointer to the device tree blob 226 * 227 * Returns the number of entries in the device tree blob's memory 228 * reservation map. This does not include the terminating 0,0 entry 229 * or any other (0,0) entries reserved for expansion. 230 * 231 * returns: 232 * the number of entries 233 */ 234int fdt_num_mem_rsv(const void *fdt); 235 236/** 237 * fdt_get_mem_rsv - retreive one memory reserve map entry 238 * @fdt: pointer to the device tree blob 239 * @address, @size: pointers to 64-bit variables 240 * 241 * On success, *address and *size will contain the address and size of 242 * the n-th reserve map entry from the device tree blob, in 243 * native-endian format. 244 * 245 * returns: 246 * 0, on success 247 * -FDT_ERR_BADMAGIC, 248 * -FDT_ERR_BADVERSION, 249 * -FDT_ERR_BADSTATE, standard meanings 250 */ 251int fdt_get_mem_rsv(const void *fdt, int n, uint64_t *address, uint64_t *size); 252 253/** 254 * fdt_subnode_offset_namelen - find a subnode based on substring 255 * @fdt: pointer to the device tree blob 256 * @parentoffset: structure block offset of a node 257 * @name: name of the subnode to locate 258 * @namelen: number of characters of name to consider 259 * 260 * Identical to fdt_subnode_offset(), but only examine the first 261 * namelen characters of name for matching the subnode name. This is 262 * useful for finding subnodes based on a portion of a larger string, 263 * such as a full path. 264 */ 265int fdt_subnode_offset_namelen(const void *fdt, int parentoffset, 266 const char *name, int namelen); 267/** 268 * fdt_subnode_offset - find a subnode of a given node 269 * @fdt: pointer to the device tree blob 270 * @parentoffset: structure block offset of a node 271 * @name: name of the subnode to locate 272 * 273 * fdt_subnode_offset() finds a subnode of the node at structure block 274 * offset parentoffset with the given name. name may include a unit 275 * address, in which case fdt_subnode_offset() will find the subnode 276 * with that unit address, or the unit address may be omitted, in 277 * which case fdt_subnode_offset() will find an arbitrary subnode 278 * whose name excluding unit address matches the given name. 279 * 280 * returns: 281 * structure block offset of the requested subnode (>=0), on success 282 * -FDT_ERR_NOTFOUND, if the requested subnode does not exist 283 * -FDT_ERR_BADOFFSET, if parentoffset did not point to an FDT_BEGIN_NODE tag 284 * -FDT_ERR_BADMAGIC, 285 * -FDT_ERR_BADVERSION, 286 * -FDT_ERR_BADSTATE, 287 * -FDT_ERR_BADSTRUCTURE, 288 * -FDT_ERR_TRUNCATED, standard meanings. 289 */ 290int fdt_subnode_offset(const void *fdt, int parentoffset, const char *name); 291 292/** 293 * fdt_path_offset - find a tree node by its full path 294 * @fdt: pointer to the device tree blob 295 * @path: full path of the node to locate 296 * 297 * fdt_path_offset() finds a node of a given path in the device tree. 298 * Each path component may omit the unit address portion, but the 299 * results of this are undefined if any such path component is 300 * ambiguous (that is if there are multiple nodes at the relevant 301 * level matching the given component, differentiated only by unit 302 * address). 303 * 304 * returns: 305 * structure block offset of the node with the requested path (>=0), on success 306 * -FDT_ERR_BADPATH, given path does not begin with '/' or is invalid 307 * -FDT_ERR_NOTFOUND, if the requested node does not exist 308 * -FDT_ERR_BADMAGIC, 309 * -FDT_ERR_BADVERSION, 310 * -FDT_ERR_BADSTATE, 311 * -FDT_ERR_BADSTRUCTURE, 312 * -FDT_ERR_TRUNCATED, standard meanings. 313 */ 314int fdt_path_offset(const void *fdt, const char *path); 315 316/** 317 * fdt_get_name - retreive the name of a given node 318 * @fdt: pointer to the device tree blob 319 * @nodeoffset: structure block offset of the starting node 320 * @lenp: pointer to an integer variable (will be overwritten) or NULL 321 * 322 * fdt_get_name() retrieves the name (including unit address) of the 323 * device tree node at structure block offset nodeoffset. If lenp is 324 * non-NULL, the length of this name is also returned, in the integer 325 * pointed to by lenp. 326 * 327 * returns: 328 * pointer to the node's name, on success 329 * If lenp is non-NULL, *lenp contains the length of that name (>=0) 330 * NULL, on error 331 * if lenp is non-NULL *lenp contains an error code (<0): 332 * -FDT_ERR_BADOFFSET, nodeoffset did not point to FDT_BEGIN_NODE tag 333 * -FDT_ERR_BADMAGIC, 334 * -FDT_ERR_BADVERSION, 335 * -FDT_ERR_BADSTATE, standard meanings 336 */ 337const char *fdt_get_name(const void *fdt, int nodeoffset, int *lenp); 338 339/** 340 * fdt_get_property - find a given property in a given node 341 * @fdt: pointer to the device tree blob 342 * @nodeoffset: offset of the node whose property to find 343 * @name: name of the property to find 344 * @lenp: pointer to an integer variable (will be overwritten) or NULL 345 * 346 * fdt_get_property() retrieves a pointer to the fdt_property 347 * structure within the device tree blob corresponding to the property 348 * named 'name' of the node at offset nodeoffset. If lenp is 349 * non-NULL, the length of the property value also returned, in the 350 * integer pointed to by lenp. 351 * 352 * returns: 353 * pointer to the structure representing the property 354 * if lenp is non-NULL, *lenp contains the length of the property 355 * value (>=0) 356 * NULL, on error 357 * if lenp is non-NULL, *lenp contains an error code (<0): 358 * -FDT_ERR_NOTFOUND, node does not have named property 359 * -FDT_ERR_BADOFFSET, nodeoffset did not point to FDT_BEGIN_NODE tag 360 * -FDT_ERR_BADMAGIC, 361 * -FDT_ERR_BADVERSION, 362 * -FDT_ERR_BADSTATE, 363 * -FDT_ERR_BADSTRUCTURE, 364 * -FDT_ERR_TRUNCATED, standard meanings 365 */ 366const struct fdt_property *fdt_get_property(const void *fdt, int nodeoffset, 367 const char *name, int *lenp); 368static inline struct fdt_property *fdt_get_property_w(void *fdt, int nodeoffset, 369 const char *name, 370 int *lenp) 371{ 372 return (struct fdt_property *)fdt_get_property(fdt, nodeoffset, 373 name, lenp); 374} 375 376/** 377 * fdt_getprop - retrieve the value of a given property 378 * @fdt: pointer to the device tree blob 379 * @nodeoffset: offset of the node whose property to find 380 * @name: name of the property to find 381 * @lenp: pointer to an integer variable (will be overwritten) or NULL 382 * 383 * fdt_getprop() retrieves a pointer to the value of the property 384 * named 'name' of the node at offset nodeoffset (this will be a 385 * pointer to within the device blob itself, not a copy of the value). 386 * If lenp is non-NULL, the length of the property value also 387 * returned, in the integer pointed to by lenp. 388 * 389 * returns: 390 * pointer to the property's value 391 * if lenp is non-NULL, *lenp contains the length of the property 392 * value (>=0) 393 * NULL, on error 394 * if lenp is non-NULL, *lenp contains an error code (<0): 395 * -FDT_ERR_NOTFOUND, node does not have named property 396 * -FDT_ERR_BADOFFSET, nodeoffset did not point to FDT_BEGIN_NODE tag 397 * -FDT_ERR_BADMAGIC, 398 * -FDT_ERR_BADVERSION, 399 * -FDT_ERR_BADSTATE, 400 * -FDT_ERR_BADSTRUCTURE, 401 * -FDT_ERR_TRUNCATED, standard meanings 402 */ 403const void *fdt_getprop(const void *fdt, int nodeoffset, 404 const char *name, int *lenp); 405static inline void *fdt_getprop_w(void *fdt, int nodeoffset, 406 const char *name, int *lenp) 407{ 408 return (void *)fdt_getprop(fdt, nodeoffset, name, lenp); 409} 410 411/** 412 * fdt_get_phandle - retreive the phandle of a given node 413 * @fdt: pointer to the device tree blob 414 * @nodeoffset: structure block offset of the node 415 * 416 * fdt_get_phandle() retrieves the phandle of the device tree node at 417 * structure block offset nodeoffset. 418 * 419 * returns: 420 * the phandle of the node at nodeoffset, on succes (!= 0, != -1) 421 * 0, if the node has no phandle, or another error occurs 422 */ 423uint32_t fdt_get_phandle(const void *fdt, int nodeoffset); 424 425/** 426 * fdt_get_path - determine the full path of a node 427 * @fdt: pointer to the device tree blob 428 * @nodeoffset: offset of the node whose path to find 429 * @buf: character buffer to contain the returned path (will be overwritten) 430 * @buflen: size of the character buffer at buf 431 * 432 * fdt_get_path() computes the full path of the node at offset 433 * nodeoffset, and records that path in the buffer at buf. 434 * 435 * NOTE: This function is expensive, as it must scan the device tree 436 * structure from the start to nodeoffset. 437 * 438 * returns: 439 * 0, on success 440 * buf contains the absolute path of the node at 441 * nodeoffset, as a NUL-terminated string. 442 * -FDT_ERR_BADOFFSET, nodeoffset does not refer to a BEGIN_NODE tag 443 * -FDT_ERR_NOSPACE, the path of the given node is longer than (bufsize-1) 444 * characters and will not fit in the given buffer. 445 * -FDT_ERR_BADMAGIC, 446 * -FDT_ERR_BADVERSION, 447 * -FDT_ERR_BADSTATE, 448 * -FDT_ERR_BADSTRUCTURE, standard meanings 449 */ 450int fdt_get_path(const void *fdt, int nodeoffset, char *buf, int buflen); 451 452/** 453 * fdt_supernode_atdepth_offset - find a specific ancestor of a node 454 * @fdt: pointer to the device tree blob 455 * @nodeoffset: offset of the node whose parent to find 456 * @supernodedepth: depth of the ancestor to find 457 * @nodedepth: pointer to an integer variable (will be overwritten) or NULL 458 * 459 * fdt_supernode_atdepth_offset() finds an ancestor of the given node 460 * at a specific depth from the root (where the root itself has depth 461 * 0, its immediate subnodes depth 1 and so forth). So 462 * fdt_supernode_atdepth_offset(fdt, nodeoffset, 0, NULL); 463 * will always return 0, the offset of the root node. If the node at 464 * nodeoffset has depth D, then: 465 * fdt_supernode_atdepth_offset(fdt, nodeoffset, D, NULL); 466 * will return nodeoffset itself. 467 * 468 * NOTE: This function is expensive, as it must scan the device tree 469 * structure from the start to nodeoffset. 470 * 471 * returns: 472 473 * structure block offset of the node at node offset's ancestor 474 * of depth supernodedepth (>=0), on success 475 * -FDT_ERR_BADOFFSET, nodeoffset does not refer to a BEGIN_NODE tag 476* -FDT_ERR_NOTFOUND, supernodedepth was greater than the depth of nodeoffset 477 * -FDT_ERR_BADMAGIC, 478 * -FDT_ERR_BADVERSION, 479 * -FDT_ERR_BADSTATE, 480 * -FDT_ERR_BADSTRUCTURE, standard meanings 481 */ 482int fdt_supernode_atdepth_offset(const void *fdt, int nodeoffset, 483 int supernodedepth, int *nodedepth); 484 485/** 486 * fdt_node_depth - find the depth of a given node 487 * @fdt: pointer to the device tree blob 488 * @nodeoffset: offset of the node whose parent to find 489 * 490 * fdt_node_depth() finds the depth of a given node. The root node 491 * has depth 0, its immediate subnodes depth 1 and so forth. 492 * 493 * NOTE: This function is expensive, as it must scan the device tree 494 * structure from the start to nodeoffset. 495 * 496 * returns: 497 * depth of the node at nodeoffset (>=0), on success 498 * -FDT_ERR_BADOFFSET, nodeoffset does not refer to a BEGIN_NODE tag 499 * -FDT_ERR_BADMAGIC, 500 * -FDT_ERR_BADVERSION, 501 * -FDT_ERR_BADSTATE, 502 * -FDT_ERR_BADSTRUCTURE, standard meanings 503 */ 504int fdt_node_depth(const void *fdt, int nodeoffset); 505 506/** 507 * fdt_parent_offset - find the parent of a given node 508 * @fdt: pointer to the device tree blob 509 * @nodeoffset: offset of the node whose parent to find 510 * 511 * fdt_parent_offset() locates the parent node of a given node (that 512 * is, it finds the offset of the node which contains the node at 513 * nodeoffset as a subnode). 514 * 515 * NOTE: This function is expensive, as it must scan the device tree 516 * structure from the start to nodeoffset, *twice*. 517 * 518 * returns: 519 * stucture block offset of the parent of the node at nodeoffset 520 * (>=0), on success 521 * -FDT_ERR_BADOFFSET, nodeoffset does not refer to a BEGIN_NODE tag 522 * -FDT_ERR_BADMAGIC, 523 * -FDT_ERR_BADVERSION, 524 * -FDT_ERR_BADSTATE, 525 * -FDT_ERR_BADSTRUCTURE, standard meanings 526 */ 527int fdt_parent_offset(const void *fdt, int nodeoffset); 528 529/** 530 * fdt_node_offset_by_prop_value - find nodes with a given property value 531 * @fdt: pointer to the device tree blob 532 * @startoffset: only find nodes after this offset 533 * @propname: property name to check 534 * @propval: property value to search for 535 * @proplen: length of the value in propval 536 * 537 * fdt_node_offset_by_prop_value() returns the offset of the first 538 * node after startoffset, which has a property named propname whose 539 * value is of length proplen and has value equal to propval; or if 540 * startoffset is -1, the very first such node in the tree. 541 * 542 * To iterate through all nodes matching the criterion, the following 543 * idiom can be used: 544 * offset = fdt_node_offset_by_prop_value(fdt, -1, propname, 545 * propval, proplen); 546 * while (offset != -FDT_ERR_NOTFOUND) { 547 * // other code here 548 * offset = fdt_node_offset_by_prop_value(fdt, offset, propname, 549 * propval, proplen); 550 * } 551 * 552 * Note the -1 in the first call to the function, if 0 is used here 553 * instead, the function will never locate the root node, even if it 554 * matches the criterion. 555 * 556 * returns: 557 * structure block offset of the located node (>= 0, >startoffset), 558 * on success 559 * -FDT_ERR_NOTFOUND, no node matching the criterion exists in the 560 * tree after startoffset 561 * -FDT_ERR_BADOFFSET, nodeoffset does not refer to a BEGIN_NODE tag 562 * -FDT_ERR_BADMAGIC, 563 * -FDT_ERR_BADVERSION, 564 * -FDT_ERR_BADSTATE, 565 * -FDT_ERR_BADSTRUCTURE, standard meanings 566 */ 567int fdt_node_offset_by_prop_value(const void *fdt, int startoffset, 568 const char *propname, 569 const void *propval, int proplen); 570 571/** 572 * fdt_node_offset_by_phandle - find the node with a given phandle 573 * @fdt: pointer to the device tree blob 574 * @phandle: phandle value 575 * 576 * fdt_node_offset_by_prop_value() returns the offset of the node 577 * which has the given phandle value. If there is more than one node 578 * in the tree with the given phandle (an invalid tree), results are 579 * undefined. 580 * 581 * returns: 582 * structure block offset of the located node (>= 0), on success 583 * -FDT_ERR_NOTFOUND, no node with that phandle exists 584 * -FDT_ERR_BADPHANDLE, given phandle value was invalid (0 or -1) 585 * -FDT_ERR_BADMAGIC, 586 * -FDT_ERR_BADVERSION, 587 * -FDT_ERR_BADSTATE, 588 * -FDT_ERR_BADSTRUCTURE, standard meanings 589 */ 590int fdt_node_offset_by_phandle(const void *fdt, uint32_t phandle); 591 592/** 593 * fdt_node_check_compatible: check a node's compatible property 594 * @fdt: pointer to the device tree blob 595 * @nodeoffset: offset of a tree node 596 * @compatible: string to match against 597 * 598 * 599 * fdt_node_check_compatible() returns 0 if the given node contains a 600 * 'compatible' property with the given string as one of its elements, 601 * it returns non-zero otherwise, or on error. 602 * 603 * returns: 604 * 0, if the node has a 'compatible' property listing the given string 605 * 1, if the node has a 'compatible' property, but it does not list 606 * the given string 607 * -FDT_ERR_NOTFOUND, if the given node has no 'compatible' property 608 * -FDT_ERR_BADOFFSET, if nodeoffset does not refer to a BEGIN_NODE tag 609 * -FDT_ERR_BADMAGIC, 610 * -FDT_ERR_BADVERSION, 611 * -FDT_ERR_BADSTATE, 612 * -FDT_ERR_BADSTRUCTURE, standard meanings 613 */ 614int fdt_node_check_compatible(const void *fdt, int nodeoffset, 615 const char *compatible); 616 617/** 618 * fdt_node_offset_by_compatible - find nodes with a given 'compatible' value 619 * @fdt: pointer to the device tree blob 620 * @startoffset: only find nodes after this offset 621 * @compatible: 'compatible' string to match against 622 * 623 * fdt_node_offset_by_compatible() returns the offset of the first 624 * node after startoffset, which has a 'compatible' property which 625 * lists the given compatible string; or if startoffset is -1, the 626 * very first such node in the tree. 627 * 628 * To iterate through all nodes matching the criterion, the following 629 * idiom can be used: 630 * offset = fdt_node_offset_by_compatible(fdt, -1, compatible); 631 * while (offset != -FDT_ERR_NOTFOUND) { 632 * // other code here 633 * offset = fdt_node_offset_by_compatible(fdt, offset, compatible); 634 * } 635 * 636 * Note the -1 in the first call to the function, if 0 is used here 637 * instead, the function will never locate the root node, even if it 638 * matches the criterion. 639 * 640 * returns: 641 * structure block offset of the located node (>= 0, >startoffset), 642 * on success 643 * -FDT_ERR_NOTFOUND, no node matching the criterion exists in the 644 * tree after startoffset 645 * -FDT_ERR_BADOFFSET, nodeoffset does not refer to a BEGIN_NODE tag 646 * -FDT_ERR_BADMAGIC, 647 * -FDT_ERR_BADVERSION, 648 * -FDT_ERR_BADSTATE, 649 * -FDT_ERR_BADSTRUCTURE, standard meanings 650 */ 651int fdt_node_offset_by_compatible(const void *fdt, int startoffset, 652 const char *compatible); 653 654/**********************************************************************/ 655/* Write-in-place functions */ 656/**********************************************************************/ 657 658int fdt_setprop_inplace(void *fdt, int nodeoffset, const char *name, 659 const void *val, int len); 660static inline int fdt_setprop_inplace_cell(void *fdt, int nodeoffset, 661 const char *name, uint32_t val) 662{ 663 val = cpu_to_fdt32(val); 664 return fdt_setprop_inplace(fdt, nodeoffset, name, &val, sizeof(val)); 665} 666 667int fdt_nop_property(void *fdt, int nodeoffset, const char *name); 668int fdt_nop_node(void *fdt, int nodeoffset); 669 670/**********************************************************************/ 671/* Sequential write functions */ 672/**********************************************************************/ 673 674int fdt_create(void *buf, int bufsize); 675int fdt_add_reservemap_entry(void *fdt, uint64_t addr, uint64_t size); 676int fdt_finish_reservemap(void *fdt); 677int fdt_begin_node(void *fdt, const char *name); 678int fdt_property(void *fdt, const char *name, const void *val, int len); 679static inline int fdt_property_cell(void *fdt, const char *name, uint32_t val) 680{ 681 val = cpu_to_fdt32(val); 682 return fdt_property(fdt, name, &val, sizeof(val)); 683} 684#define fdt_property_string(fdt, name, str) \ 685 fdt_property(fdt, name, str, strlen(str)+1) 686int fdt_end_node(void *fdt); 687int fdt_finish(void *fdt); 688 689/**********************************************************************/ 690/* Read-write functions */ 691/**********************************************************************/ 692 693int fdt_open_into(const void *fdt, void *buf, int bufsize); 694int fdt_pack(void *fdt); 695 696int fdt_add_mem_rsv(void *fdt, uint64_t address, uint64_t size); 697int fdt_del_mem_rsv(void *fdt, int n); 698 699int fdt_setprop(void *fdt, int nodeoffset, const char *name, 700 const void *val, int len); 701static inline int fdt_setprop_cell(void *fdt, int nodeoffset, const char *name, 702 uint32_t val) 703{ 704 val = cpu_to_fdt32(val); 705 return fdt_setprop(fdt, nodeoffset, name, &val, sizeof(val)); 706} 707#define fdt_setprop_string(fdt, nodeoffset, name, str) \ 708 fdt_setprop((fdt), (nodeoffset), (name), (str), strlen(str)+1) 709int fdt_delprop(void *fdt, int nodeoffset, const char *name); 710int fdt_add_subnode_namelen(void *fdt, int parentoffset, 711 const char *name, int namelen); 712int fdt_add_subnode(void *fdt, int parentoffset, const char *name); 713int fdt_del_node(void *fdt, int nodeoffset); 714 715/**********************************************************************/ 716/* Debugging / informational functions */ 717/**********************************************************************/ 718 719const char *fdt_strerror(int errval); 720 721#endif /* _LIBFDT_H */