diff options
author | Thomas Gleixner <tglx@linutronix.de> | 2005-03-15 19:03:16 +0000 |
---|---|---|
committer | Thomas Gleixner <tglx@mtd.linutronix.de> | 2005-05-23 12:53:05 +0200 |
commit | c927cd3a226bed5cf063cdf04de13cef51144cef (patch) | |
tree | ebb14c72811e3d2d76bf8be82799334302600947 /include/linux/mtd | |
parent | fb6bb52ddde0429b654ab6d4cb20fa016a1d5b0d (diff) | |
download | lwn-c927cd3a226bed5cf063cdf04de13cef51144cef.tar.gz lwn-c927cd3a226bed5cf063cdf04de13cef51144cef.zip |
[MTD] Add the reverse operation of cfi_build_cmd()
This is necessary to fix the broken status check in cfi_cmdset_0001
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Diffstat (limited to 'include/linux/mtd')
-rw-r--r-- | include/linux/mtd/cfi.h | 65 |
1 files changed, 64 insertions, 1 deletions
diff --git a/include/linux/mtd/cfi.h b/include/linux/mtd/cfi.h index 76255474a27c..66e0a32efbac 100644 --- a/include/linux/mtd/cfi.h +++ b/include/linux/mtd/cfi.h @@ -1,7 +1,7 @@ /* Common Flash Interface structures * See http://support.intel.com/design/flash/technote/index.htm - * $Id: cfi.h,v 1.52 2005/02/08 17:11:15 nico Exp $ + * $Id: cfi.h,v 1.53 2005/03/15 19:03:13 gleixner Exp $ */ #ifndef __MTD_CFI_H__ @@ -315,6 +315,69 @@ static inline map_word cfi_build_cmd(u_long cmd, struct map_info *map, struct cf } #define CMD(x) cfi_build_cmd((x), map, cfi) + +static inline unsigned char cfi_merge_status(map_word val, struct map_info *map, + struct cfi_private *cfi) +{ + int wordwidth, words_per_bus, chip_mode, chips_per_word; + unsigned long onestat, res = 0; + int i; + + /* We do it this way to give the compiler a fighting chance + of optimising away all the crap for 'bankwidth' larger than + an unsigned long, in the common case where that support is + disabled */ + if (map_bankwidth_is_large(map)) { + wordwidth = sizeof(unsigned long); + words_per_bus = (map_bankwidth(map)) / wordwidth; // i.e. normally 1 + } else { + wordwidth = map_bankwidth(map); + words_per_bus = 1; + } + + chip_mode = map_bankwidth(map) / cfi_interleave(cfi); + chips_per_word = wordwidth * cfi_interleave(cfi) / map_bankwidth(map); + + onestat = val.x[0]; + /* Or all status words together */ + for (i=1; i < words_per_bus; i++) { + onestat |= val.x[i]; + } + + res = onestat; + switch(chips_per_word) { + default: BUG(); +#if BITS_PER_LONG >= 64 + case 8: + res |= (onestat >> (chip_mode * 32)); +#endif + case 4: + res |= (onestat >> (chip_mode * 16)); + case 2: + res |= (onestat >> (chip_mode * 8)); + case 1: + ; + } + + /* Last, determine what the bit-pattern should be for a single + device, according to chip mode and endianness... */ + switch (chip_mode) { + case 1: + break; + case 2: + res = cfi16_to_cpu(res); + break; + case 4: + res = cfi32_to_cpu(res); + break; + default: BUG(); + } + return res; +} + +#define MERGESTATUS(x) cfi_merge_status((x), map, cfi) + + /* * Sends a CFI command to a bank of flash for the given geometry. * |