#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 */
}
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;
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);