From 7a172ae7a3fc439c4639605e6bf2e6205dd02fcd Mon Sep 17 00:00:00 2001 From: =?utf8?q?Lothar=20Wa=C3=9Fmann?= Date: Tue, 23 Jun 2015 12:52:51 +0200 Subject: [PATCH] fdt: fix incorrect placement of partition information for atmel_nand fdt_node_set_part_info() blindly assumes, that the first child of the given node must be the 'partitions' node where to put the part info. In case of atmel_nand this node is actually the NFC node. Use the Linux kernel logic skipping any node that has a 'compatible' property prevent adding the partitions to a wrong node or deleting the wrong parent node. --- common/fdt_support.c | 49 ++++++++++++++++++++++++++------------------ 1 file changed, 29 insertions(+), 20 deletions(-) diff --git a/common/fdt_support.c b/common/fdt_support.c index 897ace6295..891fcac08e 100644 --- a/common/fdt_support.c +++ b/common/fdt_support.c @@ -703,7 +703,7 @@ struct reg_cell { unsigned int r1; }; -int fdt_del_subnodes(const void *blob, int parent_offset) +static int fdt_del_subnodes(const void *blob, int parent_offset) { int off, ndepth; int ret; @@ -711,18 +711,20 @@ int fdt_del_subnodes(const void *blob, int parent_offset) for (ndepth = 0, off = fdt_next_node(blob, parent_offset, &ndepth); (off >= 0) && (ndepth > 0); off = fdt_next_node(blob, off, &ndepth)) { - if (ndepth == 1) { - debug("delete %s: offset: %x\n", - fdt_get_name(blob, off, 0), off); - ret = fdt_del_node((void *)blob, off); - if (ret < 0) { - printf("Can't delete node: %s\n", - fdt_strerror(ret)); - return ret; - } else { - ndepth = 0; - off = parent_offset; - } + if (ndepth != 1) + continue; + if (fdt_getprop(blob, off, "compatible", NULL)) + continue; + debug("delete %s: offset: %x\n", + fdt_get_name(blob, off, 0), off); + ret = fdt_del_node((void *)blob, off); + if (ret < 0) { + printf("Can't delete node: %s\n", + fdt_strerror(ret)); + return ret; + } else { + ndepth = 0; + off = parent_offset; } } return 0; @@ -732,11 +734,14 @@ int fdt_del_partitions(void *blob, int parent_offset) { const void *prop; int ndepth = 0; - int off; + int off = parent_offset; int ret; - off = fdt_next_node(blob, parent_offset, &ndepth); - if (off > 0 && ndepth == 1) { + while ((off = fdt_next_node(blob, off, &ndepth)) > 0) { + if (ndepth != 1) + continue; + if (fdt_getprop(blob, off, "compatible", NULL)) + continue; prop = fdt_getprop(blob, off, "label", NULL); if (prop == NULL) { /* @@ -762,7 +767,7 @@ int fdt_node_set_part_info(void *blob, int parent_offset, struct list_head *pentry; struct part_info *part; struct reg_cell cell; - int off, ndepth = 0; + int off = parent_offset, ndepth = 0; int part_num, ret; char buf[64]; @@ -774,10 +779,14 @@ int fdt_node_set_part_info(void *blob, int parent_offset, * Check if it is nand {}; subnode, adjust * the offset in this case */ - off = fdt_next_node(blob, parent_offset, &ndepth); - if (off > 0 && ndepth == 1) + while ((off = fdt_next_node(blob, off, &ndepth)) > 0) { + if (ndepth != 1) + continue; + if (fdt_getprop(blob, off, "compatible", NULL)) + continue; parent_offset = off; - + break; + } part_num = 0; list_for_each_prev(pentry, &dev->parts) { int newoff; -- 2.39.2