Skip to content

Commit

Permalink
[MTD] Add the reverse operation of cfi_build_cmd()
Browse files Browse the repository at this point in the history
This is necessary to fix the broken status check in cfi_cmdset_0001

Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
  • Loading branch information
Thomas Gleixner authored and Thomas Gleixner committed May 23, 2005
1 parent fb6bb52 commit c927cd3
Showing 1 changed file with 64 additions and 1 deletion.
65 changes: 64 additions & 1 deletion include/linux/mtd/cfi.h
Original file line number Diff line number Diff line change
@@ -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__
Expand Down Expand Up @@ -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.
*
Expand Down

0 comments on commit c927cd3

Please sign in to comment.