[OpenWrt-Devel] [PATCH 4/6] bcm53xx: bcm47xxpart: add support for parsing device tree partitions
Álvaro Fernández Rojas
noltari at gmail.com
Sat May 16 06:53:22 EDT 2015
Signed-off-by: Álvaro Fernández Rojas <noltari at gmail.com>
---
...-bcm47xxpart-parse-device-tree-partitions.patch | 156 +++++++++++++++++++++
1 file changed, 156 insertions(+)
create mode 100644 target/linux/bcm53xx/patches-3.18/401-mtd-bcm47xxpart-parse-device-tree-partitions.patch
diff --git a/target/linux/bcm53xx/patches-3.18/401-mtd-bcm47xxpart-parse-device-tree-partitions.patch b/target/linux/bcm53xx/patches-3.18/401-mtd-bcm47xxpart-parse-device-tree-partitions.patch
new file mode 100644
index 0000000..272b0ef
--- /dev/null
+++ b/target/linux/bcm53xx/patches-3.18/401-mtd-bcm47xxpart-parse-device-tree-partitions.patch
@@ -0,0 +1,156 @@
+--- a/drivers/mtd/bcm47xxpart.c
++++ b/drivers/mtd/bcm47xxpart.c
+@@ -14,6 +14,8 @@
+ #include <linux/slab.h>
+ #include <linux/mtd/mtd.h>
+ #include <linux/mtd/partitions.h>
++#include <linux/of.h>
++#include <linux/vmalloc.h>
+
+ #include <uapi/linux/magic.h>
+
+@@ -330,9 +332,143 @@ static int bcm47xxpart_parse(struct mtd_
+ return curr_part;
+ };
+
++static bool node_has_compatible(struct device_node *pp)
++{
++ return of_get_property(pp, "compatible", NULL);
++}
++
++static int parse_trxtag(struct mtd_info *master, struct mtd_partition *pparts,
++ int next_part, size_t offset, size_t size)
++{
++ struct trx_header *trx;
++ int ret, kernel_part, rootfs_part, kernel_offset, rootfs_offset;
++ size_t retlen;
++
++ /* Allocate memory for trx header */
++ trx = vmalloc(sizeof(*trx));
++ if (!trx)
++ return -ENOMEM;
++
++ /* Get the tag */
++ ret = mtd_read(master, offset, sizeof(*trx), &retlen,
++ (void *)trx);
++
++ if (retlen != sizeof(*trx)) {
++ vfree(trx);
++ return 0;
++ }
++
++ kernel_part = next_part;
++ rootfs_part = next_part + 1;
++
++ /* We have LZMA loader if offset[2] points to sth */
++ if (trx->offset[2]) {
++ kernel_offset = 1;
++ rootfs_offset = 2;
++ }
++ else {
++ kernel_offset = 0;
++ rootfs_offset = 1;
++ }
++
++ pparts[kernel_part].name = "linux";
++ pparts[kernel_part].offset = offset + trx->offset[kernel_offset];
++ pparts[kernel_part].size = trx->offset[rootfs_offset] - trx->offset[kernel_offset];
++
++ pparts[rootfs_part].name = bcm47xxpart_trx_data_part_name(master, offset + trx->offset[rootfs_offset]);
++ pparts[rootfs_part].offset = offset + trx->offset[rootfs_offset];
++ pparts[rootfs_part].size = size - trx->offset[rootfs_offset];
++
++ vfree(trx);
++
++ return 2;
++}
++
++static int bcm47xxpart_parse_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, "firmware")) {
++ 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, "firmware"))
++ i += parse_trxtag(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 bcm47xx_parse_partitions(struct mtd_info *master,
++ struct mtd_partition **pparts,
++ struct mtd_part_parser_data *data)
++{
++ if (data && data->of_node)
++ return bcm47xxpart_parse_of(master, pparts, data);
++ else
++ return bcm47xxpart_parse(master, pparts, data);
++}
++
+ static struct mtd_part_parser bcm47xxpart_mtd_parser = {
+ .owner = THIS_MODULE,
+- .parse_fn = bcm47xxpart_parse,
++ .parse_fn = bcm47xx_parse_partitions,
+ .name = "bcm47xxpart",
+ };
+
--
1.9.1
_______________________________________________
openwrt-devel mailing list
openwrt-devel at lists.openwrt.org
https://lists.openwrt.org/cgi-bin/mailman/listinfo/openwrt-devel
More information about the openwrt-devel
mailing list