OpenWrt – Rev 4

Subversion Repositories:
Rev:
--- a/drivers/mtd/ofpart.c
+++ b/drivers/mtd/ofpart.c
@@ -25,6 +25,38 @@ static bool node_has_compatible(struct d
        return of_get_property(pp, "compatible", NULL);
 }
 
+static uint8_t * brnboot_get_selected_root_part(struct mtd_info *master,
+                                               loff_t offset)
+{
+       static uint8_t root_id;
+       int err, len;
+
+       err = mtd_read(master, offset, 0x01, &len, &root_id);
+
+       if (mtd_is_bitflip(err) || !err)
+               return &root_id;
+
+       return NULL;
+}
+
+static void brnboot_set_active_root_part(struct mtd_partition *pparts,
+                                        struct device_node **part_nodes,
+                                        int nr_parts,
+                                        uint8_t *root_id)
+{
+       int i;
+
+       for (i = 0; i < nr_parts; i++) {
+               int part_root_id;
+
+               if (!of_property_read_u32(part_nodes[i], "brnboot,root-id", &part_root_id)
+                   && part_root_id == *root_id) {
+                       pparts[i].name = "firmware";
+                       break;
+               }
+       }
+}
+
 static int parse_fixed_partitions(struct mtd_info *master,
                                  const struct mtd_partition **pparts,
                                  struct mtd_part_parser_data *data)
@@ -36,7 +68,8 @@ static int parse_fixed_partitions(struct
        struct device_node *pp;
        int nr_parts, i, ret = 0;
        bool dedicated = true;
-
+       uint8_t *proot_id = NULL;
+       struct device_node **part_nodes;
 
        /* Pull of_node from the master device node */
        mtd_node = mtd_get_of_node(master);
@@ -72,7 +105,9 @@ static int parse_fixed_partitions(struct
                return 0;
 
        parts = kzalloc(nr_parts * sizeof(*parts), GFP_KERNEL);
-       if (!parts)
+       part_nodes = kzalloc(nr_parts * sizeof(*part_nodes), GFP_KERNEL);
+
+       if (!parts || !part_nodes)
                return -ENOMEM;
 
        i = 0;
@@ -121,12 +156,22 @@ static int parse_fixed_partitions(struct
                if (of_get_property(pp, "lock", &len))
                        parts[i].mask_flags |= MTD_POWERUP_LOCK;
 
+               if (!proot_id && of_device_is_compatible(pp, "brnboot,root-selector"))
+                       proot_id = brnboot_get_selected_root_part(master, parts[i].offset);
+
+               part_nodes[i] = pp;
+
                i++;
        }
 
        if (!nr_parts)
                goto ofpart_none;
 
+       if (proot_id)
+               brnboot_set_active_root_part(parts, part_nodes, nr_parts, proot_id);
+
+       kfree(part_nodes);
+
        *pparts = parts;
        return nr_parts;
 
@@ -137,6 +182,7 @@ ofpart_fail:
 ofpart_none:
        of_node_put(pp);
        kfree(parts);
+       kfree(part_nodes);
        return ret;
 }