xref: /netbsd/sys/external/bsd/libfdt/dist/fdt_wip.c (revision b9ee18de)
1 /*	$NetBSD: fdt_wip.c,v 1.1.1.3 2019/12/22 12:30:36 skrll Exp $	*/
2 
3 // SPDX-License-Identifier: (GPL-2.0-or-later OR BSD-2-Clause)
4 /*
5  * libfdt - Flat Device Tree manipulation
6  * Copyright (C) 2006 David Gibson, IBM Corporation.
7  */
8 #include "libfdt_env.h"
9 
10 #include <fdt.h>
11 #include <libfdt.h>
12 
13 #include "libfdt_internal.h"
14 
fdt_setprop_inplace_namelen_partial(void * fdt,int nodeoffset,const char * name,int namelen,uint32_t idx,const void * val,int len)15 int fdt_setprop_inplace_namelen_partial(void *fdt, int nodeoffset,
16 					const char *name, int namelen,
17 					uint32_t idx, const void *val,
18 					int len)
19 {
20 	void *propval;
21 	int proplen;
22 
23 	propval = fdt_getprop_namelen_w(fdt, nodeoffset, name, namelen,
24 					&proplen);
25 	if (!propval)
26 		return proplen;
27 
28 	if (proplen < (len + idx))
29 		return -FDT_ERR_NOSPACE;
30 
31 	memcpy((char *)propval + idx, val, len);
32 	return 0;
33 }
34 
fdt_setprop_inplace(void * fdt,int nodeoffset,const char * name,const void * val,int len)35 int fdt_setprop_inplace(void *fdt, int nodeoffset, const char *name,
36 			const void *val, int len)
37 {
38 	const void *propval;
39 	int proplen;
40 
41 	propval = fdt_getprop(fdt, nodeoffset, name, &proplen);
42 	if (!propval)
43 		return proplen;
44 
45 	if (proplen != len)
46 		return -FDT_ERR_NOSPACE;
47 
48 	return fdt_setprop_inplace_namelen_partial(fdt, nodeoffset, name,
49 						   strlen(name), 0,
50 						   val, len);
51 }
52 
fdt_nop_region_(void * start,int len)53 static void fdt_nop_region_(void *start, int len)
54 {
55 	fdt32_t *p;
56 
57 	for (p = start; (char *)p < ((char *)start + len); p++)
58 		*p = cpu_to_fdt32(FDT_NOP);
59 }
60 
fdt_nop_property(void * fdt,int nodeoffset,const char * name)61 int fdt_nop_property(void *fdt, int nodeoffset, const char *name)
62 {
63 	struct fdt_property *prop;
64 	int len;
65 
66 	prop = fdt_get_property_w(fdt, nodeoffset, name, &len);
67 	if (!prop)
68 		return len;
69 
70 	fdt_nop_region_(prop, len + sizeof(*prop));
71 
72 	return 0;
73 }
74 
fdt_node_end_offset_(void * fdt,int offset)75 int fdt_node_end_offset_(void *fdt, int offset)
76 {
77 	int depth = 0;
78 
79 	while ((offset >= 0) && (depth >= 0))
80 		offset = fdt_next_node(fdt, offset, &depth);
81 
82 	return offset;
83 }
84 
fdt_nop_node(void * fdt,int nodeoffset)85 int fdt_nop_node(void *fdt, int nodeoffset)
86 {
87 	int endoffset;
88 
89 	endoffset = fdt_node_end_offset_(fdt, nodeoffset);
90 	if (endoffset < 0)
91 		return endoffset;
92 
93 	fdt_nop_region_(fdt_offset_ptr_w(fdt, nodeoffset, 0),
94 			endoffset - nodeoffset);
95 	return 0;
96 }
97