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