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