Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit c927cd3a authored by Thomas Gleixner's avatar Thomas Gleixner Committed by Thomas Gleixner
Browse files

[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: default avatarThomas Gleixner <tglx@linutronix.de>
parent fb6bb52d
Loading
Loading
Loading
Loading
+64 −1
Original line number Diff line number Diff line

/* 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.
 *