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