From ef47683646516002694729986d19713e49b903e3 Mon Sep 17 00:00:00 2001 From: Hannes Schmelzer Date: Tue, 20 Sep 2016 18:10:43 +0200 Subject: cmd/fdt: add possibilty to have 'extrasize' on fdt resize Sometimes devicetree nodes and or properties are added out of the u-boot console, maybe through some script or manual interaction. The devicetree as loaded or embedded is quite small, so the devicetree has to be resized to take up those new nodes/properties. In original the devicetree was only extended by effective 4 * add_mem_rsv. With this commit we can add an argument to the "fdt resize" command, which takes the extrasize to be added. Signed-off-by: Hannes Schmelzer Signed-off-by: Hannes Schmelzer Acked-by: Simon Glass --- include/fdt_support.h | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) (limited to 'include') diff --git a/include/fdt_support.h b/include/fdt_support.h index 8f402310f6..506bc5a9f6 100644 --- a/include/fdt_support.h +++ b/include/fdt_support.h @@ -167,7 +167,15 @@ void ft_pci_setup(void *blob, bd_t *bd); int ft_system_setup(void *blob, bd_t *bd); void set_working_fdt_addr(ulong addr); -int fdt_shrink_to_minimum(void *blob); + +/** + * shrink down the given blob to minimum size + some extrasize if required + * + * @param blob FDT blob to update + * @param extrasize additional bytes needed + * @return 0 if ok, or -FDT_ERR_... on error + */ +int fdt_shrink_to_minimum(void *blob, uint extrasize); int fdt_increase_size(void *fdt, int add_len); int fdt_fixup_nor_flash_size(void *blob); -- cgit v1.2.1 From 9c07b9877cf07a1a971a79ed7c2369a58c0baca2 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Sun, 2 Oct 2016 17:59:27 -0600 Subject: libfdt: Sync up with upstream This includes small changes to the following functions, from upstream commit 6d1832c: - fdt_get_max_phandle() (upstream commit 84e0e134) - fdt_node_check_compatible (upstream commit 53bf130b) - fdt_setprop_inplace_namelen_partial() to remove useless brackets and use idx instead of index - _fdt_resize_property() to use idx instead of index - _fdt_splice() (upstream commit d4c7c25c) It also includes various typo fixes in libfdt.h Signed-off-by: Simon Glass --- include/libfdt.h | 77 +++++++++++++++++++++++++++++++++----------------------- 1 file changed, 45 insertions(+), 32 deletions(-) (limited to 'include') diff --git a/include/libfdt.h b/include/libfdt.h index b6a400a7a8..3b1c788f49 100644 --- a/include/libfdt.h +++ b/include/libfdt.h @@ -61,7 +61,7 @@ #define FDT_ERR_NOTFOUND 1 /* FDT_ERR_NOTFOUND: The requested node or property does not exist */ #define FDT_ERR_EXISTS 2 - /* FDT_ERR_EXISTS: Attemped to create a node or property which + /* FDT_ERR_EXISTS: Attempted to create a node or property which * already exists */ #define FDT_ERR_NOSPACE 3 /* FDT_ERR_NOSPACE: Operation needed to expand the device @@ -213,7 +213,7 @@ int fdt_next_subnode(const void *fdt, int offset); #define __fdt_set_hdr(name) \ static inline void fdt_set_##name(void *fdt, uint32_t val) \ { \ - struct fdt_header *fdth = (struct fdt_header*)fdt; \ + struct fdt_header *fdth = (struct fdt_header *)fdt; \ fdth->name = cpu_to_fdt32(val); \ } __fdt_set_hdr(magic); @@ -288,11 +288,13 @@ const char *fdt_string(const void *fdt, int stroffset); * @fdt: pointer to the device tree blob * * fdt_get_max_phandle retrieves the highest phandle in the given - * device tree + * device tree. This will ignore badly formatted phandles, or phandles + * with a value of 0 or -1. * * returns: * the highest phandle on success - * 0, if an error occurred + * 0, if no phandle was found in the device tree + * -1, if an error occurred */ uint32_t fdt_get_max_phandle(const void *fdt); @@ -356,8 +358,9 @@ int fdt_subnode_offset_namelen(const void *fdt, int parentoffset, * returns: * structure block offset of the requested subnode (>=0), on success * -FDT_ERR_NOTFOUND, if the requested subnode does not exist - * -FDT_ERR_BADOFFSET, if parentoffset did not point to an FDT_BEGIN_NODE tag - * -FDT_ERR_BADMAGIC, + * -FDT_ERR_BADOFFSET, if parentoffset did not point to an FDT_BEGIN_NODE + * tag + * -FDT_ERR_BADMAGIC, * -FDT_ERR_BADVERSION, * -FDT_ERR_BADSTATE, * -FDT_ERR_BADSTRUCTURE, @@ -366,13 +369,13 @@ int fdt_subnode_offset_namelen(const void *fdt, int parentoffset, int fdt_subnode_offset(const void *fdt, int parentoffset, const char *name); /** - * fdt_path_offset_namelen - find a tree node based on substring + * fdt_path_offset_namelen - find a tree node by its full path * @fdt: pointer to the device tree blob * @path: full path of the node to locate - * @namelen: number of characters of name to consider + * @namelen: number of characters of path to consider * - * Identical to fdt_path_offset(), but only examine the first - * namelen characters of path for matching the node path. + * Identical to fdt_path_offset(), but only consider the first namelen + * characters of path as the path name. */ int fdt_path_offset_namelen(const void *fdt, const char *path, int namelen); @@ -389,7 +392,8 @@ int fdt_path_offset_namelen(const void *fdt, const char *path, int namelen); * address). * * returns: - * structure block offset of the node with the requested path (>=0), on success + * structure block offset of the node with the requested path (>=0), on + * success * -FDT_ERR_BADPATH, given path does not begin with '/' or is invalid * -FDT_ERR_NOTFOUND, if the requested node does not exist * -FDT_ERR_BADMAGIC, @@ -416,10 +420,12 @@ static inline int fdt_path_offset(const void *fdt, const char *path) * * returns: * pointer to the node's name, on success - * If lenp is non-NULL, *lenp contains the length of that name (>=0) + * If lenp is non-NULL, *lenp contains the length of that name + * (>=0) * NULL, on error * if lenp is non-NULL *lenp contains an error code (<0): - * -FDT_ERR_BADOFFSET, nodeoffset did not point to FDT_BEGIN_NODE tag + * -FDT_ERR_BADOFFSET, nodeoffset did not point to FDT_BEGIN_NODE + * tag * -FDT_ERR_BADMAGIC, * -FDT_ERR_BADVERSION, * -FDT_ERR_BADSTATE, standard meanings @@ -468,23 +474,26 @@ int fdt_first_property_offset(const void *fdt, int nodeoffset); int fdt_next_property_offset(const void *fdt, int offset); /** - * fdt_for_each_property - iterate over all properties of a node - * @property_offset: property offset (int) + * fdt_for_each_property_offset - iterate over all properties of a node + * + * @property_offset: property offset (int, lvalue) * @fdt: FDT blob (const void *) * @node: node offset (int) * * This is actually a wrapper around a for loop and would be used like so: * - * fdt_for_each_property(fdt, node, property) { - * ... - * use property + * fdt_for_each_property_offset(property, fdt, node) { + * Use property * ... * } * + * if ((property < 0) && (property != -FDT_ERR_NOT_FOUND)) { + * Error handling + * } + * * Note that this is implemented as a macro and property is used as - * iterator in the loop. It should therefore be a locally allocated - * variable. The node variable on the other hand is never modified, so - * it can be constant or even a literal. + * iterator in the loop. The node variable can be constant or even a + * literal. */ #define fdt_for_each_property_offset(property, fdt, node) \ for (property = fdt_first_property_offset(fdt, node); \ @@ -527,8 +536,8 @@ const struct fdt_property *fdt_get_property_by_offset(const void *fdt, * @namelen: number of characters of name to consider * @lenp: pointer to an integer variable (will be overwritten) or NULL * - * Identical to fdt_get_property_namelen(), but only examine the first - * namelen characters of name for matching the property name. + * Identical to fdt_get_property(), but only examine the first namelen + * characters of name for matching the property name. */ const struct fdt_property *fdt_get_property_namelen(const void *fdt, int nodeoffset, @@ -555,7 +564,8 @@ const struct fdt_property *fdt_get_property_namelen(const void *fdt, * NULL, on error * if lenp is non-NULL, *lenp contains an error code (<0): * -FDT_ERR_NOTFOUND, node does not have named property - * -FDT_ERR_BADOFFSET, nodeoffset did not point to FDT_BEGIN_NODE tag + * -FDT_ERR_BADOFFSET, nodeoffset did not point to FDT_BEGIN_NODE + * tag * -FDT_ERR_BADMAGIC, * -FDT_ERR_BADVERSION, * -FDT_ERR_BADSTATE, @@ -647,7 +657,8 @@ static inline void *fdt_getprop_namelen_w(void *fdt, int nodeoffset, * NULL, on error * if lenp is non-NULL, *lenp contains an error code (<0): * -FDT_ERR_NOTFOUND, node does not have named property - * -FDT_ERR_BADOFFSET, nodeoffset did not point to FDT_BEGIN_NODE tag + * -FDT_ERR_BADOFFSET, nodeoffset did not point to FDT_BEGIN_NODE + * tag * -FDT_ERR_BADMAGIC, * -FDT_ERR_BADVERSION, * -FDT_ERR_BADSTATE, @@ -689,7 +700,7 @@ const char *fdt_get_alias_namelen(const void *fdt, const char *name, int namelen); /** - * fdt_get_alias - retreive the path referenced by a given alias + * fdt_get_alias - retrieve the path referenced by a given alias * @fdt: pointer to the device tree blob * @name: name of the alias th look up * @@ -749,11 +760,11 @@ int fdt_get_path(const void *fdt, int nodeoffset, char *buf, int buflen); * structure from the start to nodeoffset. * * returns: - * structure block offset of the node at node offset's ancestor * of depth supernodedepth (>=0), on success * -FDT_ERR_BADOFFSET, nodeoffset does not refer to a BEGIN_NODE tag -* -FDT_ERR_NOTFOUND, supernodedepth was greater than the depth of nodeoffset + * -FDT_ERR_NOTFOUND, supernodedepth was greater than the depth of + * nodeoffset * -FDT_ERR_BADMAGIC, * -FDT_ERR_BADVERSION, * -FDT_ERR_BADSTATE, @@ -1060,7 +1071,7 @@ int fdt_size_cells(const void *fdt, int nodeoffset); * @nodeoffset: offset of the node whose property to change * @name: name of the property to change * @namelen: number of characters of name to consider - * @index: index of the property to change in the array + * @idx: index of the property to change in the array * @val: pointer to data to replace the property value with * @len: length of the property value * @@ -1071,7 +1082,7 @@ int fdt_size_cells(const void *fdt, int nodeoffset); */ int fdt_setprop_inplace_namelen_partial(void *fdt, int nodeoffset, const char *name, int namelen, - uint32_t index, const void *val, + uint32_t idx, const void *val, int len); /** @@ -1700,9 +1711,11 @@ int fdt_add_subnode_namelen(void *fdt, int parentoffset, * change the offsets of some existing nodes. * returns: - * structure block offset of the created nodeequested subnode (>=0), on success + * structure block offset of the created nodeequested subnode (>=0), on + * success * -FDT_ERR_NOTFOUND, if the requested subnode does not exist - * -FDT_ERR_BADOFFSET, if parentoffset did not point to an FDT_BEGIN_NODE tag + * -FDT_ERR_BADOFFSET, if parentoffset did not point to an FDT_BEGIN_NODE + * tag * -FDT_ERR_EXISTS, if the node at parentoffset already has a subnode of * the given name * -FDT_ERR_NOSPACE, if there is insufficient free space in the -- cgit v1.2.1 From b02e4044ff8ee1f6ac83917a39514172a9b449fb Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Sun, 2 Oct 2016 17:59:28 -0600 Subject: libfdt: Bring in upstream stringlist functions These have now landed upstream. The naming is different and in one case the function signature has changed. Update the code to match. This applies the following upstream commits by Thierry Reding : 604e61e fdt: Add functions to retrieve strings 8702bd1 fdt: Add a function to get the index of a string 2218387 fdt: Add a function to count strings Signed-off-by: Simon Glass --- include/libfdt.h | 86 ++++++++++++++++++++++++++++++++++---------------------- 1 file changed, 53 insertions(+), 33 deletions(-) (limited to 'include') diff --git a/include/libfdt.h b/include/libfdt.h index 3b1c788f49..f3b61c9427 100644 --- a/include/libfdt.h +++ b/include/libfdt.h @@ -121,12 +121,17 @@ /* FDT_ERR_BADNCELLS: Device tree has a #address-cells, #size-cells * or similar property with a bad format or value */ -#define FDT_ERR_TOODEEP 15 +#define FDT_ERR_BADVALUE 15 + /* FDT_ERR_BADVALUE: Device tree has a property with an unexpected + * value. For example: a property expected to contain a string list + * is not NUL-terminated within the length of its value. */ + +#define FDT_ERR_TOODEEP 16 /* FDT_ERR_TOODEEP: The depth of a node has exceeded the internal * libfdt limit. This can happen if you have more than * FDT_MAX_DEPTH nested nodes. */ -#define FDT_ERR_MAX 15 +#define FDT_ERR_MAX 16 /**********************************************************************/ /* Low-level functions (you probably don't need these) */ @@ -957,51 +962,66 @@ int fdt_node_offset_by_compatible(const void *fdt, int startoffset, int fdt_stringlist_contains(const char *strlist, int listlen, const char *str); /** - * fdt_count_strings - count the number of strings in a string list + * fdt_stringlist_count - count the number of strings in a string list * @fdt: pointer to the device tree blob - * @node: offset of the node + * @nodeoffset: offset of a tree node * @property: name of the property containing the string list - * @return: the number of strings in the given property + * @return: + * the number of strings in the given property + * -FDT_ERR_BADVALUE if the property value is not NUL-terminated + * -FDT_ERR_NOTFOUND if the property does not exist */ -int fdt_count_strings(const void *fdt, int node, const char *property); +int fdt_stringlist_count(const void *fdt, int nodeoffset, const char *property); /** - * fdt_find_string - find a string in a string list and return its index + * fdt_stringlist_search - find a string in a string list and return its index * @fdt: pointer to the device tree blob - * @node: offset of the node + * @nodeoffset: offset of a tree node * @property: name of the property containing the string list * @string: string to look up in the string list - * @return: the index of the string or negative on error + * + * Note that it is possible for this function to succeed on property values + * that are not NUL-terminated. That's because the function will stop after + * finding the first occurrence of @string. This can for example happen with + * small-valued cell properties, such as #address-cells, when searching for + * the empty string. + * + * @return: + * the index of the string in the list of strings + * -FDT_ERR_BADVALUE if the property value is not NUL-terminated + * -FDT_ERR_NOTFOUND if the property does not exist or does not contain + * the given string */ -int fdt_find_string(const void *fdt, int node, const char *property, - const char *string); +int fdt_stringlist_search(const void *fdt, int nodeoffset, const char *property, + const char *string); /** - * fdt_get_string_index() - obtain the string at a given index in a string list + * fdt_stringlist_get() - obtain the string at a given index in a string list * @fdt: pointer to the device tree blob - * @node: offset of the node + * @nodeoffset: offset of a tree node * @property: name of the property containing the string list * @index: index of the string to return - * @output: return location for the string - * @return: 0 if the string was found or a negative error code otherwise - */ -int fdt_get_string_index(const void *fdt, int node, const char *property, - int index, const char **output); - -/** - * fdt_get_string() - obtain the first string in a string list - * @fdt: pointer to the device tree blob - * @node: offset of the node - * @property: name of the property containing the string list - * @output: return location for the string - * @return: 0 if the string was found or a negative error code otherwise - * - * This is a shortcut for: - * - * fdt_get_string_index(fdt, node, property, 0, output). - */ -int fdt_get_string(const void *fdt, int node, const char *property, - const char **output); + * @lenp: return location for the string length or an error code on failure + * + * Note that this will successfully extract strings from properties with + * non-NUL-terminated values. For example on small-valued cell properties + * this function will return the empty string. + * + * If non-NULL, the length of the string (on success) or a negative error-code + * (on failure) will be stored in the integer pointer to by lenp. + * + * @return: + * A pointer to the string at the given index in the string list or NULL on + * failure. On success the length of the string will be stored in the memory + * location pointed to by the lenp parameter, if non-NULL. On failure one of + * the following negative error codes will be returned in the lenp parameter + * (if non-NULL): + * -FDT_ERR_BADVALUE if the property value is not NUL-terminated + * -FDT_ERR_NOTFOUND if the property does not exist + */ +const char *fdt_stringlist_get(const void *fdt, int nodeoffset, + const char *property, int index, + int *lenp); /**********************************************************************/ /* Read-only functions (addressing related) */ -- cgit v1.2.1 From df87e6b1b815ae3484ea2aa7c53b90af382eae1b Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Sun, 2 Oct 2016 17:59:29 -0600 Subject: libfdt: Sync fdt_for_each_subnode() with upstream The signature for this macro has changed. Bring in the upstream version and adjust U-Boot's usages to suit. Signed-off-by: Simon Glass Update to drivers/power/pmic/palmas.c: Signed-off-by: Keerthy Change-Id: I6cc9021339bfe686f9df21d61a1095ca2b3776e8 --- include/libfdt.h | 25 ++++++++++++++----------- 1 file changed, 14 insertions(+), 11 deletions(-) (limited to 'include') diff --git a/include/libfdt.h b/include/libfdt.h index f3b61c9427..398748c5c4 100644 --- a/include/libfdt.h +++ b/include/libfdt.h @@ -176,24 +176,27 @@ int fdt_next_subnode(const void *fdt, int offset); /** * fdt_for_each_subnode - iterate over all subnodes of a parent * + * @node: child node (int, lvalue) + * @fdt: FDT blob (const void *) + * @parent: parent node (int) + * * This is actually a wrapper around a for loop and would be used like so: * - * fdt_for_each_subnode(fdt, node, parent) { - * ... - * use node + * fdt_for_each_subnode(node, fdt, parent) { + * Use node * ... * } * - * Note that this is implemented as a macro and node is used as iterator in - * the loop. It should therefore be a locally allocated variable. The parent - * variable on the other hand is never modified, so it can be constant or - * even a literal. + * if ((node < 0) && (node != -FDT_ERR_NOT_FOUND)) { + * Error handling + * } + * + * Note that this is implemented as a macro and @node is used as + * iterator in the loop. The parent variable be constant or even a + * literal. * - * @fdt: FDT blob (const void *) - * @node: child node (int) - * @parent: parent node (int) */ -#define fdt_for_each_subnode(fdt, node, parent) \ +#define fdt_for_each_subnode(node, fdt, parent) \ for (node = fdt_first_subnode(fdt, parent); \ node >= 0; \ node = fdt_next_subnode(fdt, node)) -- cgit v1.2.1 From 42b7600d62ae288a8c12431d232b89b26ec61721 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Sun, 2 Oct 2016 17:59:30 -0600 Subject: libfdt: Drop inlining of fdt_path_offset() The fdt_path_offset() function is not inlined in upstream libfdt. Adjust U-Boot's version to match. Signed-off-by: Simon Glass --- include/libfdt.h | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) (limited to 'include') diff --git a/include/libfdt.h b/include/libfdt.h index 398748c5c4..8746790a25 100644 --- a/include/libfdt.h +++ b/include/libfdt.h @@ -410,10 +410,7 @@ int fdt_path_offset_namelen(const void *fdt, const char *path, int namelen); * -FDT_ERR_BADSTRUCTURE, * -FDT_ERR_TRUNCATED, standard meanings. */ -static inline int fdt_path_offset(const void *fdt, const char *path) -{ - return fdt_path_offset_namelen(fdt, path, strlen(path)); -} +int fdt_path_offset(const void *fdt, const char *path); /** * fdt_get_name - retrieve the name of a given node -- cgit v1.2.1