diff --git a/common/cmd_fdt.c b/common/cmd_fdt.c
index e2225c4d5c64e188b50a2f9f205426dac11ba5df..a5e2cfcbfa8ede2fffd84d5ef1beb13e7f75ff8b 100644
--- a/common/cmd_fdt.c
+++ b/common/cmd_fdt.c
@@ -35,6 +35,9 @@
 
 #define MAX_LEVEL	32		/* how deeply nested we will go */
 #define SCRATCHPAD	1024		/* bytes of scratchpad memory */
+#ifndef CONFIG_CMD_FDT_MAX_DUMP
+#define CONFIG_CMD_FDT_MAX_DUMP 64
+#endif
 
 /*
  * Global data (for the gd->bd)
@@ -44,6 +47,7 @@ DECLARE_GLOBAL_DATA_PTR;
 static int fdt_valid(void);
 static int fdt_parse_prop(char *const*newval, int count, char *data, int *len);
 static int fdt_print(const char *pathp, char *prop, int depth);
+static int is_printable_string(const void *data, int len);
 
 /*
  * The working_fdt points to our working flattened device tree.
@@ -60,6 +64,34 @@ void set_working_fdt_addr(void *addr)
 	setenv("fdtaddr", buf);
 }
 
+/*
+ * Get a value from the fdt and format it to be set in the environment
+ */
+static int fdt_value_setenv(const void *nodep, int len, const char *var)
+{
+	if (is_printable_string(nodep, len))
+		setenv(var, (void *)nodep);
+	else if (len == 4) {
+		char buf[11];
+
+		sprintf(buf, "0x%08X", *(uint32_t *)nodep);
+		setenv(var, buf);
+	} else if (len%4 == 0 && len <= 20) {
+		/* Needed to print things like sha1 hashes. */
+		char buf[41];
+		int i;
+
+		for (i = 0; i < len; i += sizeof(unsigned int))
+			sprintf(buf + (i * 2), "%08x",
+				*(unsigned int *)(nodep + i));
+		setenv(var, buf);
+	} else {
+		printf("error: unprintable value\n");
+		return 1;
+	}
+	return 0;
+}
+
 /*
  * Flattened Device Tree command, see the help for parameter definitions.
  */
@@ -250,6 +282,117 @@ int do_fdt (cmd_tbl_t * cmdtp, int flag, int argc, char * const argv[])
 			return 1;
 		}
 
+	/********************************************************************
+	 * Get the value of a property in the working_fdt.
+	 ********************************************************************/
+	} else if (argv[1][0] == 'g') {
+		char *subcmd;		/* sub-command */
+		char *pathp;		/* path */
+		char *prop;		/* property */
+		char *var;		/* variable to store result */
+		int  nodeoffset;	/* node offset from libfdt */
+		const void *nodep;	/* property node pointer */
+		int  len = 0;		/* new length of the property */
+
+		/*
+		 * Parameters: Node path, property, optional value.
+		 */
+		if (argc < 5)
+			return CMD_RET_USAGE;
+
+		subcmd = argv[2];
+
+		if (argc < 6 && subcmd[0] != 's')
+			return CMD_RET_USAGE;
+
+		var    = argv[3];
+		pathp  = argv[4];
+		prop   = argv[5];
+
+		nodeoffset = fdt_path_offset(working_fdt, pathp);
+		if (nodeoffset < 0) {
+			/*
+			 * Not found or something else bad happened.
+			 */
+			printf("libfdt fdt_path_offset() returned %s\n",
+				fdt_strerror(nodeoffset));
+			return 1;
+		}
+
+		if (subcmd[0] == 'n' || (subcmd[0] == 's' && argc == 5)) {
+			int reqIndex = -1;
+			int startDepth = fdt_node_depth(
+				working_fdt, nodeoffset);
+			int curDepth = startDepth;
+			int curIndex = -1;
+			int nextNodeOffset = fdt_next_node(
+				working_fdt, nodeoffset, &curDepth);
+
+			if (subcmd[0] == 'n')
+				reqIndex = simple_strtoul(argv[5], NULL, 16);
+
+			while (curDepth > startDepth) {
+				if (curDepth == startDepth + 1)
+					curIndex++;
+				if (subcmd[0] == 'n' && curIndex == reqIndex) {
+					const char *nodeName = fdt_get_name(
+					    working_fdt, nextNodeOffset, NULL);
+
+					setenv(var, (char *)nodeName);
+					return 0;
+				}
+				nextNodeOffset = fdt_next_node(
+					working_fdt, nextNodeOffset, &curDepth);
+				if (nextNodeOffset < 0)
+					break;
+			}
+			if (subcmd[0] == 's') {
+				/* get the num nodes at this level */
+				char buf[11];
+
+				sprintf(buf, "%d", curIndex + 1);
+				setenv(var, buf);
+			} else {
+				/* node index not found */
+				printf("libfdt node not found\n");
+				return 1;
+			}
+		} else {
+			nodep = fdt_getprop(
+				working_fdt, nodeoffset, prop, &len);
+			if (len == 0) {
+				/* no property value */
+				setenv(var, "");
+				return 0;
+			} else if (len > 0) {
+				if (subcmd[0] == 'v') {
+					int ret;
+
+					ret = fdt_value_setenv(nodep, len, var);
+					if (ret != 0)
+						return ret;
+				} else if (subcmd[0] == 'a') {
+					/* Get address */
+					char buf[11];
+
+					sprintf(buf, "0x%08X", (uint32_t)nodep);
+					setenv(var, buf);
+				} else if (subcmd[0] == 's') {
+					/* Get size */
+					char buf[11];
+
+					sprintf(buf, "0x%08X", len);
+					setenv(var, buf);
+				} else
+					return CMD_RET_USAGE;
+				return 0;
+			} else {
+				printf("libfdt fdt_getprop(): %s\n",
+					fdt_strerror(len));
+				return 1;
+			}
+		}
+
 	/*
 	 * Print (recursive) / List (single level)
 	 */
@@ -611,12 +754,12 @@ static int is_printable_string(const void *data, int len)
 	if (len == 0)
 		return 0;
 
-	/* must terminate with zero */
-	if (s[len - 1] != '\0')
+	/* must terminate with zero or '\n' */
+	if (s[len - 1] != '\0' && s[len - 1] != '\n')
 		return 0;
 
 	/* printable or a null byte (concatenated strings) */
-	while (((*s == '\0') || isprint(*s)) && (len > 0)) {
+	while (((*s == '\0') || isprint(*s) || isspace(*s)) && (len > 0)) {
 		/*
 		 * If we see a null, there are three possibilities:
 		 * 1) If len == 1, it is the end of the string, printable
@@ -672,19 +815,28 @@ static void print_data(const void *data, int len)
 	}
 
 	if ((len %4) == 0) {
-		const u32 *p;
-
-		printf("<");
-		for (j = 0, p = data; j < len/4; j ++)
-			printf("0x%x%s", fdt32_to_cpu(p[j]), j < (len/4 - 1) ? " " : "");
-		printf(">");
+		if (len > CONFIG_CMD_FDT_MAX_DUMP)
+			printf("* 0x%08x [0x%08x]", (unsigned int)data, len);
+		else {
+			const u32 *p;
+
+			printf("<");
+			for (j = 0, p = data; j < len/4; j++)
+				printf("0x%08x%s", fdt32_to_cpu(p[j]),
+					j < (len/4 - 1) ? " " : "");
+			printf(">");
+		}
 	} else { /* anything else... hexdump */
-		const u8 *s;
-
-		printf("[");
-		for (j = 0, s = data; j < len; j++)
-			printf("%02x%s", s[j], j < len - 1 ? " " : "");
-		printf("]");
+		if (len > CONFIG_CMD_FDT_MAX_DUMP)
+			printf("* 0x%08x [0x%08x]", (unsigned int)data, len);
+		else {
+			const u8 *s;
+
+			printf("[");
+			for (j = 0, s = data; j < len; j++)
+				printf("%02x%s", s[j], j < len - 1 ? " " : "");
+			printf("]");
+		}
 	}
 }
 
@@ -824,6 +976,10 @@ U_BOOT_CMD(
 	"fdt resize                          - Resize fdt to size + padding to 4k addr\n"
 	"fdt print  <path> [<prop>]          - Recursive print starting at <path>\n"
 	"fdt list   <path> [<prop>]          - Print one level starting at <path>\n"
+	"fdt get value <var> <path> <prop>   - Get <property> and store in <var>\n"
+	"fdt get name <var> <path> <index>   - Get name of node <index> and store in <var>\n"
+	"fdt get addr <var> <path> <prop>    - Get start address of <property> and store in <var>\n"
+	"fdt get size <var> <path> [<prop>]  - Get size of [<property>] or num nodes and store in <var>\n"
 	"fdt set    <path> <prop> [<val>]    - Set <property> [to <val>]\n"
 	"fdt mknode <path> <node>            - Create a new node after <path>\n"
 	"fdt rm     <path> [<prop>]          - Delete the node or <property>\n"
diff --git a/common/image.c b/common/image.c
index f084d2baed3e0685937c6d4be3b73eb8e54add3a..750a98b6ba9e46880f222c7fc6796d4427241f0b 100644
--- a/common/image.c
+++ b/common/image.c
@@ -2496,6 +2496,36 @@ int fit_image_hash_get_value(const void *fit, int noffset, uint8_t **value,
 	return 0;
 }
 
+#ifndef USE_HOSTCC
+/**
+ * fit_image_hash_get_ignore - get hash ignore flag
+ * @fit: pointer to the FIT format image header
+ * @noffset: hash node offset
+ * @ignore: pointer to an int, will hold hash ignore flag
+ *
+ * fit_image_hash_get_ignore() finds hash ignore property in a given hash node.
+ * If the property is found and non-zero, the hash algorithm is not verified by
+ * u-boot automatically.
+ *
+ * returns:
+ *     0, on ignore not found
+ *     value, on ignore found
+ */
+int fit_image_hash_get_ignore(const void *fit, int noffset, int *ignore)
+{
+	int len;
+	int *value;
+
+	value = (int *)fdt_getprop(fit, noffset, FIT_IGNORE_PROP, &len);
+	if (value == NULL || len != sizeof(int))
+		*ignore = 0;
+	else
+		*ignore = *value;
+
+	return 0;
+}
+#endif
+
 /**
  * fit_set_timestamp - set node timestamp property
  * @fit: pointer to the FIT format image header
@@ -2759,6 +2789,9 @@ int fit_image_check_hashes(const void *fit, int image_noffset)
 	char		*algo;
 	uint8_t		*fit_value;
 	int		fit_value_len;
+#ifndef USE_HOSTCC
+	int		ignore;
+#endif
 	uint8_t		value[FIT_MAX_HASH_LEN];
 	int		value_len;
 	int		noffset;
@@ -2795,6 +2828,14 @@ int fit_image_check_hashes(const void *fit, int image_noffset)
 			}
 			printf("%s", algo);
 
+#ifndef USE_HOSTCC
+			fit_image_hash_get_ignore(fit, noffset, &ignore);
+			if (ignore) {
+				printf("-skipped ");
+				continue;
+			}
+#endif
+
 			if (fit_image_hash_get_value(fit, noffset, &fit_value,
 							&fit_value_len)) {
 				err_msg = " error!\nCan't get hash value "
@@ -2820,6 +2861,11 @@ int fit_image_check_hashes(const void *fit, int image_noffset)
 		}
 	}
 
+	if (noffset == -FDT_ERR_TRUNCATED || noffset == -FDT_ERR_BADSTRUCTURE) {
+		err_msg = " error!\nCorrupted or truncated tree";
+		goto error;
+	}
+
 	return 1;
 
 error:
diff --git a/include/image.h b/include/image.h
index e5f6649291e24ccd524f67e211cd2bb63bf482a4..4e5863ff7fbd73fb6c22b981a2445f80b2213cc1 100644
--- a/include/image.h
+++ b/include/image.h
@@ -511,6 +511,7 @@ static inline int image_check_target_arch(const image_header_t *hdr)
 #define FIT_HASH_NODENAME	"hash"
 #define FIT_ALGO_PROP		"algo"
 #define FIT_VALUE_PROP		"value"
+#define FIT_IGNORE_PROP		"uboot-ignore"
 
 /* image node */
 #define FIT_DATA_PROP		"data"
@@ -595,6 +596,9 @@ int fit_image_get_data(const void *fit, int noffset,
 int fit_image_hash_get_algo(const void *fit, int noffset, char **algo);
 int fit_image_hash_get_value(const void *fit, int noffset, uint8_t **value,
 				int *value_len);
+#ifndef USE_HOSTCC
+int fit_image_hash_get_ignore(const void *fit, int noffset, int *ignore);
+#endif
 
 int fit_set_timestamp(void *fit, int noffset, time_t timestamp);
 int fit_set_hashes(void *fit);
diff --git a/include/libfdt.h b/include/libfdt.h
index de82ed5ffdf7f4d98049fbe60f544de96a1f0f40..c93ae28833e172c3bca7ee188da1c200f3eb27c5 100644
--- a/include/libfdt.h
+++ b/include/libfdt.h
@@ -852,17 +852,17 @@ int fdt_setprop_inplace(void *fdt, int nodeoffset, const char *name,
 			const void *val, int len);
 
 /**
- * fdt_setprop_inplace_cell - change the value of a single-cell property
+ * fdt_setprop_inplace_u32 - change the value of a 32-bit integer property
  * @fdt: pointer to the device tree blob
  * @nodeoffset: offset of the node whose property to change
  * @name: name of the property to change
- * @val: cell (32-bit integer) value to replace the property with
+ * @val: 32-bit integer value to replace the property with
  *
- * fdt_setprop_inplace_cell() replaces the value of a given property
- * with the 32-bit integer cell value in val, converting val to
- * big-endian if necessary.  This function cannot change the size of a
- * property, and so will only work if the property already exists and
- * has length 4.
+ * fdt_setprop_inplace_u32() replaces the value of a given property
+ * with the 32-bit integer value in val, converting val to big-endian
+ * if necessary.  This function cannot change the size of a property,
+ * and so will only work if the property already exists and has length
+ * 4.
  *
  * This function will alter only the bytes in the blob which contain
  * the given property value, and will not alter or move any other part
@@ -871,7 +871,7 @@ int fdt_setprop_inplace(void *fdt, int nodeoffset, const char *name,
  * returns:
  *	0, on success
  *	-FDT_ERR_NOSPACE, if the property's length is not equal to 4
-  *	-FDT_ERR_NOTFOUND, node does not have the named property
+ *	-FDT_ERR_NOTFOUND, node does not have the named property
  *	-FDT_ERR_BADOFFSET, nodeoffset did not point to FDT_BEGIN_NODE tag
  *	-FDT_ERR_BADMAGIC,
  *	-FDT_ERR_BADVERSION,
@@ -879,13 +879,59 @@ int fdt_setprop_inplace(void *fdt, int nodeoffset, const char *name,
  *	-FDT_ERR_BADSTRUCTURE,
  *	-FDT_ERR_TRUNCATED, standard meanings
  */
-static inline int fdt_setprop_inplace_cell(void *fdt, int nodeoffset,
-					   const char *name, uint32_t val)
+static inline int fdt_setprop_inplace_u32(void *fdt, int nodeoffset,
+					  const char *name, uint32_t val)
 {
 	val = cpu_to_fdt32(val);
 	return fdt_setprop_inplace(fdt, nodeoffset, name, &val, sizeof(val));
 }
 
+/**
+ * fdt_setprop_inplace_u64 - change the value of a 64-bit integer property
+ * @fdt: pointer to the device tree blob
+ * @nodeoffset: offset of the node whose property to change
+ * @name: name of the property to change
+ * @val: 64-bit integer value to replace the property with
+ *
+ * fdt_setprop_inplace_u64() replaces the value of a given property
+ * with the 64-bit integer value in val, converting val to big-endian
+ * if necessary.  This function cannot change the size of a property,
+ * and so will only work if the property already exists and has length
+ * 8.
+ *
+ * This function will alter only the bytes in the blob which contain
+ * the given property value, and will not alter or move any other part
+ * of the tree.
+ *
+ * returns:
+ *	0, on success
+ *	-FDT_ERR_NOSPACE, if the property's length is not equal to 8
+ *	-FDT_ERR_NOTFOUND, node does not have the named property
+ *	-FDT_ERR_BADOFFSET, nodeoffset did not point to FDT_BEGIN_NODE tag
+ *	-FDT_ERR_BADMAGIC,
+ *	-FDT_ERR_BADVERSION,
+ *	-FDT_ERR_BADSTATE,
+ *	-FDT_ERR_BADSTRUCTURE,
+ *	-FDT_ERR_TRUNCATED, standard meanings
+ */
+static inline int fdt_setprop_inplace_u64(void *fdt, int nodeoffset,
+					  const char *name, uint64_t val)
+{
+	val = cpu_to_fdt64(val);
+	return fdt_setprop_inplace(fdt, nodeoffset, name, &val, sizeof(val));
+}
+
+/**
+ * fdt_setprop_inplace_cell - change the value of a single-cell property
+ *
+ * This is an alternative name for fdt_setprop_inplace_u32()
+ */
+static inline int fdt_setprop_inplace_cell(void *fdt, int nodeoffset,
+					   const char *name, uint32_t val)
+{
+	return fdt_setprop_inplace_u32(fdt, nodeoffset, name, val);
+}
+
 /**
  * fdt_nop_property - replace a property with nop tags
  * @fdt: pointer to the device tree blob
@@ -945,11 +991,20 @@ 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);
-static inline int fdt_property_cell(void *fdt, const char *name, uint32_t val)
+static inline int fdt_property_u32(void *fdt, const char *name, uint32_t val)
 {
 	val = cpu_to_fdt32(val);
 	return fdt_property(fdt, name, &val, sizeof(val));
 }
+static inline int fdt_property_u64(void *fdt, const char *name, uint64_t val)
+{
+	val = cpu_to_fdt64(val);
+	return fdt_property(fdt, name, &val, sizeof(val));
+}
+static inline int fdt_property_cell(void *fdt, const char *name, uint32_t val)
+{
+	return fdt_property_u32(fdt, name, val);
+}
 #define fdt_property_string(fdt, name, str) \
 	fdt_property(fdt, name, str, strlen(str)+1)
 int fdt_end_node(void *fdt);
@@ -959,6 +1014,7 @@ int fdt_finish(void *fdt);
 /* Read-write functions                                               */
 /**********************************************************************/
 
+int fdt_create_empty_tree(void *buf, int bufsize);
 int fdt_open_into(const void *fdt, void *buf, int bufsize);
 int fdt_pack(void *fdt);
 
@@ -1068,14 +1124,14 @@ int fdt_setprop(void *fdt, int nodeoffset, const char *name,
 		const void *val, int len);
 
 /**
- * fdt_setprop_cell - set a property to a single cell value
+ * fdt_setprop_u32 - set a property to a 32-bit integer
  * @fdt: pointer to the device tree blob
  * @nodeoffset: offset of the node whose property to change
  * @name: name of the property to change
  * @val: 32-bit integer value for the property (native endian)
  *
- * fdt_setprop_cell() sets the value of the named property in the
- * given node to the given cell value (converting to big-endian if
+ * fdt_setprop_u32() sets the value of the named property in the given
+ * node to the given 32-bit integer value (converting to big-endian if
  * necessary), or creates a new property with that value if it does
  * not already exist.
  *
@@ -1095,13 +1151,59 @@ int fdt_setprop(void *fdt, int nodeoffset, const char *name,
  *	-FDT_ERR_BADLAYOUT,
  *	-FDT_ERR_TRUNCATED, standard meanings
  */
-static inline int fdt_setprop_cell(void *fdt, int nodeoffset, const char *name,
-				   uint32_t val)
+static inline int fdt_setprop_u32(void *fdt, int nodeoffset, const char *name,
+				  uint32_t val)
 {
 	val = cpu_to_fdt32(val);
 	return fdt_setprop(fdt, nodeoffset, name, &val, sizeof(val));
 }
 
+/**
+ * fdt_setprop_u64 - set a property to a 64-bit integer
+ * @fdt: pointer to the device tree blob
+ * @nodeoffset: offset of the node whose property to change
+ * @name: name of the property to change
+ * @val: 64-bit integer value for the property (native endian)
+ *
+ * fdt_setprop_u64() sets the value of the named property in the given
+ * node to the given 64-bit integer value (converting to big-endian if
+ * necessary), or creates a new property with that value if it does
+ * not already exist.
+ *
+ * This function may insert or delete data from the blob, and will
+ * therefore change the offsets of some existing nodes.
+ *
+ * returns:
+ *	0, on success
+ *	-FDT_ERR_NOSPACE, there is insufficient free space in the blob to
+ *		contain the new property value
+ *	-FDT_ERR_BADOFFSET, nodeoffset did not point to FDT_BEGIN_NODE tag
+ *	-FDT_ERR_BADLAYOUT,
+ *	-FDT_ERR_BADMAGIC,
+ *	-FDT_ERR_BADVERSION,
+ *	-FDT_ERR_BADSTATE,
+ *	-FDT_ERR_BADSTRUCTURE,
+ *	-FDT_ERR_BADLAYOUT,
+ *	-FDT_ERR_TRUNCATED, standard meanings
+ */
+static inline int fdt_setprop_u64(void *fdt, int nodeoffset, const char *name,
+				  uint64_t val)
+{
+	val = cpu_to_fdt64(val);
+	return fdt_setprop(fdt, nodeoffset, name, &val, sizeof(val));
+}
+
+/**
+ * fdt_setprop_cell - set a property to a single cell value
+ *
+ * This is an alternative name for fdt_setprop_u32()
+ */
+static inline int fdt_setprop_cell(void *fdt, int nodeoffset, const char *name,
+				   uint32_t val)
+{
+	return fdt_setprop_u32(fdt, nodeoffset, name, val);
+}
+
 /**
  * fdt_setprop_string - set a property to a string value
  * @fdt: pointer to the device tree blob
@@ -1133,6 +1235,147 @@ static inline int fdt_setprop_cell(void *fdt, int nodeoffset, const char *name,
 #define fdt_setprop_string(fdt, nodeoffset, name, str) \
 	fdt_setprop((fdt), (nodeoffset), (name), (str), strlen(str)+1)
 
+/**
+ * fdt_appendprop - append to or create a property
+ * @fdt: pointer to the device tree blob
+ * @nodeoffset: offset of the node whose property to change
+ * @name: name of the property to append to
+ * @val: pointer to data to append to the property value
+ * @len: length of the data to append to the property value
+ *
+ * fdt_appendprop() appends the value to the named property in the
+ * given node, creating the property if it does not already exist.
+ *
+ * This function may insert data into the blob, and will therefore
+ * change the offsets of some existing nodes.
+ *
+ * returns:
+ *	0, on success
+ *	-FDT_ERR_NOSPACE, there is insufficient free space in the blob to
+ *		contain the new property value
+ *	-FDT_ERR_BADOFFSET, nodeoffset did not point to FDT_BEGIN_NODE tag
+ *	-FDT_ERR_BADLAYOUT,
+ *	-FDT_ERR_BADMAGIC,
+ *	-FDT_ERR_BADVERSION,
+ *	-FDT_ERR_BADSTATE,
+ *	-FDT_ERR_BADSTRUCTURE,
+ *	-FDT_ERR_BADLAYOUT,
+ *	-FDT_ERR_TRUNCATED, standard meanings
+ */
+int fdt_appendprop(void *fdt, int nodeoffset, const char *name,
+		   const void *val, int len);
+
+/**
+ * fdt_appendprop_u32 - append a 32-bit integer value to a property
+ * @fdt: pointer to the device tree blob
+ * @nodeoffset: offset of the node whose property to change
+ * @name: name of the property to change
+ * @val: 32-bit integer value to append to the property (native endian)
+ *
+ * fdt_appendprop_u32() appends the given 32-bit integer value
+ * (converting to big-endian if necessary) to the value of the named
+ * property in the given node, or creates a new property with that
+ * value if it does not already exist.
+ *
+ * This function may insert data into the blob, and will therefore
+ * change the offsets of some existing nodes.
+ *
+ * returns:
+ *	0, on success
+ *	-FDT_ERR_NOSPACE, there is insufficient free space in the blob to
+ *		contain the new property value
+ *	-FDT_ERR_BADOFFSET, nodeoffset did not point to FDT_BEGIN_NODE tag
+ *	-FDT_ERR_BADLAYOUT,
+ *	-FDT_ERR_BADMAGIC,
+ *	-FDT_ERR_BADVERSION,
+ *	-FDT_ERR_BADSTATE,
+ *	-FDT_ERR_BADSTRUCTURE,
+ *	-FDT_ERR_BADLAYOUT,
+ *	-FDT_ERR_TRUNCATED, standard meanings
+ */
+static inline int fdt_appendprop_u32(void *fdt, int nodeoffset,
+				     const char *name, uint32_t val)
+{
+	val = cpu_to_fdt32(val);
+	return fdt_appendprop(fdt, nodeoffset, name, &val, sizeof(val));
+}
+
+/**
+ * fdt_appendprop_u64 - append a 64-bit integer value to a property
+ * @fdt: pointer to the device tree blob
+ * @nodeoffset: offset of the node whose property to change
+ * @name: name of the property to change
+ * @val: 64-bit integer value to append to the property (native endian)
+ *
+ * fdt_appendprop_u64() appends the given 64-bit integer value
+ * (converting to big-endian if necessary) to the value of the named
+ * property in the given node, or creates a new property with that
+ * value if it does not already exist.
+ *
+ * This function may insert data into the blob, and will therefore
+ * change the offsets of some existing nodes.
+ *
+ * returns:
+ *	0, on success
+ *	-FDT_ERR_NOSPACE, there is insufficient free space in the blob to
+ *		contain the new property value
+ *	-FDT_ERR_BADOFFSET, nodeoffset did not point to FDT_BEGIN_NODE tag
+ *	-FDT_ERR_BADLAYOUT,
+ *	-FDT_ERR_BADMAGIC,
+ *	-FDT_ERR_BADVERSION,
+ *	-FDT_ERR_BADSTATE,
+ *	-FDT_ERR_BADSTRUCTURE,
+ *	-FDT_ERR_BADLAYOUT,
+ *	-FDT_ERR_TRUNCATED, standard meanings
+ */
+static inline int fdt_appendprop_u64(void *fdt, int nodeoffset,
+				     const char *name, uint64_t val)
+{
+	val = cpu_to_fdt64(val);
+	return fdt_appendprop(fdt, nodeoffset, name, &val, sizeof(val));
+}
+
+/**
+ * fdt_appendprop_cell - append a single cell value to a property
+ *
+ * This is an alternative name for fdt_appendprop_u32()
+ */
+static inline int fdt_appendprop_cell(void *fdt, int nodeoffset,
+				      const char *name, uint32_t val)
+{
+	return fdt_appendprop_u32(fdt, nodeoffset, name, val);
+}
+
+/**
+ * fdt_appendprop_string - append a string to a property
+ * @fdt: pointer to the device tree blob
+ * @nodeoffset: offset of the node whose property to change
+ * @name: name of the property to change
+ * @str: string value to append to the property
+ *
+ * fdt_appendprop_string() appends the given string to the value of
+ * the named property in the given node, or creates a new property
+ * with that value if it does not already exist.
+ *
+ * This function may insert data into the blob, and will therefore
+ * change the offsets of some existing nodes.
+ *
+ * returns:
+ *	0, on success
+ *	-FDT_ERR_NOSPACE, there is insufficient free space in the blob to
+ *		contain the new property value
+ *	-FDT_ERR_BADOFFSET, nodeoffset did not point to FDT_BEGIN_NODE tag
+ *	-FDT_ERR_BADLAYOUT,
+ *	-FDT_ERR_BADMAGIC,
+ *	-FDT_ERR_BADVERSION,
+ *	-FDT_ERR_BADSTATE,
+ *	-FDT_ERR_BADSTRUCTURE,
+ *	-FDT_ERR_BADLAYOUT,
+ *	-FDT_ERR_TRUNCATED, standard meanings
+ */
+#define fdt_appendprop_string(fdt, nodeoffset, name, str) \
+	fdt_appendprop((fdt), (nodeoffset), (name), (str), strlen(str)+1)
+
 /**
  * fdt_delprop - delete a property
  * @fdt: pointer to the device tree blob
diff --git a/lib/libfdt/Makefile b/lib/libfdt/Makefile
index c965577dc093e7a21325b9e37b74ab9ebdb7645e..0693d4bf5585541d85e9f173d5e8aa2e16d95162 100644
--- a/lib/libfdt/Makefile
+++ b/lib/libfdt/Makefile
@@ -27,7 +27,7 @@ LIB	= $(obj)libfdt.o
 
 SOBJS	=
 
-COBJS-libfdt += fdt.o fdt_ro.o fdt_rw.o fdt_strerror.o fdt_sw.o fdt_wip.o
+COBJS-libfdt += fdt.o fdt_ro.o fdt_rw.o fdt_strerror.o fdt_sw.o fdt_wip.o fdt_empty_tree.o
 
 COBJS-$(CONFIG_OF_LIBFDT) += $(COBJS-libfdt)
 COBJS-$(CONFIG_FIT) += $(COBJS-libfdt)
diff --git a/lib/libfdt/fdt_empty_tree.c b/lib/libfdt/fdt_empty_tree.c
new file mode 100644
index 0000000000000000000000000000000000000000..f72d13b1d19c0bce7a27658e18a5f9fe26b2453c
--- /dev/null
+++ b/lib/libfdt/fdt_empty_tree.c
@@ -0,0 +1,84 @@
+/*
+ * libfdt - Flat Device Tree manipulation
+ * Copyright (C) 2012 David Gibson, IBM Corporation.
+ *
+ * libfdt is dual licensed: you can use it either under the terms of
+ * the GPL, or the BSD license, at your option.
+ *
+ *  a) This library is free software; you can redistribute it and/or
+ *     modify it under the terms of the GNU General Public License as
+ *     published by the Free Software Foundation; either version 2 of the
+ *     License, or (at your option) any later version.
+ *
+ *     This library is distributed in the hope that it will be useful,
+ *     but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *     GNU General Public License for more details.
+ *
+ *     You should have received a copy of the GNU General Public
+ *     License along with this library; if not, write to the Free
+ *     Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
+ *     MA 02110-1301 USA
+ *
+ * Alternatively,
+ *
+ *  b) Redistribution and use in source and binary forms, with or
+ *     without modification, are permitted provided that the following
+ *     conditions are met:
+ *
+ *     1. Redistributions of source code must retain the above
+ *        copyright notice, this list of conditions and the following
+ *        disclaimer.
+ *     2. Redistributions in binary form must reproduce the above
+ *        copyright notice, this list of conditions and the following
+ *        disclaimer in the documentation and/or other materials
+ *        provided with the distribution.
+ *
+ *     THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
+ *     CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ *     INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ *     MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ *     DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ *     CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ *     SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ *     NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ *     LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ *     HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ *     CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ *     OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+ *     EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+#include "libfdt_env.h"
+
+#include <fdt.h>
+#include <libfdt.h>
+
+#include "libfdt_internal.h"
+
+int fdt_create_empty_tree(void *buf, int bufsize)
+{
+	int err;
+
+	err = fdt_create(buf, bufsize);
+	if (err)
+		return err;
+
+	err = fdt_finish_reservemap(buf);
+	if (err)
+		return err;
+
+	err = fdt_begin_node(buf, "");
+	if (err)
+		return err;
+
+	err =  fdt_end_node(buf);
+	if (err)
+		return err;
+
+	err = fdt_finish(buf);
+	if (err)
+		return err;
+
+	return fdt_open_into(buf, buf, bufsize);
+}
+
diff --git a/lib/libfdt/fdt_rw.c b/lib/libfdt/fdt_rw.c
index 5c27a677e3536ed7320ee399113666975e5d545b..5ed23d6f1934699540b60cb437f0c740dc43956c 100644
--- a/lib/libfdt/fdt_rw.c
+++ b/lib/libfdt/fdt_rw.c
@@ -293,6 +293,33 @@ int fdt_setprop(void *fdt, int nodeoffset, const char *name,
 	return 0;
 }
 
+int fdt_appendprop(void *fdt, int nodeoffset, const char *name,
+		   const void *val, int len)
+{
+	struct fdt_property *prop;
+	int err, oldlen, newlen;
+
+	FDT_RW_CHECK_HEADER(fdt);
+
+	prop = fdt_get_property_w(fdt, nodeoffset, name, &oldlen);
+	if (prop) {
+		newlen = len + oldlen;
+		err = _fdt_splice_struct(fdt, prop->data,
+					 FDT_TAGALIGN(oldlen),
+					 FDT_TAGALIGN(newlen));
+		if (err)
+			return err;
+		prop->len = cpu_to_fdt32(newlen);
+		memcpy(prop->data + oldlen, val, len);
+	} else {
+		err = _fdt_add_property(fdt, nodeoffset, name, len, &prop);
+		if (err)
+			return err;
+		memcpy(prop->data, val, len);
+	}
+	return 0;
+}
+
 int fdt_delprop(void *fdt, int nodeoffset, const char *name)
 {
 	struct fdt_property *prop;