adds new lantiq kernel. once the codebase is fully tested and know to be working...
[openwrt/openwrt.git] / target / linux / lantiq / patches / 211-nor_split.patch
1 --- a/drivers/mtd/maps/lantiq.c
2 +++ b/drivers/mtd/maps/lantiq.c
3 @@ -24,6 +24,10 @@
4 #include <lantiq.h>
5 #include <lantiq_platform.h>
6
7 +#ifdef CONFIG_SOC_LANTIQ_XWAY
8 +#include <xway.h>
9 +#endif
10 +
11 static map_word
12 lq_read16(struct map_info *map, unsigned long adr)
13 {
14 @@ -77,6 +81,75 @@ lq_copy_to(struct map_info *map, unsigne
15 spin_unlock_irqrestore(&ebu_lock, flags);
16 }
17
18 +static unsigned long
19 +find_uImage_size(struct map_info *map, unsigned long offset)
20 +{
21 +#define UBOOT_MAGIC 0x56190527
22 + unsigned long magic;
23 + unsigned long temp;
24 + map->copy_from(map, &magic, offset, 4);
25 + if (le32_to_cpu(magic) != UBOOT_MAGIC)
26 + return 0;
27 + map->copy_from(map, &temp, offset + 12, 4);
28 + return temp + 0x40;
29 +}
30 +
31 +static int
32 +detect_squashfs_partition(struct map_info *map, unsigned long offset)
33 +{
34 + unsigned long temp;
35 + map->copy_from(map, &temp, offset, 4);
36 + return le32_to_cpu(temp) == SQUASHFS_MAGIC;
37 +}
38 +
39 +static struct mtd_partition split_partitions[] = {
40 + {
41 + .name = "kernel",
42 + .offset = 0x0,
43 + .size = 0x0,
44 + }, {
45 + .name = "rootfs",
46 + .offset = 0x0,
47 + .size = 0x0,
48 + },
49 +};
50 +
51 +static int
52 +mtd_split_linux(struct map_info *map, struct mtd_info *mtd,
53 + struct mtd_partition *parts, int nr_parts)
54 +{
55 + int base_part = 0;
56 + int i;
57 + for (i = 0; i < nr_parts && !base_part; i++) {
58 + if(!strcmp("linux", parts[i].name))
59 + base_part = i;
60 + }
61 + if (!base_part)
62 + return 0;
63 + split_partitions[0].size = find_uImage_size(map, parts[base_part].offset);
64 + if (!split_partitions[0].size) {
65 + printk(KERN_INFO "lq_nor: no uImage found in linux partition");
66 + return -1;
67 + }
68 + if (!detect_squashfs_partition(map,
69 + parts[base_part].offset + split_partitions[0].size)) {
70 + split_partitions[0].size &= ~(mtd->erasesize - 1);
71 + split_partitions[0].size += mtd->erasesize;
72 + }
73 + split_partitions[0].offset = parts[base_part].offset;
74 + split_partitions[1].offset =
75 + parts[base_part].offset + split_partitions[0].size;
76 + split_partitions[1].size =
77 + parts[base_part].size - split_partitions[0].size;
78 +
79 + base_part++;
80 + add_mtd_partitions(mtd, parts, base_part);
81 + add_mtd_partitions(mtd, split_partitions, 2);
82 + if(nr_parts != base_part)
83 + add_mtd_partitions(mtd, &parts[base_part], nr_parts - base_part);
84 + return nr_parts + 2;
85 +}
86 +
87 static const char *part_probe_types[] = { "cmdlinepart", NULL };
88
89 static struct map_info lq_map = {
90 @@ -142,7 +215,8 @@ lq_mtd_probe(struct platform_device *pde
91 parts = lq_mtd_data->parts;
92 }
93
94 - add_mtd_partitions(lq_mtd, parts, nr_parts);
95 + if (!mtd_split_linux(&lq_map, lq_mtd, parts, nr_parts))
96 + add_mtd_partitions(lq_mtd, parts, nr_parts);
97 return 0;
98 }
99