diff options
Diffstat (limited to 'target/linux/lantiq/patches/211-nor_split.patch')
-rw-r--r-- | target/linux/lantiq/patches/211-nor_split.patch | 99 |
1 files changed, 99 insertions, 0 deletions
diff --git a/target/linux/lantiq/patches/211-nor_split.patch b/target/linux/lantiq/patches/211-nor_split.patch new file mode 100644 index 0000000000..2f77681b8c --- /dev/null +++ b/target/linux/lantiq/patches/211-nor_split.patch @@ -0,0 +1,99 @@ +--- a/drivers/mtd/maps/lantiq.c ++++ b/drivers/mtd/maps/lantiq.c +@@ -24,6 +24,10 @@ + #include <lantiq.h> + #include <lantiq_platform.h> + ++#ifdef CONFIG_SOC_LANTIQ_XWAY ++#include <xway.h> ++#endif ++ + static map_word + lq_read16(struct map_info *map, unsigned long adr) + { +@@ -77,6 +81,75 @@ lq_copy_to(struct map_info *map, unsigne + spin_unlock_irqrestore(&ebu_lock, flags); + } + ++static unsigned long ++find_uImage_size(struct map_info *map, unsigned long offset) ++{ ++#define UBOOT_MAGIC 0x56190527 ++ unsigned long magic; ++ unsigned long temp; ++ map->copy_from(map, &magic, offset, 4); ++ if (le32_to_cpu(magic) != UBOOT_MAGIC) ++ return 0; ++ map->copy_from(map, &temp, offset + 12, 4); ++ return temp + 0x40; ++} ++ ++static int ++detect_squashfs_partition(struct map_info *map, unsigned long offset) ++{ ++ unsigned long temp; ++ map->copy_from(map, &temp, offset, 4); ++ return le32_to_cpu(temp) == SQUASHFS_MAGIC; ++} ++ ++static struct mtd_partition split_partitions[] = { ++ { ++ .name = "kernel", ++ .offset = 0x0, ++ .size = 0x0, ++ }, { ++ .name = "rootfs", ++ .offset = 0x0, ++ .size = 0x0, ++ }, ++}; ++ ++static int ++mtd_split_linux(struct map_info *map, struct mtd_info *mtd, ++ struct mtd_partition *parts, int nr_parts) ++{ ++ int base_part = 0; ++ int i; ++ for (i = 0; i < nr_parts && !base_part; i++) { ++ if(!strcmp("linux", parts[i].name)) ++ base_part = i; ++ } ++ if (!base_part) ++ return 0; ++ split_partitions[0].size = find_uImage_size(map, parts[base_part].offset); ++ if (!split_partitions[0].size) { ++ printk(KERN_INFO "lq_nor: no uImage found in linux partition"); ++ return -1; ++ } ++ if (!detect_squashfs_partition(map, ++ parts[base_part].offset + split_partitions[0].size)) { ++ split_partitions[0].size &= ~(mtd->erasesize - 1); ++ split_partitions[0].size += mtd->erasesize; ++ } ++ split_partitions[0].offset = parts[base_part].offset; ++ split_partitions[1].offset = ++ parts[base_part].offset + split_partitions[0].size; ++ split_partitions[1].size = ++ parts[base_part].size - split_partitions[0].size; ++ ++ base_part++; ++ add_mtd_partitions(mtd, parts, base_part); ++ add_mtd_partitions(mtd, split_partitions, 2); ++ if(nr_parts != base_part) ++ add_mtd_partitions(mtd, &parts[base_part], nr_parts - base_part); ++ return nr_parts + 2; ++} ++ + static const char *part_probe_types[] = { "cmdlinepart", NULL }; + + static struct map_info lq_map = { +@@ -142,7 +215,8 @@ lq_mtd_probe(struct platform_device *pde + parts = lq_mtd_data->parts; + } + +- add_mtd_partitions(lq_mtd, parts, nr_parts); ++ if (!mtd_split_linux(&lq_map, lq_mtd, parts, nr_parts)) ++ add_mtd_partitions(lq_mtd, parts, nr_parts); + return 0; + } + |