diff options
author | Kevin Cernekee <cernekee@gmail.com> | 2010-10-30 21:11:03 -0700 |
---|---|---|
committer | Javier Jardón <jjardon@gnome.org> | 2015-05-06 16:15:36 +0100 |
commit | 856b0f757f2011eed19170984a084d82747a3d7c (patch) | |
tree | 8e6808f067f4689868bfa3cee8057aee4e092ce3 | |
parent | 5842f4785d19e212b89e48ef66970b843f6032f0 (diff) | |
download | linux-stable-856b0f757f2011eed19170984a084d82747a3d7c.tar.gz |
mtd: m25p80: Add support for Macronix MX25L25635E
This is a 256Mbit (32MiB) part so minor changes were made to support
4-byte addressing.
Signed-off-by: Kevin Cernekee <cernekee@gmail.com>
Signed-off-by: Artem Bityutskiy <Artem.Bityutskiy@nokia.com>
Signed-off-by: David Woodhouse <David.Woodhouse@intel.com>
(cherry picked from commit 4b7f7422b0331e802f8b7c593e058ccee981cff5)
Conflicts:
drivers/mtd/devices/m25p80.c
-rw-r--r-- | drivers/mtd/devices/m25p80.c | 31 |
1 files changed, 28 insertions, 3 deletions
diff --git a/drivers/mtd/devices/m25p80.c b/drivers/mtd/devices/m25p80.c index 686aff7f4c3b..0e754894505a 100644 --- a/drivers/mtd/devices/m25p80.c +++ b/drivers/mtd/devices/m25p80.c @@ -46,6 +46,10 @@ #define OPCODE_WRDI 0x04 /* Write disable */ #define OPCODE_AAI_WP 0xad /* Auto address increment word program */ +/* Used for Macronix flashes only. */ +#define OPCODE_EN4B 0xb7 /* Enter 4-byte mode */ +#define OPCODE_EX4B 0xe9 /* Exit 4-byte mode */ + /* Status Register bits. */ #define SR_WIP 1 /* Write in progress */ #define SR_WEL 2 /* Write enable latch */ @@ -57,7 +61,7 @@ /* Define max times to check status register before we give up. */ #define MAX_READY_WAIT_JIFFIES (40 * HZ) /* M25P16 specs 40s max chip erase */ -#define MAX_CMD_SIZE 4 +#define MAX_CMD_SIZE 5 #ifdef CONFIG_M25PXX_USE_FAST_READ #define OPCODE_READ OPCODE_FAST_READ @@ -153,6 +157,16 @@ static inline int write_disable(struct m25p *flash) } /* + * Enable/disable 4-byte addressing mode. + */ +static inline int set_4byte(struct m25p *flash, int enable) +{ + u8 code = enable ? OPCODE_EN4B : OPCODE_EX4B; + + return spi_write_then_read(flash->spi, &code, 1, NULL, 0); +} + +/* * Service routine to read status register until ready, or timeout occurs. * Returns non-zero if error. */ @@ -208,6 +222,7 @@ static void m25p_addr2cmd(struct m25p *flash, unsigned int addr, u8 *cmd) cmd[1] = addr >> (flash->addr_width * 8 - 8); cmd[2] = addr >> (flash->addr_width * 8 - 16); cmd[3] = addr >> (flash->addr_width * 8 - 24); + cmd[4] = addr >> (flash->addr_width * 8 - 32); } static int m25p_cmdsz(struct m25p *flash) @@ -608,7 +623,7 @@ struct flash_info { }; #define INFO(_jedec_id, _ext_id, _sector_size, _n_sectors, _flags) \ - _jedec_id, _ext_id, _sector_size, _n_sectors, 256, 3, _flags + _jedec_id, _ext_id, _sector_size, _n_sectors, 256, _flags #define CAT25_INFO(_sector_size, _n_sectors, _page_size, _addr_width) \ 0, 0, _sector_size, _n_sectors, _page_size, _addr_width, M25P_NO_ERASE @@ -831,7 +846,17 @@ static int __devinit m25p_probe(struct spi_device *spi) flash->mtd.flags |= MTD_NO_ERASE; flash->page_size = info->page_size; - flash->addr_width = info->addr_width; + + if (info->addr_width) + flash->addr_width = info->addr_width; + else { + /* enable 4-byte addressing if the device exceeds 16MiB */ + if (flash->mtd.size > 0x1000000) { + flash->addr_width = 4; + set_4byte(flash, 1); + } else + flash->addr_width = 3; + } dev_info(&spi->dev, "%s (%lld Kbytes)\n", info->name, (long long)flash->mtd.size >> 10); |