aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGrant Likely <grant.likely@linaro.org>2014-11-28 16:03:33 +0000
committerAlex Shi <alex.shi@linaro.org>2015-12-16 15:29:20 +0800
commitc682b26287d3bc5f349fd6ff09a17671905f27e3 (patch)
tree84da9f5b77d91a4de2bdc14f2fadea615e67a7f0
parent5ca64887e2e56cebb64e32d5832db032bb305b59 (diff)
of: Drop ->next pointer from struct device_node
The ->next pointer in struct device_node is a hanger-on from when it was used to iterate over the whole tree by a particular device_type property value. Those days are long over, but the fdt unflattening code still uses it to put nodes in the unflattened tree into the same order as node in the flat tree. By reworking the unflattening code to reverse the list after unflattening all the children of a node, the pointer can be dropped which gives a small amount of memory savings. Signed-off-by: Grant Likely <grant.likely@linaro.org> Acked-by: Frank Rowand <frank.rowand@sonymobile.com> Cc: Gaurav Minocha <gaurav.minocha.os@gmail.com> (cherry picked from commit 70161ff336674ecfd20614a9c0c61cb17a6e9e83) Signed-off-by: Alex Shi <alex.shi@linaro.org>
-rw-r--r--drivers/of/fdt.c24
-rw-r--r--include/linux/of.h1
2 files changed, 18 insertions, 7 deletions
diff --git a/drivers/of/fdt.c b/drivers/of/fdt.c
index 88c997c8677d..510074226d57 100644
--- a/drivers/of/fdt.c
+++ b/drivers/of/fdt.c
@@ -226,12 +226,8 @@ static void * unflatten_dt_node(void *blob,
prev_pp = &np->properties;
if (dad != NULL) {
np->parent = dad;
- /* we temporarily use the next field as `last_child'*/
- if (dad->next == NULL)
- dad->child = np;
- else
- dad->next->sibling = np;
- dad->next = np;
+ np->sibling = dad->child;
+ dad->child = np;
}
}
/* process properties */
@@ -329,6 +325,22 @@ static void * unflatten_dt_node(void *blob,
if (*poffset < 0 && *poffset != -FDT_ERR_NOTFOUND)
pr_err("unflatten: error %d processing FDT\n", *poffset);
+
+ /*
+ * Reverse the child list. Some drivers assumes node order matches .dts
+ * node order
+ */
+ if (!dryrun && np->child) {
+ struct device_node *child = np->child;
+ np->child = NULL;
+ while (child) {
+ struct device_node *next = child->sibling;
+ child->sibling = np->child;
+ np->child = child;
+ child = next;
+ }
+ }
+
if (nodepp)
*nodepp = np;
diff --git a/include/linux/of.h b/include/linux/of.h
index 3dbebf38b45b..45447c6f21f7 100644
--- a/include/linux/of.h
+++ b/include/linux/of.h
@@ -57,7 +57,6 @@ struct device_node {
struct device_node *parent;
struct device_node *child;
struct device_node *sibling;
- struct device_node *next; /* next device of same type */
struct kobject kobj;
unsigned long _flags;
void *data;