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