| 1 | |
| 2 | |
| 3 | * libfdt - Flat Device Tree manipulation
|
| 4 | * Copyright (C) 2006 David Gibson, IBM Corporation.
|
| 5 |
|
| 6 | #include "libfdt_env.h"
|
| 7 |
|
| 8 | #include <fdt.h>
|
| 9 | #include <libfdt.h>
|
| 10 |
|
| 11 | #include "libfdt_internal.h"
|
| 12 |
|
| 13 | int 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)
|
| 17 | {
|
| 18 | void *propval;
|
| 19 | int proplen;
|
| 20 |
|
| 21 | propval = fdt_getprop_namelen_w(fdt, nodeoffset, name, namelen,
|
| 22 | &proplen);
|
| 23 | if (!propval)
|
| 24 | return proplen;
|
| 25 |
|
| 26 | if ((unsigned)proplen < (len + idx))
|
| 27 | return -FDT_ERR_NOSPACE;
|
| 28 |
|
| 29 | memcpy((char *)propval + idx, val, len);
|
| 30 | return 0;
|
| 31 | }
|
| 32 |
|
| 33 | int 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);
|
| 40 | if (!propval)
|
| 41 | return proplen;
|
| 42 |
|
| 43 | if (proplen != len)
|
| 44 | return -FDT_ERR_NOSPACE;
|
| 45 |
|
| 46 | return fdt_setprop_inplace_namelen_partial(fdt, nodeoffset, name,
|
| 47 | strlen(name), 0,
|
| 48 | val, len);
|
| 49 | }
|
| 50 |
|
| 51 | static void fdt_nop_region_(void *start, int len)
|
| 52 | {
|
| 53 | fdt32_t *p;
|
| 54 |
|
| 55 | for (p = start; (char *)p < ((char *)start + len); p++)
|
| 56 | *p = cpu_to_fdt32(FDT_NOP);
|
| 57 | }
|
| 58 |
|
| 59 | int 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);
|
| 65 | if (!prop)
|
| 66 | return len;
|
| 67 |
|
| 68 | fdt_nop_region_(prop, len + sizeof(*prop));
|
| 69 |
|
| 70 | return 0;
|
| 71 | }
|
| 72 |
|
| 73 | int fdt_node_end_offset_(void *fdt, int offset)
|
| 74 | {
|
| 75 | int depth = 0;
|
| 76 |
|
| 77 | while ((offset >= 0) && (depth >= 0))
|
| 78 | offset = fdt_next_node(fdt, offset, &depth);
|
| 79 |
|
| 80 | return offset;
|
| 81 | }
|
| 82 |
|
| 83 | int fdt_nop_node(void *fdt, int nodeoffset)
|
| 84 | {
|
| 85 | int endoffset;
|
| 86 |
|
| 87 | endoffset = fdt_node_end_offset_(fdt, nodeoffset);
|
| 88 | if (endoffset < 0)
|
| 89 | return endoffset;
|
| 90 |
|
| 91 | fdt_nop_region_(fdt_offset_ptr_w(fdt, nodeoffset, 0),
|
| 92 | endoffset - nodeoffset);
|
| 93 | return 0;
|
| 94 | }
|