[ramips] add patches for v3.8
[15.05/openwrt.git] / target / linux / ramips / patches-3.8 / 0208-owrt-mtd-split.patch
1 From 2a295753a10823a47542c779a25bbb1f52c71281 Mon Sep 17 00:00:00 2001
2 From: John Crispin <blogic@openwrt.org>
3 Date: Fri, 3 Aug 2012 10:27:13 +0200
4 Subject: [PATCH 19/25] owrt mtd split
5
6 ---
7  .../mips/include/asm/mach-lantiq/xway/lantiq_soc.h |    1 +
8  arch/mips/lantiq/setup.c                           |    7 +
9  drivers/mtd/Kconfig                                |    4 +
10  drivers/mtd/mtdpart.c                              |  173 +++++++++++++++++++-
11  4 files changed, 184 insertions(+), 1 deletions(-)
12
13 Index: linux-3.9-rc4/drivers/mtd/Kconfig
14 ===================================================================
15 --- linux-3.9-rc4.orig/drivers/mtd/Kconfig      2013-03-27 09:26:32.005789709 +0100
16 +++ linux-3.9-rc4/drivers/mtd/Kconfig   2013-03-27 09:26:35.669789796 +0100
17 @@ -31,6 +31,10 @@
18         bool "Automatically split 'rootfs' partition for squashfs"
19         default y
20  
21 +config MTD_UIMAGE_SPLIT
22 +       bool "Automatically split 'linux' partition into 'kernel' and 'rootfs'"
23 +       default y
24 +
25  config MTD_REDBOOT_PARTS
26         tristate "RedBoot partition table parsing"
27         ---help---
28 Index: linux-3.9-rc4/drivers/mtd/mtdpart.c
29 ===================================================================
30 --- linux-3.9-rc4.orig/drivers/mtd/mtdpart.c    2013-03-27 09:26:32.281789715 +0100
31 +++ linux-3.9-rc4/drivers/mtd/mtdpart.c 2013-03-27 17:20:12.874466937 +0100
32 @@ -844,6 +844,99 @@
33  }
34  #endif /* CONFIG_MTD_ROOTFS_SPLIT */
35  
36 +#ifdef CONFIG_MTD_UIMAGE_SPLIT
37 +static unsigned long find_uimage_size(struct mtd_info *mtd,
38 +                                     unsigned long offset)
39 +{
40 +#define UBOOT_MAGIC    0x56190527
41 +       unsigned long magic = 0;
42 +       unsigned long temp;
43 +       size_t len;
44 +       int ret;
45 +
46 +       ret = mtd_read(mtd, offset, 4, &len, (void *)&magic);
47 +       if (ret || len != sizeof(magic))
48 +               return 0;
49 +
50 +       if (le32_to_cpu(magic) != UBOOT_MAGIC)
51 +               return 0;
52 +
53 +       ret = mtd_read(mtd, offset + 12, 4, &len, (void *)&temp);
54 +       if (ret || len != sizeof(temp))
55 +               return 0;
56 +
57 +       return be32_to_cpu(temp) + 0x40;
58 +}
59 +
60 +static int detect_squashfs_partition(struct mtd_info *mtd, unsigned long offset)
61 +{
62 +       unsigned long temp;
63 +       size_t len;
64 +       int ret;
65 +
66 +       ret = mtd_read(mtd, offset, 4, &len, (void *)&temp);
67 +       if (ret || len != sizeof(temp))
68 +               return 0;
69 +
70 +       return le32_to_cpu(temp) == SQUASHFS_MAGIC;
71 +}
72 +
73 +static unsigned long find_squashfs_offset(struct mtd_info *mtd, unsigned long _offset)
74 +{
75 +       /* scan the first 2MB at 64K offsets */
76 +       int i;
77 +
78 +       for (i = 0; i < 32; i++) {
79 +               unsigned long offset = i * 64 * 1024;
80 +               if (detect_squashfs_partition(mtd, _offset + offset))
81 +                       return offset;
82 +       }
83 +       return 0;
84 +}
85 +
86 +static int split_uimage(struct mtd_info *mtd,
87 +                       const struct mtd_partition *part)
88 +{
89 +       static struct mtd_partition split_partitions[] = {
90 +               {
91 +                       .name = "kernel",
92 +                       .offset = 0x0,
93 +                       .size = 0x0,
94 +               }, {
95 +                       .name = "rootfs",
96 +                       .offset = 0x0,
97 +                       .size = 0x0,
98 +               },
99 +       };
100 +
101 +       split_partitions[0].size = find_uimage_size(mtd, part->offset);
102 +       if (!split_partitions[0].size) {
103 +               split_partitions[0].size = find_squashfs_offset(mtd, part->offset);
104 +               if (!split_partitions[0].size) {
105 +                       pr_err("failed to split firmware partition\n");
106 +                       return -1;
107 +               }
108 +       }
109 +
110 +       if (!detect_squashfs_partition(mtd,
111 +                                      part->offset
112 +                                      + split_partitions[0].size)) {
113 +               split_partitions[0].size &= ~(mtd->erasesize - 1);
114 +               split_partitions[0].size += mtd->erasesize;
115 +       } else {
116 +               pr_info("found squashfs behind kernel\n");
117 +       }
118 +
119 +       split_partitions[0].offset = part->offset;
120 +       split_partitions[1].offset = part->offset + split_partitions[0].size;
121 +       split_partitions[1].size = part->size - split_partitions[0].size;
122 +
123 +       add_mtd_partitions(mtd, split_partitions, 2);
124 +
125 +       return 0;
126 +}
127 +#endif
128 +
129  /*
130   * This function, given a master MTD object and a partition table, creates
131   * and registers slave MTD objects which are bound to the master according to
132 @@ -860,7 +953,7 @@
133         struct mtd_part *slave;
134         uint64_t cur_offset = 0;
135         int i;
136 -#ifdef CONFIG_MTD_ROOTFS_SPLIT
137 +#if defined(CONFIG_MTD_ROOTFS_SPLIT) || defined(CONFIG_MTD_UIMAGE_SPLIT)
138         int ret;
139  #endif
140  
141 @@ -877,6 +970,14 @@
142  
143                 add_mtd_device(&slave->mtd);
144  
145 +#ifdef CONFIG_MTD_UIMAGE_SPLIT
146 +               if (!strcmp(parts[i].name, "firmware")) {
147 +                       ret = split_uimage(master, &parts[i]);
148 +                       if (ret)
149 +                               printk(KERN_WARNING "Can't split firmware partition\n");
150 +               }
151 +#endif
152 +
153                 if (!strcmp(parts[i].name, "rootfs")) {
154  #ifdef CONFIG_MTD_ROOTFS_ROOT_DEV
155                         if (ROOT_DEV == 0) {