--- zzzz-none-000/linux-3.10.107/drivers/mtd/ofpart.c 2017-06-27 09:49:32.000000000 +0000 +++ scorpion-7490-727/linux-3.10.107/drivers/mtd/ofpart.c 2021-02-04 17:41:59.000000000 +0000 @@ -20,28 +20,55 @@ #include #include -static int parse_ofpart_partitions(struct mtd_info *master, +static bool node_has_compatible(struct device_node *pp) +{ + return of_get_property(pp, "compatible", NULL); +} + +// Nicht mehr static, weil das Teil vom avm/partparse.c mtd_parser_cb benutzt wird. +int parse_ofpart_partitions(struct mtd_info *master, struct mtd_partition **pparts, struct mtd_part_parser_data *data) { - struct device_node *node; + struct device_node *mtd_node; + struct device_node *ofpart_node; const char *partname; struct device_node *pp; - int nr_parts, i; + int nr_parts, i, ret = 0; + bool dedicated = true; if (!data) return 0; - node = data->of_node; - if (!node) + mtd_node = data->of_node; + if (!mtd_node) + return 0; + + ofpart_node = of_get_child_by_name(mtd_node, "partitions"); + if (!ofpart_node) { + /* + * We might get here even when ofpart isn't used at all (e.g., + * when using another parser), so don't be louder than + * KERN_DEBUG + */ + pr_debug("%s: 'partitions' subnode not found on %s. Trying to parse direct subnodes as partitions.\n", + master->name, mtd_node->full_name); + ofpart_node = mtd_node; + dedicated = false; + } else if (!of_device_is_compatible(ofpart_node, "fixed-partitions")) { + /* The 'partitions' subnode might be used by another parser */ return 0; + } /* First count the subnodes */ - pp = NULL; nr_parts = 0; - while ((pp = of_get_next_child(node, pp))) + for_each_child_of_node(ofpart_node, pp) { + if (!dedicated && node_has_compatible(pp)) + continue; + nr_parts++; + } if (nr_parts == 0) return 0; @@ -50,47 +77,68 @@ if (!*pparts) return -ENOMEM; - pp = NULL; i = 0; - while ((pp = of_get_next_child(node, pp))) { + for_each_child_of_node(ofpart_node, pp) { const __be32 *reg; int len; int a_cells, s_cells; + if (!dedicated && node_has_compatible(pp)) + continue; + reg = of_get_property(pp, "reg", &len); if (!reg) { - nr_parts--; - continue; + if (dedicated) { + pr_debug("%s: ofpart partition %s (%s) missing reg property.\n", + master->name, pp->full_name, + mtd_node->full_name); + goto ofpart_fail; + } else { + nr_parts--; + continue; + } } a_cells = of_n_addr_cells(pp); s_cells = of_n_size_cells(pp); + if (len / 4 != a_cells + s_cells) { + pr_debug("%s: ofpart partition %s (%s) error parsing reg property.\n", + master->name, pp->full_name, + mtd_node->full_name); + goto ofpart_fail; + } + (*pparts)[i].offset = of_read_number(reg, a_cells); (*pparts)[i].size = of_read_number(reg + a_cells, s_cells); partname = of_get_property(pp, "label", &len); if (!partname) partname = of_get_property(pp, "name", &len); - (*pparts)[i].name = (char *)partname; + (*pparts)[i].name = partname; if (of_get_property(pp, "read-only", &len)) (*pparts)[i].mask_flags |= MTD_WRITEABLE; if (of_get_property(pp, "lock", &len)) (*pparts)[i].mask_flags |= MTD_POWERUP_LOCK; - + pr_debug("[%s]: Found partition %d; name=%s\n", __func__, i, partname); // DEBUG AMY i++; } - if (!i) { - of_node_put(pp); - pr_err("No valid partition found on %s\n", node->full_name); - kfree(*pparts); - *pparts = NULL; - return -EINVAL; - } + if (!nr_parts) + goto ofpart_none; return nr_parts; + +ofpart_fail: + pr_err("%s: error parsing ofpart partition %s (%s)\n", + master->name, pp->full_name, mtd_node->full_name); + ret = -EINVAL; +ofpart_none: + of_node_put(pp); + kfree(*pparts); + *pparts = NULL; + return ret; } static struct mtd_part_parser ofpart_parser = { @@ -142,7 +190,7 @@ if (names && (plen > 0)) { int len = strlen(names) + 1; - (*pparts)[i].name = (char *)names; + (*pparts)[i].name = names; plen -= len; names += len; } else { @@ -163,18 +211,9 @@ static int __init ofpart_parser_init(void) { - int rc; - rc = register_mtd_parser(&ofpart_parser); - if (rc) - goto out; - - rc = register_mtd_parser(&ofoldpart_parser); - if (!rc) - return 0; - - deregister_mtd_parser(&ofoldpart_parser); -out: - return rc; + register_mtd_parser(&ofpart_parser); + register_mtd_parser(&ofoldpart_parser); + return 0; } static void __exit ofpart_parser_exit(void)