libfdt: Use void * to refer to device tree blobs

At present, the blob containing a device tree is passed to the various
fdt_*() functions as a (struct fdt_header *) i.e. a pointer to the
header structure at the beginning of the blob.

This patch changes all the functions so that they instead take a (void
*) pointing to the blob.  Under some circumstances can avoid the need
for the caller to cast a blob pointer into a (struct fdt_header *)
before passing it to the fdt_*() functions.

Using a (void *) also reduce the temptation for users of the library
to directly dereference toe (struct fdt_header *) to access header
fields.  Instead they must use the fdt_get_header() or
fdt_set_header() macros, or the fdt_magic(), fdt_totalsize()
etc. wrappers around them which are safer, since they will always
handle endian conversion.

With this change, the whole-tree moving, or manipulating functions:
fdt_move(), fdt_open_into() and fdt_pack() no longer need to return a
pointer to the "new" tree.  The given (void *) buffer pointer they
take can instead be used directly by the caller as the new tree.
Those functions are thus changed to instead return an error code
(which in turn reduces the number of functions using the ugly encoding
of error values into pointers).

Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
diff --git a/fdt.c b/fdt.c
index 3b900a8..bc3ec22 100644
--- a/fdt.c
+++ b/fdt.c
@@ -23,7 +23,7 @@
 
 #include "libfdt_internal.h"
 
-int _fdt_check_header(const struct fdt_header *fdt)
+int _fdt_check_header(const void *fdt)
 {
 	if (fdt_magic(fdt) == FDT_MAGIC) {
 		/* Complete tree */
@@ -42,7 +42,7 @@
 	return 0;
 }
 
-void *fdt_offset_ptr(const struct fdt_header *fdt, int offset, int len)
+void *fdt_offset_ptr(const void *fdt, int offset, int len)
 {
 	void *p;
 
@@ -58,7 +58,7 @@
 	return p;
 }
 
-uint32_t _fdt_next_tag(const struct fdt_header *fdt, int offset, int *nextoffset)
+uint32_t _fdt_next_tag(const void *fdt, int offset, int *nextoffset)
 {
 	const uint32_t *tagp, *lenp;
 	uint32_t tag;
@@ -109,16 +109,16 @@
 	return NULL;
 }
 
-struct fdt_header *fdt_move(const struct fdt_header *fdt, void *buf, int bufsize)
+int fdt_move(const void *fdt, void *buf, int bufsize)
 {
 	int err = _fdt_check_header(fdt);
 
 	if (err)
-		return PTR_ERROR(err);
+		return err;
 
 	if (fdt_totalsize(fdt) > bufsize)
-		return PTR_ERROR(FDT_ERR_NOSPACE);
+		return FDT_ERR_NOSPACE;
 
 	memmove(buf, fdt, fdt_totalsize(fdt));
-	return (struct fdt_header *)buf;
+	return FDT_ERR_OK;
 }
diff --git a/fdt_ro.c b/fdt_ro.c
index 1b2383c..b58029a 100644
--- a/fdt_ro.c
+++ b/fdt_ro.c
@@ -37,7 +37,7 @@
 			return PTR_ERROR(err); \
 	}
 
-static int offset_streq(const struct fdt_header *fdt, int offset,
+static int offset_streq(const void *fdt, int offset,
 			const char *s, int len)
 {
 	const char *p = fdt_offset_ptr(fdt, offset, len+1);
@@ -55,12 +55,12 @@
 	return 1;
 }
 
-char *fdt_string(const struct fdt_header *fdt, int stroffset)
+char *fdt_string(const void *fdt, int stroffset)
 {
 	return (char *)fdt + fdt_off_dt_strings(fdt) + stroffset;
 }
 
-int fdt_subnode_offset_namelen(const struct fdt_header *fdt, int parentoffset,
+int fdt_subnode_offset_namelen(const void *fdt, int parentoffset,
 			       const char *name, int namelen)
 {
 	int level = 0;
@@ -106,13 +106,13 @@
 	return OFFSET_ERROR(FDT_ERR_NOTFOUND);
 }
 
-int fdt_subnode_offset(const struct fdt_header *fdt, int parentoffset,
+int fdt_subnode_offset(const void *fdt, int parentoffset,
 		       const char *name)
 {
 	return fdt_subnode_offset_namelen(fdt, parentoffset, name, strlen(name));
 }
 
-int fdt_path_offset(const struct fdt_header *fdt, const char *path)
+int fdt_path_offset(const void *fdt, const char *path)
 {
 	const char *end = path + strlen(path);
 	const char *p = path;
@@ -144,7 +144,7 @@
 	return offset;	
 }
 
-struct fdt_property *fdt_get_property(const struct fdt_header *fdt,
+struct fdt_property *fdt_get_property(const void *fdt,
 				      int nodeoffset,
 				      const char *name, int *lenp)
 {
@@ -215,7 +215,7 @@
 	return PTR_ERROR(FDT_ERR_NOTFOUND);
 }
 
-void *fdt_getprop(const struct fdt_header *fdt, int nodeoffset,
+void *fdt_getprop(const void *fdt, int nodeoffset,
 		  const char *name, int *lenp)
 {
 	const struct fdt_property *prop;
diff --git a/fdt_rw.c b/fdt_rw.c
index 8049205..4b7d1d5 100644
--- a/fdt_rw.c
+++ b/fdt_rw.c
@@ -23,7 +23,7 @@
 
 #include "libfdt_internal.h"
 
-static int rw_check_header(struct fdt_header *fdt)
+static int rw_check_header(void *fdt)
 {
 	int err;
 
@@ -31,7 +31,7 @@
 		return err;
 	if (fdt_version(fdt) < 0x11)
 		return FDT_ERR_BADVERSION;
-	if (fdt_off_mem_rsvmap(fdt) < ALIGN(sizeof(*fdt), 8))
+	if (fdt_off_mem_rsvmap(fdt) < ALIGN(sizeof(struct fdt_header), 8))
 		return FDT_ERR_BADLAYOUT;
 	if (fdt_off_dt_struct(fdt) <
 	    (fdt_off_mem_rsvmap(fdt) + sizeof(struct fdt_reserve_entry)))
@@ -52,25 +52,24 @@
 			return OFFSET_ERROR(err); \
 	}
 
-static inline int _blob_data_size(struct fdt_header *fdt)
+static inline int _blob_data_size(void *fdt)
 {
 	return fdt_off_dt_strings(fdt) + fdt_size_dt_strings(fdt);
 }
 
-static int _blob_splice(struct fdt_header *fdt, void *p, int oldlen, int newlen)
+static int _blob_splice(void *fdt, void *p, int oldlen, int newlen)
 {
-	void *blob = fdt;
-	void *end = blob + _blob_data_size(fdt);
+	void *end = fdt + _blob_data_size(fdt);
 
 	if (((p + oldlen) < p) || ((p + oldlen) > end))
 		return FDT_ERR_BADOFFSET;
-	if ((end - oldlen + newlen) > (blob + fdt_totalsize(fdt)))
+	if ((end - oldlen + newlen) > (fdt + fdt_totalsize(fdt)))
 		return FDT_ERR_NOSPACE;
 	memmove(p + newlen, p + oldlen, end - p - oldlen);
 	return 0;
 }
 
-static int _blob_splice_struct(struct fdt_header *fdt, void *p,
+static int _blob_splice_struct(void *fdt, void *p,
 			       int oldlen, int newlen)
 {
 	int delta = newlen - oldlen;
@@ -79,25 +78,24 @@
 	if ((err = _blob_splice(fdt, p, oldlen, newlen)))
 		return err;
 
-	fdt->size_dt_struct = cpu_to_fdt32(fdt_size_dt_struct(fdt) + delta);
-	fdt->off_dt_strings = cpu_to_fdt32(fdt_off_dt_strings(fdt) + delta);
+	fdt_set_header(fdt, size_dt_struct, fdt_size_dt_struct(fdt) + delta);
+	fdt_set_header(fdt, off_dt_strings, fdt_off_dt_strings(fdt) + delta);
 	return 0;
 }
 
-static int _blob_splice_string(struct fdt_header *fdt, int newlen)
+static int _blob_splice_string(void *fdt, int newlen)
 {
-	void *blob = fdt;
-	void *p = blob + fdt_off_dt_strings(fdt) + fdt_size_dt_strings(fdt);
+	void *p = fdt + fdt_off_dt_strings(fdt) + fdt_size_dt_strings(fdt);
 	int err;
 
 	if ((err = _blob_splice(fdt, p, 0, newlen)))
 		return err;
 
-	fdt->size_dt_strings = cpu_to_fdt32(fdt_size_dt_strings(fdt) + newlen);
+	fdt_set_header(fdt, size_dt_strings, fdt_size_dt_strings(fdt) + newlen);
 	return 0;
 }
 
-static int _find_add_string(struct fdt_header *fdt, const char *s)
+static int _find_add_string(void *fdt, const char *s)
 {
 	char *strtab = (char *)fdt + fdt_off_dt_strings(fdt);
 	const char *p;
@@ -119,7 +117,7 @@
 	return (new - strtab);
 }
 
-static struct fdt_property *_resize_property(struct fdt_header *fdt, int nodeoffset,
+static struct fdt_property *_resize_property(void *fdt, int nodeoffset,
 					     const char *name, int len)
 {
 	struct fdt_property *prop;
@@ -139,7 +137,7 @@
 	return prop;
 }
 
-static struct fdt_property *_add_property(struct fdt_header *fdt, int nodeoffset,
+static struct fdt_property *_add_property(void *fdt, int nodeoffset,
 					  const char *name, int len)
 {
 	uint32_t tag;
@@ -170,7 +168,7 @@
 	return prop;
 }
 
-int fdt_setprop(struct fdt_header *fdt, int nodeoffset, const char *name,
+int fdt_setprop(void *fdt, int nodeoffset, const char *name,
 		const void *val, int len)
 {
 	struct fdt_property *prop;
@@ -192,7 +190,7 @@
 	return 0;
 }
 
-int fdt_delprop(struct fdt_header *fdt, int nodeoffset, const char *name)
+int fdt_delprop(void *fdt, int nodeoffset, const char *name)
 {
 	struct fdt_property *prop;
 	int len, proplen;
@@ -208,7 +206,7 @@
 	return _blob_splice_struct(fdt, prop, proplen, 0);
 }
 
-int fdt_add_subnode_namelen(struct fdt_header *fdt, int parentoffset,
+int fdt_add_subnode_namelen(void *fdt, int parentoffset,
 			    const char *name, int namelen)
 {
 	struct fdt_node_header *nh;
@@ -249,12 +247,12 @@
 	return offset;
 }
 
-int fdt_add_subnode(struct fdt_header *fdt, int parentoffset, const char *name)
+int fdt_add_subnode(void *fdt, int parentoffset, const char *name)
 {
 	return fdt_add_subnode_namelen(fdt, parentoffset, name, strlen(name));
 }
 
-int fdt_del_node(struct fdt_header *fdt, int nodeoffset)
+int fdt_del_node(void *fdt, int nodeoffset)
 {
 	int endoffset;
 	int err;
@@ -267,35 +265,36 @@
 				   endoffset - nodeoffset, 0);
 }
 
-struct fdt_header *fdt_open_into(struct fdt_header *fdt, void *buf, int bufsize)
+int fdt_open_into(void *fdt, void *buf, int bufsize)
 {
 	int err;
 
-	fdt = fdt_move(fdt, buf, bufsize);
-	if ((err = fdt_ptr_error(fdt)))
-		return PTR_ERROR(err);
+	err = fdt_move(fdt, buf, bufsize);
+	if (err)
+		return err;
 
-	fdt->totalsize = cpu_to_fdt32(bufsize);
+	fdt = buf;
+
+	fdt_set_header(fdt, totalsize, bufsize);
 
 	/* FIXME: re-order if necessary */
 
 	err = rw_check_header(fdt);
 	if (err)
-		return PTR_ERROR(err);
+		return err;
 
-	return fdt;
+	return FDT_ERR_OK;
 }
 
-struct fdt_header *fdt_pack(struct fdt_header *fdt)
+int fdt_pack(void *fdt)
 {
 	int err;
 
 	err = rw_check_header(fdt);
 	if (err)
-		return PTR_ERROR(err);
+		return err;
 
 	/* FIXME: pack components */
-
-	fdt->totalsize = cpu_to_fdt32(_blob_data_size(fdt));
-	return fdt;
+	fdt_set_header(fdt, totalsize, _blob_data_size(fdt));
+	return FDT_ERR_OK;
 }
diff --git a/fdt_sw.c b/fdt_sw.c
index 1a6b2cf..806b259 100644
--- a/fdt_sw.c
+++ b/fdt_sw.c
@@ -23,14 +23,14 @@
 
 #include "libfdt_internal.h"
 
-static int check_header_sw(struct fdt_header *fdt)
+static int check_header_sw(void *fdt)
 {
 	if (fdt_magic(fdt) != SW_MAGIC)
 		return FDT_ERR_BADMAGIC;
 	return 0;
 }
 
-static void *grab_space(struct fdt_header *fdt, int len)
+static void *grab_space(void *fdt, int len)
 {
 	int offset = fdt_size_dt_struct(fdt);
 	int spaceleft;
@@ -41,33 +41,33 @@
 	if ((offset + len < offset) || (offset + len > spaceleft))
 		return NULL;
 
-	fdt->size_dt_struct = cpu_to_fdt32(offset + len);
+	fdt_set_header(fdt, size_dt_struct, offset + len);
 	return fdt_offset_ptr(fdt, offset, len);
 }
 
-struct fdt_header *fdt_create(void *buf, int bufsize)
+int fdt_create(void *buf, int bufsize)
 {
-	struct fdt_header *fdt = buf;
+	void *fdt = buf;
 
 	if (bufsize < sizeof(struct fdt_header))
-		return NULL;
+		return FDT_ERR_NOSPACE;
 
 	memset(buf, 0, bufsize);
 
-	fdt->magic = cpu_to_fdt32(SW_MAGIC);
-	fdt->version = cpu_to_fdt32(FDT_LAST_SUPPORTED_VERSION);
-	fdt->last_comp_version= cpu_to_fdt32(FDT_FIRST_SUPPORTED_VERSION);
-	fdt->totalsize = cpu_to_fdt32(bufsize);
+	fdt_set_header(fdt, magic, SW_MAGIC);
+	fdt_set_header(fdt, version, FDT_LAST_SUPPORTED_VERSION);
+	fdt_set_header(fdt, last_comp_version, FDT_FIRST_SUPPORTED_VERSION);
+	fdt_set_header(fdt, totalsize, bufsize);
 
-	fdt->off_mem_rsvmap = cpu_to_fdt32(ALIGN(sizeof(*fdt),
-						 sizeof(struct fdt_reserve_entry)));
-	fdt->off_dt_struct = fdt->off_mem_rsvmap;
-	fdt->off_dt_strings = fdt32_to_cpu(bufsize);
+	fdt_set_header(fdt, off_mem_rsvmap, ALIGN(sizeof(struct fdt_header),
+					      sizeof(struct fdt_reserve_entry)));
+	fdt_set_header(fdt, off_dt_struct, fdt_off_mem_rsvmap(fdt));
+	fdt_set_header(fdt, off_dt_strings, bufsize);
 
-	return fdt;
+	return FDT_ERR_OK;
 }
 
-int fdt_add_reservemap_entry(struct fdt_header *fdt, uint64_t addr, uint64_t size)
+int fdt_add_reservemap_entry(void *fdt, uint64_t addr, uint64_t size)
 {
 	struct fdt_reserve_entry *re;
 	int err = check_header_sw(fdt);
@@ -86,17 +86,17 @@
 	re->address = cpu_to_fdt64(addr);
 	re->size = cpu_to_fdt64(size);
 
-	fdt->off_dt_struct = cpu_to_fdt32(offset + sizeof(*re));
+	fdt_set_header(fdt, off_dt_struct, offset + sizeof(*re));
 
 	return 0;
 }
 
-int fdt_finish_reservemap(struct fdt_header *fdt)
+int fdt_finish_reservemap(void *fdt)
 {
 	return fdt_add_reservemap_entry(fdt, 0, 0);
 }
 
-int fdt_begin_node(struct fdt_header *fdt, const char *name)
+int fdt_begin_node(void *fdt, const char *name)
 {
 	struct fdt_node_header *nh;
 	int err = check_header_sw(fdt);
@@ -114,7 +114,7 @@
 	return 0;
 }
 
-int fdt_end_node(struct fdt_header *fdt)
+int fdt_end_node(void *fdt)
 {
 	uint32_t *en;
 	int err = check_header_sw(fdt);
@@ -130,7 +130,7 @@
 	return 0;
 }
 
-static int find_add_string(struct fdt_header *fdt, const char *s)
+static int find_add_string(void *fdt, const char *s)
 {
 	char *strtab = (char *)fdt + fdt_totalsize(fdt);
 	const char *p;
@@ -149,11 +149,11 @@
 		return 0; /* no more room :( */
 
 	memcpy(strtab + offset, s, len);
-	fdt->size_dt_strings = cpu_to_fdt32(strtabsize + len);
+	fdt_set_header(fdt, size_dt_strings, strtabsize + len);
 	return offset;
 }
 
-int fdt_property(struct fdt_header *fdt, const char *name, const void *val, int len)
+int fdt_property(void *fdt, const char *name, const void *val, int len)
 {
 	struct fdt_property *prop;
 	int err = check_header_sw(fdt);
@@ -177,7 +177,7 @@
 	return 0;
 }
 
-int fdt_finish(struct fdt_header *fdt)
+int fdt_finish(void *fdt)
 {
 	int err = check_header_sw(fdt);
 	char *p = (char *)fdt;
@@ -199,7 +199,7 @@
 	oldstroffset = fdt_totalsize(fdt) - fdt_size_dt_strings(fdt);
 	newstroffset = fdt_off_dt_struct(fdt) + fdt_size_dt_struct(fdt);
 	memmove(p + newstroffset, p + oldstroffset, fdt_size_dt_strings(fdt));
-	fdt->off_dt_strings = fdt32_to_cpu(newstroffset);
+	fdt_set_header(fdt, off_dt_strings, newstroffset);
 
 	/* Walk the structure, correcting string offsets */
 	offset = 0;
@@ -220,7 +220,7 @@
 	}
 
 	/* Finally, adjust the header */
-	fdt->totalsize = cpu_to_fdt32(newstroffset + fdt_size_dt_strings(fdt));
-	fdt->magic = cpu_to_fdt32(FDT_MAGIC);
+	fdt_set_header(fdt, totalsize, newstroffset + fdt_size_dt_strings(fdt));
+	fdt_set_header(fdt, magic, FDT_MAGIC);
 	return 0;
 }
diff --git a/fdt_wip.c b/fdt_wip.c
index fa0df78..d353377 100644
--- a/fdt_wip.c
+++ b/fdt_wip.c
@@ -23,7 +23,7 @@
 
 #include "libfdt_internal.h"
 
-int fdt_setprop_inplace(struct fdt_header *fdt, int nodeoffset, const char *name,
+int fdt_setprop_inplace(void *fdt, int nodeoffset, const char *name,
 			const void *val, int len)
 {
 	void *propval;
@@ -49,7 +49,7 @@
 		*p = cpu_to_fdt32(FDT_NOP);
 }
 
-int fdt_nop_property(struct fdt_header *fdt, int nodeoffset, const char *name)
+int fdt_nop_property(void *fdt, int nodeoffset, const char *name)
 {
 	struct fdt_property *prop;
 	int len;
@@ -64,7 +64,7 @@
 	return 0;
 }
 
-int _fdt_node_end_offset(struct fdt_header *fdt, int nodeoffset)
+int _fdt_node_end_offset(void *fdt, int nodeoffset)
 {
 	int level = 0;
 	uint32_t tag;
@@ -101,7 +101,7 @@
 	return nextoffset;
 }
 
-int fdt_nop_node(struct fdt_header *fdt, int nodeoffset)
+int fdt_nop_node(void *fdt, int nodeoffset)
 {
 	int endoffset;
 	int err;
diff --git a/libfdt.h b/libfdt.h
index cee2b3c..ed834bd 100644
--- a/libfdt.h
+++ b/libfdt.h
@@ -45,18 +45,23 @@
 
 #define FDT_ERR_MAX		14
 
-#define fdt_magic(fdt)			(fdt32_to_cpu(fdt->magic))
-#define fdt_totalsize(fdt)		(fdt32_to_cpu(fdt->totalsize))
-#define fdt_off_dt_struct(fdt)		(fdt32_to_cpu(fdt->off_dt_struct))
-#define fdt_off_dt_strings(fdt)		(fdt32_to_cpu(fdt->off_dt_strings))
-#define fdt_off_mem_rsvmap(fdt)		(fdt32_to_cpu(fdt->off_mem_rsvmap))
-#define fdt_version(fdt)		(fdt32_to_cpu(fdt->version))
-#define fdt_last_comp_version(fdt)	(fdt32_to_cpu(fdt->last_comp_version))
-#define fdt_boot_cpuid_phys(fdt)	(fdt32_to_cpu(fdt->boot_cpuid_phys))
-#define fdt_size_dt_strings(fdt)	(fdt32_to_cpu(fdt->size_dt_strings))
-#define fdt_size_dt_struct(fdt)		(fdt32_to_cpu(fdt->size_dt_struct))
+#define fdt_get_header(fdt, field) \
+	(fdt32_to_cpu(((struct fdt_header *)(fdt))->field))
+#define fdt_magic(fdt) 			(fdt_get_header(fdt, magic))
+#define fdt_totalsize(fdt)		(fdt_get_header(fdt, totalsize))
+#define fdt_off_dt_struct(fdt)		(fdt_get_header(fdt, off_dt_struct))
+#define fdt_off_dt_strings(fdt)		(fdt_get_header(fdt, off_dt_strings))
+#define fdt_off_mem_rsvmap(fdt)		(fdt_get_header(fdt, off_mem_rsvmap))
+#define fdt_version(fdt)		(fdt_get_header(fdt, version))
+#define fdt_last_comp_version(fdt) 	(fdt_get_header(fdt, last_comp_version))
+#define fdt_boot_cpuid_phys(fdt) 	(fdt_get_header(fdt, boot_cpuid_phys))
+#define fdt_size_dt_strings(fdt) 	(fdt_get_header(fdt, size_dt_strings))
+#define fdt_size_dt_struct(fdt)		(fdt_get_header(fdt, size_dt_struct))
 
-void *fdt_offset_ptr(const struct fdt_header *fdt, int offset, int checklen);
+#define fdt_set_header(fdt, field, val) \
+	((struct fdt_header *)(fdt))->field = cpu_to_fdt32(val)
+
+void *fdt_offset_ptr(const void *fdt, int offset, int checklen);
 
 #define fdt_offset_ptr_typed(fdt, offset, var) \
 	((typeof(var))(fdt_offset_ptr((fdt), (offset), sizeof(*(var)))))
@@ -67,26 +72,24 @@
 #define fdt_ptr_error(ptr) \
 	( (((long)(ptr) < 0) && ((long)(ptr) >= -FDT_ERR_MAX)) ? -(long)(ptr) : 0 )
 
-struct fdt_header *fdt_move(const struct fdt_header *fdt, void *buf, int bufsize);
+int fdt_move(const void *fdt, void *buf, int bufsize);
 
 /* Read-only functions */
-char *fdt_string(const struct fdt_header *fdt, int stroffset);
+char *fdt_string(const void *fdt, int stroffset);
 
-int fdt_subnode_offset_namelen(const struct fdt_header *fdt, int parentoffset,
+int fdt_subnode_offset_namelen(const void *fdt, int parentoffset,
 			       const char *name, int namelen);
-int fdt_subnode_offset(const struct fdt_header *fdt, int parentoffset,
-		       const char *name);
+int fdt_subnode_offset(const void *fdt, int parentoffset, const char *name);
 
-int fdt_path_offset(const struct fdt_header *fdt, const char *path);
+int fdt_path_offset(const void *fdt, const char *path);
 
-struct fdt_property *fdt_get_property(const struct fdt_header *fdt,
-				      int nodeoffset,
+struct fdt_property *fdt_get_property(const void *fdt, int nodeoffset,
 				      const char *name, int *lenp);
-void *fdt_getprop(const struct fdt_header *fdt, int nodeoffset,
+void *fdt_getprop(const void *fdt, int nodeoffset,
 		  const char *name, int *lenp);
 
 /* Write-in-place functions */
-int fdt_setprop_inplace(struct fdt_header *fdt, int nodeoffset, const char *name,
+int fdt_setprop_inplace(void *fdt, int nodeoffset, const char *name,
 			const void *val, int len);
 
 #define fdt_setprop_inplace_typed(fdt, nodeoffset, name, val) \
@@ -95,15 +98,15 @@
 		fdt_setprop_inplace(fdt, nodeoffset, name, &x, sizeof(x)); \
 	})
 
-int fdt_nop_property(struct fdt_header *fdt, int nodeoffset, const char *name);
-int fdt_nop_node(struct fdt_header *fdt, int nodeoffset);
+int fdt_nop_property(void *fdt, int nodeoffset, const char *name);
+int fdt_nop_node(void *fdt, int nodeoffset);
 
 /* Sequential-write functions */
-struct fdt_header *fdt_create(void *buf, int bufsize);
-int fdt_add_reservemap_entry(struct fdt_header *fdt, uint64_t addr, uint64_t size);
-int fdt_finish_reservemap(struct fdt_header *fdt);
-int fdt_begin_node(struct fdt_header *fdt, const char *name);
-int fdt_property(struct fdt_header *fdt, const char *name, const void *val, int len);
+int fdt_create(void *buf, int bufsize);
+int fdt_add_reservemap_entry(void *fdt, uint64_t addr, uint64_t size);
+int fdt_finish_reservemap(void *fdt);
+int fdt_begin_node(void *fdt, const char *name);
+int fdt_property(void *fdt, const char *name, const void *val, int len);
 #define fdt_property_typed(fdt, name, val) \
 	({ \
 		typeof(val) x = (val); \
@@ -111,14 +114,14 @@
 	})
 #define fdt_property_string(fdt, name, str) \
 	fdt_property(fdt, name, str, strlen(str)+1)
-int fdt_end_node(struct fdt_header *fdt);
-int fdt_finish(struct fdt_header *fdt);
+int fdt_end_node(void *fdt);
+int fdt_finish(void *fdt);
 
 /* Read-write functions */
-struct fdt_header *fdt_open_into(struct fdt_header *fdt, void *buf, int bufsize);
-struct fdt_header *fdt_pack(struct fdt_header *fdt);
+int fdt_open_into(void *fdt, void *buf, int bufsize);
+int fdt_pack(void *fdt);
 
-int fdt_setprop(struct fdt_header *fdt, int nodeoffset, const char *name,
+int fdt_setprop(void *fdt, int nodeoffset, const char *name,
 		const void *val, int len);
 #define fdt_setprop_typed(fdt, nodeoffset, name, val) \
 	({ \
@@ -127,10 +130,10 @@
 	})
 #define fdt_setprop_string(fdt, nodeoffset, name, str) \
 	fdt_setprop((fdt), (nodeoffset), (name), (str), strlen(str)+1)
-int fdt_delprop(struct fdt_header *fdt, int nodeoffset, const char *name);
-int fdt_add_subnode_namelen(struct fdt_header *fdt, int parentoffset,
+int fdt_delprop(void *fdt, int nodeoffset, const char *name);
+int fdt_add_subnode_namelen(void *fdt, int parentoffset,
 			    const char *name, int namelen);
-int fdt_add_subnode(struct fdt_header *fdt, int parentoffset, const char *name);
-int fdt_del_node(struct fdt_header *fdt, int nodeoffset);
+int fdt_add_subnode(void *fdt, int parentoffset, const char *name);
+int fdt_del_node(void *fdt, int nodeoffset);
 
 #endif /* _LIBFDT_H */
diff --git a/libfdt_internal.h b/libfdt_internal.h
index d8c7551..9cb8a8c 100644
--- a/libfdt_internal.h
+++ b/libfdt_internal.h
@@ -26,10 +26,10 @@
 #define memeq(p, q, n)	(memcmp((p), (q), (n)) == 0)
 #define streq(p, q)	(strcmp((p), (q)) == 0)
 
-int _fdt_check_header(const struct fdt_header *fdt);
-uint32_t _fdt_next_tag(const struct fdt_header *fdt, int startoffset, int *nextoffset);
+int _fdt_check_header(const void *fdt);
+uint32_t _fdt_next_tag(const void *fdt, int startoffset, int *nextoffset);
 const char *_fdt_find_string(const char *strtab, int tabsize, const char *s);
-int _fdt_node_end_offset(struct fdt_header *fdt, int nodeoffset);
+int _fdt_node_end_offset(void *fdt, int nodeoffset);
 
 static inline void *_fdt_offset_ptr(const struct fdt_header *fdt, int offset)
 {
diff --git a/tests/del_node.c b/tests/del_node.c
index 71d6831..87be4b5 100644
--- a/tests/del_node.c
+++ b/tests/del_node.c
@@ -31,7 +31,7 @@
 
 int main(int argc, char *argv[])
 {
-	struct fdt_header *fdt;
+	void *fdt;
 	int subnode1_offset, subnode2_offset, subsubnode2_offset;
 	int err;
 	int oldsize, delsize, newsize;
@@ -98,8 +98,8 @@
 
 	delsize = fdt_totalsize(fdt);
 
-	fdt = fdt_pack(fdt);
-	if ((err = fdt_ptr_error(fdt)))
+	err = fdt_pack(fdt);
+	if (err)
 		FAIL("fdt_pack(): %s", fdt_strerror(err));
 
 	newsize = fdt_totalsize(fdt);
diff --git a/tests/del_property.c b/tests/del_property.c
index 94bf47a..d63cf5a 100644
--- a/tests/del_property.c
+++ b/tests/del_property.c
@@ -31,7 +31,7 @@
 
 int main(int argc, char *argv[])
 {
-	struct fdt_header *fdt;
+	void *fdt;
 	uint32_t *intp;
 	char *strp;
 	int err;
@@ -72,8 +72,8 @@
 
 	delsize = fdt_totalsize(fdt);
 
-	fdt = fdt_pack(fdt);
-	if ((err = fdt_ptr_error(fdt)))
+	err = fdt_pack(fdt);
+	if (err)
 		FAIL("fdt_pack(): %s\n", fdt_strerror(err));
 
 	newsize = fdt_totalsize(fdt);
diff --git a/tests/dumptrees.c b/tests/dumptrees.c
index f0a9b2c..bea943b 100644
--- a/tests/dumptrees.c
+++ b/tests/dumptrees.c
@@ -4,12 +4,13 @@
 #include <fcntl.h>
 
 #include <fdt.h>
+#include <libfdt.h>
 #include <libfdt_env.h>
 
 #include "testdata.h"
 
 struct {
-	struct fdt_header *fdt;
+	void *blob;
 	const char *filename;
 } trees[] = {
 #define TREE(name)	{ &_##name, #name ".dtb" }
@@ -23,13 +24,13 @@
 	int i;
 
 	for (i = 0; i < NUM_TREES; i++) {
-		struct fdt_header *fdt = trees[i].fdt;
+		void *blob = trees[i].blob;
 		const char *filename = trees[i].filename;
 		int size;
 		int fd;
 		int ret;
 
-		size = fdt32_to_cpu(fdt->totalsize);
+		size = fdt_totalsize(blob);
 
 		printf("Tree \"%s\", %d bytes\n", filename, size);
 
@@ -37,7 +38,7 @@
 		if (fd < 0)
 			perror("open()");
 
-		ret = write(fd, fdt, size);
+		ret = write(fd, blob, size);
 		if (ret != size)
 			perror("write()");
 
diff --git a/tests/find_property.c b/tests/find_property.c
index 1745258..8a8e9aa 100644
--- a/tests/find_property.c
+++ b/tests/find_property.c
@@ -29,7 +29,7 @@
 
 int main(int argc, char *argv[])
 {
-	struct fdt_header *fdt;
+	void *fdt;
 
 	test_init(argc, argv);
 	fdt = load_blob_arg(argc, argv);
diff --git a/tests/getprop.c b/tests/getprop.c
index 962b912..22dc03b 100644
--- a/tests/getprop.c
+++ b/tests/getprop.c
@@ -30,7 +30,7 @@
 
 int main(int argc, char *argv[])
 {
-	struct fdt_header *fdt;
+	void *fdt;
 
 	test_init(argc, argv);
 	fdt = load_blob_arg(argc, argv);
diff --git a/tests/move_and_save.c b/tests/move_and_save.c
index 526f615..4b4824e 100644
--- a/tests/move_and_save.c
+++ b/tests/move_and_save.c
@@ -30,7 +30,7 @@
 
 int main(int argc, char *argv[])
 {
-	struct fdt_header *fdt, *fdt1, *fdt2, *fdt3;
+	void *fdt, *fdt1, *fdt2, *fdt3;
 	void *buf;
 	int shuntsize;
 	int bufsize;
@@ -46,22 +46,25 @@
 	bufsize = fdt_totalsize(fdt) + shuntsize;
 	buf = xmalloc(bufsize);
 
-	fdt1 = fdt_move(fdt, buf, bufsize);
-	if ((err = fdt_ptr_error(fdt1)))
+	fdt1 = buf;
+	err = fdt_move(fdt, fdt1, bufsize);
+	if (err)
 		FAIL("Failed to move tree into new buffer: %s",
 		     fdt_strerror(err));
 	sprintf(outname, "moved.%s", inname);
 	save_blob(outname, fdt1);
 
-	fdt2 = fdt_move(fdt1, buf + shuntsize, bufsize-shuntsize);
-	if ((err = fdt_ptr_error(fdt2)))
+	fdt2 = buf + shuntsize;
+	err = fdt_move(fdt1, fdt2, bufsize-shuntsize);
+	if (err)
 		FAIL("Failed to shunt tree %d bytes: %s",
 		     shuntsize, fdt_strerror(err));
 	sprintf(outname, "shunted.%s", inname);
 	save_blob(outname, fdt2);
 
-	fdt3 = fdt_move(fdt2, buf, bufsize);
-	if ((err = fdt_ptr_error(fdt3)))
+	fdt3 = buf;
+	err = fdt_move(fdt2, fdt3, bufsize);
+	if (err)
 		FAIL("Failed to deshunt tree %d bytes: %s",
 		     shuntsize, fdt_strerror(err));
 	sprintf(outname, "deshunted.%s", inname);
diff --git a/tests/nop_node.c b/tests/nop_node.c
index df421c0..2db1b29 100644
--- a/tests/nop_node.c
+++ b/tests/nop_node.c
@@ -31,7 +31,7 @@
 
 int main(int argc, char *argv[])
 {
-	struct fdt_header *fdt;
+	void *fdt;
 	int subnode1_offset, subnode2_offset, subsubnode2_offset;
 	int err;
 
diff --git a/tests/nop_property.c b/tests/nop_property.c
index 94c8e74..14754b0 100644
--- a/tests/nop_property.c
+++ b/tests/nop_property.c
@@ -31,7 +31,7 @@
 
 int main(int argc, char *argv[])
 {
-	struct fdt_header *fdt;
+	void *fdt;
 	uint32_t *intp;
 	char *strp;
 	int err;
diff --git a/tests/notfound.c b/tests/notfound.c
index 9cdc29c..d2821a5 100644
--- a/tests/notfound.c
+++ b/tests/notfound.c
@@ -37,7 +37,7 @@
 int main(int argc, char *argv[])
 {
 	struct fdt_property *prop;
-	struct fdt_header *fdt;
+	void *fdt;
 	int offset;
 	int subnode1_offset;
 	void *val;
diff --git a/tests/open_pack.c b/tests/open_pack.c
index c651694..1aa66e4 100644
--- a/tests/open_pack.c
+++ b/tests/open_pack.c
@@ -31,7 +31,7 @@
 
 int main(int argc, char *argv[])
 {
-	struct fdt_header *fdt, *fdt1, *fdt2;
+	void *fdt, *fdt1;
 	void *buf;
 	int oldsize, bufsize, packsize;
 	int err;
@@ -48,19 +48,20 @@
 
 	buf = xmalloc(bufsize);
 
-	fdt1 = fdt_open_into(fdt, buf, bufsize);
-	if ((err = fdt_ptr_error(fdt1)))
+	fdt1 = buf;
+	err = fdt_open_into(fdt, fdt1, bufsize);
+	if (err)
 		FAIL("fdt_open_into(): %s", fdt_strerror(err));
 	sprintf(outname, "opened.%s", inname);
 	save_blob(outname, fdt1);
 
-	fdt2 = fdt_pack(fdt1);
-	if ((err = fdt_ptr_error(fdt2)))
+	err = fdt_pack(fdt1);
+	if (err)
 		FAIL("fdt_pack(): %s", fdt_strerror(err));
 	sprintf(outname, "repacked.%s", inname);
-	save_blob(outname, fdt2);
+	save_blob(outname, fdt1);
 
-	packsize = fdt_totalsize(fdt2);
+	packsize = fdt_totalsize(fdt1);
 
 	verbose_printf("oldsize = %d, bufsize = %d, packsize = %d\n",
 		       oldsize, bufsize, packsize);
diff --git a/tests/path_offset.c b/tests/path_offset.c
index 32222be..5d5a246 100644
--- a/tests/path_offset.c
+++ b/tests/path_offset.c
@@ -27,7 +27,7 @@
 #include "tests.h"
 #include "testdata.h"
 
-int check_subnode(struct fdt_header *fdt, int parent, const char *name)
+int check_subnode(void *fdt, int parent, const char *name)
 {
 	int offset;
 	int err;
@@ -57,7 +57,7 @@
 
 int main(int argc, char *argv[])
 {
-	struct fdt_header *fdt;
+	void *fdt;
 	int subnode1_offset, subnode2_offset;
 	int subnode1_offset_p, subnode2_offset_p;
 	int subsubnode1_offset, subsubnode2_offset;
diff --git a/tests/root_node.c b/tests/root_node.c
index d331bdf..4258b91 100644
--- a/tests/root_node.c
+++ b/tests/root_node.c
@@ -30,7 +30,7 @@
 
 int main(int argc, char *argv[])
 {
-	struct fdt_header *fdt;
+	void *fdt;
 	struct fdt_node_header *nh;
 
 	test_init(argc, argv);
diff --git a/tests/rw_tree1.c b/tests/rw_tree1.c
index 8c5582a..cc5b926 100644
--- a/tests/rw_tree1.c
+++ b/tests/rw_tree1.c
@@ -38,13 +38,6 @@
 			FAIL(#code ": %s", fdt_strerror(err)); \
 	}
 
-#define PTR_CHECK(ptr, code) \
-	{ \
-		err = fdt_ptr_error((ptr) = (code)); \
-		if (err) \
-			FAIL(#code ": %s", fdt_strerror(err)); \
-	}
-
 #define OFF_CHECK(off, code) \
 	{ \
 		err = fdt_offset_error((off) = (code)); \
@@ -54,17 +47,16 @@
 
 int main(int argc, char *argv[])
 {
-	void *buf;
-	struct fdt_header *fdt;
+	void *fdt;
 	int err;
 	int offset;
 
 	test_init(argc, argv);
 
-	buf = xmalloc(SPACE);
+	fdt = xmalloc(SPACE);
 
 	/* First create empty tree with SW */
-	fdt = fdt_create(buf, SPACE);
+	CHECK(fdt_create(fdt, SPACE));
 
 	CHECK(fdt_finish_reservemap(fdt));
 	CHECK(fdt_begin_node(fdt, ""));
@@ -72,9 +64,9 @@
 	CHECK(fdt_finish(fdt));
 
 	verbose_printf("Built empty tree, totalsize = %d\n",
-		       fdt32_to_cpu(fdt->totalsize));
+		       fdt_totalsize(fdt));
 
-	PTR_CHECK(fdt, fdt_open_into(fdt, buf, SPACE));
+	CHECK(fdt_open_into(fdt, fdt, SPACE));
 
 	CHECK(fdt_setprop_typed(fdt, 0, "prop-int", TEST_VALUE_1));
 	CHECK(fdt_setprop_string(fdt, 0, "prop-str", TEST_STRING_1));
@@ -90,7 +82,7 @@
 
 	CHECK(fdt_setprop_typed(fdt, offset, "prop-int", TEST_VALUE_2));
 
-	PTR_CHECK(fdt, fdt_pack(fdt));
+	CHECK(fdt_pack(fdt));
 
 	save_blob("rw_tree1.test.dtb", fdt);
 
diff --git a/tests/setprop.c b/tests/setprop.c
index 3df854d..fc70910 100644
--- a/tests/setprop.c
+++ b/tests/setprop.c
@@ -34,7 +34,7 @@
 
 int main(int argc, char *argv[])
 {
-	struct fdt_header *fdt;
+	void *fdt;
 	void *buf;
 	uint32_t *intp;
 	char *strp;
@@ -45,10 +45,12 @@
 
 	buf = xmalloc(SPACE);
 
-	fdt = fdt_open_into(fdt, buf, SPACE);
-	if ((err = fdt_ptr_error(fdt)))
+	err = fdt_open_into(fdt, buf, SPACE);
+	if (err)
 		FAIL("fdt_open_into(): %s", fdt_strerror(err));
 
+	fdt = buf;
+
 	intp = check_getprop_typed(fdt, 0, "prop-int", TEST_VALUE_1);
 
 	verbose_printf("Old int value was 0x%08x\n", *intp);
diff --git a/tests/setprop_inplace.c b/tests/setprop_inplace.c
index 61de789..f674ec6 100644
--- a/tests/setprop_inplace.c
+++ b/tests/setprop_inplace.c
@@ -31,7 +31,7 @@
 
 int main(int argc, char *argv[])
 {
-	struct fdt_header *fdt;
+	void *fdt;
 	uint32_t *intp;
 	char *strp, *xstr;
 	int xlen, i;
diff --git a/tests/subnode_offset.c b/tests/subnode_offset.c
index 0552b05..3283e1a 100644
--- a/tests/subnode_offset.c
+++ b/tests/subnode_offset.c
@@ -57,7 +57,7 @@
 
 int main(int argc, char *argv[])
 {
-	struct fdt_header *fdt;
+	void *fdt;
 	int subnode1_offset, subnode2_offset;
 	int subsubnode1_offset, subsubnode2_offset;
 
diff --git a/tests/sw_tree1.c b/tests/sw_tree1.c
index 6f72006..51aa4d7 100644
--- a/tests/sw_tree1.c
+++ b/tests/sw_tree1.c
@@ -40,14 +40,13 @@
 
 int main(int argc, char *argv[])
 {
-	void *buf;
-	struct fdt_header *fdt;
+	void *fdt;
 	int err;
 
 	test_init(argc, argv);
 
-	buf = xmalloc(SPACE);
-	fdt = fdt_create(buf, SPACE);
+	fdt = xmalloc(SPACE);
+	CHECK(fdt_create(fdt, SPACE));
 
 	CHECK(fdt_finish_reservemap(fdt));
 	CHECK(fdt_begin_node(fdt, ""));
@@ -75,7 +74,7 @@
 	CHECK(fdt_finish(fdt));
 
 	verbose_printf("Completed tree, totalsize = %d\n",
-		       fdt32_to_cpu(fdt->totalsize));
+		       fdt_totalsize(fdt));
 
 	save_blob("sw_tree1.test.dtb", fdt);
 
diff --git a/tests/tests.h b/tests/tests.h
index a673b61..b4dd10a 100644
--- a/tests/tests.h
+++ b/tests/tests.h
@@ -109,7 +109,7 @@
 }
 
 const char *fdt_strerror(int errval);
-void check_property(struct fdt_header *fdt, int nodeoffset, const char *name,
+void check_property(void *fdt, int nodeoffset, const char *name,
 		    int len, const void *val);
 #define check_property_typed(fdt, nodeoffset, name, val) \
 	({ \
@@ -118,7 +118,7 @@
 	})
 
 
-void *check_getprop(struct fdt_header *fdt, int nodeoffset, const char *name,
+void *check_getprop(void *fdt, int nodeoffset, const char *name,
 		    int len, const void *val);
 #define check_getprop_typed(fdt, nodeoffset, name, val) \
 	({ \
@@ -129,6 +129,6 @@
 	check_getprop((fdt), (nodeoffset), (name), strlen(s)+1, (s))
 //void *load_blob(const char *filename);
 void *load_blob_arg(int argc, char *argv[]);
-void save_blob(const char *filename, struct fdt_header *fdt);
+void save_blob(const char *filename, void *blob);
 
 #endif /* _TESTS_H */
diff --git a/tests/testutils.c b/tests/testutils.c
index 994cdae..1f7a894 100644
--- a/tests/testutils.c
+++ b/tests/testutils.c
@@ -103,7 +103,7 @@
 		return "Unknown FDT error code";
 }
 
-void check_property(struct fdt_header *fdt, int nodeoffset, const char *name,
+void check_property(void *fdt, int nodeoffset, const char *name,
 		    int len, const void *val)
 {
 	const struct fdt_property *prop;
@@ -135,7 +135,7 @@
 	
 }
 
-void *check_getprop(struct fdt_header *fdt, int nodeoffset, const char *name,
+void *check_getprop(void *fdt, int nodeoffset, const char *name,
 		    int len, const void *val)
 {
 	void *propval;
@@ -195,7 +195,7 @@
 	return load_blob(argv[1]);
 }
 
-void save_blob(const char *filename, struct fdt_header *fdt)
+void save_blob(const char *filename, void *fdt)
 {
 	int fd;
 	int totalsize;
@@ -208,7 +208,7 @@
 		CONFIG("Couldn't open \"%s\" to write blob: %s", filename,
 		       strerror(errno));
 
-	totalsize = fdt32_to_cpu(fdt->totalsize);
+	totalsize = fdt_totalsize(fdt);
 	offset = 0;
 	p = fdt;