brcm63xx: enhance dt partitions support to match upstream more closely
[openwrt/openwrt.git] / target / linux / brcm63xx / patches-4.4 / 425-bcm63xxpart_parse_paritions_from_dt.patch
index 330ec1ecafa32b22debfb53077dc8207ad419e06..ea73690d80c851e54d3a5e236403daacbf29e175 100644 (file)
@@ -8,7 +8,7 @@
  
  #include <asm/mach-bcm63xx/bcm63xx_nvram.h>
  #include <asm/mach-bcm63xx/bcm963xx_tag.h>
-@@ -43,66 +44,35 @@
+@@ -43,46 +44,35 @@
  
  #define BCM63XX_CFE_MAGIC_OFFSET 0x4e0
  
 +      u32 computed_crc;
        int ret;
        size_t retlen;
--      unsigned int rootfsaddr, kerneladdr, spareaddr, nvramaddr;
+-      unsigned int rootfsaddr, kerneladdr, spareaddr;
 -      unsigned int rootfslen, kernellen, sparelen, totallen;
 -      unsigned int cfelen, nvramlen;
 -      unsigned int cfe_erasesize;
--      unsigned int caldatalen1 = 0, caldataaddr1 = 0;
--      unsigned int caldatalen2 = 0, caldataaddr2 = 0;
 -      int i;
 -      u32 computed_crc;
 +      unsigned int rootfsaddr, kerneladdr;
 -      cfelen = cfe_erasesize;
 -      nvramlen = bcm63xx_nvram_get_psi_size() * SZ_1K;
 -      nvramlen = roundup(nvramlen, cfe_erasesize);
--      nvramaddr = master->size - nvramlen;
--
--      if (data) {
--              if (data->caldata[0]) {
--                      caldatalen1 = cfe_erasesize;
--                      caldataaddr1 = rounddown(data->caldata[0],
--                                               cfe_erasesize);
--              }
--              if (data->caldata[1]) {
--                      caldatalen2 = cfe_erasesize;
--                      caldataaddr2 = rounddown(data->caldata[1],
--                                               cfe_erasesize);
--              }
--              if (caldataaddr1 == caldataaddr2) {
--                      caldataaddr2 = 0;
--                      caldatalen2 = 0;
--              }
--      }
 +      int curr_part = next_part;
  
        /* Allocate memory for buffer */
@@ -90,7 +70,7 @@
        }
  
        computed_crc = crc32_le(IMAGETAG_CRC_START, (u8 *)buf,
-@@ -121,7 +91,6 @@ static int bcm63xx_parse_cfe_partitions(
+@@ -101,7 +91,6 @@ static int bcm63xx_parse_cfe_partitions(
  
                kerneladdr = kerneladdr - BCM63XX_EXTENDED_SIZE;
                rootfsaddr = rootfsaddr - BCM63XX_EXTENDED_SIZE;
@@ -98,7 +78,7 @@
  
                if (rootfsaddr < kerneladdr) {
                        /* default Broadcom layout */
-@@ -130,8 +99,8 @@ static int bcm63xx_parse_cfe_partitions(
+@@ -110,8 +99,8 @@ static int bcm63xx_parse_cfe_partitions(
                } else {
                        /* OpenWrt layout */
                        rootfsaddr = kerneladdr + kernellen;
                }
        } else {
                pr_warn("CFE boot tag CRC invalid (expected %08x, actual %08x)\n",
-@@ -139,16 +108,153 @@ static int bcm63xx_parse_cfe_partitions(
+@@ -119,23 +108,145 @@ static int bcm63xx_parse_cfe_partitions(
                kernellen = 0;
                rootfslen = 0;
                rootfsaddr = 0;
 -              spareaddr = cfelen;
        }
--      sparelen = min_not_zero(nvramaddr, caldataaddr1) - spareaddr;
+-      sparelen = master->size - spareaddr - nvramlen;
  
 -      /* Determine number of partitions */
 -      if (rootfslen > 0)
 -              nrparts++;
 +      if (kernellen > 0) {
 +              int kernelpart = curr_part;
--      if (kernellen > 0)
--              nrparts++;
++
 +              if (rootfslen > 0 && rootfs_first)
 +                      kernelpart++;
 +              pparts[kernelpart].name = "kernel";
 +                                         struct mtd_partition **pparts,
 +                                         struct mtd_part_parser_data *data)
 +{
-+      struct device_node *dp = mtd_get_of_node(master);
++      struct device_node *dp, *mtd_node = mtd_get_of_node(master);
 +      struct device_node *pp;
 +      int i, nr_parts = 0;
 +      const char *partname;
 +      int len;
 +
++      dp = of_get_child_by_name(mtd_node, "partitions");
++      if (!dp)
++              dp = mtd_node;
++
 +      for_each_child_of_node(dp, pp) {
-+              if (node_has_compatible(pp))
++              if (node_has_compatible(pp) && dp == mtd_node)
 +                      continue;
 +
 +              if (!of_get_property(pp, "reg", &len))
 +              if (!partname)
 +                      partname = of_get_property(pp, "name", &len);
 +
-+              if (!strcmp(partname, "linux"))
++              if (!strcmp(partname, "linux") ||
++                  of_device_is_compatible(pp, "brcm,bcm963xx-imagetag"))
 +                      nr_parts += 2;
 +
 +              nr_parts++;
 +              int a_cells, s_cells;
 +              size_t size, offset;
 +
-+              if (node_has_compatible(pp))
++              if (node_has_compatible(pp) && dp == mtd_node)
 +                      continue;
 +
 +              reg = of_get_property(pp, "reg", &len);
 +              if (!partname)
 +                      partname = of_get_property(pp, "name", &len);
 +
-+              if (!strcmp(partname, "linux"))
++              if (!strcmp(partname, "linux") ||
++                  of_device_is_compatible(pp, "brcm,bcm963xx-imagetag"))
 +                      i += parse_bcmtag(master, *pparts, i, offset, size);
 +
 +              if (of_get_property(pp, "read-only", &len))
 +      unsigned int nvramaddr;
 +      unsigned int cfelen, nvramlen;
 +      unsigned int cfe_erasesize;
-+      unsigned int caldatalen1 = 0, caldataaddr1 = 0;
-+      unsigned int caldatalen2 = 0, caldataaddr2 = 0;
 +      unsigned int imageaddr, imagelen;
 +      int i;
 +
 +      nvramlen = bcm63xx_nvram_get_psi_size() * SZ_1K;
 +      nvramlen = roundup(nvramlen, cfe_erasesize);
 +      nvramaddr = master->size - nvramlen;
-+
-+      if (data) {
-+              if (data->caldata[0]) {
-+                      caldatalen1 = cfe_erasesize;
-+                      caldataaddr1 = rounddown(data->caldata[0],
-+                                               cfe_erasesize);
-+              }
-+              if (data->caldata[1]) {
-+                      caldatalen2 = cfe_erasesize;
-+                      caldataaddr2 = rounddown(data->caldata[1],
-+                                               cfe_erasesize);
-+              }
-+              if (caldataaddr1 == caldataaddr2) {
-+                      caldataaddr2 = 0;
-+                      caldatalen2 = 0;
-+              }
-+      }
-+
-+      imageaddr = cfelen;
-+      imagelen = min_not_zero(nvramaddr, caldataaddr1) - imageaddr;
  
-       if (caldatalen1 > 0)
-               nrparts++;
-@@ -158,10 +264,8 @@ static int bcm63xx_parse_cfe_partitions(
+-      if (kernellen > 0)
+-              nrparts++;
++      imageaddr = cfelen;
++      imagelen = nvramaddr - imageaddr;
  
        /* Ask kernel for more memory */
        parts = kzalloc(sizeof(*parts) * nrparts + 10 * nrparts, GFP_KERNEL);
  
        /* Start building partition list */
        parts[curpart].name = "CFE";
-@@ -169,29 +273,7 @@ static int bcm63xx_parse_cfe_partitions(
+@@ -143,29 +254,7 @@ static int bcm63xx_parse_cfe_partitions(
        parts[curpart].size = cfelen;
        curpart++;
  
 -      }
 +      curpart += parse_bcmtag(master, parts, curpart, imageaddr, imagelen);
  
-       if (caldatalen1 > 0) {
-               if (caldatalen2 > 0)
-@@ -217,25 +299,33 @@ static int bcm63xx_parse_cfe_partitions(
+       parts[curpart].name = "nvram";
+       parts[curpart].offset = master->size - nvramlen;
+@@ -174,25 +263,37 @@ static int bcm63xx_parse_cfe_partitions(
  
        /* Global partition "linux" to make easy firmware upgrade */
        parts[curpart].name = "linux";
 -      parts[curpart].offset = cfelen;
--      parts[curpart].size = min_not_zero(nvramaddr, caldataaddr1) - cfelen;
+-      parts[curpart].size = master->size - cfelen - nvramlen;
 +      parts[curpart].offset = imageaddr;
 +      parts[curpart].size = imagelen;
 +      curpart++;
 +                                  struct mtd_partition **pparts,
 +                                  struct mtd_part_parser_data *data)
 +{
-+      if (mtd_get_of_node(master))
++      struct device_node *np, *mtd_node = mtd_get_of_node(master);
++      np = of_get_child_by_name(mtd_node, "partitions");
++
++      if ((np && of_device_is_compatible(np, "fixed-partitions")) ||
++          (!np && of_get_child_count(mtd_node)))
 +              return bcm63xx_parse_cfe_partitions_of(master, pparts, data);
 +      else
 +              return bcm63xx_parse_cfe_partitions(master, pparts, data);