lib: libfdt: Add a new API for appending string properties

appendprop is currently appending the source property
to the destination property without removing the NULL
character. This would result in failure while appending
strings. Hence use the new API appendprop_string for
appending string properties.

Change-Id: Ie8243c823b4bdf29a71f3d829495bfabcd2e6f74
diff --git a/lib/libfdt/fdt_rw.c b/lib/libfdt/fdt_rw.c
index 9ed0d4d..a3f8fad 100644
--- a/lib/libfdt/fdt_rw.c
+++ b/lib/libfdt/fdt_rw.c
@@ -316,6 +316,36 @@
 	return 0;
 }
 
+int fdt_appendprop_str(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);
+
+		/* Add space to separate the appended strings */
+		prop->data[oldlen-1] = 0x20;
+		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;
diff --git a/lib/libfdt/libfdt.h b/lib/libfdt/libfdt.h
index 73f4975..667964c 100644
--- a/lib/libfdt/libfdt.h
+++ b/lib/libfdt/libfdt.h
@@ -1264,6 +1264,35 @@
  */
 int fdt_appendprop(void *fdt, int nodeoffset, const char *name,
 		   const void *val, int len);
+/**
+ * fdt_appendprop_str - append a string 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 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_str() appends the string 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 along with a space between
+ * the the two strings 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_str(void *fdt, int nodeoffset, const char *name,
+		   const void *val, int len);
 
 /**
  * fdt_appendprop_u32 - append a 32-bit integer value to a property
@@ -1374,7 +1403,7 @@
  *	-FDT_ERR_TRUNCATED, standard meanings
  */
 #define fdt_appendprop_string(fdt, nodeoffset, name, str) \
-	fdt_appendprop((fdt), (nodeoffset), (name), (str), strlen(str)+1)
+	fdt_appendprop_str((fdt), (nodeoffset), (name), (str), strlen(str)+1)
 
 /**
  * fdt_delprop - delete a property