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