summaryrefslogtreecommitdiffstats
path: root/drivers/mtd/chips/jedec_probe.c
diff options
context:
space:
mode:
authorMike Rapoport <mike@compulab.co.il>2008-05-27 10:20:03 +0200
committerDavid Woodhouse <dwmw2@infradead.org>2008-06-04 18:22:59 +0200
commit5c9c11e1c47c2101253a95c54ef72e13edcc728a (patch)
treeb1af123309e5827d174fe3cea0efae106550ffc3 /drivers/mtd/chips/jedec_probe.c
parent[MTD] [NOR] Add support for AMD AM29SL800D[BT] NOR flash chips (diff)
downloadlinux-5c9c11e1c47c2101253a95c54ef72e13edcc728a.tar.xz
linux-5c9c11e1c47c2101253a95c54ef72e13edcc728a.zip
[MTD] [NOR] Add support for flash chips with ID in bank other than 0
According to JEDEC "Standard Manufacturer's Identification Code" (http://www.jedec.org/download/search/jep106W.pdf) several first banks of NOR flash can contain 0x7f instead of actual ID. This patch adds support for reading manufacturer ID from banks other than 0. Signed-off-by: Mike Rapoport <mike@compulab.co.il> Signed-off-by: David Woodhouse <dwmw2@infradead.org>
Diffstat (limited to 'drivers/mtd/chips/jedec_probe.c')
-rw-r--r--drivers/mtd/chips/jedec_probe.c19
1 files changed, 16 insertions, 3 deletions
diff --git a/drivers/mtd/chips/jedec_probe.c b/drivers/mtd/chips/jedec_probe.c
index b717f1a5d6b2..279fe60b7855 100644
--- a/drivers/mtd/chips/jedec_probe.c
+++ b/drivers/mtd/chips/jedec_probe.c
@@ -37,6 +37,7 @@
#define MANUFACTURER_ST 0x0020
#define MANUFACTURER_TOSHIBA 0x0098
#define MANUFACTURER_WINBOND 0x00da
+#define CONTINUATION_CODE 0x007f
/* AMD */
@@ -1760,9 +1761,21 @@ static inline u32 jedec_read_mfr(struct map_info *map, uint32_t base,
{
map_word result;
unsigned long mask;
- u32 ofs = cfi_build_cmd_addr(0, cfi_interleave(cfi), cfi->device_type);
- mask = (1 << (cfi->device_type * 8)) -1;
- result = map_read(map, base + ofs);
+ int bank = 0;
+
+ /* According to JEDEC "Standard Manufacturer's Identification Code"
+ * (http://www.jedec.org/download/search/jep106W.pdf)
+ * several first banks can contain 0x7f instead of actual ID
+ */
+ do {
+ uint32_t ofs = cfi_build_cmd_addr(0 + (bank << 8),
+ cfi_interleave(cfi),
+ cfi->device_type);
+ mask = (1 << (cfi->device_type * 8)) - 1;
+ result = map_read(map, base + ofs);
+ bank++;
+ } while ((result.x[0] & mask) == CONTINUATION_CODE);
+
return result.x[0] & mask;
}