aboutsummaryrefslogtreecommitdiffstats
path: root/scripts/dtc/libfdt/libfdt.h
diff options
context:
space:
mode:
authorDavid Gibson <david@gibson.dropbear.id.au>2009-04-30 01:25:53 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2009-05-02 19:52:26 -0400
commit9fffb55f66127b52c937ede5196ebfa0c0d50bce (patch)
tree11664fb82734ba8dcde9556b8d47e780451a740a /scripts/dtc/libfdt/libfdt.h
parentafc1e702e8e8355faa712d4e90d9afe26a4995a5 (diff)
Move dtc and libfdt sources from arch/powerpc/boot to scripts/dtc
The powerpc kernel always requires an Open Firmware like device tree to supply device information. On systems without OF, this comes from a flattened device tree blob. This blob is usually generated by dtc, a tool which compiles a text description of the device tree into the flattened format used by the kernel. Sometimes, the bootwrapper makes small changes to the pre-compiled device tree blob (e.g. filling in the size of RAM). To do this it uses the libfdt library. Because these are only used on powerpc, the code for both these tools is included under arch/powerpc/boot (these were imported and are periodically updated from the upstream dtc tree). However, the microblaze architecture, currently being prepared for merging to mainline also uses dtc to produce device tree blobs. A few other archs have also mentioned some interest in using dtc. Therefore, this patch moves dtc and libfdt from arch/powerpc into scripts, where it can be used by any architecture. The vast bulk of this patch is a literal move, the rest is adjusting the various Makefiles to use dtc and libfdt correctly from their new locations. Signed-off-by: David Gibson <david@gibson.dropbear.id.au> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'scripts/dtc/libfdt/libfdt.h')
-rw-r--r--scripts/dtc/libfdt/libfdt.h1076
1 files changed, 1076 insertions, 0 deletions
diff --git a/scripts/dtc/libfdt/libfdt.h b/scripts/dtc/libfdt/libfdt.h
new file mode 100644
index 000000000000..ce80e4fb41b2
--- /dev/null
+++ b/scripts/dtc/libfdt/libfdt.h
@@ -0,0 +1,1076 @@
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 *)(uintptr_t)fdt_offset_ptr(fdt, offset, checklen);
129}
130
131uint32_t fdt_next_tag(const void *fdt, int offset, int *nextoffset);
132
133/**********************************************************************/
134/* Traversal functions */
135/**********************************************************************/
136
137int fdt_next_node(const void *fdt, int offset, int *depth);
138
139/**********************************************************************/
140/* General functions */
141/**********************************************************************/
142
143#define fdt_get_header(fdt, field) \
144 (fdt32_to_cpu(((const struct fdt_header *)(fdt))->field))
145#define fdt_magic(fdt) (fdt_get_header(fdt, magic))
146#define fdt_totalsize(fdt) (fdt_get_header(fdt, totalsize))
147#define fdt_off_dt_struct(fdt) (fdt_get_header(fdt, off_dt_struct))
148#define fdt_off_dt_strings(fdt) (fdt_get_header(fdt, off_dt_strings))
149#define fdt_off_mem_rsvmap(fdt) (fdt_get_header(fdt, off_mem_rsvmap))
150#define fdt_version(fdt) (fdt_get_header(fdt, version))
151#define fdt_last_comp_version(fdt) (fdt_get_header(fdt, last_comp_version))
152#define fdt_boot_cpuid_phys(fdt) (fdt_get_header(fdt, boot_cpuid_phys))
153#define fdt_size_dt_strings(fdt) (fdt_get_header(fdt, size_dt_strings))
154#define fdt_size_dt_struct(fdt) (fdt_get_header(fdt, size_dt_struct))
155
156#define __fdt_set_hdr(name) \
157 static inline void fdt_set_##name(void *fdt, uint32_t val) \
158 { \
159 struct fdt_header *fdth = fdt; \
160 fdth->name = cpu_to_fdt32(val); \
161 }
162__fdt_set_hdr(magic);
163__fdt_set_hdr(totalsize);
164__fdt_set_hdr(off_dt_struct);
165__fdt_set_hdr(off_dt_strings);
166__fdt_set_hdr(off_mem_rsvmap);
167__fdt_set_hdr(version);
168__fdt_set_hdr(last_comp_version);
169__fdt_set_hdr(boot_cpuid_phys);
170__fdt_set_hdr(size_dt_strings);
171__fdt_set_hdr(size_dt_struct);
172#undef __fdt_set_hdr
173
174/**
175 * fdt_check_header - sanity check a device tree or possible device tree
176 * @fdt: pointer to data which might be a flattened device tree
177 *
178 * fdt_check_header() checks that the given buffer contains what
179 * appears to be a flattened device tree with sane information in its
180 * header.
181 *
182 * returns:
183 * 0, if the buffer appears to contain a valid device tree
184 * -FDT_ERR_BADMAGIC,
185 * -FDT_ERR_BADVERSION,
186 * -FDT_ERR_BADSTATE, standard meanings, as above
187 */
188int fdt_check_header(const void *fdt);
189
190/**
191 * fdt_move - move a device tree around in memory
192 * @fdt: pointer to the device tree to move
193 * @buf: pointer to memory where the device is to be moved
194 * @bufsize: size of the memory space at buf
195 *
196 * fdt_move() relocates, if possible, the device tree blob located at
197 * fdt to the buffer at buf of size bufsize. The buffer may overlap
198 * with the existing device tree blob at fdt. Therefore,
199 * fdt_move(fdt, fdt, fdt_totalsize(fdt))
200 * should always succeed.
201 *
202 * returns:
203 * 0, on success
204 * -FDT_ERR_NOSPACE, bufsize is insufficient to contain the device tree
205 * -FDT_ERR_BADMAGIC,
206 * -FDT_ERR_BADVERSION,
207 * -FDT_ERR_BADSTATE, standard meanings
208 */
209int fdt_move(const void *fdt, void *buf, int bufsize);
210
211/**********************************************************************/
212/* Read-only functions */
213/**********************************************************************/
214
215/**
216 * fdt_string - retrieve a string from the strings block of a device tree
217 * @fdt: pointer to the device tree blob
218 * @stroffset: offset of the string within the strings block (native endian)
219 *
220 * fdt_string() retrieves a pointer to a single string from the
221 * strings block of the device tree blob at fdt.
222 *
223 * returns:
224 * a pointer to the string, on success
225 * NULL, if stroffset is out of bounds
226 */
227const char *fdt_string(const void *fdt, int stroffset);
228
229/**
230 * fdt_num_mem_rsv - retrieve the number of memory reserve map entries
231 * @fdt: pointer to the device tree blob
232 *
233 * Returns the number of entries in the device tree blob's memory
234 * reservation map. This does not include the terminating 0,0 entry
235 * or any other (0,0) entries reserved for expansion.
236 *
237 * returns:
238 * the number of entries
239 */
240int fdt_num_mem_rsv(const void *fdt);
241
242/**
243 * fdt_get_mem_rsv - retrieve one memory reserve map entry
244 * @fdt: pointer to the device tree blob
245 * @address, @size: pointers to 64-bit variables
246 *
247 * On success, *address and *size will contain the address and size of
248 * the n-th reserve map entry from the device tree blob, in
249 * native-endian format.
250 *
251 * returns:
252 * 0, on success
253 * -FDT_ERR_BADMAGIC,
254 * -FDT_ERR_BADVERSION,
255 * -FDT_ERR_BADSTATE, standard meanings
256 */
257int fdt_get_mem_rsv(const void *fdt, int n, uint64_t *address, uint64_t *size);
258
259/**
260 * fdt_subnode_offset_namelen - find a subnode based on substring
261 * @fdt: pointer to the device tree blob
262 * @parentoffset: structure block offset of a node
263 * @name: name of the subnode to locate
264 * @namelen: number of characters of name to consider
265 *
266 * Identical to fdt_subnode_offset(), but only examine the first
267 * namelen characters of name for matching the subnode name. This is
268 * useful for finding subnodes based on a portion of a larger string,
269 * such as a full path.
270 */
271int fdt_subnode_offset_namelen(const void *fdt, int parentoffset,
272 const char *name, int namelen);
273/**
274 * fdt_subnode_offset - find a subnode of a given node
275 * @fdt: pointer to the device tree blob
276 * @parentoffset: structure block offset of a node
277 * @name: name of the subnode to locate
278 *
279 * fdt_subnode_offset() finds a subnode of the node at structure block
280 * offset parentoffset with the given name. name may include a unit
281 * address, in which case fdt_subnode_offset() will find the subnode
282 * with that unit address, or the unit address may be omitted, in
283 * which case fdt_subnode_offset() will find an arbitrary subnode
284 * whose name excluding unit address matches the given name.
285 *
286 * returns:
287 * structure block offset of the requested subnode (>=0), on success
288 * -FDT_ERR_NOTFOUND, if the requested subnode does not exist
289 * -FDT_ERR_BADOFFSET, if parentoffset did not point to an FDT_BEGIN_NODE tag
290 * -FDT_ERR_BADMAGIC,
291 * -FDT_ERR_BADVERSION,
292 * -FDT_ERR_BADSTATE,
293 * -FDT_ERR_BADSTRUCTURE,
294 * -FDT_ERR_TRUNCATED, standard meanings.
295 */
296int fdt_subnode_offset(const void *fdt, int parentoffset, const char *name);
297
298/**
299 * fdt_path_offset - find a tree node by its full path
300 * @fdt: pointer to the device tree blob
301 * @path: full path of the node to locate
302 *
303 * fdt_path_offset() finds a node of a given path in the device tree.
304 * Each path component may omit the unit address portion, but the
305 * results of this are undefined if any such path component is
306 * ambiguous (that is if there are multiple nodes at the relevant
307 * level matching the given component, differentiated only by unit
308 * address).
309 *
310 * returns:
311 * structure block offset of the node with the requested path (>=0), on success
312 * -FDT_ERR_BADPATH, given path does not begin with '/' or is invalid
313 * -FDT_ERR_NOTFOUND, if the requested node does not exist
314 * -FDT_ERR_BADMAGIC,
315 * -FDT_ERR_BADVERSION,
316 * -FDT_ERR_BADSTATE,
317 * -FDT_ERR_BADSTRUCTURE,
318 * -FDT_ERR_TRUNCATED, standard meanings.
319 */
320int fdt_path_offset(const void *fdt, const char *path);
321
322/**
323 * fdt_get_name - retrieve the name of a given node
324 * @fdt: pointer to the device tree blob
325 * @nodeoffset: structure block offset of the starting node
326 * @lenp: pointer to an integer variable (will be overwritten) or NULL
327 *
328 * fdt_get_name() retrieves the name (including unit address) of the
329 * device tree node at structure block offset nodeoffset. If lenp is
330 * non-NULL, the length of this name is also returned, in the integer
331 * pointed to by lenp.
332 *
333 * returns:
334 * pointer to the node's name, on success
335 * If lenp is non-NULL, *lenp contains the length of that name (>=0)
336 * NULL, on error
337 * if lenp is non-NULL *lenp contains an error code (<0):
338 * -FDT_ERR_BADOFFSET, nodeoffset did not point to FDT_BEGIN_NODE tag
339 * -FDT_ERR_BADMAGIC,
340 * -FDT_ERR_BADVERSION,
341 * -FDT_ERR_BADSTATE, standard meanings
342 */
343const char *fdt_get_name(const void *fdt, int nodeoffset, int *lenp);
344
345/**
346 * fdt_get_property - find a given property in a given node
347 * @fdt: pointer to the device tree blob
348 * @nodeoffset: offset of the node whose property to find
349 * @name: name of the property to find
350 * @lenp: pointer to an integer variable (will be overwritten) or NULL
351 *
352 * fdt_get_property() retrieves a pointer to the fdt_property
353 * structure within the device tree blob corresponding to the property
354 * named 'name' of the node at offset nodeoffset. If lenp is
355 * non-NULL, the length of the property value is also returned, in the
356 * integer pointed to by lenp.
357 *
358 * returns:
359 * pointer to the structure representing the property
360 * if lenp is non-NULL, *lenp contains the length of the property
361 * value (>=0)
362 * NULL, on error
363 * if lenp is non-NULL, *lenp contains an error code (<0):
364 * -FDT_ERR_NOTFOUND, node does not have named property
365 * -FDT_ERR_BADOFFSET, nodeoffset did not point to FDT_BEGIN_NODE tag
366 * -FDT_ERR_BADMAGIC,
367 * -FDT_ERR_BADVERSION,
368 * -FDT_ERR_BADSTATE,
369 * -FDT_ERR_BADSTRUCTURE,
370 * -FDT_ERR_TRUNCATED, standard meanings
371 */
372const struct fdt_property *fdt_get_property(const void *fdt, int nodeoffset,
373 const char *name, int *lenp);
374static inline struct fdt_property *fdt_get_property_w(void *fdt, int nodeoffset,
375 const char *name,
376 int *lenp)
377{
378 return (struct fdt_property *)(uintptr_t)
379 fdt_get_property(fdt, nodeoffset, name, lenp);
380}
381
382/**
383 * fdt_getprop - retrieve the value of a given property
384 * @fdt: pointer to the device tree blob
385 * @nodeoffset: offset of the node whose property to find
386 * @name: name of the property to find
387 * @lenp: pointer to an integer variable (will be overwritten) or NULL
388 *
389 * fdt_getprop() retrieves a pointer to the value of the property
390 * named 'name' of the node at offset nodeoffset (this will be a
391 * pointer to within the device blob itself, not a copy of the value).
392 * If lenp is non-NULL, the length of the property value is also
393 * returned, in the integer pointed to by lenp.
394 *
395 * returns:
396 * pointer to the property's value
397 * if lenp is non-NULL, *lenp contains the length of the property
398 * value (>=0)
399 * NULL, on error
400 * if lenp is non-NULL, *lenp contains an error code (<0):
401 * -FDT_ERR_NOTFOUND, node does not have named property
402 * -FDT_ERR_BADOFFSET, nodeoffset did not point to FDT_BEGIN_NODE tag
403 * -FDT_ERR_BADMAGIC,
404 * -FDT_ERR_BADVERSION,
405 * -FDT_ERR_BADSTATE,
406 * -FDT_ERR_BADSTRUCTURE,
407 * -FDT_ERR_TRUNCATED, standard meanings
408 */
409const void *fdt_getprop(const void *fdt, int nodeoffset,
410 const char *name, int *lenp);
411static inline void *fdt_getprop_w(void *fdt, int nodeoffset,
412 const char *name, int *lenp)
413{
414 return (void *)(uintptr_t)fdt_getprop(fdt, nodeoffset, name, lenp);
415}
416
417/**
418 * fdt_get_phandle - retrieve the phandle of a given node
419 * @fdt: pointer to the device tree blob
420 * @nodeoffset: structure block offset of the node
421 *
422 * fdt_get_phandle() retrieves the phandle of the device tree node at
423 * structure block offset nodeoffset.
424 *
425 * returns:
426 * the phandle of the node at nodeoffset, on success (!= 0, != -1)
427 * 0, if the node has no phandle, or another error occurs
428 */
429uint32_t fdt_get_phandle(const void *fdt, int nodeoffset);
430
431/**
432 * fdt_get_path - determine the full path of a node
433 * @fdt: pointer to the device tree blob
434 * @nodeoffset: offset of the node whose path to find
435 * @buf: character buffer to contain the returned path (will be overwritten)
436 * @buflen: size of the character buffer at buf
437 *
438 * fdt_get_path() computes the full path of the node at offset
439 * nodeoffset, and records that path in the buffer at buf.
440 *
441 * NOTE: This function is expensive, as it must scan the device tree
442 * structure from the start to nodeoffset.
443 *
444 * returns:
445 * 0, on success
446 * buf contains the absolute path of the node at
447 * nodeoffset, as a NUL-terminated string.
448 * -FDT_ERR_BADOFFSET, nodeoffset does not refer to a BEGIN_NODE tag
449 * -FDT_ERR_NOSPACE, the path of the given node is longer than (bufsize-1)
450 * characters and will not fit in the given buffer.
451 * -FDT_ERR_BADMAGIC,
452 * -FDT_ERR_BADVERSION,
453 * -FDT_ERR_BADSTATE,
454 * -FDT_ERR_BADSTRUCTURE, standard meanings
455 */
456int fdt_get_path(const void *fdt, int nodeoffset, char *buf, int buflen);
457
458/**
459 * fdt_supernode_atdepth_offset - find a specific ancestor of a node
460 * @fdt: pointer to the device tree blob
461 * @nodeoffset: offset of the node whose parent to find
462 * @supernodedepth: depth of the ancestor to find
463 * @nodedepth: pointer to an integer variable (will be overwritten) or NULL
464 *
465 * fdt_supernode_atdepth_offset() finds an ancestor of the given node
466 * at a specific depth from the root (where the root itself has depth
467 * 0, its immediate subnodes depth 1 and so forth). So
468 * fdt_supernode_atdepth_offset(fdt, nodeoffset, 0, NULL);
469 * will always return 0, the offset of the root node. If the node at
470 * nodeoffset has depth D, then:
471 * fdt_supernode_atdepth_offset(fdt, nodeoffset, D, NULL);
472 * will return nodeoffset itself.
473 *
474 * NOTE: This function is expensive, as it must scan the device tree
475 * structure from the start to nodeoffset.
476 *
477 * returns:
478
479 * structure block offset of the node at node offset's ancestor
480 * of depth supernodedepth (>=0), on success
481 * -FDT_ERR_BADOFFSET, nodeoffset does not refer to a BEGIN_NODE tag
482* -FDT_ERR_NOTFOUND, supernodedepth was greater than the depth of nodeoffset
483 * -FDT_ERR_BADMAGIC,
484 * -FDT_ERR_BADVERSION,
485 * -FDT_ERR_BADSTATE,
486 * -FDT_ERR_BADSTRUCTURE, standard meanings
487 */
488int fdt_supernode_atdepth_offset(const void *fdt, int nodeoffset,
489 int supernodedepth, int *nodedepth);
490
491/**
492 * fdt_node_depth - find the depth of a given node
493 * @fdt: pointer to the device tree blob
494 * @nodeoffset: offset of the node whose parent to find
495 *
496 * fdt_node_depth() finds the depth of a given node. The root node
497 * has depth 0, its immediate subnodes depth 1 and so forth.
498 *
499 * NOTE: This function is expensive, as it must scan the device tree
500 * structure from the start to nodeoffset.
501 *
502 * returns:
503 * depth of the node at nodeoffset (>=0), on success
504 * -FDT_ERR_BADOFFSET, nodeoffset does not refer to a BEGIN_NODE tag
505 * -FDT_ERR_BADMAGIC,
506 * -FDT_ERR_BADVERSION,
507 * -FDT_ERR_BADSTATE,
508 * -FDT_ERR_BADSTRUCTURE, standard meanings
509 */
510int fdt_node_depth(const void *fdt, int nodeoffset);
511
512/**
513 * fdt_parent_offset - find the parent of a given node
514 * @fdt: pointer to the device tree blob
515 * @nodeoffset: offset of the node whose parent to find
516 *
517 * fdt_parent_offset() locates the parent node of a given node (that
518 * is, it finds the offset of the node which contains the node at
519 * nodeoffset as a subnode).
520 *
521 * NOTE: This function is expensive, as it must scan the device tree
522 * structure from the start to nodeoffset, *twice*.
523 *
524 * returns:
525 * structure block offset of the parent of the node at nodeoffset
526 * (>=0), on success
527 * -FDT_ERR_BADOFFSET, nodeoffset does not refer to a BEGIN_NODE tag
528 * -FDT_ERR_BADMAGIC,
529 * -FDT_ERR_BADVERSION,
530 * -FDT_ERR_BADSTATE,
531 * -FDT_ERR_BADSTRUCTURE, standard meanings
532 */
533int fdt_parent_offset(const void *fdt, int nodeoffset);
534
535/**
536 * fdt_node_offset_by_prop_value - find nodes with a given property value
537 * @fdt: pointer to the device tree blob
538 * @startoffset: only find nodes after this offset
539 * @propname: property name to check
540 * @propval: property value to search for
541 * @proplen: length of the value in propval
542 *
543 * fdt_node_offset_by_prop_value() returns the offset of the first
544 * node after startoffset, which has a property named propname whose
545 * value is of length proplen and has value equal to propval; or if
546 * startoffset is -1, the very first such node in the tree.
547 *
548 * To iterate through all nodes matching the criterion, the following
549 * idiom can be used:
550 * offset = fdt_node_offset_by_prop_value(fdt, -1, propname,
551 * propval, proplen);
552 * while (offset != -FDT_ERR_NOTFOUND) {
553 * // other code here
554 * offset = fdt_node_offset_by_prop_value(fdt, offset, propname,
555 * propval, proplen);
556 * }
557 *
558 * Note the -1 in the first call to the function, if 0 is used here
559 * instead, the function will never locate the root node, even if it
560 * matches the criterion.
561 *
562 * returns:
563 * structure block offset of the located node (>= 0, >startoffset),
564 * on success
565 * -FDT_ERR_NOTFOUND, no node matching the criterion exists in the
566 * tree after startoffset
567 * -FDT_ERR_BADOFFSET, nodeoffset does not refer to a BEGIN_NODE tag
568 * -FDT_ERR_BADMAGIC,
569 * -FDT_ERR_BADVERSION,
570 * -FDT_ERR_BADSTATE,
571 * -FDT_ERR_BADSTRUCTURE, standard meanings
572 */
573int fdt_node_offset_by_prop_value(const void *fdt, int startoffset,
574 const char *propname,
575 const void *propval, int proplen);
576
577/**
578 * fdt_node_offset_by_phandle - find the node with a given phandle
579 * @fdt: pointer to the device tree blob
580 * @phandle: phandle value
581 *
582 * fdt_node_offset_by_phandle() returns the offset of the node
583 * which has the given phandle value. If there is more than one node
584 * in the tree with the given phandle (an invalid tree), results are
585 * undefined.
586 *
587 * returns:
588 * structure block offset of the located node (>= 0), on success
589 * -FDT_ERR_NOTFOUND, no node with that phandle exists
590 * -FDT_ERR_BADPHANDLE, given phandle value was invalid (0 or -1)
591 * -FDT_ERR_BADMAGIC,
592 * -FDT_ERR_BADVERSION,
593 * -FDT_ERR_BADSTATE,
594 * -FDT_ERR_BADSTRUCTURE, standard meanings
595 */
596int fdt_node_offset_by_phandle(const void *fdt, uint32_t phandle);
597
598/**
599 * fdt_node_check_compatible: check a node's compatible property
600 * @fdt: pointer to the device tree blob
601 * @nodeoffset: offset of a tree node
602 * @compatible: string to match against
603 *
604 *
605 * fdt_node_check_compatible() returns 0 if the given node contains a
606 * 'compatible' property with the given string as one of its elements,
607 * it returns non-zero otherwise, or on error.
608 *
609 * returns:
610 * 0, if the node has a 'compatible' property listing the given string
611 * 1, if the node has a 'compatible' property, but it does not list
612 * the given string
613 * -FDT_ERR_NOTFOUND, if the given node has no 'compatible' property
614 * -FDT_ERR_BADOFFSET, if nodeoffset does not refer to a BEGIN_NODE tag
615 * -FDT_ERR_BADMAGIC,
616 * -FDT_ERR_BADVERSION,
617 * -FDT_ERR_BADSTATE,
618 * -FDT_ERR_BADSTRUCTURE, standard meanings
619 */
620int fdt_node_check_compatible(const void *fdt, int nodeoffset,
621 const char *compatible);
622
623/**
624 * fdt_node_offset_by_compatible - find nodes with a given 'compatible' value
625 * @fdt: pointer to the device tree blob
626 * @startoffset: only find nodes after this offset
627 * @compatible: 'compatible' string to match against
628 *
629 * fdt_node_offset_by_compatible() returns the offset of the first
630 * node after startoffset, which has a 'compatible' property which
631 * lists the given compatible string; or if startoffset is -1, the
632 * very first such node in the tree.
633 *
634 * To iterate through all nodes matching the criterion, the following
635 * idiom can be used:
636 * offset = fdt_node_offset_by_compatible(fdt, -1, compatible);
637 * while (offset != -FDT_ERR_NOTFOUND) {
638 * // other code here
639 * offset = fdt_node_offset_by_compatible(fdt, offset, compatible);
640 * }
641 *
642 * Note the -1 in the first call to the function, if 0 is used here
643 * instead, the function will never locate the root node, even if it
644 * matches the criterion.
645 *
646 * returns:
647 * structure block offset of the located node (>= 0, >startoffset),
648 * on success
649 * -FDT_ERR_NOTFOUND, no node matching the criterion exists in the
650 * tree after startoffset
651 * -FDT_ERR_BADOFFSET, nodeoffset does not refer to a BEGIN_NODE tag
652 * -FDT_ERR_BADMAGIC,
653 * -FDT_ERR_BADVERSION,
654 * -FDT_ERR_BADSTATE,
655 * -FDT_ERR_BADSTRUCTURE, standard meanings
656 */
657int fdt_node_offset_by_compatible(const void *fdt, int startoffset,
658 const char *compatible);
659
660/**********************************************************************/
661/* Write-in-place functions */
662/**********************************************************************/
663
664/**
665 * fdt_setprop_inplace - change a property's value, but not its size
666 * @fdt: pointer to the device tree blob
667 * @nodeoffset: offset of the node whose property to change
668 * @name: name of the property to change
669 * @val: pointer to data to replace the property value with
670 * @len: length of the property value
671 *
672 * fdt_setprop_inplace() replaces the value of a given property with
673 * the data in val, of length len. This function cannot change the
674 * size of a property, and so will only work if len is equal to the
675 * current length of the property.
676 *
677 * This function will alter only the bytes in the blob which contain
678 * the given property value, and will not alter or move any other part
679 * of the tree.
680 *
681 * returns:
682 * 0, on success
683 * -FDT_ERR_NOSPACE, if len is not equal to the property's current length
684 * -FDT_ERR_NOTFOUND, node does not have the named property
685 * -FDT_ERR_BADOFFSET, nodeoffset did not point to FDT_BEGIN_NODE tag
686 * -FDT_ERR_BADMAGIC,
687 * -FDT_ERR_BADVERSION,
688 * -FDT_ERR_BADSTATE,
689 * -FDT_ERR_BADSTRUCTURE,
690 * -FDT_ERR_TRUNCATED, standard meanings
691 */
692int fdt_setprop_inplace(void *fdt, int nodeoffset, const char *name,
693 const void *val, int len);
694
695/**
696 * fdt_setprop_inplace_cell - change the value of a single-cell property
697 * @fdt: pointer to the device tree blob
698 * @nodeoffset: offset of the node whose property to change
699 * @name: name of the property to change
700 * @val: cell (32-bit integer) value to replace the property with
701 *
702 * fdt_setprop_inplace_cell() replaces the value of a given property
703 * with the 32-bit integer cell value in val, converting val to
704 * big-endian if necessary. This function cannot change the size of a
705 * property, and so will only work if the property already exists and
706 * has length 4.
707 *
708 * This function will alter only the bytes in the blob which contain
709 * the given property value, and will not alter or move any other part
710 * of the tree.
711 *
712 * returns:
713 * 0, on success
714 * -FDT_ERR_NOSPACE, if the property's length is not equal to 4
715 * -FDT_ERR_NOTFOUND, node does not have the named property
716 * -FDT_ERR_BADOFFSET, nodeoffset did not point to FDT_BEGIN_NODE tag
717 * -FDT_ERR_BADMAGIC,
718 * -FDT_ERR_BADVERSION,
719 * -FDT_ERR_BADSTATE,
720 * -FDT_ERR_BADSTRUCTURE,
721 * -FDT_ERR_TRUNCATED, standard meanings
722 */
723static inline int fdt_setprop_inplace_cell(void *fdt, int nodeoffset,
724 const char *name, uint32_t val)
725{
726 val = cpu_to_fdt32(val);
727 return fdt_setprop_inplace(fdt, nodeoffset, name, &val, sizeof(val));
728}
729
730/**
731 * fdt_nop_property - replace a property with nop tags
732 * @fdt: pointer to the device tree blob
733 * @nodeoffset: offset of the node whose property to nop
734 * @name: name of the property to nop
735 *
736 * fdt_nop_property() will replace a given property's representation
737 * in the blob with FDT_NOP tags, effectively removing it from the
738 * tree.
739 *
740 * This function will alter only the bytes in the blob which contain
741 * the property, and will not alter or move any other part of the
742 * tree.
743 *
744 * returns:
745 * 0, on success
746 * -FDT_ERR_NOTFOUND, node does not have the named property
747 * -FDT_ERR_BADOFFSET, nodeoffset did not point to FDT_BEGIN_NODE tag
748 * -FDT_ERR_BADMAGIC,
749 * -FDT_ERR_BADVERSION,
750 * -FDT_ERR_BADSTATE,
751 * -FDT_ERR_BADSTRUCTURE,
752 * -FDT_ERR_TRUNCATED, standard meanings
753 */
754int fdt_nop_property(void *fdt, int nodeoffset, const char *name);
755
756/**
757 * fdt_nop_node - replace a node (subtree) with nop tags
758 * @fdt: pointer to the device tree blob
759 * @nodeoffset: offset of the node to nop
760 *
761 * fdt_nop_node() will replace a given node's representation in the
762 * blob, including all its subnodes, if any, with FDT_NOP tags,
763 * effectively removing it from the tree.
764 *
765 * This function will alter only the bytes in the blob which contain
766 * the node and its properties and subnodes, and will not alter or
767 * move any other part of the tree.
768 *
769 * returns:
770 * 0, on success
771 * -FDT_ERR_BADOFFSET, nodeoffset did not point to FDT_BEGIN_NODE tag
772 * -FDT_ERR_BADMAGIC,
773 * -FDT_ERR_BADVERSION,
774 * -FDT_ERR_BADSTATE,
775 * -FDT_ERR_BADSTRUCTURE,
776 * -FDT_ERR_TRUNCATED, standard meanings
777 */
778int fdt_nop_node(void *fdt, int nodeoffset);
779
780/**********************************************************************/
781/* Sequential write functions */
782/**********************************************************************/
783
784int fdt_create(void *buf, int bufsize);
785int fdt_add_reservemap_entry(void *fdt, uint64_t addr, uint64_t size);
786int fdt_finish_reservemap(void *fdt);
787int fdt_begin_node(void *fdt, const char *name);
788int fdt_property(void *fdt, const char *name, const void *val, int len);
789static inline int fdt_property_cell(void *fdt, const char *name, uint32_t val)
790{
791 val = cpu_to_fdt32(val);
792 return fdt_property(fdt, name, &val, sizeof(val));
793}
794#define fdt_property_string(fdt, name, str) \
795 fdt_property(fdt, name, str, strlen(str)+1)
796int fdt_end_node(void *fdt);
797int fdt_finish(void *fdt);
798
799/**********************************************************************/
800/* Read-write functions */
801/**********************************************************************/
802
803int fdt_open_into(const void *fdt, void *buf, int bufsize);
804int fdt_pack(void *fdt);
805
806/**
807 * fdt_add_mem_rsv - add one memory reserve map entry
808 * @fdt: pointer to the device tree blob
809 * @address, @size: 64-bit values (native endian)
810 *
811 * Adds a reserve map entry to the given blob reserving a region at
812 * address address of length size.
813 *
814 * This function will insert data into the reserve map and will
815 * therefore change the indexes of some entries in the table.
816 *
817 * returns:
818 * 0, on success
819 * -FDT_ERR_NOSPACE, there is insufficient free space in the blob to
820 * contain the new reservation entry
821 * -FDT_ERR_BADMAGIC,
822 * -FDT_ERR_BADVERSION,
823 * -FDT_ERR_BADSTATE,
824 * -FDT_ERR_BADSTRUCTURE,
825 * -FDT_ERR_BADLAYOUT,
826 * -FDT_ERR_TRUNCATED, standard meanings
827 */
828int fdt_add_mem_rsv(void *fdt, uint64_t address, uint64_t size);
829
830/**
831 * fdt_del_mem_rsv - remove a memory reserve map entry
832 * @fdt: pointer to the device tree blob
833 * @n: entry to remove
834 *
835 * fdt_del_mem_rsv() removes the n-th memory reserve map entry from
836 * the blob.
837 *
838 * This function will delete data from the reservation table and will
839 * therefore change the indexes of some entries in the table.
840 *
841 * returns:
842 * 0, on success
843 * -FDT_ERR_NOTFOUND, there is no entry of the given index (i.e. there
844 * are less than n+1 reserve map entries)
845 * -FDT_ERR_BADMAGIC,
846 * -FDT_ERR_BADVERSION,
847 * -FDT_ERR_BADSTATE,
848 * -FDT_ERR_BADSTRUCTURE,
849 * -FDT_ERR_BADLAYOUT,
850 * -FDT_ERR_TRUNCATED, standard meanings
851 */
852int fdt_del_mem_rsv(void *fdt, int n);
853
854/**
855 * fdt_set_name - change the name of a given node
856 * @fdt: pointer to the device tree blob
857 * @nodeoffset: structure block offset of a node
858 * @name: name to give the node
859 *
860 * fdt_set_name() replaces the name (including unit address, if any)
861 * of the given node with the given string. NOTE: this function can't
862 * efficiently check if the new name is unique amongst the given
863 * node's siblings; results are undefined if this function is invoked
864 * with a name equal to one of the given node's siblings.
865 *
866 * This function may insert or delete data from the blob, and will
867 * therefore change the offsets of some existing nodes.
868 *
869 * returns:
870 * 0, on success
871 * -FDT_ERR_NOSPACE, there is insufficient free space in the blob
872 * to contain the new name
873 * -FDT_ERR_BADOFFSET, nodeoffset did not point to FDT_BEGIN_NODE tag
874 * -FDT_ERR_BADMAGIC,
875 * -FDT_ERR_BADVERSION,
876 * -FDT_ERR_BADSTATE, standard meanings
877 */
878int fdt_set_name(void *fdt, int nodeoffset, const char *name);
879
880/**
881 * fdt_setprop - create or change a property
882 * @fdt: pointer to the device tree blob
883 * @nodeoffset: offset of the node whose property to change
884 * @name: name of the property to change
885 * @val: pointer to data to set the property value to
886 * @len: length of the property value
887 *
888 * fdt_setprop() sets the value of the named property in the given
889 * node to the given value and length, creating the property if it
890 * does not already exist.
891 *
892 * This function may insert or delete data from the blob, and will
893 * therefore change the offsets of some existing nodes.
894 *
895 * returns:
896 * 0, on success
897 * -FDT_ERR_NOSPACE, there is insufficient free space in the blob to
898 * contain the new property value
899 * -FDT_ERR_BADOFFSET, nodeoffset did not point to FDT_BEGIN_NODE tag
900 * -FDT_ERR_BADLAYOUT,
901 * -FDT_ERR_BADMAGIC,
902 * -FDT_ERR_BADVERSION,
903 * -FDT_ERR_BADSTATE,
904 * -FDT_ERR_BADSTRUCTURE,
905 * -FDT_ERR_BADLAYOUT,
906 * -FDT_ERR_TRUNCATED, standard meanings
907 */
908int fdt_setprop(void *fdt, int nodeoffset, const char *name,
909 const void *val, int len);
910
911/**
912 * fdt_setprop_cell - set a property to a single cell value
913 * @fdt: pointer to the device tree blob
914 * @nodeoffset: offset of the node whose property to change
915 * @name: name of the property to change
916 * @val: 32-bit integer value for the property (native endian)
917 *
918 * fdt_setprop_cell() sets the value of the named property in the
919 * given node to the given cell value (converting to big-endian if
920 * necessary), or creates a new property with that value if it does
921 * not already exist.
922 *
923 * This function may insert or delete data from the blob, and will
924 * therefore change the offsets of some existing nodes.
925 *
926 * returns:
927 * 0, on success
928 * -FDT_ERR_NOSPACE, there is insufficient free space in the blob to
929 * contain the new property value
930 * -FDT_ERR_BADOFFSET, nodeoffset did not point to FDT_BEGIN_NODE tag
931 * -FDT_ERR_BADLAYOUT,
932 * -FDT_ERR_BADMAGIC,
933 * -FDT_ERR_BADVERSION,
934 * -FDT_ERR_BADSTATE,
935 * -FDT_ERR_BADSTRUCTURE,
936 * -FDT_ERR_BADLAYOUT,
937 * -FDT_ERR_TRUNCATED, standard meanings
938 */
939static inline int fdt_setprop_cell(void *fdt, int nodeoffset, const char *name,
940 uint32_t val)
941{
942 val = cpu_to_fdt32(val);
943 return fdt_setprop(fdt, nodeoffset, name, &val, sizeof(val));
944}
945
946/**
947 * fdt_setprop_string - set a property to a string value
948 * @fdt: pointer to the device tree blob
949 * @nodeoffset: offset of the node whose property to change
950 * @name: name of the property to change
951 * @str: string value for the property
952 *
953 * fdt_setprop_string() sets the value of the named property in the
954 * given node to the given string value (using the length of the
955 * string to determine the new length of the property), or creates a
956 * new property with that value if it does not already exist.
957 *
958 * This function may insert or delete data from the blob, and will
959 * therefore change the offsets of some existing nodes.
960 *
961 * returns:
962 * 0, on success
963 * -FDT_ERR_NOSPACE, there is insufficient free space in the blob to
964 * contain the new property value
965 * -FDT_ERR_BADOFFSET, nodeoffset did not point to FDT_BEGIN_NODE tag
966 * -FDT_ERR_BADLAYOUT,
967 * -FDT_ERR_BADMAGIC,
968 * -FDT_ERR_BADVERSION,
969 * -FDT_ERR_BADSTATE,
970 * -FDT_ERR_BADSTRUCTURE,
971 * -FDT_ERR_BADLAYOUT,
972 * -FDT_ERR_TRUNCATED, standard meanings
973 */
974#define fdt_setprop_string(fdt, nodeoffset, name, str) \
975 fdt_setprop((fdt), (nodeoffset), (name), (str), strlen(str)+1)
976
977/**
978 * fdt_delprop - delete a property
979 * @fdt: pointer to the device tree blob
980 * @nodeoffset: offset of the node whose property to nop
981 * @name: name of the property to nop
982 *
983 * fdt_del_property() will delete the given property.
984 *
985 * This function will delete data from the blob, and will therefore
986 * change the offsets of some existing nodes.
987 *
988 * returns:
989 * 0, on success
990 * -FDT_ERR_NOTFOUND, node does not have the named property
991 * -FDT_ERR_BADOFFSET, nodeoffset did not point to FDT_BEGIN_NODE tag
992 * -FDT_ERR_BADLAYOUT,
993 * -FDT_ERR_BADMAGIC,
994 * -FDT_ERR_BADVERSION,
995 * -FDT_ERR_BADSTATE,
996 * -FDT_ERR_BADSTRUCTURE,
997 * -FDT_ERR_TRUNCATED, standard meanings
998 */
999int fdt_delprop(void *fdt, int nodeoffset, const char *name);
1000
1001/**
1002 * fdt_add_subnode_namelen - creates a new node based on substring
1003 * @fdt: pointer to the device tree blob
1004 * @parentoffset: structure block offset of a node
1005 * @name: name of the subnode to locate
1006 * @namelen: number of characters of name to consider
1007 *
1008 * Identical to fdt_add_subnode(), but use only the first namelen
1009 * characters of name as the name of the new node. This is useful for
1010 * creating subnodes based on a portion of a larger string, such as a
1011 * full path.
1012 */
1013int fdt_add_subnode_namelen(void *fdt, int parentoffset,
1014 const char *name, int namelen);
1015
1016/**
1017 * fdt_add_subnode - creates a new node
1018 * @fdt: pointer to the device tree blob
1019 * @parentoffset: structure block offset of a node
1020 * @name: name of the subnode to locate
1021 *
1022 * fdt_add_subnode() creates a new node as a subnode of the node at
1023 * structure block offset parentoffset, with the given name (which
1024 * should include the unit address, if any).
1025 *
1026 * This function will insert data into the blob, and will therefore
1027 * change the offsets of some existing nodes.
1028
1029 * returns:
1030 * structure block offset of the created nodeequested subnode (>=0), on success
1031 * -FDT_ERR_NOTFOUND, if the requested subnode does not exist
1032 * -FDT_ERR_BADOFFSET, if parentoffset did not point to an FDT_BEGIN_NODE tag
1033 * -FDT_ERR_EXISTS, if the node at parentoffset already has a subnode of
1034 * the given name
1035 * -FDT_ERR_NOSPACE, if there is insufficient free space in the
1036 * blob to contain the new node
1037 * -FDT_ERR_NOSPACE
1038 * -FDT_ERR_BADLAYOUT
1039 * -FDT_ERR_BADMAGIC,
1040 * -FDT_ERR_BADVERSION,
1041 * -FDT_ERR_BADSTATE,
1042 * -FDT_ERR_BADSTRUCTURE,
1043 * -FDT_ERR_TRUNCATED, standard meanings.
1044 */
1045int fdt_add_subnode(void *fdt, int parentoffset, const char *name);
1046
1047/**
1048 * fdt_del_node - delete a node (subtree)
1049 * @fdt: pointer to the device tree blob
1050 * @nodeoffset: offset of the node to nop
1051 *
1052 * fdt_del_node() will remove the given node, including all its
1053 * subnodes if any, from the blob.
1054 *
1055 * This function will delete data from the blob, and will therefore
1056 * change the offsets of some existing nodes.
1057 *
1058 * returns:
1059 * 0, on success
1060 * -FDT_ERR_BADOFFSET, nodeoffset did not point to FDT_BEGIN_NODE tag
1061 * -FDT_ERR_BADLAYOUT,
1062 * -FDT_ERR_BADMAGIC,
1063 * -FDT_ERR_BADVERSION,
1064 * -FDT_ERR_BADSTATE,
1065 * -FDT_ERR_BADSTRUCTURE,
1066 * -FDT_ERR_TRUNCATED, standard meanings
1067 */
1068int fdt_del_node(void *fdt, int nodeoffset);
1069
1070/**********************************************************************/
1071/* Debugging / informational functions */
1072/**********************************************************************/
1073
1074const char *fdt_strerror(int errval);
1075
1076#endif /* _LIBFDT_H */