summaryrefslogtreecommitdiff
path: root/target/linux/lantiq/patches/211-nor_split.patch
diff options
context:
space:
mode:
Diffstat (limited to 'target/linux/lantiq/patches/211-nor_split.patch')
-rw-r--r--target/linux/lantiq/patches/211-nor_split.patch99
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;
+ }
+