1*5a485aa9Sskrll /* $NetBSD: fdt_wip.c,v 1.1.1.3 2019/12/22 12:30:36 skrll Exp $ */
2fc885a42Sskrll
3*5a485aa9Sskrll // SPDX-License-Identifier: (GPL-2.0-or-later OR BSD-2-Clause)
46233fbe7Smacallan /*
56233fbe7Smacallan * libfdt - Flat Device Tree manipulation
66233fbe7Smacallan * Copyright (C) 2006 David Gibson, IBM Corporation.
76233fbe7Smacallan */
86233fbe7Smacallan #include "libfdt_env.h"
96233fbe7Smacallan
106233fbe7Smacallan #include <fdt.h>
116233fbe7Smacallan #include <libfdt.h>
126233fbe7Smacallan
136233fbe7Smacallan #include "libfdt_internal.h"
146233fbe7Smacallan
fdt_setprop_inplace_namelen_partial(void * fdt,int nodeoffset,const char * name,int namelen,uint32_t idx,const void * val,int len)15fc885a42Sskrll int fdt_setprop_inplace_namelen_partial(void *fdt, int nodeoffset,
16fc885a42Sskrll const char *name, int namelen,
17fc885a42Sskrll uint32_t idx, const void *val,
18fc885a42Sskrll int len)
196233fbe7Smacallan {
206233fbe7Smacallan void *propval;
216233fbe7Smacallan int proplen;
226233fbe7Smacallan
23fc885a42Sskrll propval = fdt_getprop_namelen_w(fdt, nodeoffset, name, namelen,
24fc885a42Sskrll &proplen);
25fc885a42Sskrll if (!propval)
26fc885a42Sskrll return proplen;
27fc885a42Sskrll
28fc885a42Sskrll if (proplen < (len + idx))
29fc885a42Sskrll return -FDT_ERR_NOSPACE;
30fc885a42Sskrll
31fc885a42Sskrll memcpy((char *)propval + idx, val, len);
32fc885a42Sskrll return 0;
33fc885a42Sskrll }
34fc885a42Sskrll
fdt_setprop_inplace(void * fdt,int nodeoffset,const char * name,const void * val,int len)35fc885a42Sskrll int fdt_setprop_inplace(void *fdt, int nodeoffset, const char *name,
36fc885a42Sskrll const void *val, int len)
37fc885a42Sskrll {
38fc885a42Sskrll const void *propval;
39fc885a42Sskrll int proplen;
40fc885a42Sskrll
41fc885a42Sskrll propval = fdt_getprop(fdt, nodeoffset, name, &proplen);
426233fbe7Smacallan if (!propval)
436233fbe7Smacallan return proplen;
446233fbe7Smacallan
456233fbe7Smacallan if (proplen != len)
466233fbe7Smacallan return -FDT_ERR_NOSPACE;
476233fbe7Smacallan
48fc885a42Sskrll return fdt_setprop_inplace_namelen_partial(fdt, nodeoffset, name,
49fc885a42Sskrll strlen(name), 0,
50fc885a42Sskrll val, len);
516233fbe7Smacallan }
526233fbe7Smacallan
fdt_nop_region_(void * start,int len)53*5a485aa9Sskrll static void fdt_nop_region_(void *start, int len)
546233fbe7Smacallan {
556233fbe7Smacallan fdt32_t *p;
566233fbe7Smacallan
576233fbe7Smacallan for (p = start; (char *)p < ((char *)start + len); p++)
586233fbe7Smacallan *p = cpu_to_fdt32(FDT_NOP);
596233fbe7Smacallan }
606233fbe7Smacallan
fdt_nop_property(void * fdt,int nodeoffset,const char * name)616233fbe7Smacallan int fdt_nop_property(void *fdt, int nodeoffset, const char *name)
626233fbe7Smacallan {
636233fbe7Smacallan struct fdt_property *prop;
646233fbe7Smacallan int len;
656233fbe7Smacallan
666233fbe7Smacallan prop = fdt_get_property_w(fdt, nodeoffset, name, &len);
676233fbe7Smacallan if (!prop)
686233fbe7Smacallan return len;
696233fbe7Smacallan
70*5a485aa9Sskrll fdt_nop_region_(prop, len + sizeof(*prop));
716233fbe7Smacallan
726233fbe7Smacallan return 0;
736233fbe7Smacallan }
746233fbe7Smacallan
fdt_node_end_offset_(void * fdt,int offset)75*5a485aa9Sskrll int fdt_node_end_offset_(void *fdt, int offset)
766233fbe7Smacallan {
776233fbe7Smacallan int depth = 0;
786233fbe7Smacallan
796233fbe7Smacallan while ((offset >= 0) && (depth >= 0))
806233fbe7Smacallan offset = fdt_next_node(fdt, offset, &depth);
816233fbe7Smacallan
826233fbe7Smacallan return offset;
836233fbe7Smacallan }
846233fbe7Smacallan
fdt_nop_node(void * fdt,int nodeoffset)856233fbe7Smacallan int fdt_nop_node(void *fdt, int nodeoffset)
866233fbe7Smacallan {
876233fbe7Smacallan int endoffset;
886233fbe7Smacallan
89*5a485aa9Sskrll endoffset = fdt_node_end_offset_(fdt, nodeoffset);
906233fbe7Smacallan if (endoffset < 0)
916233fbe7Smacallan return endoffset;
926233fbe7Smacallan
93*5a485aa9Sskrll fdt_nop_region_(fdt_offset_ptr_w(fdt, nodeoffset, 0),
946233fbe7Smacallan endoffset - nodeoffset);
956233fbe7Smacallan return 0;
966233fbe7Smacallan }
97