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