diff options
Diffstat (limited to 'target/linux/brcm63xx/patches-3.14/425-bcm63xxpart_parse_paritions_from_dt.patch')
-rw-r--r-- | target/linux/brcm63xx/patches-3.14/425-bcm63xxpart_parse_paritions_from_dt.patch | 357 |
1 files changed, 0 insertions, 357 deletions
diff --git a/target/linux/brcm63xx/patches-3.14/425-bcm63xxpart_parse_paritions_from_dt.patch b/target/linux/brcm63xx/patches-3.14/425-bcm63xxpart_parse_paritions_from_dt.patch deleted file mode 100644 index 53fc4c5d23..0000000000 --- a/target/linux/brcm63xx/patches-3.14/425-bcm63xxpart_parse_paritions_from_dt.patch +++ /dev/null @@ -1,357 +0,0 @@ ---- a/drivers/mtd/bcm63xxpart.c -+++ b/drivers/mtd/bcm63xxpart.c -@@ -32,6 +32,7 @@ - #include <linux/vmalloc.h> - #include <linux/mtd/mtd.h> - #include <linux/mtd/partitions.h> -+#include <linux/of.h> - - #include <asm/mach-bcm63xx/bcm63xx_nvram.h> - #include <asm/mach-bcm63xx/bcm963xx_tag.h> -@@ -43,66 +44,35 @@ - - #define BCM63XX_CFE_MAGIC_OFFSET 0x4e0 - --static int bcm63xx_parse_cfe_partitions(struct mtd_info *master, -- struct mtd_partition **pparts, -- struct mtd_part_parser_data *data) -+static bool node_has_compatible(struct device_node *pp) -+{ -+ return of_get_property(pp, "compatible", NULL); -+} -+ -+static int parse_bcmtag(struct mtd_info *master, struct mtd_partition *pparts, -+ int next_part, size_t offset, size_t size) - { -- /* CFE, NVRAM and global Linux are always present */ -- int nrparts = 3, curpart = 0; - struct bcm_tag *buf; -- struct mtd_partition *parts; -+ u32 computed_crc; - int ret; - size_t retlen; -- unsigned int rootfsaddr, kerneladdr, spareaddr, nvramaddr; -- 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; -+ unsigned int rootfslen, kernellen, totallen; - bool rootfs_first = false; -- -- if (!bcm63xx_is_cfe_present()) -- return -EINVAL; -- -- cfe_erasesize = max_t(uint32_t, master->erasesize, -- BCM63XX_CFE_BLOCK_SIZE); -- -- 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 */ -- buf = vmalloc(sizeof(struct bcm_tag)); -+ buf = vmalloc(sizeof(*buf)); - if (!buf) - return -ENOMEM; - - /* Get the tag */ -- ret = mtd_read(master, cfelen, sizeof(struct bcm_tag), &retlen, -+ ret = mtd_read(master, offset, sizeof(*buf), &retlen, - (void *)buf); - -- if (retlen != sizeof(struct bcm_tag)) { -+ if (retlen != sizeof(*buf)) { - vfree(buf); -- return -EIO; -+ return 0; - } - - computed_crc = crc32_le(IMAGETAG_CRC_START, (u8 *)buf, -@@ -121,7 +91,6 @@ static int bcm63xx_parse_cfe_partitions( - - kerneladdr = kerneladdr - BCM63XX_EXTENDED_SIZE; - rootfsaddr = rootfsaddr - BCM63XX_EXTENDED_SIZE; -- spareaddr = roundup(totallen, master->erasesize) + cfelen; - - if (rootfsaddr < kerneladdr) { - /* default Broadcom layout */ -@@ -130,8 +99,8 @@ static int bcm63xx_parse_cfe_partitions( - } else { - /* OpenWrt layout */ - rootfsaddr = kerneladdr + kernellen; -- rootfslen = buf->real_rootfs_length; -- spareaddr = rootfsaddr + rootfslen; -+ rootfslen = size - kernellen - -+ sizeof(*buf); - } - } else { - pr_warn("CFE boot tag CRC invalid (expected %08x, actual %08x)\n", -@@ -139,16 +108,153 @@ static int bcm63xx_parse_cfe_partitions( - kernellen = 0; - rootfslen = 0; - rootfsaddr = 0; -- spareaddr = cfelen; - } -- sparelen = min_not_zero(nvramaddr, caldataaddr1) - spareaddr; - -- /* 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"; -+ pparts[kernelpart].offset = kerneladdr; -+ pparts[kernelpart].size = kernellen; -+ curr_part++; -+ } -+ -+ if (rootfslen > 0) { -+ int rootfspart = curr_part; -+ -+ if (kernellen > 0 && rootfs_first) -+ rootfspart--; -+ pparts[rootfspart].name = "rootfs"; -+ pparts[rootfspart].offset = rootfsaddr; -+ pparts[rootfspart].size = rootfslen; -+ -+ curr_part++; -+ } -+ -+ vfree(buf); -+ -+ return curr_part - next_part; -+} -+ -+ -+static int bcm63xx_parse_cfe_partitions_of(struct mtd_info *master, -+ struct mtd_partition **pparts, -+ struct mtd_part_parser_data *data) -+{ -+ struct device_node *dp = data->of_node; -+ struct device_node *pp; -+ int i, nr_parts = 0; -+ const char *partname; -+ int len; -+ -+ for_each_child_of_node(dp, pp) { -+ if (node_has_compatible(pp)) -+ continue; -+ -+ if (!of_get_property(pp, "reg", &len)) -+ continue; -+ -+ partname = of_get_property(pp, "label", &len); -+ if (!partname) -+ partname = of_get_property(pp, "name", &len); -+ -+ if (!strcmp(partname, "linux")) -+ nr_parts += 2; -+ -+ nr_parts++; -+ } -+ -+ *pparts = kzalloc(nr_parts * sizeof(**pparts), GFP_KERNEL); -+ if (!*pparts) -+ return -ENOMEM; -+ -+ i = 0; -+ for_each_child_of_node(dp, pp) { -+ const __be32 *reg; -+ int a_cells, s_cells; -+ size_t size, offset; -+ -+ if (node_has_compatible(pp)) -+ continue; -+ -+ reg = of_get_property(pp, "reg", &len); -+ if (!reg) -+ continue; -+ -+ a_cells = of_n_addr_cells(pp); -+ s_cells = of_n_size_cells(pp); -+ offset = of_read_number(reg, a_cells); -+ 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); -+ -+ if (!strcmp(partname, "linux")) -+ i += parse_bcmtag(master, *pparts, i, offset, size); -+ -+ 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; -+ -+ (*pparts)[i].offset = offset; -+ (*pparts)[i].size = size; -+ (*pparts)[i].name = partname; -+ -+ i++; -+ } -+ -+ return i; -+} -+ -+static int bcm63xx_parse_cfe_partitions(struct mtd_info *master, -+ struct mtd_partition **pparts, -+ struct mtd_part_parser_data *data) -+{ -+ /* CFE, NVRAM and global Linux are always present */ -+ int nrparts = 5, curpart = 0; -+ struct mtd_partition *parts; -+ 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; -+ -+ if (!bcm63xx_is_cfe_present()) -+ return -EINVAL; -+ -+ cfe_erasesize = max_t(uint32_t, master->erasesize, -+ BCM63XX_CFE_BLOCK_SIZE); -+ -+ 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; -+ } -+ } -+ -+ imageaddr = cfelen; -+ imagelen = min_not_zero(nvramaddr, caldataaddr1) - imageaddr; - - if (caldatalen1 > 0) - nrparts++; -@@ -158,10 +264,8 @@ static int bcm63xx_parse_cfe_partitions( - - /* Ask kernel for more memory */ - parts = kzalloc(sizeof(*parts) * nrparts + 10 * nrparts, GFP_KERNEL); -- if (!parts) { -- vfree(buf); -+ if (!parts) - return -ENOMEM; -- } - - /* Start building partition list */ - parts[curpart].name = "CFE"; -@@ -169,29 +273,7 @@ static int bcm63xx_parse_cfe_partitions( - parts[curpart].size = cfelen; - curpart++; - -- if (kernellen > 0) { -- int kernelpart = curpart; -- -- if (rootfslen > 0 && rootfs_first) -- kernelpart++; -- parts[kernelpart].name = "kernel"; -- parts[kernelpart].offset = kerneladdr; -- parts[kernelpart].size = kernellen; -- curpart++; -- } -- -- if (rootfslen > 0) { -- int rootfspart = curpart; -- -- if (kernellen > 0 && rootfs_first) -- rootfspart--; -- parts[rootfspart].name = "rootfs"; -- parts[rootfspart].offset = rootfsaddr; -- parts[rootfspart].size = rootfslen; -- if (sparelen > 0 && !rootfs_first) -- parts[rootfspart].size += sparelen; -- 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( - - /* 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].offset = imageaddr; -+ parts[curpart].size = imagelen; -+ curpart++; - -- for (i = 0; i < nrparts; i++) -+ for (i = 0; i < curpart; i++) - pr_info("Partition %d is %s offset %llx and length %llx\n", i, - parts[i].name, parts[i].offset, parts[i].size); - -- pr_info("Spare partition is offset %x and length %x\n", spareaddr, -- sparelen); -- - *pparts = parts; -- vfree(buf); - - return nrparts; - }; - -+ -+static int bcm63xx_parse_partitions(struct mtd_info *master, -+ struct mtd_partition **pparts, -+ struct mtd_part_parser_data *data) -+{ -+ if (data && data->of_node) -+ return bcm63xx_parse_cfe_partitions_of(master, pparts, data); -+ else -+ return bcm63xx_parse_cfe_partitions(master, pparts, data); -+} -+ - static struct mtd_part_parser bcm63xx_cfe_parser = { - .owner = THIS_MODULE, -- .parse_fn = bcm63xx_parse_cfe_partitions, -+ .parse_fn = bcm63xx_parse_partitions, - .name = "bcm63xxpart", - }; - |