source: rtems/cpukit/include/libfdt.h @ bef6dfc5

5
Last change on this file since bef6dfc5 was bef6dfc5, checked in by David Gibson <david@…>, on 11/19/18 at 05:36:15

libfdt: Don't use memcpy to handle unaligned reads on ARM

6dcb8ba4 "libfdt: Add helpers for accessing unaligned words" introduced
the fdt32_ld() and fdt64_ld() helpers for loading values from the FDT blob
which might not be naturally aligned. This matters for ARM, where
attempting a plain unaligned load will often cause an exception.

However, it seems the memcpy() we used here was surprisingly expensive,
making libfdt nearly 6x slower on at least some ARM platforms.

This patch takes an alternative approach, using a bunch of 1-byte loads
and shifts to implement the helpers.

Signed-off-by: David Gibson <david@…>

  • Property mode set to 100644
File size: 69.6 KB
Line 
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     0x02
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: Attempted 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         * This can be caused either by an invalid phandle property
84         * length, or the phandle value was either 0 or -1, which are
85         * not permitted. */
86#define FDT_ERR_BADSTATE        7
87        /* FDT_ERR_BADSTATE: Function was passed an incomplete device
88         * tree created by the sequential-write functions, which is
89         * not sufficiently complete for the requested operation. */
90
91/* Error codes: codes for bad device tree blobs */
92#define FDT_ERR_TRUNCATED       8
93        /* FDT_ERR_TRUNCATED: FDT or a sub-block is improperly
94         * terminated (overflows, goes outside allowed bounds, or
95         * isn't properly terminated).  */
96#define FDT_ERR_BADMAGIC        9
97        /* FDT_ERR_BADMAGIC: Given "device tree" appears not to be a
98         * device tree at all - it is missing the flattened device
99         * tree magic number. */
100#define FDT_ERR_BADVERSION      10
101        /* FDT_ERR_BADVERSION: Given device tree has a version which
102         * can't be handled by the requested operation.  For
103         * read-write functions, this may mean that fdt_open_into() is
104         * required to convert the tree to the expected version. */
105#define FDT_ERR_BADSTRUCTURE    11
106        /* FDT_ERR_BADSTRUCTURE: Given device tree has a corrupt
107         * structure block or other serious error (e.g. misnested
108         * nodes, or subnodes preceding properties). */
109#define FDT_ERR_BADLAYOUT       12
110        /* FDT_ERR_BADLAYOUT: For read-write functions, the given
111         * device tree has it's sub-blocks in an order that the
112         * function can't handle (memory reserve map, then structure,
113         * then strings).  Use fdt_open_into() to reorganize the tree
114         * into a form suitable for the read-write operations. */
115
116/* "Can't happen" error indicating a bug in libfdt */
117#define FDT_ERR_INTERNAL        13
118        /* FDT_ERR_INTERNAL: libfdt has failed an internal assertion.
119         * Should never be returned, if it is, it indicates a bug in
120         * libfdt itself. */
121
122/* Errors in device tree content */
123#define FDT_ERR_BADNCELLS       14
124        /* FDT_ERR_BADNCELLS: Device tree has a #address-cells, #size-cells
125         * or similar property with a bad format or value */
126
127#define FDT_ERR_BADVALUE        15
128        /* FDT_ERR_BADVALUE: Device tree has a property with an unexpected
129         * value. For example: a property expected to contain a string list
130         * is not NUL-terminated within the length of its value. */
131
132#define FDT_ERR_BADOVERLAY      16
133        /* FDT_ERR_BADOVERLAY: The device tree overlay, while
134         * correctly structured, cannot be applied due to some
135         * unexpected or missing value, property or node. */
136
137#define FDT_ERR_NOPHANDLES      17
138        /* FDT_ERR_NOPHANDLES: The device tree doesn't have any
139         * phandle available anymore without causing an overflow */
140
141#define FDT_ERR_MAX             17
142
143/**********************************************************************/
144/* Low-level functions (you probably don't need these)                */
145/**********************************************************************/
146
147#ifndef SWIG /* This function is not useful in Python */
148const void *fdt_offset_ptr(const void *fdt, int offset, unsigned int checklen);
149#endif
150static inline void *fdt_offset_ptr_w(void *fdt, int offset, int checklen)
151{
152        return (void *)(uintptr_t)fdt_offset_ptr(fdt, offset, checklen);
153}
154
155uint32_t fdt_next_tag(const void *fdt, int offset, int *nextoffset);
156
157/*
158 * Alignment helpers:
159 *     These helpers access words from a device tree blob.  They're
160 *     built to work even with unaligned pointers on platforms (ike
161 *     ARM) that don't like unaligned loads and stores
162 */
163
164static inline uint32_t fdt32_ld(const fdt32_t *p)
165{
166        const uint8_t *bp = (const uint8_t *)p;
167
168        return ((uint32_t)bp[0] << 24)
169                | ((uint32_t)bp[1] << 16)
170                | ((uint32_t)bp[2] << 8)
171                | bp[3];
172}
173
174static inline uint64_t fdt64_ld(const fdt64_t *p)
175{
176        const uint8_t *bp = (const uint8_t *)p;
177
178        return ((uint64_t)bp[0] << 56)
179                | ((uint64_t)bp[1] << 48)
180                | ((uint64_t)bp[2] << 40)
181                | ((uint64_t)bp[3] << 32)
182                | ((uint64_t)bp[4] << 24)
183                | ((uint64_t)bp[5] << 16)
184                | ((uint64_t)bp[6] << 8)
185                | bp[7];
186}
187
188/**********************************************************************/
189/* Traversal functions                                                */
190/**********************************************************************/
191
192int fdt_next_node(const void *fdt, int offset, int *depth);
193
194/**
195 * fdt_first_subnode() - get offset of first direct subnode
196 *
197 * @fdt:        FDT blob
198 * @offset:     Offset of node to check
199 * @return offset of first subnode, or -FDT_ERR_NOTFOUND if there is none
200 */
201int fdt_first_subnode(const void *fdt, int offset);
202
203/**
204 * fdt_next_subnode() - get offset of next direct subnode
205 *
206 * After first calling fdt_first_subnode(), call this function repeatedly to
207 * get direct subnodes of a parent node.
208 *
209 * @fdt:        FDT blob
210 * @offset:     Offset of previous subnode
211 * @return offset of next subnode, or -FDT_ERR_NOTFOUND if there are no more
212 * subnodes
213 */
214int fdt_next_subnode(const void *fdt, int offset);
215
216/**
217 * fdt_for_each_subnode - iterate over all subnodes of a parent
218 *
219 * @node:       child node (int, lvalue)
220 * @fdt:        FDT blob (const void *)
221 * @parent:     parent node (int)
222 *
223 * This is actually a wrapper around a for loop and would be used like so:
224 *
225 *      fdt_for_each_subnode(node, fdt, parent) {
226 *              Use node
227 *              ...
228 *      }
229 *
230 *      if ((node < 0) && (node != -FDT_ERR_NOT_FOUND)) {
231 *              Error handling
232 *      }
233 *
234 * Note that this is implemented as a macro and @node is used as
235 * iterator in the loop. The parent variable be constant or even a
236 * literal.
237 *
238 */
239#define fdt_for_each_subnode(node, fdt, parent)         \
240        for (node = fdt_first_subnode(fdt, parent);     \
241             node >= 0;                                 \
242             node = fdt_next_subnode(fdt, node))
243
244/**********************************************************************/
245/* General functions                                                  */
246/**********************************************************************/
247#define fdt_get_header(fdt, field) \
248        (fdt32_ld(&((const struct fdt_header *)(fdt))->field))
249#define fdt_magic(fdt)                  (fdt_get_header(fdt, magic))
250#define fdt_totalsize(fdt)              (fdt_get_header(fdt, totalsize))
251#define fdt_off_dt_struct(fdt)          (fdt_get_header(fdt, off_dt_struct))
252#define fdt_off_dt_strings(fdt)         (fdt_get_header(fdt, off_dt_strings))
253#define fdt_off_mem_rsvmap(fdt)         (fdt_get_header(fdt, off_mem_rsvmap))
254#define fdt_version(fdt)                (fdt_get_header(fdt, version))
255#define fdt_last_comp_version(fdt)      (fdt_get_header(fdt, last_comp_version))
256#define fdt_boot_cpuid_phys(fdt)        (fdt_get_header(fdt, boot_cpuid_phys))
257#define fdt_size_dt_strings(fdt)        (fdt_get_header(fdt, size_dt_strings))
258#define fdt_size_dt_struct(fdt)         (fdt_get_header(fdt, size_dt_struct))
259
260#define fdt_set_hdr_(name) \
261        static inline void fdt_set_##name(void *fdt, uint32_t val) \
262        { \
263                struct fdt_header *fdth = (struct fdt_header *)fdt; \
264                fdth->name = cpu_to_fdt32(val); \
265        }
266fdt_set_hdr_(magic);
267fdt_set_hdr_(totalsize);
268fdt_set_hdr_(off_dt_struct);
269fdt_set_hdr_(off_dt_strings);
270fdt_set_hdr_(off_mem_rsvmap);
271fdt_set_hdr_(version);
272fdt_set_hdr_(last_comp_version);
273fdt_set_hdr_(boot_cpuid_phys);
274fdt_set_hdr_(size_dt_strings);
275fdt_set_hdr_(size_dt_struct);
276#undef fdt_set_hdr_
277
278/**
279 * fdt_header_size - return the size of the tree's header
280 * @fdt: pointer to a flattened device tree
281 */
282size_t fdt_header_size_(uint32_t version);
283static inline size_t fdt_header_size(const void *fdt)
284{
285        return fdt_header_size_(fdt_version(fdt));
286}
287
288/**
289 * fdt_check_header - sanity check a device tree header
290
291 * @fdt: pointer to data which might be a flattened device tree
292 *
293 * fdt_check_header() checks that the given buffer contains what
294 * appears to be a flattened device tree, and that the header contains
295 * valid information (to the extent that can be determined from the
296 * header alone).
297 *
298 * returns:
299 *     0, if the buffer appears to contain a valid device tree
300 *     -FDT_ERR_BADMAGIC,
301 *     -FDT_ERR_BADVERSION,
302 *     -FDT_ERR_BADSTATE,
303 *     -FDT_ERR_TRUNCATED, standard meanings, as above
304 */
305int fdt_check_header(const void *fdt);
306
307/**
308 * fdt_move - move a device tree around in memory
309 * @fdt: pointer to the device tree to move
310 * @buf: pointer to memory where the device is to be moved
311 * @bufsize: size of the memory space at buf
312 *
313 * fdt_move() relocates, if possible, the device tree blob located at
314 * fdt to the buffer at buf of size bufsize.  The buffer may overlap
315 * with the existing device tree blob at fdt.  Therefore,
316 *     fdt_move(fdt, fdt, fdt_totalsize(fdt))
317 * should always succeed.
318 *
319 * returns:
320 *     0, on success
321 *     -FDT_ERR_NOSPACE, bufsize is insufficient to contain the device tree
322 *     -FDT_ERR_BADMAGIC,
323 *     -FDT_ERR_BADVERSION,
324 *     -FDT_ERR_BADSTATE, standard meanings
325 */
326int fdt_move(const void *fdt, void *buf, int bufsize);
327
328/**********************************************************************/
329/* Read-only functions                                                */
330/**********************************************************************/
331
332int fdt_check_full(const void *fdt, size_t bufsize);
333
334/**
335 * fdt_get_string - retrieve a string from the strings block of a device tree
336 * @fdt: pointer to the device tree blob
337 * @stroffset: offset of the string within the strings block (native endian)
338 * @lenp: optional pointer to return the string's length
339 *
340 * fdt_get_string() retrieves a pointer to a single string from the
341 * strings block of the device tree blob at fdt, and optionally also
342 * returns the string's length in *lenp.
343 *
344 * returns:
345 *     a pointer to the string, on success
346 *     NULL, if stroffset is out of bounds, or doesn't point to a valid string
347 */
348const char *fdt_get_string(const void *fdt, int stroffset, int *lenp);
349
350/**
351 * fdt_string - retrieve a string from the strings block of a device tree
352 * @fdt: pointer to the device tree blob
353 * @stroffset: offset of the string within the strings block (native endian)
354 *
355 * fdt_string() retrieves a pointer to a single string from the
356 * strings block of the device tree blob at fdt.
357 *
358 * returns:
359 *     a pointer to the string, on success
360 *     NULL, if stroffset is out of bounds, or doesn't point to a valid string
361 */
362const char *fdt_string(const void *fdt, int stroffset);
363
364/**
365 * fdt_get_max_phandle - retrieves the highest phandle in a tree
366 * @fdt: pointer to the device tree blob
367 *
368 * fdt_get_max_phandle retrieves the highest phandle in the given
369 * device tree. This will ignore badly formatted phandles, or phandles
370 * with a value of 0 or -1.
371 *
372 * returns:
373 *      the highest phandle on success
374 *      0, if no phandle was found in the device tree
375 *      -1, if an error occurred
376 */
377uint32_t fdt_get_max_phandle(const void *fdt);
378
379/**
380 * fdt_num_mem_rsv - retrieve the number of memory reserve map entries
381 * @fdt: pointer to the device tree blob
382 *
383 * Returns the number of entries in the device tree blob's memory
384 * reservation map.  This does not include the terminating 0,0 entry
385 * or any other (0,0) entries reserved for expansion.
386 *
387 * returns:
388 *     the number of entries
389 */
390int fdt_num_mem_rsv(const void *fdt);
391
392/**
393 * fdt_get_mem_rsv - retrieve one memory reserve map entry
394 * @fdt: pointer to the device tree blob
395 * @address, @size: pointers to 64-bit variables
396 *
397 * On success, *address and *size will contain the address and size of
398 * the n-th reserve map entry from the device tree blob, in
399 * native-endian format.
400 *
401 * returns:
402 *     0, on success
403 *     -FDT_ERR_BADMAGIC,
404 *     -FDT_ERR_BADVERSION,
405 *     -FDT_ERR_BADSTATE, standard meanings
406 */
407int fdt_get_mem_rsv(const void *fdt, int n, uint64_t *address, uint64_t *size);
408
409/**
410 * fdt_subnode_offset_namelen - find a subnode based on substring
411 * @fdt: pointer to the device tree blob
412 * @parentoffset: structure block offset of a node
413 * @name: name of the subnode to locate
414 * @namelen: number of characters of name to consider
415 *
416 * Identical to fdt_subnode_offset(), but only examine the first
417 * namelen characters of name for matching the subnode name.  This is
418 * useful for finding subnodes based on a portion of a larger string,
419 * such as a full path.
420 */
421#ifndef SWIG /* Not available in Python */
422int fdt_subnode_offset_namelen(const void *fdt, int parentoffset,
423                               const char *name, int namelen);
424#endif
425/**
426 * fdt_subnode_offset - find a subnode of a given node
427 * @fdt: pointer to the device tree blob
428 * @parentoffset: structure block offset of a node
429 * @name: name of the subnode to locate
430 *
431 * fdt_subnode_offset() finds a subnode of the node at structure block
432 * offset parentoffset with the given name.  name may include a unit
433 * address, in which case fdt_subnode_offset() will find the subnode
434 * with that unit address, or the unit address may be omitted, in
435 * which case fdt_subnode_offset() will find an arbitrary subnode
436 * whose name excluding unit address matches the given name.
437 *
438 * returns:
439 *      structure block offset of the requested subnode (>=0), on success
440 *      -FDT_ERR_NOTFOUND, if the requested subnode does not exist
441 *      -FDT_ERR_BADOFFSET, if parentoffset did not point to an FDT_BEGIN_NODE
442 *              tag
443 *      -FDT_ERR_BADMAGIC,
444 *      -FDT_ERR_BADVERSION,
445 *      -FDT_ERR_BADSTATE,
446 *      -FDT_ERR_BADSTRUCTURE,
447 *      -FDT_ERR_TRUNCATED, standard meanings.
448 */
449int fdt_subnode_offset(const void *fdt, int parentoffset, const char *name);
450
451/**
452 * fdt_path_offset_namelen - find a tree node by its full path
453 * @fdt: pointer to the device tree blob
454 * @path: full path of the node to locate
455 * @namelen: number of characters of path to consider
456 *
457 * Identical to fdt_path_offset(), but only consider the first namelen
458 * characters of path as the path name.
459 */
460#ifndef SWIG /* Not available in Python */
461int fdt_path_offset_namelen(const void *fdt, const char *path, int namelen);
462#endif
463
464/**
465 * fdt_path_offset - find a tree node by its full path
466 * @fdt: pointer to the device tree blob
467 * @path: full path of the node to locate
468 *
469 * fdt_path_offset() finds a node of a given path in the device tree.
470 * Each path component may omit the unit address portion, but the
471 * results of this are undefined if any such path component is
472 * ambiguous (that is if there are multiple nodes at the relevant
473 * level matching the given component, differentiated only by unit
474 * address).
475 *
476 * returns:
477 *      structure block offset of the node with the requested path (>=0), on
478 *              success
479 *      -FDT_ERR_BADPATH, given path does not begin with '/' or is invalid
480 *      -FDT_ERR_NOTFOUND, if the requested node does not exist
481 *      -FDT_ERR_BADMAGIC,
482 *      -FDT_ERR_BADVERSION,
483 *      -FDT_ERR_BADSTATE,
484 *      -FDT_ERR_BADSTRUCTURE,
485 *      -FDT_ERR_TRUNCATED, standard meanings.
486 */
487int fdt_path_offset(const void *fdt, const char *path);
488
489/**
490 * fdt_get_name - retrieve the name of a given node
491 * @fdt: pointer to the device tree blob
492 * @nodeoffset: structure block offset of the starting node
493 * @lenp: pointer to an integer variable (will be overwritten) or NULL
494 *
495 * fdt_get_name() retrieves the name (including unit address) of the
496 * device tree node at structure block offset nodeoffset.  If lenp is
497 * non-NULL, the length of this name is also returned, in the integer
498 * pointed to by lenp.
499 *
500 * returns:
501 *      pointer to the node's name, on success
502 *              If lenp is non-NULL, *lenp contains the length of that name
503 *                      (>=0)
504 *      NULL, on error
505 *              if lenp is non-NULL *lenp contains an error code (<0):
506 *              -FDT_ERR_BADOFFSET, nodeoffset did not point to FDT_BEGIN_NODE
507 *                      tag
508 *              -FDT_ERR_BADMAGIC,
509 *              -FDT_ERR_BADVERSION,
510 *              -FDT_ERR_BADSTATE, standard meanings
511 */
512const char *fdt_get_name(const void *fdt, int nodeoffset, int *lenp);
513
514/**
515 * fdt_first_property_offset - find the offset of a node's first property
516 * @fdt: pointer to the device tree blob
517 * @nodeoffset: structure block offset of a node
518 *
519 * fdt_first_property_offset() finds the first property of the node at
520 * the given structure block offset.
521 *
522 * returns:
523 *      structure block offset of the property (>=0), on success
524 *      -FDT_ERR_NOTFOUND, if the requested node has no properties
525 *      -FDT_ERR_BADOFFSET, if nodeoffset did not point to an FDT_BEGIN_NODE tag
526 *      -FDT_ERR_BADMAGIC,
527 *      -FDT_ERR_BADVERSION,
528 *      -FDT_ERR_BADSTATE,
529 *      -FDT_ERR_BADSTRUCTURE,
530 *      -FDT_ERR_TRUNCATED, standard meanings.
531 */
532int fdt_first_property_offset(const void *fdt, int nodeoffset);
533
534/**
535 * fdt_next_property_offset - step through a node's properties
536 * @fdt: pointer to the device tree blob
537 * @offset: structure block offset of a property
538 *
539 * fdt_next_property_offset() finds the property immediately after the
540 * one at the given structure block offset.  This will be a property
541 * of the same node as the given property.
542 *
543 * returns:
544 *      structure block offset of the next property (>=0), on success
545 *      -FDT_ERR_NOTFOUND, if the given property is the last in its node
546 *      -FDT_ERR_BADOFFSET, if nodeoffset did not point to an FDT_PROP tag
547 *      -FDT_ERR_BADMAGIC,
548 *      -FDT_ERR_BADVERSION,
549 *      -FDT_ERR_BADSTATE,
550 *      -FDT_ERR_BADSTRUCTURE,
551 *      -FDT_ERR_TRUNCATED, standard meanings.
552 */
553int fdt_next_property_offset(const void *fdt, int offset);
554
555/**
556 * fdt_for_each_property_offset - iterate over all properties of a node
557 *
558 * @property_offset:    property offset (int, lvalue)
559 * @fdt:                FDT blob (const void *)
560 * @node:               node offset (int)
561 *
562 * This is actually a wrapper around a for loop and would be used like so:
563 *
564 *      fdt_for_each_property_offset(property, fdt, node) {
565 *              Use property
566 *              ...
567 *      }
568 *
569 *      if ((property < 0) && (property != -FDT_ERR_NOT_FOUND)) {
570 *              Error handling
571 *      }
572 *
573 * Note that this is implemented as a macro and property is used as
574 * iterator in the loop. The node variable can be constant or even a
575 * literal.
576 */
577#define fdt_for_each_property_offset(property, fdt, node)       \
578        for (property = fdt_first_property_offset(fdt, node);   \
579             property >= 0;                                     \
580             property = fdt_next_property_offset(fdt, property))
581
582/**
583 * fdt_get_property_by_offset - retrieve the property at a given offset
584 * @fdt: pointer to the device tree blob
585 * @offset: offset of the property to retrieve
586 * @lenp: pointer to an integer variable (will be overwritten) or NULL
587 *
588 * fdt_get_property_by_offset() retrieves a pointer to the
589 * fdt_property structure within the device tree blob at the given
590 * offset.  If lenp is non-NULL, the length of the property value is
591 * also returned, in the integer pointed to by lenp.
592 *
593 * Note that this code only works on device tree versions >= 16. fdt_getprop()
594 * works on all versions.
595 *
596 * returns:
597 *      pointer to the structure representing the property
598 *              if lenp is non-NULL, *lenp contains the length of the property
599 *              value (>=0)
600 *      NULL, on error
601 *              if lenp is non-NULL, *lenp contains an error code (<0):
602 *              -FDT_ERR_BADOFFSET, nodeoffset did not point to FDT_PROP tag
603 *              -FDT_ERR_BADMAGIC,
604 *              -FDT_ERR_BADVERSION,
605 *              -FDT_ERR_BADSTATE,
606 *              -FDT_ERR_BADSTRUCTURE,
607 *              -FDT_ERR_TRUNCATED, standard meanings
608 */
609const struct fdt_property *fdt_get_property_by_offset(const void *fdt,
610                                                      int offset,
611                                                      int *lenp);
612
613/**
614 * fdt_get_property_namelen - find a property based on substring
615 * @fdt: pointer to the device tree blob
616 * @nodeoffset: offset of the node whose property to find
617 * @name: name of the property to find
618 * @namelen: number of characters of name to consider
619 * @lenp: pointer to an integer variable (will be overwritten) or NULL
620 *
621 * Identical to fdt_get_property(), but only examine the first namelen
622 * characters of name for matching the property name.
623 */
624#ifndef SWIG /* Not available in Python */
625const struct fdt_property *fdt_get_property_namelen(const void *fdt,
626                                                    int nodeoffset,
627                                                    const char *name,
628                                                    int namelen, int *lenp);
629#endif
630
631/**
632 * fdt_get_property - find a given property in a given node
633 * @fdt: pointer to the device tree blob
634 * @nodeoffset: offset of the node whose property to find
635 * @name: name of the property to find
636 * @lenp: pointer to an integer variable (will be overwritten) or NULL
637 *
638 * fdt_get_property() retrieves a pointer to the fdt_property
639 * structure within the device tree blob corresponding to the property
640 * named 'name' of the node at offset nodeoffset.  If lenp is
641 * non-NULL, the length of the property value is also returned, in the
642 * integer pointed to by lenp.
643 *
644 * returns:
645 *      pointer to the structure representing the property
646 *              if lenp is non-NULL, *lenp contains the length of the property
647 *              value (>=0)
648 *      NULL, on error
649 *              if lenp is non-NULL, *lenp contains an error code (<0):
650 *              -FDT_ERR_NOTFOUND, node does not have named property
651 *              -FDT_ERR_BADOFFSET, nodeoffset did not point to FDT_BEGIN_NODE
652 *                      tag
653 *              -FDT_ERR_BADMAGIC,
654 *              -FDT_ERR_BADVERSION,
655 *              -FDT_ERR_BADSTATE,
656 *              -FDT_ERR_BADSTRUCTURE,
657 *              -FDT_ERR_TRUNCATED, standard meanings
658 */
659const struct fdt_property *fdt_get_property(const void *fdt, int nodeoffset,
660                                            const char *name, int *lenp);
661static inline struct fdt_property *fdt_get_property_w(void *fdt, int nodeoffset,
662                                                      const char *name,
663                                                      int *lenp)
664{
665        return (struct fdt_property *)(uintptr_t)
666                fdt_get_property(fdt, nodeoffset, name, lenp);
667}
668
669/**
670 * fdt_getprop_by_offset - retrieve the value of a property at a given offset
671 * @fdt: pointer to the device tree blob
672 * @ffset: offset of the property to read
673 * @namep: pointer to a string variable (will be overwritten) or NULL
674 * @lenp: pointer to an integer variable (will be overwritten) or NULL
675 *
676 * fdt_getprop_by_offset() retrieves a pointer to the value of the
677 * property at structure block offset 'offset' (this will be a pointer
678 * to within the device blob itself, not a copy of the value).  If
679 * lenp is non-NULL, the length of the property value is also
680 * returned, in the integer pointed to by lenp.  If namep is non-NULL,
681 * the property's namne will also be returned in the char * pointed to
682 * by namep (this will be a pointer to within the device tree's string
683 * block, not a new copy of the name).
684 *
685 * returns:
686 *      pointer to the property's value
687 *              if lenp is non-NULL, *lenp contains the length of the property
688 *              value (>=0)
689 *              if namep is non-NULL *namep contiains a pointer to the property
690 *              name.
691 *      NULL, on error
692 *              if lenp is non-NULL, *lenp contains an error code (<0):
693 *              -FDT_ERR_BADOFFSET, nodeoffset did not point to FDT_PROP tag
694 *              -FDT_ERR_BADMAGIC,
695 *              -FDT_ERR_BADVERSION,
696 *              -FDT_ERR_BADSTATE,
697 *              -FDT_ERR_BADSTRUCTURE,
698 *              -FDT_ERR_TRUNCATED, standard meanings
699 */
700#ifndef SWIG /* This function is not useful in Python */
701const void *fdt_getprop_by_offset(const void *fdt, int offset,
702                                  const char **namep, int *lenp);
703#endif
704
705/**
706 * fdt_getprop_namelen - get property value based on substring
707 * @fdt: pointer to the device tree blob
708 * @nodeoffset: offset of the node whose property to find
709 * @name: name of the property to find
710 * @namelen: number of characters of name to consider
711 * @lenp: pointer to an integer variable (will be overwritten) or NULL
712 *
713 * Identical to fdt_getprop(), but only examine the first namelen
714 * characters of name for matching the property name.
715 */
716#ifndef SWIG /* Not available in Python */
717const void *fdt_getprop_namelen(const void *fdt, int nodeoffset,
718                                const char *name, int namelen, int *lenp);
719static inline void *fdt_getprop_namelen_w(void *fdt, int nodeoffset,
720                                          const char *name, int namelen,
721                                          int *lenp)
722{
723        return (void *)(uintptr_t)fdt_getprop_namelen(fdt, nodeoffset, name,
724                                                      namelen, lenp);
725}
726#endif
727
728/**
729 * fdt_getprop - retrieve the value of a given property
730 * @fdt: pointer to the device tree blob
731 * @nodeoffset: offset of the node whose property to find
732 * @name: name of the property to find
733 * @lenp: pointer to an integer variable (will be overwritten) or NULL
734 *
735 * fdt_getprop() retrieves a pointer to the value of the property
736 * named 'name' of the node at offset nodeoffset (this will be a
737 * pointer to within the device blob itself, not a copy of the value).
738 * If lenp is non-NULL, the length of the property value is also
739 * returned, in the integer pointed to by lenp.
740 *
741 * returns:
742 *      pointer to the property's value
743 *              if lenp is non-NULL, *lenp contains the length of the property
744 *              value (>=0)
745 *      NULL, on error
746 *              if lenp is non-NULL, *lenp contains an error code (<0):
747 *              -FDT_ERR_NOTFOUND, node does not have named property
748 *              -FDT_ERR_BADOFFSET, nodeoffset did not point to FDT_BEGIN_NODE
749 *                      tag
750 *              -FDT_ERR_BADMAGIC,
751 *              -FDT_ERR_BADVERSION,
752 *              -FDT_ERR_BADSTATE,
753 *              -FDT_ERR_BADSTRUCTURE,
754 *              -FDT_ERR_TRUNCATED, standard meanings
755 */
756const void *fdt_getprop(const void *fdt, int nodeoffset,
757                        const char *name, int *lenp);
758static inline void *fdt_getprop_w(void *fdt, int nodeoffset,
759                                  const char *name, int *lenp)
760{
761        return (void *)(uintptr_t)fdt_getprop(fdt, nodeoffset, name, lenp);
762}
763
764/**
765 * fdt_get_phandle - retrieve the phandle of a given node
766 * @fdt: pointer to the device tree blob
767 * @nodeoffset: structure block offset of the node
768 *
769 * fdt_get_phandle() retrieves the phandle of the device tree node at
770 * structure block offset nodeoffset.
771 *
772 * returns:
773 *      the phandle of the node at nodeoffset, on success (!= 0, != -1)
774 *      0, if the node has no phandle, or another error occurs
775 */
776uint32_t fdt_get_phandle(const void *fdt, int nodeoffset);
777
778/**
779 * fdt_get_alias_namelen - get alias based on substring
780 * @fdt: pointer to the device tree blob
781 * @name: name of the alias th look up
782 * @namelen: number of characters of name to consider
783 *
784 * Identical to fdt_get_alias(), but only examine the first namelen
785 * characters of name for matching the alias name.
786 */
787#ifndef SWIG /* Not available in Python */
788const char *fdt_get_alias_namelen(const void *fdt,
789                                  const char *name, int namelen);
790#endif
791
792/**
793 * fdt_get_alias - retrieve the path referenced by a given alias
794 * @fdt: pointer to the device tree blob
795 * @name: name of the alias th look up
796 *
797 * fdt_get_alias() retrieves the value of a given alias.  That is, the
798 * value of the property named 'name' in the node /aliases.
799 *
800 * returns:
801 *      a pointer to the expansion of the alias named 'name', if it exists
802 *      NULL, if the given alias or the /aliases node does not exist
803 */
804const char *fdt_get_alias(const void *fdt, const char *name);
805
806/**
807 * fdt_get_path - determine the full path of a node
808 * @fdt: pointer to the device tree blob
809 * @nodeoffset: offset of the node whose path to find
810 * @buf: character buffer to contain the returned path (will be overwritten)
811 * @buflen: size of the character buffer at buf
812 *
813 * fdt_get_path() computes the full path of the node at offset
814 * nodeoffset, and records that path in the buffer at buf.
815 *
816 * NOTE: This function is expensive, as it must scan the device tree
817 * structure from the start to nodeoffset.
818 *
819 * returns:
820 *      0, on success
821 *              buf contains the absolute path of the node at
822 *              nodeoffset, as a NUL-terminated string.
823 *      -FDT_ERR_BADOFFSET, nodeoffset does not refer to a BEGIN_NODE tag
824 *      -FDT_ERR_NOSPACE, the path of the given node is longer than (bufsize-1)
825 *              characters and will not fit in the given buffer.
826 *      -FDT_ERR_BADMAGIC,
827 *      -FDT_ERR_BADVERSION,
828 *      -FDT_ERR_BADSTATE,
829 *      -FDT_ERR_BADSTRUCTURE, standard meanings
830 */
831int fdt_get_path(const void *fdt, int nodeoffset, char *buf, int buflen);
832
833/**
834 * fdt_supernode_atdepth_offset - find a specific ancestor of a node
835 * @fdt: pointer to the device tree blob
836 * @nodeoffset: offset of the node whose parent to find
837 * @supernodedepth: depth of the ancestor to find
838 * @nodedepth: pointer to an integer variable (will be overwritten) or NULL
839 *
840 * fdt_supernode_atdepth_offset() finds an ancestor of the given node
841 * at a specific depth from the root (where the root itself has depth
842 * 0, its immediate subnodes depth 1 and so forth).  So
843 *      fdt_supernode_atdepth_offset(fdt, nodeoffset, 0, NULL);
844 * will always return 0, the offset of the root node.  If the node at
845 * nodeoffset has depth D, then:
846 *      fdt_supernode_atdepth_offset(fdt, nodeoffset, D, NULL);
847 * will return nodeoffset itself.
848 *
849 * NOTE: This function is expensive, as it must scan the device tree
850 * structure from the start to nodeoffset.
851 *
852 * returns:
853 *      structure block offset of the node at node offset's ancestor
854 *              of depth supernodedepth (>=0), on success
855 *      -FDT_ERR_BADOFFSET, nodeoffset does not refer to a BEGIN_NODE tag
856 *      -FDT_ERR_NOTFOUND, supernodedepth was greater than the depth of
857 *              nodeoffset
858 *      -FDT_ERR_BADMAGIC,
859 *      -FDT_ERR_BADVERSION,
860 *      -FDT_ERR_BADSTATE,
861 *      -FDT_ERR_BADSTRUCTURE, standard meanings
862 */
863int fdt_supernode_atdepth_offset(const void *fdt, int nodeoffset,
864                                 int supernodedepth, int *nodedepth);
865
866/**
867 * fdt_node_depth - find the depth of a given node
868 * @fdt: pointer to the device tree blob
869 * @nodeoffset: offset of the node whose parent to find
870 *
871 * fdt_node_depth() finds the depth of a given node.  The root node
872 * has depth 0, its immediate subnodes depth 1 and so forth.
873 *
874 * NOTE: This function is expensive, as it must scan the device tree
875 * structure from the start to nodeoffset.
876 *
877 * returns:
878 *      depth of the node at nodeoffset (>=0), on success
879 *      -FDT_ERR_BADOFFSET, nodeoffset does not refer to a BEGIN_NODE tag
880 *      -FDT_ERR_BADMAGIC,
881 *      -FDT_ERR_BADVERSION,
882 *      -FDT_ERR_BADSTATE,
883 *      -FDT_ERR_BADSTRUCTURE, standard meanings
884 */
885int fdt_node_depth(const void *fdt, int nodeoffset);
886
887/**
888 * fdt_parent_offset - find the parent of a given node
889 * @fdt: pointer to the device tree blob
890 * @nodeoffset: offset of the node whose parent to find
891 *
892 * fdt_parent_offset() locates the parent node of a given node (that
893 * is, it finds the offset of the node which contains the node at
894 * nodeoffset as a subnode).
895 *
896 * NOTE: This function is expensive, as it must scan the device tree
897 * structure from the start to nodeoffset, *twice*.
898 *
899 * returns:
900 *      structure block offset of the parent of the node at nodeoffset
901 *              (>=0), on success
902 *      -FDT_ERR_BADOFFSET, nodeoffset does not refer to a BEGIN_NODE tag
903 *      -FDT_ERR_BADMAGIC,
904 *      -FDT_ERR_BADVERSION,
905 *      -FDT_ERR_BADSTATE,
906 *      -FDT_ERR_BADSTRUCTURE, standard meanings
907 */
908int fdt_parent_offset(const void *fdt, int nodeoffset);
909
910/**
911 * fdt_node_offset_by_prop_value - find nodes with a given property value
912 * @fdt: pointer to the device tree blob
913 * @startoffset: only find nodes after this offset
914 * @propname: property name to check
915 * @propval: property value to search for
916 * @proplen: length of the value in propval
917 *
918 * fdt_node_offset_by_prop_value() returns the offset of the first
919 * node after startoffset, which has a property named propname whose
920 * value is of length proplen and has value equal to propval; or if
921 * startoffset is -1, the very first such node in the tree.
922 *
923 * To iterate through all nodes matching the criterion, the following
924 * idiom can be used:
925 *      offset = fdt_node_offset_by_prop_value(fdt, -1, propname,
926 *                                             propval, proplen);
927 *      while (offset != -FDT_ERR_NOTFOUND) {
928 *              // other code here
929 *              offset = fdt_node_offset_by_prop_value(fdt, offset, propname,
930 *                                                     propval, proplen);
931 *      }
932 *
933 * Note the -1 in the first call to the function, if 0 is used here
934 * instead, the function will never locate the root node, even if it
935 * matches the criterion.
936 *
937 * returns:
938 *      structure block offset of the located node (>= 0, >startoffset),
939 *               on success
940 *      -FDT_ERR_NOTFOUND, no node matching the criterion exists in the
941 *              tree after startoffset
942 *      -FDT_ERR_BADOFFSET, nodeoffset does not refer to a BEGIN_NODE tag
943 *      -FDT_ERR_BADMAGIC,
944 *      -FDT_ERR_BADVERSION,
945 *      -FDT_ERR_BADSTATE,
946 *      -FDT_ERR_BADSTRUCTURE, standard meanings
947 */
948int fdt_node_offset_by_prop_value(const void *fdt, int startoffset,
949                                  const char *propname,
950                                  const void *propval, int proplen);
951
952/**
953 * fdt_node_offset_by_phandle - find the node with a given phandle
954 * @fdt: pointer to the device tree blob
955 * @phandle: phandle value
956 *
957 * fdt_node_offset_by_phandle() returns the offset of the node
958 * which has the given phandle value.  If there is more than one node
959 * in the tree with the given phandle (an invalid tree), results are
960 * undefined.
961 *
962 * returns:
963 *      structure block offset of the located node (>= 0), on success
964 *      -FDT_ERR_NOTFOUND, no node with that phandle exists
965 *      -FDT_ERR_BADPHANDLE, given phandle value was invalid (0 or -1)
966 *      -FDT_ERR_BADMAGIC,
967 *      -FDT_ERR_BADVERSION,
968 *      -FDT_ERR_BADSTATE,
969 *      -FDT_ERR_BADSTRUCTURE, standard meanings
970 */
971int fdt_node_offset_by_phandle(const void *fdt, uint32_t phandle);
972
973/**
974 * fdt_node_check_compatible: check a node's compatible property
975 * @fdt: pointer to the device tree blob
976 * @nodeoffset: offset of a tree node
977 * @compatible: string to match against
978 *
979 *
980 * fdt_node_check_compatible() returns 0 if the given node contains a
981 * 'compatible' property with the given string as one of its elements,
982 * it returns non-zero otherwise, or on error.
983 *
984 * returns:
985 *      0, if the node has a 'compatible' property listing the given string
986 *      1, if the node has a 'compatible' property, but it does not list
987 *              the given string
988 *      -FDT_ERR_NOTFOUND, if the given node has no 'compatible' property
989 *      -FDT_ERR_BADOFFSET, if nodeoffset does not refer to a BEGIN_NODE tag
990 *      -FDT_ERR_BADMAGIC,
991 *      -FDT_ERR_BADVERSION,
992 *      -FDT_ERR_BADSTATE,
993 *      -FDT_ERR_BADSTRUCTURE, standard meanings
994 */
995int fdt_node_check_compatible(const void *fdt, int nodeoffset,
996                              const char *compatible);
997
998/**
999 * fdt_node_offset_by_compatible - find nodes with a given 'compatible' value
1000 * @fdt: pointer to the device tree blob
1001 * @startoffset: only find nodes after this offset
1002 * @compatible: 'compatible' string to match against
1003 *
1004 * fdt_node_offset_by_compatible() returns the offset of the first
1005 * node after startoffset, which has a 'compatible' property which
1006 * lists the given compatible string; or if startoffset is -1, the
1007 * very first such node in the tree.
1008 *
1009 * To iterate through all nodes matching the criterion, the following
1010 * idiom can be used:
1011 *      offset = fdt_node_offset_by_compatible(fdt, -1, compatible);
1012 *      while (offset != -FDT_ERR_NOTFOUND) {
1013 *              // other code here
1014 *              offset = fdt_node_offset_by_compatible(fdt, offset, compatible);
1015 *      }
1016 *
1017 * Note the -1 in the first call to the function, if 0 is used here
1018 * instead, the function will never locate the root node, even if it
1019 * matches the criterion.
1020 *
1021 * returns:
1022 *      structure block offset of the located node (>= 0, >startoffset),
1023 *               on success
1024 *      -FDT_ERR_NOTFOUND, no node matching the criterion exists in the
1025 *              tree after startoffset
1026 *      -FDT_ERR_BADOFFSET, nodeoffset does not refer to a BEGIN_NODE tag
1027 *      -FDT_ERR_BADMAGIC,
1028 *      -FDT_ERR_BADVERSION,
1029 *      -FDT_ERR_BADSTATE,
1030 *      -FDT_ERR_BADSTRUCTURE, standard meanings
1031 */
1032int fdt_node_offset_by_compatible(const void *fdt, int startoffset,
1033                                  const char *compatible);
1034
1035/**
1036 * fdt_stringlist_contains - check a string list property for a string
1037 * @strlist: Property containing a list of strings to check
1038 * @listlen: Length of property
1039 * @str: String to search for
1040 *
1041 * This is a utility function provided for convenience. The list contains
1042 * one or more strings, each terminated by \0, as is found in a device tree
1043 * "compatible" property.
1044 *
1045 * @return: 1 if the string is found in the list, 0 not found, or invalid list
1046 */
1047int fdt_stringlist_contains(const char *strlist, int listlen, const char *str);
1048
1049/**
1050 * fdt_stringlist_count - count the number of strings in a string list
1051 * @fdt: pointer to the device tree blob
1052 * @nodeoffset: offset of a tree node
1053 * @property: name of the property containing the string list
1054 * @return:
1055 *   the number of strings in the given property
1056 *   -FDT_ERR_BADVALUE if the property value is not NUL-terminated
1057 *   -FDT_ERR_NOTFOUND if the property does not exist
1058 */
1059int fdt_stringlist_count(const void *fdt, int nodeoffset, const char *property);
1060
1061/**
1062 * fdt_stringlist_search - find a string in a string list and return its index
1063 * @fdt: pointer to the device tree blob
1064 * @nodeoffset: offset of a tree node
1065 * @property: name of the property containing the string list
1066 * @string: string to look up in the string list
1067 *
1068 * Note that it is possible for this function to succeed on property values
1069 * that are not NUL-terminated. That's because the function will stop after
1070 * finding the first occurrence of @string. This can for example happen with
1071 * small-valued cell properties, such as #address-cells, when searching for
1072 * the empty string.
1073 *
1074 * @return:
1075 *   the index of the string in the list of strings
1076 *   -FDT_ERR_BADVALUE if the property value is not NUL-terminated
1077 *   -FDT_ERR_NOTFOUND if the property does not exist or does not contain
1078 *                     the given string
1079 */
1080int fdt_stringlist_search(const void *fdt, int nodeoffset, const char *property,
1081                          const char *string);
1082
1083/**
1084 * fdt_stringlist_get() - obtain the string at a given index in a string list
1085 * @fdt: pointer to the device tree blob
1086 * @nodeoffset: offset of a tree node
1087 * @property: name of the property containing the string list
1088 * @index: index of the string to return
1089 * @lenp: return location for the string length or an error code on failure
1090 *
1091 * Note that this will successfully extract strings from properties with
1092 * non-NUL-terminated values. For example on small-valued cell properties
1093 * this function will return the empty string.
1094 *
1095 * If non-NULL, the length of the string (on success) or a negative error-code
1096 * (on failure) will be stored in the integer pointer to by lenp.
1097 *
1098 * @return:
1099 *   A pointer to the string at the given index in the string list or NULL on
1100 *   failure. On success the length of the string will be stored in the memory
1101 *   location pointed to by the lenp parameter, if non-NULL. On failure one of
1102 *   the following negative error codes will be returned in the lenp parameter
1103 *   (if non-NULL):
1104 *     -FDT_ERR_BADVALUE if the property value is not NUL-terminated
1105 *     -FDT_ERR_NOTFOUND if the property does not exist
1106 */
1107const char *fdt_stringlist_get(const void *fdt, int nodeoffset,
1108                               const char *property, int index,
1109                               int *lenp);
1110
1111/**********************************************************************/
1112/* Read-only functions (addressing related)                           */
1113/**********************************************************************/
1114
1115/**
1116 * FDT_MAX_NCELLS - maximum value for #address-cells and #size-cells
1117 *
1118 * This is the maximum value for #address-cells, #size-cells and
1119 * similar properties that will be processed by libfdt.  IEE1275
1120 * requires that OF implementations handle values up to 4.
1121 * Implementations may support larger values, but in practice higher
1122 * values aren't used.
1123 */
1124#define FDT_MAX_NCELLS          4
1125
1126/**
1127 * fdt_address_cells - retrieve address size for a bus represented in the tree
1128 * @fdt: pointer to the device tree blob
1129 * @nodeoffset: offset of the node to find the address size for
1130 *
1131 * When the node has a valid #address-cells property, returns its value.
1132 *
1133 * returns:
1134 *      0 <= n < FDT_MAX_NCELLS, on success
1135 *      2, if the node has no #address-cells property
1136 *      -FDT_ERR_BADNCELLS, if the node has a badly formatted or invalid
1137 *              #address-cells property
1138 *      -FDT_ERR_BADMAGIC,
1139 *      -FDT_ERR_BADVERSION,
1140 *      -FDT_ERR_BADSTATE,
1141 *      -FDT_ERR_BADSTRUCTURE,
1142 *      -FDT_ERR_TRUNCATED, standard meanings
1143 */
1144int fdt_address_cells(const void *fdt, int nodeoffset);
1145
1146/**
1147 * fdt_size_cells - retrieve address range size for a bus represented in the
1148 *                  tree
1149 * @fdt: pointer to the device tree blob
1150 * @nodeoffset: offset of the node to find the address range size for
1151 *
1152 * When the node has a valid #size-cells property, returns its value.
1153 *
1154 * returns:
1155 *      0 <= n < FDT_MAX_NCELLS, on success
1156 *      1, if the node has no #size-cells property
1157 *      -FDT_ERR_BADNCELLS, if the node has a badly formatted or invalid
1158 *              #size-cells property
1159 *      -FDT_ERR_BADMAGIC,
1160 *      -FDT_ERR_BADVERSION,
1161 *      -FDT_ERR_BADSTATE,
1162 *      -FDT_ERR_BADSTRUCTURE,
1163 *      -FDT_ERR_TRUNCATED, standard meanings
1164 */
1165int fdt_size_cells(const void *fdt, int nodeoffset);
1166
1167
1168/**********************************************************************/
1169/* Write-in-place functions                                           */
1170/**********************************************************************/
1171
1172/**
1173 * fdt_setprop_inplace_namelen_partial - change a property's value,
1174 *                                       but not its size
1175 * @fdt: pointer to the device tree blob
1176 * @nodeoffset: offset of the node whose property to change
1177 * @name: name of the property to change
1178 * @namelen: number of characters of name to consider
1179 * @idx: index of the property to change in the array
1180 * @val: pointer to data to replace the property value with
1181 * @len: length of the property value
1182 *
1183 * Identical to fdt_setprop_inplace(), but modifies the given property
1184 * starting from the given index, and using only the first characters
1185 * of the name. It is useful when you want to manipulate only one value of
1186 * an array and you have a string that doesn't end with \0.
1187 */
1188#ifndef SWIG /* Not available in Python */
1189int fdt_setprop_inplace_namelen_partial(void *fdt, int nodeoffset,
1190                                        const char *name, int namelen,
1191                                        uint32_t idx, const void *val,
1192                                        int len);
1193#endif
1194
1195/**
1196 * fdt_setprop_inplace - change a property's value, but not its size
1197 * @fdt: pointer to the device tree blob
1198 * @nodeoffset: offset of the node whose property to change
1199 * @name: name of the property to change
1200 * @val: pointer to data to replace the property value with
1201 * @len: length of the property value
1202 *
1203 * fdt_setprop_inplace() replaces the value of a given property with
1204 * the data in val, of length len.  This function cannot change the
1205 * size of a property, and so will only work if len is equal to the
1206 * current length of the property.
1207 *
1208 * This function will alter only the bytes in the blob which contain
1209 * the given property value, and will not alter or move any other part
1210 * of the tree.
1211 *
1212 * returns:
1213 *      0, on success
1214 *      -FDT_ERR_NOSPACE, if len is not equal to the property's current length
1215 *      -FDT_ERR_NOTFOUND, node does not have the named property
1216 *      -FDT_ERR_BADOFFSET, nodeoffset did not point to FDT_BEGIN_NODE tag
1217 *      -FDT_ERR_BADMAGIC,
1218 *      -FDT_ERR_BADVERSION,
1219 *      -FDT_ERR_BADSTATE,
1220 *      -FDT_ERR_BADSTRUCTURE,
1221 *      -FDT_ERR_TRUNCATED, standard meanings
1222 */
1223#ifndef SWIG /* Not available in Python */
1224int fdt_setprop_inplace(void *fdt, int nodeoffset, const char *name,
1225                        const void *val, int len);
1226#endif
1227
1228/**
1229 * fdt_setprop_inplace_u32 - change the value of a 32-bit integer property
1230 * @fdt: pointer to the device tree blob
1231 * @nodeoffset: offset of the node whose property to change
1232 * @name: name of the property to change
1233 * @val: 32-bit integer value to replace the property with
1234 *
1235 * fdt_setprop_inplace_u32() replaces the value of a given property
1236 * with the 32-bit integer value in val, converting val to big-endian
1237 * if necessary.  This function cannot change the size of a property,
1238 * and so will only work if the property already exists and has length
1239 * 4.
1240 *
1241 * This function will alter only the bytes in the blob which contain
1242 * the given property value, and will not alter or move any other part
1243 * of the tree.
1244 *
1245 * returns:
1246 *      0, on success
1247 *      -FDT_ERR_NOSPACE, if the property's length is not equal to 4
1248 *      -FDT_ERR_NOTFOUND, node does not have the named property
1249 *      -FDT_ERR_BADOFFSET, nodeoffset did not point to FDT_BEGIN_NODE tag
1250 *      -FDT_ERR_BADMAGIC,
1251 *      -FDT_ERR_BADVERSION,
1252 *      -FDT_ERR_BADSTATE,
1253 *      -FDT_ERR_BADSTRUCTURE,
1254 *      -FDT_ERR_TRUNCATED, standard meanings
1255 */
1256static inline int fdt_setprop_inplace_u32(void *fdt, int nodeoffset,
1257                                          const char *name, uint32_t val)
1258{
1259        fdt32_t tmp = cpu_to_fdt32(val);
1260        return fdt_setprop_inplace(fdt, nodeoffset, name, &tmp, sizeof(tmp));
1261}
1262
1263/**
1264 * fdt_setprop_inplace_u64 - change the value of a 64-bit integer property
1265 * @fdt: pointer to the device tree blob
1266 * @nodeoffset: offset of the node whose property to change
1267 * @name: name of the property to change
1268 * @val: 64-bit integer value to replace the property with
1269 *
1270 * fdt_setprop_inplace_u64() replaces the value of a given property
1271 * with the 64-bit integer value in val, converting val to big-endian
1272 * if necessary.  This function cannot change the size of a property,
1273 * and so will only work if the property already exists and has length
1274 * 8.
1275 *
1276 * This function will alter only the bytes in the blob which contain
1277 * the given property value, and will not alter or move any other part
1278 * of the tree.
1279 *
1280 * returns:
1281 *      0, on success
1282 *      -FDT_ERR_NOSPACE, if the property's length is not equal to 8
1283 *      -FDT_ERR_NOTFOUND, node does not have the named property
1284 *      -FDT_ERR_BADOFFSET, nodeoffset did not point to FDT_BEGIN_NODE tag
1285 *      -FDT_ERR_BADMAGIC,
1286 *      -FDT_ERR_BADVERSION,
1287 *      -FDT_ERR_BADSTATE,
1288 *      -FDT_ERR_BADSTRUCTURE,
1289 *      -FDT_ERR_TRUNCATED, standard meanings
1290 */
1291static inline int fdt_setprop_inplace_u64(void *fdt, int nodeoffset,
1292                                          const char *name, uint64_t val)
1293{
1294        fdt64_t tmp = cpu_to_fdt64(val);
1295        return fdt_setprop_inplace(fdt, nodeoffset, name, &tmp, sizeof(tmp));
1296}
1297
1298/**
1299 * fdt_setprop_inplace_cell - change the value of a single-cell property
1300 *
1301 * This is an alternative name for fdt_setprop_inplace_u32()
1302 */
1303static inline int fdt_setprop_inplace_cell(void *fdt, int nodeoffset,
1304                                           const char *name, uint32_t val)
1305{
1306        return fdt_setprop_inplace_u32(fdt, nodeoffset, name, val);
1307}
1308
1309/**
1310 * fdt_nop_property - replace a property with nop tags
1311 * @fdt: pointer to the device tree blob
1312 * @nodeoffset: offset of the node whose property to nop
1313 * @name: name of the property to nop
1314 *
1315 * fdt_nop_property() will replace a given property's representation
1316 * in the blob with FDT_NOP tags, effectively removing it from the
1317 * tree.
1318 *
1319 * This function will alter only the bytes in the blob which contain
1320 * the property, and will not alter or move any other part of the
1321 * tree.
1322 *
1323 * returns:
1324 *      0, on success
1325 *      -FDT_ERR_NOTFOUND, node does not have the named property
1326 *      -FDT_ERR_BADOFFSET, nodeoffset did not point to FDT_BEGIN_NODE tag
1327 *      -FDT_ERR_BADMAGIC,
1328 *      -FDT_ERR_BADVERSION,
1329 *      -FDT_ERR_BADSTATE,
1330 *      -FDT_ERR_BADSTRUCTURE,
1331 *      -FDT_ERR_TRUNCATED, standard meanings
1332 */
1333int fdt_nop_property(void *fdt, int nodeoffset, const char *name);
1334
1335/**
1336 * fdt_nop_node - replace a node (subtree) with nop tags
1337 * @fdt: pointer to the device tree blob
1338 * @nodeoffset: offset of the node to nop
1339 *
1340 * fdt_nop_node() will replace a given node's representation in the
1341 * blob, including all its subnodes, if any, with FDT_NOP tags,
1342 * effectively removing it from the tree.
1343 *
1344 * This function will alter only the bytes in the blob which contain
1345 * the node and its properties and subnodes, and will not alter or
1346 * move any other part of the tree.
1347 *
1348 * returns:
1349 *      0, on success
1350 *      -FDT_ERR_BADOFFSET, nodeoffset did not point to FDT_BEGIN_NODE tag
1351 *      -FDT_ERR_BADMAGIC,
1352 *      -FDT_ERR_BADVERSION,
1353 *      -FDT_ERR_BADSTATE,
1354 *      -FDT_ERR_BADSTRUCTURE,
1355 *      -FDT_ERR_TRUNCATED, standard meanings
1356 */
1357int fdt_nop_node(void *fdt, int nodeoffset);
1358
1359/**********************************************************************/
1360/* Sequential write functions                                         */
1361/**********************************************************************/
1362
1363int fdt_create(void *buf, int bufsize);
1364int fdt_resize(void *fdt, void *buf, int bufsize);
1365int fdt_add_reservemap_entry(void *fdt, uint64_t addr, uint64_t size);
1366int fdt_finish_reservemap(void *fdt);
1367int fdt_begin_node(void *fdt, const char *name);
1368int fdt_property(void *fdt, const char *name, const void *val, int len);
1369static inline int fdt_property_u32(void *fdt, const char *name, uint32_t val)
1370{
1371        fdt32_t tmp = cpu_to_fdt32(val);
1372        return fdt_property(fdt, name, &tmp, sizeof(tmp));
1373}
1374static inline int fdt_property_u64(void *fdt, const char *name, uint64_t val)
1375{
1376        fdt64_t tmp = cpu_to_fdt64(val);
1377        return fdt_property(fdt, name, &tmp, sizeof(tmp));
1378}
1379
1380#ifndef SWIG /* Not available in Python */
1381static inline int fdt_property_cell(void *fdt, const char *name, uint32_t val)
1382{
1383        return fdt_property_u32(fdt, name, val);
1384}
1385#endif
1386
1387/**
1388 * fdt_property_placeholder - add a new property and return a ptr to its value
1389 *
1390 * @fdt: pointer to the device tree blob
1391 * @name: name of property to add
1392 * @len: length of property value in bytes
1393 * @valp: returns a pointer to where where the value should be placed
1394 *
1395 * returns:
1396 *      0, on success
1397 *      -FDT_ERR_BADMAGIC,
1398 *      -FDT_ERR_NOSPACE, standard meanings
1399 */
1400int fdt_property_placeholder(void *fdt, const char *name, int len, void **valp);
1401
1402#define fdt_property_string(fdt, name, str) \
1403        fdt_property(fdt, name, str, strlen(str)+1)
1404int fdt_end_node(void *fdt);
1405int fdt_finish(void *fdt);
1406
1407/**********************************************************************/
1408/* Read-write functions                                               */
1409/**********************************************************************/
1410
1411int fdt_create_empty_tree(void *buf, int bufsize);
1412int fdt_open_into(const void *fdt, void *buf, int bufsize);
1413int fdt_pack(void *fdt);
1414
1415/**
1416 * fdt_add_mem_rsv - add one memory reserve map entry
1417 * @fdt: pointer to the device tree blob
1418 * @address, @size: 64-bit values (native endian)
1419 *
1420 * Adds a reserve map entry to the given blob reserving a region at
1421 * address address of length size.
1422 *
1423 * This function will insert data into the reserve map and will
1424 * therefore change the indexes of some entries in the table.
1425 *
1426 * returns:
1427 *      0, on success
1428 *      -FDT_ERR_NOSPACE, there is insufficient free space in the blob to
1429 *              contain the new reservation entry
1430 *      -FDT_ERR_BADMAGIC,
1431 *      -FDT_ERR_BADVERSION,
1432 *      -FDT_ERR_BADSTATE,
1433 *      -FDT_ERR_BADSTRUCTURE,
1434 *      -FDT_ERR_BADLAYOUT,
1435 *      -FDT_ERR_TRUNCATED, standard meanings
1436 */
1437int fdt_add_mem_rsv(void *fdt, uint64_t address, uint64_t size);
1438
1439/**
1440 * fdt_del_mem_rsv - remove a memory reserve map entry
1441 * @fdt: pointer to the device tree blob
1442 * @n: entry to remove
1443 *
1444 * fdt_del_mem_rsv() removes the n-th memory reserve map entry from
1445 * the blob.
1446 *
1447 * This function will delete data from the reservation table and will
1448 * therefore change the indexes of some entries in the table.
1449 *
1450 * returns:
1451 *      0, on success
1452 *      -FDT_ERR_NOTFOUND, there is no entry of the given index (i.e. there
1453 *              are less than n+1 reserve map entries)
1454 *      -FDT_ERR_BADMAGIC,
1455 *      -FDT_ERR_BADVERSION,
1456 *      -FDT_ERR_BADSTATE,
1457 *      -FDT_ERR_BADSTRUCTURE,
1458 *      -FDT_ERR_BADLAYOUT,
1459 *      -FDT_ERR_TRUNCATED, standard meanings
1460 */
1461int fdt_del_mem_rsv(void *fdt, int n);
1462
1463/**
1464 * fdt_set_name - change the name of a given node
1465 * @fdt: pointer to the device tree blob
1466 * @nodeoffset: structure block offset of a node
1467 * @name: name to give the node
1468 *
1469 * fdt_set_name() replaces the name (including unit address, if any)
1470 * of the given node with the given string.  NOTE: this function can't
1471 * efficiently check if the new name is unique amongst the given
1472 * node's siblings; results are undefined if this function is invoked
1473 * with a name equal to one of the given node's siblings.
1474 *
1475 * This function may insert or delete data from the blob, and will
1476 * therefore change the offsets of some existing nodes.
1477 *
1478 * returns:
1479 *      0, on success
1480 *      -FDT_ERR_NOSPACE, there is insufficient free space in the blob
1481 *              to contain the new name
1482 *      -FDT_ERR_BADOFFSET, nodeoffset did not point to FDT_BEGIN_NODE tag
1483 *      -FDT_ERR_BADMAGIC,
1484 *      -FDT_ERR_BADVERSION,
1485 *      -FDT_ERR_BADSTATE, standard meanings
1486 */
1487int fdt_set_name(void *fdt, int nodeoffset, const char *name);
1488
1489/**
1490 * fdt_setprop - create or change a property
1491 * @fdt: pointer to the device tree blob
1492 * @nodeoffset: offset of the node whose property to change
1493 * @name: name of the property to change
1494 * @val: pointer to data to set the property value to
1495 * @len: length of the property value
1496 *
1497 * fdt_setprop() sets the value of the named property in the given
1498 * node to the given value and length, creating the property if it
1499 * does not already exist.
1500 *
1501 * This function may insert or delete data from the blob, and will
1502 * therefore change the offsets of some existing nodes.
1503 *
1504 * returns:
1505 *      0, on success
1506 *      -FDT_ERR_NOSPACE, there is insufficient free space in the blob to
1507 *              contain the new property value
1508 *      -FDT_ERR_BADOFFSET, nodeoffset did not point to FDT_BEGIN_NODE tag
1509 *      -FDT_ERR_BADLAYOUT,
1510 *      -FDT_ERR_BADMAGIC,
1511 *      -FDT_ERR_BADVERSION,
1512 *      -FDT_ERR_BADSTATE,
1513 *      -FDT_ERR_BADSTRUCTURE,
1514 *      -FDT_ERR_BADLAYOUT,
1515 *      -FDT_ERR_TRUNCATED, standard meanings
1516 */
1517int fdt_setprop(void *fdt, int nodeoffset, const char *name,
1518                const void *val, int len);
1519
1520/**
1521 * fdt_setprop_placeholder - allocate space for a property
1522 * @fdt: pointer to the device tree blob
1523 * @nodeoffset: offset of the node whose property to change
1524 * @name: name of the property to change
1525 * @len: length of the property value
1526 * @prop_data: return pointer to property data
1527 *
1528 * fdt_setprop_placeholer() allocates the named property in the given node.
1529 * If the property exists it is resized. In either case a pointer to the
1530 * property data is returned.
1531 *
1532 * This function may insert or delete data from the blob, and will
1533 * therefore change the offsets of some existing nodes.
1534 *
1535 * returns:
1536 *      0, on success
1537 *      -FDT_ERR_NOSPACE, there is insufficient free space in the blob to
1538 *              contain the new property value
1539 *      -FDT_ERR_BADOFFSET, nodeoffset did not point to FDT_BEGIN_NODE tag
1540 *      -FDT_ERR_BADLAYOUT,
1541 *      -FDT_ERR_BADMAGIC,
1542 *      -FDT_ERR_BADVERSION,
1543 *      -FDT_ERR_BADSTATE,
1544 *      -FDT_ERR_BADSTRUCTURE,
1545 *      -FDT_ERR_BADLAYOUT,
1546 *      -FDT_ERR_TRUNCATED, standard meanings
1547 */
1548int fdt_setprop_placeholder(void *fdt, int nodeoffset, const char *name,
1549                            int len, void **prop_data);
1550
1551/**
1552 * fdt_setprop_u32 - set a property to a 32-bit integer
1553 * @fdt: pointer to the device tree blob
1554 * @nodeoffset: offset of the node whose property to change
1555 * @name: name of the property to change
1556 * @val: 32-bit integer value for the property (native endian)
1557 *
1558 * fdt_setprop_u32() sets the value of the named property in the given
1559 * node to the given 32-bit integer value (converting to big-endian if
1560 * necessary), or creates a new property with that value if it does
1561 * not already exist.
1562 *
1563 * This function may insert or delete data from the blob, and will
1564 * therefore change the offsets of some existing nodes.
1565 *
1566 * returns:
1567 *      0, on success
1568 *      -FDT_ERR_NOSPACE, there is insufficient free space in the blob to
1569 *              contain the new property value
1570 *      -FDT_ERR_BADOFFSET, nodeoffset did not point to FDT_BEGIN_NODE tag
1571 *      -FDT_ERR_BADLAYOUT,
1572 *      -FDT_ERR_BADMAGIC,
1573 *      -FDT_ERR_BADVERSION,
1574 *      -FDT_ERR_BADSTATE,
1575 *      -FDT_ERR_BADSTRUCTURE,
1576 *      -FDT_ERR_BADLAYOUT,
1577 *      -FDT_ERR_TRUNCATED, standard meanings
1578 */
1579static inline int fdt_setprop_u32(void *fdt, int nodeoffset, const char *name,
1580                                  uint32_t val)
1581{
1582        fdt32_t tmp = cpu_to_fdt32(val);
1583        return fdt_setprop(fdt, nodeoffset, name, &tmp, sizeof(tmp));
1584}
1585
1586/**
1587 * fdt_setprop_u64 - set a property to a 64-bit integer
1588 * @fdt: pointer to the device tree blob
1589 * @nodeoffset: offset of the node whose property to change
1590 * @name: name of the property to change
1591 * @val: 64-bit integer value for the property (native endian)
1592 *
1593 * fdt_setprop_u64() sets the value of the named property in the given
1594 * node to the given 64-bit integer value (converting to big-endian if
1595 * necessary), or creates a new property with that value if it does
1596 * not already exist.
1597 *
1598 * This function may insert or delete data from the blob, and will
1599 * therefore change the offsets of some existing nodes.
1600 *
1601 * returns:
1602 *      0, on success
1603 *      -FDT_ERR_NOSPACE, there is insufficient free space in the blob to
1604 *              contain the new property value
1605 *      -FDT_ERR_BADOFFSET, nodeoffset did not point to FDT_BEGIN_NODE tag
1606 *      -FDT_ERR_BADLAYOUT,
1607 *      -FDT_ERR_BADMAGIC,
1608 *      -FDT_ERR_BADVERSION,
1609 *      -FDT_ERR_BADSTATE,
1610 *      -FDT_ERR_BADSTRUCTURE,
1611 *      -FDT_ERR_BADLAYOUT,
1612 *      -FDT_ERR_TRUNCATED, standard meanings
1613 */
1614static inline int fdt_setprop_u64(void *fdt, int nodeoffset, const char *name,
1615                                  uint64_t val)
1616{
1617        fdt64_t tmp = cpu_to_fdt64(val);
1618        return fdt_setprop(fdt, nodeoffset, name, &tmp, sizeof(tmp));
1619}
1620
1621/**
1622 * fdt_setprop_cell - set a property to a single cell value
1623 *
1624 * This is an alternative name for fdt_setprop_u32()
1625 */
1626static inline int fdt_setprop_cell(void *fdt, int nodeoffset, const char *name,
1627                                   uint32_t val)
1628{
1629        return fdt_setprop_u32(fdt, nodeoffset, name, val);
1630}
1631
1632/**
1633 * fdt_setprop_string - set a property to a string value
1634 * @fdt: pointer to the device tree blob
1635 * @nodeoffset: offset of the node whose property to change
1636 * @name: name of the property to change
1637 * @str: string value for the property
1638 *
1639 * fdt_setprop_string() sets the value of the named property in the
1640 * given node to the given string value (using the length of the
1641 * string to determine the new length of the property), or creates a
1642 * new property with that value if it does not already exist.
1643 *
1644 * This function may insert or delete data from the blob, and will
1645 * therefore change the offsets of some existing nodes.
1646 *
1647 * returns:
1648 *      0, on success
1649 *      -FDT_ERR_NOSPACE, there is insufficient free space in the blob to
1650 *              contain the new property value
1651 *      -FDT_ERR_BADOFFSET, nodeoffset did not point to FDT_BEGIN_NODE tag
1652 *      -FDT_ERR_BADLAYOUT,
1653 *      -FDT_ERR_BADMAGIC,
1654 *      -FDT_ERR_BADVERSION,
1655 *      -FDT_ERR_BADSTATE,
1656 *      -FDT_ERR_BADSTRUCTURE,
1657 *      -FDT_ERR_BADLAYOUT,
1658 *      -FDT_ERR_TRUNCATED, standard meanings
1659 */
1660#define fdt_setprop_string(fdt, nodeoffset, name, str) \
1661        fdt_setprop((fdt), (nodeoffset), (name), (str), strlen(str)+1)
1662
1663
1664/**
1665 * fdt_setprop_empty - set a property to an empty value
1666 * @fdt: pointer to the device tree blob
1667 * @nodeoffset: offset of the node whose property to change
1668 * @name: name of the property to change
1669 *
1670 * fdt_setprop_empty() sets the value of the named property in the
1671 * given node to an empty (zero length) value, or creates a new empty
1672 * property if it does not already exist.
1673 *
1674 * This function may insert or delete data from the blob, and will
1675 * therefore change the offsets of some existing nodes.
1676 *
1677 * returns:
1678 *      0, on success
1679 *      -FDT_ERR_NOSPACE, there is insufficient free space in the blob to
1680 *              contain the new property value
1681 *      -FDT_ERR_BADOFFSET, nodeoffset did not point to FDT_BEGIN_NODE tag
1682 *      -FDT_ERR_BADLAYOUT,
1683 *      -FDT_ERR_BADMAGIC,
1684 *      -FDT_ERR_BADVERSION,
1685 *      -FDT_ERR_BADSTATE,
1686 *      -FDT_ERR_BADSTRUCTURE,
1687 *      -FDT_ERR_BADLAYOUT,
1688 *      -FDT_ERR_TRUNCATED, standard meanings
1689 */
1690#define fdt_setprop_empty(fdt, nodeoffset, name) \
1691        fdt_setprop((fdt), (nodeoffset), (name), NULL, 0)
1692
1693/**
1694 * fdt_appendprop - append to or create a property
1695 * @fdt: pointer to the device tree blob
1696 * @nodeoffset: offset of the node whose property to change
1697 * @name: name of the property to append to
1698 * @val: pointer to data to append to the property value
1699 * @len: length of the data to append to the property value
1700 *
1701 * fdt_appendprop() appends the value to the named property in the
1702 * given node, creating the property if it does not already exist.
1703 *
1704 * This function may insert data into the blob, and will therefore
1705 * change the offsets of some existing nodes.
1706 *
1707 * returns:
1708 *      0, on success
1709 *      -FDT_ERR_NOSPACE, there is insufficient free space in the blob to
1710 *              contain the new property value
1711 *      -FDT_ERR_BADOFFSET, nodeoffset did not point to FDT_BEGIN_NODE tag
1712 *      -FDT_ERR_BADLAYOUT,
1713 *      -FDT_ERR_BADMAGIC,
1714 *      -FDT_ERR_BADVERSION,
1715 *      -FDT_ERR_BADSTATE,
1716 *      -FDT_ERR_BADSTRUCTURE,
1717 *      -FDT_ERR_BADLAYOUT,
1718 *      -FDT_ERR_TRUNCATED, standard meanings
1719 */
1720int fdt_appendprop(void *fdt, int nodeoffset, const char *name,
1721                   const void *val, int len);
1722
1723/**
1724 * fdt_appendprop_u32 - append a 32-bit integer value to a property
1725 * @fdt: pointer to the device tree blob
1726 * @nodeoffset: offset of the node whose property to change
1727 * @name: name of the property to change
1728 * @val: 32-bit integer value to append to the property (native endian)
1729 *
1730 * fdt_appendprop_u32() appends the given 32-bit integer value
1731 * (converting to big-endian if necessary) to the value of the named
1732 * property in the given node, or creates a new property with that
1733 * value if it does not already exist.
1734 *
1735 * This function may insert data into the blob, and will therefore
1736 * change the offsets of some existing nodes.
1737 *
1738 * returns:
1739 *      0, on success
1740 *      -FDT_ERR_NOSPACE, there is insufficient free space in the blob to
1741 *              contain the new property value
1742 *      -FDT_ERR_BADOFFSET, nodeoffset did not point to FDT_BEGIN_NODE tag
1743 *      -FDT_ERR_BADLAYOUT,
1744 *      -FDT_ERR_BADMAGIC,
1745 *      -FDT_ERR_BADVERSION,
1746 *      -FDT_ERR_BADSTATE,
1747 *      -FDT_ERR_BADSTRUCTURE,
1748 *      -FDT_ERR_BADLAYOUT,
1749 *      -FDT_ERR_TRUNCATED, standard meanings
1750 */
1751static inline int fdt_appendprop_u32(void *fdt, int nodeoffset,
1752                                     const char *name, uint32_t val)
1753{
1754        fdt32_t tmp = cpu_to_fdt32(val);
1755        return fdt_appendprop(fdt, nodeoffset, name, &tmp, sizeof(tmp));
1756}
1757
1758/**
1759 * fdt_appendprop_u64 - append a 64-bit integer value to a property
1760 * @fdt: pointer to the device tree blob
1761 * @nodeoffset: offset of the node whose property to change
1762 * @name: name of the property to change
1763 * @val: 64-bit integer value to append to the property (native endian)
1764 *
1765 * fdt_appendprop_u64() appends the given 64-bit integer value
1766 * (converting to big-endian if necessary) to the value of the named
1767 * property in the given node, or creates a new property with that
1768 * value if it does not already exist.
1769 *
1770 * This function may insert data into the blob, and will therefore
1771 * change the offsets of some existing nodes.
1772 *
1773 * returns:
1774 *      0, on success
1775 *      -FDT_ERR_NOSPACE, there is insufficient free space in the blob to
1776 *              contain the new property value
1777 *      -FDT_ERR_BADOFFSET, nodeoffset did not point to FDT_BEGIN_NODE tag
1778 *      -FDT_ERR_BADLAYOUT,
1779 *      -FDT_ERR_BADMAGIC,
1780 *      -FDT_ERR_BADVERSION,
1781 *      -FDT_ERR_BADSTATE,
1782 *      -FDT_ERR_BADSTRUCTURE,
1783 *      -FDT_ERR_BADLAYOUT,
1784 *      -FDT_ERR_TRUNCATED, standard meanings
1785 */
1786static inline int fdt_appendprop_u64(void *fdt, int nodeoffset,
1787                                     const char *name, uint64_t val)
1788{
1789        fdt64_t tmp = cpu_to_fdt64(val);
1790        return fdt_appendprop(fdt, nodeoffset, name, &tmp, sizeof(tmp));
1791}
1792
1793/**
1794 * fdt_appendprop_cell - append a single cell value to a property
1795 *
1796 * This is an alternative name for fdt_appendprop_u32()
1797 */
1798static inline int fdt_appendprop_cell(void *fdt, int nodeoffset,
1799                                      const char *name, uint32_t val)
1800{
1801        return fdt_appendprop_u32(fdt, nodeoffset, name, val);
1802}
1803
1804/**
1805 * fdt_appendprop_string - append a string to a property
1806 * @fdt: pointer to the device tree blob
1807 * @nodeoffset: offset of the node whose property to change
1808 * @name: name of the property to change
1809 * @str: string value to append to the property
1810 *
1811 * fdt_appendprop_string() appends the given string to the value of
1812 * the named property in the given node, or creates a new property
1813 * with that value if it does not already exist.
1814 *
1815 * This function may insert data into the blob, and will therefore
1816 * change the offsets of some existing nodes.
1817 *
1818 * returns:
1819 *      0, on success
1820 *      -FDT_ERR_NOSPACE, there is insufficient free space in the blob to
1821 *              contain the new property value
1822 *      -FDT_ERR_BADOFFSET, nodeoffset did not point to FDT_BEGIN_NODE tag
1823 *      -FDT_ERR_BADLAYOUT,
1824 *      -FDT_ERR_BADMAGIC,
1825 *      -FDT_ERR_BADVERSION,
1826 *      -FDT_ERR_BADSTATE,
1827 *      -FDT_ERR_BADSTRUCTURE,
1828 *      -FDT_ERR_BADLAYOUT,
1829 *      -FDT_ERR_TRUNCATED, standard meanings
1830 */
1831#define fdt_appendprop_string(fdt, nodeoffset, name, str) \
1832        fdt_appendprop((fdt), (nodeoffset), (name), (str), strlen(str)+1)
1833
1834/**
1835 * fdt_delprop - delete a property
1836 * @fdt: pointer to the device tree blob
1837 * @nodeoffset: offset of the node whose property to nop
1838 * @name: name of the property to nop
1839 *
1840 * fdt_del_property() will delete the given property.
1841 *
1842 * This function will delete data from the blob, and will therefore
1843 * change the offsets of some existing nodes.
1844 *
1845 * returns:
1846 *      0, on success
1847 *      -FDT_ERR_NOTFOUND, node does not have the named property
1848 *      -FDT_ERR_BADOFFSET, nodeoffset did not point to FDT_BEGIN_NODE tag
1849 *      -FDT_ERR_BADLAYOUT,
1850 *      -FDT_ERR_BADMAGIC,
1851 *      -FDT_ERR_BADVERSION,
1852 *      -FDT_ERR_BADSTATE,
1853 *      -FDT_ERR_BADSTRUCTURE,
1854 *      -FDT_ERR_TRUNCATED, standard meanings
1855 */
1856int fdt_delprop(void *fdt, int nodeoffset, const char *name);
1857
1858/**
1859 * fdt_add_subnode_namelen - creates a new node based on substring
1860 * @fdt: pointer to the device tree blob
1861 * @parentoffset: structure block offset of a node
1862 * @name: name of the subnode to locate
1863 * @namelen: number of characters of name to consider
1864 *
1865 * Identical to fdt_add_subnode(), but use only the first namelen
1866 * characters of name as the name of the new node.  This is useful for
1867 * creating subnodes based on a portion of a larger string, such as a
1868 * full path.
1869 */
1870#ifndef SWIG /* Not available in Python */
1871int fdt_add_subnode_namelen(void *fdt, int parentoffset,
1872                            const char *name, int namelen);
1873#endif
1874
1875/**
1876 * fdt_add_subnode - creates a new node
1877 * @fdt: pointer to the device tree blob
1878 * @parentoffset: structure block offset of a node
1879 * @name: name of the subnode to locate
1880 *
1881 * fdt_add_subnode() creates a new node as a subnode of the node at
1882 * structure block offset parentoffset, with the given name (which
1883 * should include the unit address, if any).
1884 *
1885 * This function will insert data into the blob, and will therefore
1886 * change the offsets of some existing nodes.
1887
1888 * returns:
1889 *      structure block offset of the created nodeequested subnode (>=0), on
1890 *              success
1891 *      -FDT_ERR_NOTFOUND, if the requested subnode does not exist
1892 *      -FDT_ERR_BADOFFSET, if parentoffset did not point to an FDT_BEGIN_NODE
1893 *              tag
1894 *      -FDT_ERR_EXISTS, if the node at parentoffset already has a subnode of
1895 *              the given name
1896 *      -FDT_ERR_NOSPACE, if there is insufficient free space in the
1897 *              blob to contain the new node
1898 *      -FDT_ERR_NOSPACE
1899 *      -FDT_ERR_BADLAYOUT
1900 *      -FDT_ERR_BADMAGIC,
1901 *      -FDT_ERR_BADVERSION,
1902 *      -FDT_ERR_BADSTATE,
1903 *      -FDT_ERR_BADSTRUCTURE,
1904 *      -FDT_ERR_TRUNCATED, standard meanings.
1905 */
1906int fdt_add_subnode(void *fdt, int parentoffset, const char *name);
1907
1908/**
1909 * fdt_del_node - delete a node (subtree)
1910 * @fdt: pointer to the device tree blob
1911 * @nodeoffset: offset of the node to nop
1912 *
1913 * fdt_del_node() will remove the given node, including all its
1914 * subnodes if any, from the blob.
1915 *
1916 * This function will delete data from the blob, and will therefore
1917 * change the offsets of some existing nodes.
1918 *
1919 * returns:
1920 *      0, on success
1921 *      -FDT_ERR_BADOFFSET, nodeoffset did not point to FDT_BEGIN_NODE tag
1922 *      -FDT_ERR_BADLAYOUT,
1923 *      -FDT_ERR_BADMAGIC,
1924 *      -FDT_ERR_BADVERSION,
1925 *      -FDT_ERR_BADSTATE,
1926 *      -FDT_ERR_BADSTRUCTURE,
1927 *      -FDT_ERR_TRUNCATED, standard meanings
1928 */
1929int fdt_del_node(void *fdt, int nodeoffset);
1930
1931/**
1932 * fdt_overlay_apply - Applies a DT overlay on a base DT
1933 * @fdt: pointer to the base device tree blob
1934 * @fdto: pointer to the device tree overlay blob
1935 *
1936 * fdt_overlay_apply() will apply the given device tree overlay on the
1937 * given base device tree.
1938 *
1939 * Expect the base device tree to be modified, even if the function
1940 * returns an error.
1941 *
1942 * returns:
1943 *      0, on success
1944 *      -FDT_ERR_NOSPACE, there's not enough space in the base device tree
1945 *      -FDT_ERR_NOTFOUND, the overlay points to some inexistant nodes or
1946 *              properties in the base DT
1947 *      -FDT_ERR_BADPHANDLE,
1948 *      -FDT_ERR_BADOVERLAY,
1949 *      -FDT_ERR_NOPHANDLES,
1950 *      -FDT_ERR_INTERNAL,
1951 *      -FDT_ERR_BADLAYOUT,
1952 *      -FDT_ERR_BADMAGIC,
1953 *      -FDT_ERR_BADOFFSET,
1954 *      -FDT_ERR_BADPATH,
1955 *      -FDT_ERR_BADVERSION,
1956 *      -FDT_ERR_BADSTRUCTURE,
1957 *      -FDT_ERR_BADSTATE,
1958 *      -FDT_ERR_TRUNCATED, standard meanings
1959 */
1960int fdt_overlay_apply(void *fdt, void *fdto);
1961
1962/**********************************************************************/
1963/* Debugging / informational functions                                */
1964/**********************************************************************/
1965
1966const char *fdt_strerror(int errval);
1967
1968#endif /* LIBFDT_H */
Note: See TracBrowser for help on using the repository browser.