[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>
This commit is contained in:
Thomas Gleixner 2005-03-15 19:03:16 +00:00 committed by Thomas Gleixner
parent fb6bb52ddd
commit c927cd3a22
1 changed files with 64 additions and 1 deletions

View File

@ -1,7 +1,7 @@
/* Common Flash Interface structures /* Common Flash Interface structures
* See http://support.intel.com/design/flash/technote/index.htm * 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__ #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) #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. * Sends a CFI command to a bank of flash for the given geometry.
* *