]> git.kernelconcepts.de Git - karo-tx-uboot.git/blob - patches/0058-ENGR00119171-ubifs-support-for-android-recovery-mod.patch
imported Ka-Ro specific additions to U-Boot 2009.08 for TX28
[karo-tx-uboot.git] / patches / 0058-ENGR00119171-ubifs-support-for-android-recovery-mod.patch
1 From 1ee27e13d6fdb19d297f8d1d6d3d7d8449d0361e Mon Sep 17 00:00:00 2001
2 From: Terry Lv <r65388@freescale.com>
3 Date: Thu, 10 Dec 2009 11:26:52 +0800
4 Subject: [PATCH] ENGR00119171: ubifs support for android recovery mode.
5
6 ubifs support for android recovery mode.
7
8 Signed-off-by: Terry Lv <r65388@freescale.com>
9 ---
10  board/freescale/mx51_3stack/flash_header.S |    4 +-
11  board/freescale/mx51_3stack/mx51_3stack.c  |  251 ++++++++++++++++------------
12  fs/ubifs/super.c                           |    1 +
13  fs/ubifs/ubifs.c                           |   72 +++++---
14  fs/ubifs/ubifs.h                           |   32 ----
15  include/asm-arm/bitops.h                   |   81 +++++----
16  include/asm-arm/proc-armv/system.h         |   30 ----
17  include/configs/mx35_3stack.h              |    4 +
18  include/configs/mx51_3stack_android.h      |   18 ++-
19  include/linux/bitops.h                     |   83 +++++++++
20  10 files changed, 337 insertions(+), 239 deletions(-)
21
22 diff --git a/board/freescale/mx51_3stack/flash_header.S b/board/freescale/mx51_3stack/flash_header.S
23 index 172220a..bbfa474 100644
24 --- a/board/freescale/mx51_3stack/flash_header.S
25 +++ b/board/freescale/mx51_3stack/flash_header.S
26 @@ -108,6 +108,6 @@ MXC_DCD_ITEM(54, 4, ESDCTL_BASE_ADDR + ESDCTL_ESDMISC, 0x000ad6d0)
27  MXC_DCD_ITEM(55, 4, ESDCTL_BASE_ADDR + ESDCTL_ESDCDLYGD, 0x90000000)
28  MXC_DCD_ITEM(56, 4, ESDCTL_BASE_ADDR + ESDCTL_ESDSCR, 0x00000000)
29  dcd_data_end:
30 -image_len:             .word   0x80000
31 -//image_len:           .word   _end - _start
32 +//image_len:           .word   0x80000
33 +image_len:             .word   __u_boot_cmd_end - TEXT_BASE
34  #endif
35 diff --git a/board/freescale/mx51_3stack/mx51_3stack.c b/board/freescale/mx51_3stack/mx51_3stack.c
36 index 2dc6b2d..38eed4f 100644
37 --- a/board/freescale/mx51_3stack/mx51_3stack.c
38 +++ b/board/freescale/mx51_3stack/mx51_3stack.c
39 @@ -535,7 +535,7 @@ int board_init(void)
40  #ifdef BOARD_LATE_INIT
41  
42  #if defined(CONFIG_FSL_ANDROID) && defined(CONFIG_MXC_KPD)
43 -inline int waiting_for_func_key_pressing(void)
44 +static int waiting_for_func_key_pressing(void)
45  {
46         struct kpp_key_info key_info = {0, 0};
47         int switch_delay = CONFIG_ANDROID_BOOTMOD_DELAY;
48 @@ -607,7 +607,7 @@ inline int waiting_for_func_key_pressing(void)
49         return 0;
50  }
51  
52 -inline int switch_to_recovery_mode(void)
53 +static int switch_to_recovery_mode(void)
54  {
55         char *env = NULL;
56         char *boot_args = NULL;
57 @@ -648,127 +648,164 @@ inline int switch_to_recovery_mode(void)
58         return 0;
59  }
60  
61 -inline int check_recovery_cmd_file(void)
62 +static int check_mmc_recovery_cmd_file(int dev_num, int part_num, char *path)
63  {
64 +       block_dev_desc_t *dev_desc = NULL;
65 +       struct mmc *mmc = find_mmc_device(dev_num);
66         disk_partition_t info;
67 -       ulong part_length;
68 -       int filelen;
69 +       ulong part_length = 0;
70 +       int filelen = 0;
71  
72 -       switch (get_boot_device()) {
73 -       case MMC_BOOT:
74 -               {
75 -                       block_dev_desc_t *dev_desc = NULL;
76 -                       struct mmc *mmc = find_mmc_device(0);
77 +       memset(&info, 0, sizeof(disk_partition_t));
78  
79 -                       dev_desc = get_dev("mmc", 0);
80 +       dev_desc = get_dev("mmc", dev_num);
81  
82 -                       if (NULL == dev_desc) {
83 -                               puts("** Block device MMC 0 not supported\n");
84 -                               return 0;
85 -                       }
86 +       if (NULL == dev_desc) {
87 +               printf("** Block device MMC %d not supported\n",
88 +                               dev_num);
89 +               return 0;
90 +       }
91  
92 -                       mmc_init(mmc);
93 +       mmc_init(mmc);
94  
95 -                       if (get_partition_info(dev_desc,
96 -                                       CONFIG_ANDROID_CACHE_PARTITION_MMC,
97 -                                       &info)) {
98 -                               printf("** Bad partition %d **\n",
99 -                                       CONFIG_ANDROID_CACHE_PARTITION_MMC);
100 -                               return 0;
101 -                       }
102 +       if (get_partition_info(dev_desc,
103 +                       part_num,
104 +                       &info)) {
105 +               printf("** Bad partition %d **\n",
106 +                       part_num);
107 +               return 0;
108 +       }
109  
110 -                       part_length = ext2fs_set_blk_dev(dev_desc,
111 -                                                               CONFIG_ANDROID_CACHE_PARTITION_MMC);
112 -                       if (part_length == 0) {
113 -                               printf("** Bad partition - mmc 0:%d **\n",
114 -                                       CONFIG_ANDROID_CACHE_PARTITION_MMC);
115 -                               ext2fs_close();
116 -                               return 0;
117 -                       }
118 +       part_length = ext2fs_set_blk_dev(dev_desc,
119 +                                               part_num);
120 +       if (part_length == 0) {
121 +               printf("** Bad partition - mmc 0:%d **\n",
122 +                       part_num);
123 +               ext2fs_close();
124 +               return 0;
125 +       }
126  
127 -                       if (!ext2fs_mount(part_length)) {
128 -                               printf("** Bad ext2 partition or disk - mmc 0:%d **\n",
129 -                                       CONFIG_ANDROID_CACHE_PARTITION_MMC);
130 -                               ext2fs_close();
131 -                               return 0;
132 -                       }
133 +       if (!ext2fs_mount(part_length)) {
134 +               printf("** Bad ext2 partition or disk - mmc 0:%d **\n",
135 +                       part_num);
136 +               ext2fs_close();
137 +               return 0;
138 +       }
139  
140 -                       filelen = ext2fs_open(CONFIG_ANDROID_RECOVERY_CMD_FILE);
141 +       filelen = ext2fs_open(path);
142  
143 -                       ext2fs_close();
144 -               }
145 -               break;
146 -       case NAND_BOOT:
147 -               {
148 -                       #if 0
149 -                       struct mtd_device *dev_desc = NULL;
150 -                       struct part_info *part = NULL;
151 -                       struct mtd_partition mtd_part;
152 -                       struct mtd_info *mtd_info;
153 -                       char mtd_dev[16] = { 0 };
154 -                       char mtd_buffer[80] = { 0 };
155 -                       u8 pnum;
156 -                       int err;
157 -                       u8 read_test;
158 -
159 -                       /* ========== ubi and mtd operations ========== */
160 -                       if (mtdparts_init() != 0) {
161 -                               printf("Error initializing mtdparts!\n");
162 -                               return 0;
163 -                       }
164 +       ext2fs_close();
165  
166 -                       if (find_dev_and_part("nand", &dev_desc, &pnum, &part)) {
167 -                               printf("Partition %s not found!\n", "nand");
168 -                               return 0;
169 -                       }
170 -                       sprintf(mtd_dev, "%s%d",
171 -                                       MTD_DEV_TYPE(dev_desc->id->type),
172 -                                       dev_desc->id->num);
173 -                       mtd_info = get_mtd_device_nm(mtd_dev);
174 -                       if (IS_ERR(mtd_info)) {
175 -                               printf("Partition %s not found on device %s!\n",
176 -                                       "nand", mtd_dev);
177 -                               return 0;
178 -                       }
179 +       return (filelen > 0) ? 1 : 0;
180 +}
181  
182 -                       sprintf(mtd_buffer, "mtd=%d", pnum);
183 -                       memset(&mtd_part, 0, sizeof(mtd_part));
184 -                       mtd_part.name = mtd_buffer;
185 -                       mtd_part.size = part->size;
186 -                       mtd_part.offset = part->offset;
187 -                       add_mtd_partitions(&info, &mtd_part, 1);
188 -
189 -                       err = ubi_mtd_param_parse(mtd_buffer, NULL);
190 -                       if (err) {
191 -                               del_mtd_partitions(&info);
192 -                               return 0;
193 -                       }
194 +extern int ubifs_init(void);
195 +extern int ubifs_mount(char *vol_name);
196 +extern int ubifs_load(char *filename, u32 addr, u32 size);
197  
198 -                       err = ubi_init();
199 -                       if (err) {
200 -                               del_mtd_partitions(&info);
201 -                               return 0;
202 -                       }
203 +static int check_nand_recovery_cmd_file(char *mtd_part_name,
204 +                               char *ubi_part_name,
205 +                               char *path)
206 +{
207 +       struct mtd_device *dev_desc = NULL;
208 +       struct part_info *part = NULL;
209 +       struct mtd_partition mtd_part;
210 +       struct mtd_info *mtd_info = NULL;
211 +       char mtd_dev[16] = { 0 };
212 +       char mtd_buffer[80] = { 0 };
213 +       u8 pnum = 0,
214 +          read_test = 0;
215 +       int err = 0,
216 +               filelen = 0;
217 +
218 +       memset(&mtd_part, 0, sizeof(struct mtd_partition));
219 +
220 +       /* ========== ubi and mtd operations ========== */
221 +       if (mtdparts_init() != 0) {
222 +               printf("Error initializing mtdparts!\n");
223 +               return 0;
224 +       }
225  
226 -                       /* ========== ubifs operations ========== */
227 -                       /* Init ubifs */
228 -                       ubifs_init();
229 +       if (find_dev_and_part(mtd_part_name, &dev_desc, &pnum, &part)) {
230 +               printf("Partition %s not found!\n", mtd_part_name);
231 +               return 0;
232 +       }
233 +       sprintf(mtd_dev, "%s%d",
234 +                       MTD_DEV_TYPE(dev_desc->id->type),
235 +                       dev_desc->id->num);
236 +       mtd_info = get_mtd_device_nm(mtd_dev);
237 +       if (IS_ERR(mtd_info)) {
238 +               printf("Partition %s not found on device %s!\n",
239 +                       "nand", mtd_dev);
240 +               return 0;
241 +       }
242  
243 -                       if (ubifs_mount(CONFIG_ANDROID_CACHE_PARTITION_NAND)) {
244 -                               printf("Mount ubifs volume %s fail!\n",
245 -                                               CONFIG_ANDROID_CACHE_PARTITION_NAND);
246 -                               return 0;
247 -                       }
248 +       sprintf(mtd_buffer, "mtd=%d", pnum);
249 +       memset(&mtd_part, 0, sizeof(mtd_part));
250 +       mtd_part.name = mtd_buffer;
251 +       mtd_part.size = part->size;
252 +       mtd_part.offset = part->offset;
253 +       add_mtd_partitions(mtd_info, &mtd_part, 1);
254  
255 -                       /* Try to read one byte for a read test. */
256 -                       if (ubifs_load(CONFIG_ANDROID_RECOVERY_CMD_FILE,
257 -                                               &read_test, 1)) {
258 -                               /* File not found */
259 -                               filelen = 0;
260 -                       } else
261 -                               filelen = 1;
262 -               #endif
263 -               }
264 +       err = ubi_mtd_param_parse(mtd_buffer, NULL);
265 +       if (err) {
266 +               del_mtd_partitions(mtd_info);
267 +               return 0;
268 +       }
269 +
270 +       err = ubi_init();
271 +       if (err) {
272 +               del_mtd_partitions(mtd_info);
273 +               return 0;
274 +       }
275 +
276 +       /* ========== ubifs operations ========== */
277 +       /* Init ubifs */
278 +       ubifs_init();
279 +
280 +       if (ubifs_mount(ubi_part_name)) {
281 +               printf("Mount ubifs volume %s fail!\n",
282 +                               ubi_part_name);
283 +               return 0;
284 +       }
285 +
286 +       /* Try to read one byte for a read test. */
287 +       if (ubifs_load(path, (u32)&read_test, 1)) {
288 +               /* File not found */
289 +               filelen = 0;
290 +       } else
291 +               filelen = 1;
292 +
293 +       return filelen;
294 +}
295 +
296 +static int check_recovery_cmd_file(void)
297 +{
298 +       int if_exist;
299 +       char *env = NULL;
300 +
301 +       switch (get_boot_device()) {
302 +       case MMC_BOOT:
303 +               if_exist = check_mmc_recovery_cmd_file(0,
304 +                               CONFIG_ANDROID_CACHE_PARTITION_MMC,
305 +                               CONFIG_ANDROID_RECOVERY_CMD_FILE);
306 +               break;
307 +       case NAND_BOOT:
308 +               env = getenv("mtdparts");
309 +               if (!env)
310 +                       setenv("mtdparts", MTDPARTS_DEFAULT);
311 +
312 +               env = getenv("mtdids");
313 +               if (!env)
314 +                       setenv("mtdids", MTDIDS_DEFAULT);
315 +
316 +               env = getenv("partition");
317 +               if (!env)
318 +                       setenv("partition", MTD_ACTIVE_PART);
319 +
320 +               if_exist = check_nand_recovery_cmd_file(CONFIG_ANDROID_UBIFS_PARTITION_NM,
321 +                                               CONFIG_ANDROID_CACHE_PARTITION_NAND,
322 +                                               CONFIG_ANDROID_RECOVERY_CMD_FILE);
323                 break;
324         case SPI_NOR_BOOT:
325                 return 0;
326 @@ -779,7 +816,7 @@ inline int check_recovery_cmd_file(void)
327                 break;
328         }
329  
330 -       return (filelen > 0) ? 1 : 0;
331 +       return if_exist;
332  }
333  #endif
334  
335 diff --git a/fs/ubifs/super.c b/fs/ubifs/super.c
336 index 391dea4..9efe7cd 100644
337 --- a/fs/ubifs/super.c
338 +++ b/fs/ubifs/super.c
339 @@ -1178,6 +1178,7 @@ int ubifs_mount(char *vol_name)
340                 ubifs_umount(ubifs_sb->s_fs_info);
341  
342         INIT_LIST_HEAD(&ubifs_infos);
343 +       INIT_LIST_HEAD(&(ubifs_fs_type.fs_supers));
344  
345         /*
346          * Mount in read-only mode
347 diff --git a/fs/ubifs/ubifs.c b/fs/ubifs/ubifs.c
348 index 8ede188..82f1c54 100644
349 --- a/fs/ubifs/ubifs.c
350 +++ b/fs/ubifs/ubifs.c
351 @@ -124,9 +124,13 @@ int ubifs_decompress(const void *in_buf, int in_len, void *out_buf,
352  static int __init compr_init(struct ubifs_compressor *compr)
353  {
354         ubifs_compressors[compr->compr_type] = compr;
355 +
356 +#ifndef CONFIG_RELOC_FIXUP_WORKS
357         ubifs_compressors[compr->compr_type]->name += gd->reloc_off;
358         ubifs_compressors[compr->compr_type]->capi_name += gd->reloc_off;
359         ubifs_compressors[compr->compr_type]->decompress += gd->reloc_off;
360 +#endif
361 +
362         return 0;
363  }
364  
365 @@ -379,9 +383,11 @@ static unsigned long ubifs_findfile(struct super_block *sb, char *filename)
366         int ret;
367         char *next;
368         char fpath[128];
369 +       char symlinkpath[128];
370         char *name = fpath;
371         unsigned long root_inum = 1;
372         unsigned long inum;
373 +       int symlink_count = 0; /* Don't allow symlink recursion */
374  
375         strcpy(fpath, filename);
376  
377 @@ -397,6 +403,9 @@ static unsigned long ubifs_findfile(struct super_block *sb, char *filename)
378                 return inum;
379  
380         for (;;) {
381 +               struct inode *inode;
382 +               struct ubifs_inode *ui;
383 +
384                 /* Extract the actual part from the pathname.  */
385                 next = strchr(name, '/');
386                 if (next) {
387 @@ -406,18 +415,48 @@ static unsigned long ubifs_findfile(struct super_block *sb, char *filename)
388                 }
389  
390                 ret = ubifs_finddir(sb, name, root_inum, &inum);
391 +               if (!ret)
392 +                       return 0;
393 +               inode = ubifs_iget(sb, inum);
394 +
395 +               if (!inode)
396 +                       return 0;
397 +               ui = ubifs_inode(inode);
398 +
399 +               if ((inode->i_mode & S_IFMT) == S_IFLNK) {
400 +                       char link_name[64];
401 +                       char buf[128];
402 +
403 +                       /* We have some sort of symlink recursion, bail out */
404 +                       if (symlink_count++ > 8) {
405 +                               printf("Symlink recursion, aborting\n");
406 +                               return 0;
407 +                       }
408 +                       memcpy(link_name, ui->data, ui->data_len);
409 +                       link_name[ui->data_len] = '\0';
410 +
411 +                       if (link_name[0] == '/') {
412 +                               /* Absolute path, redo everything without
413 +                                * the leading slash */
414 +                               next = name = link_name + 1;
415 +                               root_inum = 1;
416 +                               continue;
417 +                       }
418 +                       /* Relative to cur dir */
419 +                       sprintf(buf, "%s/%s",
420 +                                       link_name, next == NULL ? "" : next);
421 +                       memcpy(symlinkpath, buf, sizeof(buf));
422 +                       next = name = symlinkpath;
423 +                       continue;
424 +               }
425  
426                 /*
427                  * Check if directory with this name exists
428                  */
429  
430                 /* Found the node!  */
431 -               if (!next || *next == '\0') {
432 -                       if (ret)
433 -                               return inum;
434 -
435 -                       break;
436 -               }
437 +               if (!next || *next == '\0')
438 +                       return inum;
439  
440                 root_inum = inum;
441                 name = next;
442 @@ -614,10 +653,10 @@ int ubifs_load(char *filename, u32 addr, u32 size)
443         int err = 0;
444         int i;
445         int count;
446 -       char link_name[64];
447 -       struct ubifs_inode *ui;
448  
449         c->ubi = ubi_open_volume(c->vi.ubi_num, c->vi.vol_id, UBI_READONLY);
450 +       /* ubifs_findfile will resolve symlinks, so we know that we get
451 +        * the real file here */
452         inum = ubifs_findfile(ubifs_sb, filename);
453         if (!inum) {
454                 err = -1;
455 @@ -635,23 +674,6 @@ int ubifs_load(char *filename, u32 addr, u32 size)
456         }
457  
458         /*
459 -        * Check for symbolic link
460 -        */
461 -       ui = ubifs_inode(inode);
462 -       if (((inode->i_mode & S_IFMT) == S_IFLNK) && ui->data_len) {
463 -               memcpy(link_name, ui->data, ui->data_len);
464 -               link_name[ui->data_len] = '\0';
465 -               printf("%s is linked to %s!\n", filename, link_name);
466 -               ubifs_iput(inode);
467 -
468 -               /*
469 -                * Now we have the "real" filename, call ubifs_load()
470 -                * again (recursive call) to load this file instead
471 -                */
472 -               return ubifs_load(link_name, addr, size);
473 -       }
474 -
475 -       /*
476          * If no size was specified or if size bigger than filesize
477          * set size to filesize
478          */
479 diff --git a/fs/ubifs/ubifs.h b/fs/ubifs/ubifs.h
480 index 43865aa..06772af 100644
481 --- a/fs/ubifs/ubifs.h
482 +++ b/fs/ubifs/ubifs.h
483 @@ -449,38 +449,6 @@ static inline ino_t parent_ino(struct dentry *dentry)
484         return res;
485  }
486  
487 -/* linux/include/linux/bitops.h */
488 -
489 -#define BIT_MASK(nr)           (1UL << ((nr) % BITS_PER_LONG))
490 -#define BIT_WORD(nr)           ((nr) / BITS_PER_LONG)
491 -
492 -/* linux/include/asm-generic/bitops/non-atomic.h */
493 -
494 -/**
495 - * __set_bit - Set a bit in memory
496 - * @nr: the bit to set
497 - * @addr: the address to start counting from
498 - *
499 - * Unlike set_bit(), this function is non-atomic and may be reordered.
500 - * If it's called on the same region of memory simultaneously, the effect
501 - * may be that only one operation succeeds.
502 - */
503 -static inline void __set_bit(int nr, volatile unsigned long *addr)
504 -{
505 -       unsigned long mask = BIT_MASK(nr);
506 -       unsigned long *p = ((unsigned long *)addr) + BIT_WORD(nr);
507 -
508 -       *p  |= mask;
509 -}
510 -
511 -static inline void __clear_bit(int nr, volatile unsigned long *addr)
512 -{
513 -       unsigned long mask = BIT_MASK(nr);
514 -       unsigned long *p = ((unsigned long *)addr) + BIT_WORD(nr);
515 -
516 -       *p &= ~mask;
517 -}
518 -
519  /* debug.c */
520  
521  #define DEFINE_SPINLOCK(...)
522 diff --git a/include/asm-arm/bitops.h b/include/asm-arm/bitops.h
523 index 4b8bab2..8eeada5 100644
524 --- a/include/asm-arm/bitops.h
525 +++ b/include/asm-arm/bitops.h
526 @@ -17,6 +17,8 @@
527  
528  #ifdef __KERNEL__
529  
530 +#include <asm/proc/system.h>
531 +
532  #define smp_mb__before_clear_bit()     do { } while (0)
533  #define smp_mb__after_clear_bit()      do { } while (0)
534  
535 @@ -25,59 +27,72 @@
536   */
537  extern void set_bit(int nr, volatile void * addr);
538  
539 -static inline void __set_bit(int nr, volatile void *addr)
540 -{
541 -       ((unsigned char *) addr)[nr >> 3] |= (1U << (nr & 7));
542 -}
543 -
544  extern void clear_bit(int nr, volatile void * addr);
545  
546 -static inline void __clear_bit(int nr, volatile void *addr)
547 -{
548 -       ((unsigned char *) addr)[nr >> 3] &= ~(1U << (nr & 7));
549 -}
550 -
551  extern void change_bit(int nr, volatile void * addr);
552  
553  static inline void __change_bit(int nr, volatile void *addr)
554  {
555 -       ((unsigned char *) addr)[nr >> 3] ^= (1U << (nr & 7));
556 -}
557 +       unsigned long mask = BIT_MASK(nr);
558 +       unsigned long *p = ((unsigned long *)addr) + BIT_WORD(nr);
559  
560 -extern int test_and_set_bit(int nr, volatile void * addr);
561 +       *p ^= mask;
562 +}
563  
564  static inline int __test_and_set_bit(int nr, volatile void *addr)
565  {
566 -       unsigned int mask = 1 << (nr & 7);
567 -       unsigned int oldval;
568 +       unsigned long mask = BIT_MASK(nr);
569 +       unsigned long *p = ((unsigned long *)addr) + BIT_WORD(nr);
570 +       unsigned long old = *p;
571  
572 -       oldval = ((unsigned char *) addr)[nr >> 3];
573 -       ((unsigned char *) addr)[nr >> 3] = oldval | mask;
574 -       return oldval & mask;
575 +       *p = old | mask;
576 +       return (old & mask) != 0;
577  }
578  
579 -extern int test_and_clear_bit(int nr, volatile void * addr);
580 +static inline int test_and_set_bit(int nr, volatile void *addr)
581 +{
582 +       unsigned long flags;
583 +       int out;
584 +
585 +       local_irq_save(flags);
586 +       out = __test_and_set_bit(nr, addr);
587 +       local_irq_restore(flags);
588 +
589 +       return out;
590 +}
591  
592  static inline int __test_and_clear_bit(int nr, volatile void *addr)
593  {
594 -       unsigned int mask = 1 << (nr & 7);
595 -       unsigned int oldval;
596 +       unsigned long mask = BIT_MASK(nr);
597 +       unsigned long *p = ((unsigned long *)addr) + BIT_WORD(nr);
598 +       unsigned long old = *p;
599  
600 -       oldval = ((unsigned char *) addr)[nr >> 3];
601 -       ((unsigned char *) addr)[nr >> 3] = oldval & ~mask;
602 -       return oldval & mask;
603 +       *p = old & ~mask;
604 +       return (old & mask) != 0;
605 +}
606 +
607 +static inline int test_and_clear_bit(int nr, volatile void *addr)
608 +{
609 +       unsigned long flags;
610 +       int out;
611 +
612 +       local_irq_save(flags);
613 +       out = __test_and_clear_bit(nr, addr);
614 +       local_irq_restore(flags);
615 +
616 +       return out;
617  }
618  
619  extern int test_and_change_bit(int nr, volatile void * addr);
620  
621  static inline int __test_and_change_bit(int nr, volatile void *addr)
622  {
623 -       unsigned int mask = 1 << (nr & 7);
624 -       unsigned int oldval;
625 +       unsigned long mask = BIT_MASK(nr);
626 +       unsigned long *p = ((unsigned long *)addr) + BIT_WORD(nr);
627 +       unsigned long old = *p;
628  
629 -       oldval = ((unsigned char *) addr)[nr >> 3];
630 -       ((unsigned char *) addr)[nr >> 3] = oldval ^ mask;
631 -       return oldval & mask;
632 +       *p = old ^ mask;
633 +       return (old & mask) != 0;
634  }
635  
636  extern int find_first_zero_bit(void * addr, unsigned size);
637 @@ -110,14 +125,6 @@ static inline unsigned long ffz(unsigned long word)
638  }
639  
640  /*
641 - * ffs: find first bit set. This is defined the same way as
642 - * the libc and compiler builtin ffs routines, therefore
643 - * differs in spirit from the above ffz (man ffs).
644 - */
645 -
646 -#define ffs(x) generic_ffs(x)
647 -
648 -/*
649   * hweightN: returns the hamming weight (i.e. the number
650   * of bits set) of a N-bit word
651   */
652 diff --git a/include/asm-arm/proc-armv/system.h b/include/asm-arm/proc-armv/system.h
653 index e7b0fe6..b4cfa68 100644
654 --- a/include/asm-arm/proc-armv/system.h
655 +++ b/include/asm-arm/proc-armv/system.h
656 @@ -12,36 +12,6 @@
657  
658  #include <linux/config.h>
659  
660 -#define set_cr(x)                                      \
661 -       __asm__ __volatile__(                           \
662 -       "mcr    p15, 0, %0, c1, c0      @ set CR"       \
663 -       : : "r" (x))
664 -
665 -#define CR_M   (1 << 0)        /* MMU enable                           */
666 -#define CR_A   (1 << 1)        /* Alignment abort enable               */
667 -#define CR_C   (1 << 2)        /* Dcache enable                        */
668 -#define CR_W   (1 << 3)        /* Write buffer enable                  */
669 -#define CR_P   (1 << 4)        /* 32-bit exception handler             */
670 -#define CR_D   (1 << 5)        /* 32-bit data address range            */
671 -#define CR_L   (1 << 6)        /* Implementation defined               */
672 -#define CD_B   (1 << 7)        /* Big endian                           */
673 -#define CR_S   (1 << 8)        /* System MMU protection                */
674 -#define CD_R   (1 << 9)        /* ROM MMU protection                   */
675 -#define CR_F   (1 << 10)       /* Implementation defined               */
676 -#define CR_Z   (1 << 11)       /* Implementation defined               */
677 -#define CR_I   (1 << 12)       /* Icache enable                        */
678 -#define CR_V   (1 << 13)       /* Vectors relocated to 0xffff0000      */
679 -#define CR_RR  (1 << 14)       /* Round Robin cache replacement        */
680 -
681 -extern unsigned long cr_no_alignment;  /* defined in entry-armv.S */
682 -extern unsigned long cr_alignment;     /* defined in entry-armv.S */
683 -
684 -#if __LINUX_ARM_ARCH__ >= 4
685 -#define vectors_base() ((cr_alignment & CR_V) ? 0xffff0000 : 0)
686 -#else
687 -#define vectors_base() (0)
688 -#endif
689 -
690  /*
691   * Save the current interrupt enable state & disable IRQs
692   */
693 diff --git a/include/configs/mx35_3stack.h b/include/configs/mx35_3stack.h
694 index b2fb714..789424e 100644
695 --- a/include/configs/mx35_3stack.h
696 +++ b/include/configs/mx35_3stack.h
697 @@ -35,6 +35,10 @@
698  #define CONFIG_DISPLAY_CPUINFO
699  #define CONFIG_DISPLAY_BOARDINFO
700  
701 +#define CONFIG_FLASH_HEADER     1
702 +#define CONFIG_FLASH_HEADER_OFFSET 0x400
703 +#define CONFIG_FLASH_HEADER_BARKER 0xB1
704 +
705  #define BOARD_LATE_INIT
706  /*
707   * Disabled for now due to build problems under Debian and a significant increase
708 diff --git a/include/configs/mx51_3stack_android.h b/include/configs/mx51_3stack_android.h
709 index bed1200..ed0611b 100644
710 --- a/include/configs/mx51_3stack_android.h
711 +++ b/include/configs/mx51_3stack_android.h
712 @@ -58,7 +58,7 @@
713  /*
714   * Size of malloc() pool
715   */
716 -#define CONFIG_SYS_MALLOC_LEN          (CONFIG_ENV_SIZE + 2 * 1024 * 1024)
717 +#define CONFIG_SYS_MALLOC_LEN          (CONFIG_ENV_SIZE + 4 * 1024 * 1024)
718  /* size in bytes reserved for initial data */
719  #define CONFIG_SYS_GBL_DATA_SIZE       128
720  
721 @@ -90,12 +90,17 @@
722  #define CONFIG_CMD_MII
723  #define CONFIG_CMD_NET
724  #define CONFIG_NET_RETRY_COUNT 100
725 -/*
726 +
727  #define CONFIG_CMD_UBI
728  #define CONFIG_CMD_UBIFS
729 +#define CONFIG_CMD_MTDPARTS
730 +#define CONFIG_MTD_DEVICE
731 +#define CONFIG_MTD_PARTITIONS
732 +#define MTDIDS_DEFAULT "nand0=nand0"
733 +#define MTDPARTS_DEFAULT "mtdparts=nand0:0x700000@0x0(BOOT),0x100000@0x700000(MISC),0x1400000@0x800000(RECOVERY),-@0x1c00000(ROOT)"
734 +#define MTD_ACTIVE_PART "nand0,3"
735  #define CONFIG_RBTREE
736  #define CONFIG_LZO
737 -*/
738  
739  /*
740   * Android support Configs
741 @@ -125,7 +130,8 @@
742  #define CONFIG_ANDROID_RECOVERY_CMD_FILE "/recovery/command"
743  #define CONFIG_ANDROID_BOOTMOD_DELAY 3
744  #define CONFIG_ANDROID_CACHE_PARTITION_MMC 6
745 -#define CONFIG_ANDROID_CACHE_PARTITION_NAND 2
746 +#define CONFIG_ANDROID_UBIFS_PARTITION_NM  "ROOT"
747 +#define CONFIG_ANDROID_CACHE_PARTITION_NAND "cache"
748  
749  /* allow to overwrite serial and ethaddr */
750  #define CONFIG_ENV_OVERWRITE
751 @@ -172,8 +178,8 @@
752                 "bootcmd_net=run bootargs_base bootargs_nfs; "          \
753                         "tftpboot ${loadaddr} ${kernel}; bootm\0"       \
754                 "bootcmd_android=run bootargs_base bootargs_android; "  \
755 -                       "mmcinit;cp.b 0x100000 ${loadaddr} 0x250000; "  \
756 -                       "cp.b 0x400000 ${rd_loadaddr} 0x4B000; "        \
757 +                       "mmc read 0 ${loadaddr} 0x800 0x1280; " \
758 +                       "mmc read 0 ${rd_loadaddr} 0x2000 0x258; "      \
759                         "bootm ${loadaddr} ${rd_loadaddr}\0"            \
760                 "prg_uboot=tftpboot ${loadaddr} ${uboot}; "             \
761                         "protect off ${uboot_addr} 0xa003ffff; "        \
762 diff --git a/include/linux/bitops.h b/include/linux/bitops.h
763 index 7d41ae6..e724310 100644
764 --- a/include/linux/bitops.h
765 +++ b/include/linux/bitops.h
766 @@ -1,6 +1,7 @@
767  #ifndef _LINUX_BITOPS_H
768  #define _LINUX_BITOPS_H
769  
770 +#include <asm/types.h>
771  
772  /*
773   * ffs: find first bit set. This is defined the same way as
774 @@ -37,6 +38,43 @@ static inline int generic_ffs(int x)
775         return r;
776  }
777  
778 +/**
779 + * fls - find last (most-significant) bit set
780 + * @x: the word to search
781 + *
782 + * This is defined the same way as ffs.
783 + * Note fls(0) = 0, fls(1) = 1, fls(0x80000000) = 32.
784 + */
785 +static inline int generic_fls(int x)
786 +{
787 +       int r = 32;
788 +
789 +       if (!x)
790 +               return 0;
791 +       if (!(x & 0xffff0000u)) {
792 +               x <<= 16;
793 +               r -= 16;
794 +       }
795 +       if (!(x & 0xff000000u)) {
796 +               x <<= 8;
797 +               r -= 8;
798 +       }
799 +       if (!(x & 0xf0000000u)) {
800 +               x <<= 4;
801 +               r -= 4;
802 +       }
803 +       if (!(x & 0xc0000000u)) {
804 +               x <<= 2;
805 +               r -= 2;
806 +       }
807 +       if (!(x & 0x80000000u)) {
808 +               x <<= 1;
809 +               r -= 1;
810 +       }
811 +       return r;
812 +}
813 +
814 +
815  /*
816   * hweightN: returns the hamming weight (i.e. the number
817   * of bits set) of a N-bit word
818 @@ -66,7 +104,52 @@ static inline unsigned int generic_hweight8(unsigned int w)
819         return (res & 0x0F) + ((res >> 4) & 0x0F);
820  }
821  
822 +#define BIT_MASK(nr)           (1UL << ((nr) % BITS_PER_LONG))
823 +#define BIT_WORD(nr)           ((nr) / BITS_PER_LONG)
824 +
825  #include <asm/bitops.h>
826  
827 +/* linux/include/asm-generic/bitops/non-atomic.h */
828 +
829 +#ifndef PLATFORM__SET_BIT
830 +# define __set_bit generic_set_bit
831 +#endif
832 +
833 +#ifndef PLATFORM__CLEAR_BIT
834 +# define __clear_bit generic_clear_bit
835 +#endif
836 +
837 +#ifndef PLATFORM_FFS
838 +# define ffs generic_ffs
839 +#endif
840 +
841 +#ifndef PLATFORM_FLS
842 +# define fls generic_fls
843 +#endif
844 +
845 +/**
846 + * __set_bit - Set a bit in memory
847 + * @nr: the bit to set
848 + * @addr: the address to start counting from
849 + *
850 + * Unlike set_bit(), this function is non-atomic and may be reordered.
851 + * If it's called on the same region of memory simultaneously, the effect
852 + * may be that only one operation succeeds.
853 + */
854 +static inline void generic_set_bit(int nr, volatile unsigned long *addr)
855 +{
856 +       unsigned long mask = BIT_MASK(nr);
857 +       unsigned long *p = ((unsigned long *)addr) + BIT_WORD(nr);
858 +
859 +       *p  |= mask;
860 +}
861 +
862 +static inline void generic_clear_bit(int nr, volatile unsigned long *addr)
863 +{
864 +       unsigned long mask = BIT_MASK(nr);
865 +       unsigned long *p = ((unsigned long *)addr) + BIT_WORD(nr);
866 +
867 +       *p &= ~mask;
868 +}
869  
870  #endif
871 -- 
872 1.5.4.4
873