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 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 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 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 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 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 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