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.
6 ubifs support for android recovery mode.
8 Signed-off-by: Terry Lv <r65388@freescale.com>
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(-)
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)
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
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
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)
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)
52 -inline int switch_to_recovery_mode(void)
53 +static int switch_to_recovery_mode(void)
56 char *boot_args = NULL;
57 @@ -648,127 +648,164 @@ inline int switch_to_recovery_mode(void)
61 -inline int check_recovery_cmd_file(void)
62 +static int check_mmc_recovery_cmd_file(int dev_num, int part_num, char *path)
64 + block_dev_desc_t *dev_desc = NULL;
65 + struct mmc *mmc = find_mmc_device(dev_num);
66 disk_partition_t info;
69 + ulong part_length = 0;
72 - switch (get_boot_device()) {
75 - block_dev_desc_t *dev_desc = NULL;
76 - struct mmc *mmc = find_mmc_device(0);
77 + memset(&info, 0, sizeof(disk_partition_t));
79 - dev_desc = get_dev("mmc", 0);
80 + dev_desc = get_dev("mmc", dev_num);
82 - if (NULL == dev_desc) {
83 - puts("** Block device MMC 0 not supported\n");
86 + if (NULL == dev_desc) {
87 + printf("** Block device MMC %d not supported\n",
95 - if (get_partition_info(dev_desc,
96 - CONFIG_ANDROID_CACHE_PARTITION_MMC,
98 - printf("** Bad partition %d **\n",
99 - CONFIG_ANDROID_CACHE_PARTITION_MMC);
102 + if (get_partition_info(dev_desc,
105 + printf("** Bad partition %d **\n",
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);
118 + part_length = ext2fs_set_blk_dev(dev_desc,
120 + if (part_length == 0) {
121 + printf("** Bad partition - mmc 0:%d **\n",
127 - if (!ext2fs_mount(part_length)) {
128 - printf("** Bad ext2 partition or disk - mmc 0:%d **\n",
129 - CONFIG_ANDROID_CACHE_PARTITION_MMC);
133 + if (!ext2fs_mount(part_length)) {
134 + printf("** Bad ext2 partition or disk - mmc 0:%d **\n",
140 - filelen = ext2fs_open(CONFIG_ANDROID_RECOVERY_CMD_FILE);
141 + filelen = ext2fs_open(path);
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 };
159 - /* ========== ubi and mtd operations ========== */
160 - if (mtdparts_init() != 0) {
161 - printf("Error initializing mtdparts!\n");
166 - if (find_dev_and_part("nand", &dev_desc, &pnum, &part)) {
167 - printf("Partition %s not found!\n", "nand");
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",
179 + return (filelen > 0) ? 1 : 0;
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);
189 - err = ubi_mtd_param_parse(mtd_buffer, NULL);
191 - del_mtd_partitions(&info);
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);
200 - del_mtd_partitions(&info);
203 +static int check_nand_recovery_cmd_file(char *mtd_part_name,
204 + char *ubi_part_name,
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 };
218 + memset(&mtd_part, 0, sizeof(struct mtd_partition));
220 + /* ========== ubi and mtd operations ========== */
221 + if (mtdparts_init() != 0) {
222 + printf("Error initializing mtdparts!\n");
226 - /* ========== ubifs operations ========== */
229 + if (find_dev_and_part(mtd_part_name, &dev_desc, &pnum, &part)) {
230 + printf("Partition %s not found!\n", mtd_part_name);
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",
243 - if (ubifs_mount(CONFIG_ANDROID_CACHE_PARTITION_NAND)) {
244 - printf("Mount ubifs volume %s fail!\n",
245 - CONFIG_ANDROID_CACHE_PARTITION_NAND);
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);
255 - /* Try to read one byte for a read test. */
256 - if (ubifs_load(CONFIG_ANDROID_RECOVERY_CMD_FILE,
258 - /* File not found */
264 + err = ubi_mtd_param_parse(mtd_buffer, NULL);
266 + del_mtd_partitions(mtd_info);
272 + del_mtd_partitions(mtd_info);
276 + /* ========== ubifs operations ========== */
280 + if (ubifs_mount(ubi_part_name)) {
281 + printf("Mount ubifs volume %s fail!\n",
286 + /* Try to read one byte for a read test. */
287 + if (ubifs_load(path, (u32)&read_test, 1)) {
288 + /* File not found */
296 +static int check_recovery_cmd_file(void)
301 + switch (get_boot_device()) {
303 + if_exist = check_mmc_recovery_cmd_file(0,
304 + CONFIG_ANDROID_CACHE_PARTITION_MMC,
305 + CONFIG_ANDROID_RECOVERY_CMD_FILE);
308 + env = getenv("mtdparts");
310 + setenv("mtdparts", MTDPARTS_DEFAULT);
312 + env = getenv("mtdids");
314 + setenv("mtdids", MTDIDS_DEFAULT);
316 + env = getenv("partition");
318 + setenv("partition", MTD_ACTIVE_PART);
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);
326 @@ -779,7 +816,7 @@ inline int check_recovery_cmd_file(void)
330 - return (filelen > 0) ? 1 : 0;
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);
342 INIT_LIST_HEAD(&ubifs_infos);
343 + INIT_LIST_HEAD(&(ubifs_fs_type.fs_supers));
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)
354 ubifs_compressors[compr->compr_type] = compr;
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;
365 @@ -379,9 +383,11 @@ static unsigned long ubifs_findfile(struct super_block *sb, char *filename)
369 + char symlinkpath[128];
371 unsigned long root_inum = 1;
373 + int symlink_count = 0; /* Don't allow symlink recursion */
375 strcpy(fpath, filename);
377 @@ -397,6 +403,9 @@ static unsigned long ubifs_findfile(struct super_block *sb, char *filename)
381 + struct inode *inode;
382 + struct ubifs_inode *ui;
384 /* Extract the actual part from the pathname. */
385 next = strchr(name, '/');
387 @@ -406,18 +415,48 @@ static unsigned long ubifs_findfile(struct super_block *sb, char *filename)
390 ret = ubifs_finddir(sb, name, root_inum, &inum);
393 + inode = ubifs_iget(sb, inum);
397 + ui = ubifs_inode(inode);
399 + if ((inode->i_mode & S_IFMT) == S_IFLNK) {
400 + char link_name[64];
403 + /* We have some sort of symlink recursion, bail out */
404 + if (symlink_count++ > 8) {
405 + printf("Symlink recursion, aborting\n");
408 + memcpy(link_name, ui->data, ui->data_len);
409 + link_name[ui->data_len] = '\0';
411 + if (link_name[0] == '/') {
412 + /* Absolute path, redo everything without
413 + * the leading slash */
414 + next = name = link_name + 1;
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;
427 * Check if directory with this name exists
430 /* Found the node! */
431 - if (!next || *next == '\0') {
437 + if (!next || *next == '\0')
442 @@ -614,10 +653,10 @@ int ubifs_load(char *filename, u32 addr, u32 size)
446 - char link_name[64];
447 - struct ubifs_inode *ui;
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);
455 @@ -635,23 +674,6 @@ int ubifs_load(char *filename, u32 addr, u32 size)
459 - * Check for symbolic link
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);
469 - * Now we have the "real" filename, call ubifs_load()
470 - * again (recursive call) to load this file instead
472 - return ubifs_load(link_name, addr, size);
476 * If no size was specified or if size bigger than filesize
477 * set size to filesize
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)
487 -/* linux/include/linux/bitops.h */
489 -#define BIT_MASK(nr) (1UL << ((nr) % BITS_PER_LONG))
490 -#define BIT_WORD(nr) ((nr) / BITS_PER_LONG)
492 -/* linux/include/asm-generic/bitops/non-atomic.h */
495 - * __set_bit - Set a bit in memory
496 - * @nr: the bit to set
497 - * @addr: the address to start counting from
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.
503 -static inline void __set_bit(int nr, volatile unsigned long *addr)
505 - unsigned long mask = BIT_MASK(nr);
506 - unsigned long *p = ((unsigned long *)addr) + BIT_WORD(nr);
511 -static inline void __clear_bit(int nr, volatile unsigned long *addr)
513 - unsigned long mask = BIT_MASK(nr);
514 - unsigned long *p = ((unsigned long *)addr) + BIT_WORD(nr);
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
530 +#include <asm/proc/system.h>
532 #define smp_mb__before_clear_bit() do { } while (0)
533 #define smp_mb__after_clear_bit() do { } while (0)
537 extern void set_bit(int nr, volatile void * addr);
539 -static inline void __set_bit(int nr, volatile void *addr)
541 - ((unsigned char *) addr)[nr >> 3] |= (1U << (nr & 7));
544 extern void clear_bit(int nr, volatile void * addr);
546 -static inline void __clear_bit(int nr, volatile void *addr)
548 - ((unsigned char *) addr)[nr >> 3] &= ~(1U << (nr & 7));
551 extern void change_bit(int nr, volatile void * addr);
553 static inline void __change_bit(int nr, volatile void *addr)
555 - ((unsigned char *) addr)[nr >> 3] ^= (1U << (nr & 7));
557 + unsigned long mask = BIT_MASK(nr);
558 + unsigned long *p = ((unsigned long *)addr) + BIT_WORD(nr);
560 -extern int test_and_set_bit(int nr, volatile void * addr);
564 static inline int __test_and_set_bit(int nr, volatile void *addr)
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;
572 - oldval = ((unsigned char *) addr)[nr >> 3];
573 - ((unsigned char *) addr)[nr >> 3] = oldval | mask;
574 - return oldval & mask;
576 + return (old & mask) != 0;
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)
582 + unsigned long flags;
585 + local_irq_save(flags);
586 + out = __test_and_set_bit(nr, addr);
587 + local_irq_restore(flags);
592 static inline int __test_and_clear_bit(int nr, volatile void *addr)
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;
600 - oldval = ((unsigned char *) addr)[nr >> 3];
601 - ((unsigned char *) addr)[nr >> 3] = oldval & ~mask;
602 - return oldval & mask;
604 + return (old & mask) != 0;
607 +static inline int test_and_clear_bit(int nr, volatile void *addr)
609 + unsigned long flags;
612 + local_irq_save(flags);
613 + out = __test_and_clear_bit(nr, addr);
614 + local_irq_restore(flags);
619 extern int test_and_change_bit(int nr, volatile void * addr);
621 static inline int __test_and_change_bit(int nr, volatile void *addr)
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;
629 - oldval = ((unsigned char *) addr)[nr >> 3];
630 - ((unsigned char *) addr)[nr >> 3] = oldval ^ mask;
631 - return oldval & mask;
633 + return (old & mask) != 0;
636 extern int find_first_zero_bit(void * addr, unsigned size);
637 @@ -110,14 +125,6 @@ static inline unsigned long ffz(unsigned long word)
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).
646 -#define ffs(x) generic_ffs(x)
649 * hweightN: returns the hamming weight (i.e. the number
650 * of bits set) of a N-bit word
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
658 #include <linux/config.h>
661 - __asm__ __volatile__( \
662 - "mcr p15, 0, %0, c1, c0 @ set CR" \
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 */
681 -extern unsigned long cr_no_alignment; /* defined in entry-armv.S */
682 -extern unsigned long cr_alignment; /* defined in entry-armv.S */
684 -#if __LINUX_ARM_ARCH__ >= 4
685 -#define vectors_base() ((cr_alignment & CR_V) ? 0xffff0000 : 0)
687 -#define vectors_base() (0)
691 * Save the current interrupt enable state & disable IRQs
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
698 #define CONFIG_DISPLAY_CPUINFO
699 #define CONFIG_DISPLAY_BOARDINFO
701 +#define CONFIG_FLASH_HEADER 1
702 +#define CONFIG_FLASH_HEADER_OFFSET 0x400
703 +#define CONFIG_FLASH_HEADER_BARKER 0xB1
705 #define BOARD_LATE_INIT
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
714 * Size of malloc() pool
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
722 #define CONFIG_CMD_MII
723 #define CONFIG_CMD_NET
724 #define CONFIG_NET_RETRY_COUNT 100
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
740 * Android support Configs
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"
749 /* allow to overwrite serial and ethaddr */
750 #define CONFIG_ENV_OVERWRITE
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
767 #ifndef _LINUX_BITOPS_H
768 #define _LINUX_BITOPS_H
770 +#include <asm/types.h>
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)
779 + * fls - find last (most-significant) bit set
780 + * @x: the word to search
782 + * This is defined the same way as ffs.
783 + * Note fls(0) = 0, fls(1) = 1, fls(0x80000000) = 32.
785 +static inline int generic_fls(int x)
791 + if (!(x & 0xffff0000u)) {
795 + if (!(x & 0xff000000u)) {
799 + if (!(x & 0xf0000000u)) {
803 + if (!(x & 0xc0000000u)) {
807 + if (!(x & 0x80000000u)) {
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);
822 +#define BIT_MASK(nr) (1UL << ((nr) % BITS_PER_LONG))
823 +#define BIT_WORD(nr) ((nr) / BITS_PER_LONG)
825 #include <asm/bitops.h>
827 +/* linux/include/asm-generic/bitops/non-atomic.h */
829 +#ifndef PLATFORM__SET_BIT
830 +# define __set_bit generic_set_bit
833 +#ifndef PLATFORM__CLEAR_BIT
834 +# define __clear_bit generic_clear_bit
837 +#ifndef PLATFORM_FFS
838 +# define ffs generic_ffs
841 +#ifndef PLATFORM_FLS
842 +# define fls generic_fls
846 + * __set_bit - Set a bit in memory
847 + * @nr: the bit to set
848 + * @addr: the address to start counting from
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.
854 +static inline void generic_set_bit(int nr, volatile unsigned long *addr)
856 + unsigned long mask = BIT_MASK(nr);
857 + unsigned long *p = ((unsigned long *)addr) + BIT_WORD(nr);
862 +static inline void generic_clear_bit(int nr, volatile unsigned long *addr)
864 + unsigned long mask = BIT_MASK(nr);
865 + unsigned long *p = ((unsigned long *)addr) + BIT_WORD(nr);