Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

[MTD] CFI: Use 16-bit access to autoselect/read device id data

Recent models of Intel/Sharp and Spansion CFI flash now have significant
bits in the upper byte of device ID codes, read via what Spansion calls
"autoselect" and Intel calls "read device identifier". Currently these
values are truncated to the low 8 bits in the mtd data structures, as
all CFI read query info has previously been read one byte at a time.
Add a new method for reading 16-bit info, currently just manufacturer
and device codes; datasheets hint at future uses for upper bytes in
other fields.

Signed-off-by: Todd Poynor <tpoynor@mvista.com>
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>

authored by

Todd Poynor and committed by
Thomas Gleixner
987d2401 3eb8ceac

+20 -4
+3 -3
drivers/mtd/chips/cfi_probe.c
··· 1 1 /* 2 2 Common Flash Interface probe code. 3 3 (C) 2000 Red Hat. GPL'd. 4 - $Id: cfi_probe.c,v 1.84 2005/11/07 11:14:23 gleixner Exp $ 4 + $Id: cfi_probe.c,v 1.85 2005/11/15 23:28:17 tpoynor Exp $ 5 5 */ 6 6 7 7 #include <linux/config.h> ··· 230 230 cfi_send_gen_cmd(0xaa, 0x555, base, map, cfi, cfi->device_type, NULL); 231 231 cfi_send_gen_cmd(0x55, 0x2aa, base, map, cfi, cfi->device_type, NULL); 232 232 cfi_send_gen_cmd(0x90, 0x555, base, map, cfi, cfi->device_type, NULL); 233 - cfi->mfr = cfi_read_query(map, base); 234 - cfi->id = cfi_read_query(map, base + ofs_factor); 233 + cfi->mfr = cfi_read_query16(map, base); 234 + cfi->id = cfi_read_query16(map, base + ofs_factor); 235 235 236 236 /* Put it back into Read Mode */ 237 237 cfi_send_gen_cmd(0xF0, 0, base, map, cfi, cfi->device_type, NULL);
+17 -1
include/linux/mtd/cfi.h
··· 1 1 2 2 /* Common Flash Interface structures 3 3 * See http://support.intel.com/design/flash/technote/index.htm 4 - * $Id: cfi.h,v 1.56 2005/11/07 11:14:54 gleixner Exp $ 4 + * $Id: cfi.h,v 1.57 2005/11/15 23:28:17 tpoynor Exp $ 5 5 */ 6 6 7 7 #ifndef __MTD_CFI_H__ ··· 416 416 417 417 if (map_bankwidth_is_1(map)) { 418 418 return val.x[0]; 419 + } else if (map_bankwidth_is_2(map)) { 420 + return cfi16_to_cpu(val.x[0]); 421 + } else { 422 + /* No point in a 64-bit byteswap since that would just be 423 + swapping the responses from different chips, and we are 424 + only interested in one chip (a representative sample) */ 425 + return cfi32_to_cpu(val.x[0]); 426 + } 427 + } 428 + 429 + static inline uint16_t cfi_read_query16(struct map_info *map, uint32_t addr) 430 + { 431 + map_word val = map_read(map, addr); 432 + 433 + if (map_bankwidth_is_1(map)) { 434 + return val.x[0] & 0xff; 419 435 } else if (map_bankwidth_is_2(map)) { 420 436 return cfi16_to_cpu(val.x[0]); 421 437 } else {