blob: c2d7566a67dcf114cb15e0e233c8bff126744365 [file] [log] [blame]
Rob Herring12869ec2019-06-21 08:18:32 -06001// SPDX-License-Identifier: (GPL-2.0-or-later OR BSD-2-Clause)
David Gibson1cade992007-12-10 14:28:39 +11002/*
3 * libfdt - Flat Device Tree manipulation
4 * Copyright (C) 2006 David Gibson, IBM Corporation.
David Gibson1cade992007-12-10 14:28:39 +11005 */
6#include "libfdt_env.h"
7
8#include <fdt.h>
9#include <libfdt.h>
10
11#include "libfdt_internal.h"
12
Rob Herring6f05afc2017-01-04 10:45:20 -060013int fdt_setprop_inplace_namelen_partial(void *fdt, int nodeoffset,
14 const char *name, int namelen,
15 uint32_t idx, const void *val,
16 int len)
David Gibson1cade992007-12-10 14:28:39 +110017{
18 void *propval;
19 int proplen;
20
Rob Herring6f05afc2017-01-04 10:45:20 -060021 propval = fdt_getprop_namelen_w(fdt, nodeoffset, name, namelen,
22 &proplen);
23 if (!propval)
24 return proplen;
25
Rob Herring6e9c9682020-10-12 09:58:15 -050026 if ((unsigned)proplen < (len + idx))
Rob Herring6f05afc2017-01-04 10:45:20 -060027 return -FDT_ERR_NOSPACE;
28
29 memcpy((char *)propval + idx, val, len);
30 return 0;
31}
32
33int fdt_setprop_inplace(void *fdt, int nodeoffset, const char *name,
34 const void *val, int len)
35{
36 const void *propval;
37 int proplen;
38
39 propval = fdt_getprop(fdt, nodeoffset, name, &proplen);
Rob Herring4201d052017-10-03 11:37:04 -050040 if (!propval)
David Gibson1cade992007-12-10 14:28:39 +110041 return proplen;
42
43 if (proplen != len)
44 return -FDT_ERR_NOSPACE;
45
Rob Herring6f05afc2017-01-04 10:45:20 -060046 return fdt_setprop_inplace_namelen_partial(fdt, nodeoffset, name,
47 strlen(name), 0,
48 val, len);
David Gibson1cade992007-12-10 14:28:39 +110049}
50
Rob Herring9130ba82018-02-27 17:40:38 -060051static void fdt_nop_region_(void *start, int len)
David Gibson1cade992007-12-10 14:28:39 +110052{
Rob Herring47605972015-04-29 16:00:05 -050053 fdt32_t *p;
David Gibson1cade992007-12-10 14:28:39 +110054
David Gibsoned95d742008-08-07 12:24:17 +100055 for (p = start; (char *)p < ((char *)start + len); p++)
David Gibson1cade992007-12-10 14:28:39 +110056 *p = cpu_to_fdt32(FDT_NOP);
57}
58
59int fdt_nop_property(void *fdt, int nodeoffset, const char *name)
60{
61 struct fdt_property *prop;
62 int len;
63
64 prop = fdt_get_property_w(fdt, nodeoffset, name, &len);
Rob Herring4201d052017-10-03 11:37:04 -050065 if (!prop)
David Gibson1cade992007-12-10 14:28:39 +110066 return len;
67
Rob Herring9130ba82018-02-27 17:40:38 -060068 fdt_nop_region_(prop, len + sizeof(*prop));
David Gibson1cade992007-12-10 14:28:39 +110069
70 return 0;
71}
72
Rob Herring9130ba82018-02-27 17:40:38 -060073int fdt_node_end_offset_(void *fdt, int offset)
David Gibson1cade992007-12-10 14:28:39 +110074{
Stephen Warrencd296722012-09-28 21:25:59 +000075 int depth = 0;
David Gibson1cade992007-12-10 14:28:39 +110076
Stephen Warrencd296722012-09-28 21:25:59 +000077 while ((offset >= 0) && (depth >= 0))
78 offset = fdt_next_node(fdt, offset, &depth);
David Gibson1cade992007-12-10 14:28:39 +110079
Stephen Warrencd296722012-09-28 21:25:59 +000080 return offset;
David Gibson1cade992007-12-10 14:28:39 +110081}
82
83int fdt_nop_node(void *fdt, int nodeoffset)
84{
85 int endoffset;
86
Rob Herring9130ba82018-02-27 17:40:38 -060087 endoffset = fdt_node_end_offset_(fdt, nodeoffset);
David Gibson1cade992007-12-10 14:28:39 +110088 if (endoffset < 0)
89 return endoffset;
90
Rob Herring9130ba82018-02-27 17:40:38 -060091 fdt_nop_region_(fdt_offset_ptr_w(fdt, nodeoffset, 0),
David Gibsoned95d742008-08-07 12:24:17 +100092 endoffset - nodeoffset);
David Gibson1cade992007-12-10 14:28:39 +110093 return 0;
94}