From c9f7ec30848637989b85a9f0ac5d4aa33c49916e Mon Sep 17 00:00:00 2001 From: Nicolas Pitre Date: Fri, 23 Oct 2009 16:02:42 -0400 Subject: mtd: add missing put_chip() in cfi_intelext_reset() Signed-off-by: Nicolas Pitre Signed-off-by: Artem Bityutskiy Signed-off-by: David Woodhouse --- drivers/mtd/chips/cfi_cmdset_0001.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers/mtd/chips') diff --git a/drivers/mtd/chips/cfi_cmdset_0001.c b/drivers/mtd/chips/cfi_cmdset_0001.c index e7563a9872d..d923a2d88f9 100644 --- a/drivers/mtd/chips/cfi_cmdset_0001.c +++ b/drivers/mtd/chips/cfi_cmdset_0001.c @@ -2564,6 +2564,7 @@ static int cfi_intelext_reset(struct mtd_info *mtd) if (!ret) { map_write(map, CMD(0xff), chip->start); chip->state = FL_SHUTDOWN; + put_chip(map, chip, chip->start); } spin_unlock(chip->mutex); } -- cgit v1.2.3 From 8dbaea4bfcecacaf496a3e2ae92867baedbcab8e Mon Sep 17 00:00:00 2001 From: Hans-Christian Egtvedt Date: Thu, 5 Nov 2009 15:53:37 +0100 Subject: mtd: add lock fixup for AT49BV640D and AT49BV640DT chips This patch sets the MTD_POWERUP_LOCK flag for AT49BV640D and AT49BV640DT devices, since the devices are locked when powered up and needs to be unlocked before interfaced. Quote datasheet; "At power-up and reset, all sectors have their Softlock protection mode enabled.". Tested on AVR32 hardware platform with an AT49BV640D flash device. Signed-off-by: Hans-Christian Egtvedt Acked-by: Nicolas Pitre Signed-off-by: Artem Bityutskiy Signed-off-by: David Woodhouse --- drivers/mtd/chips/cfi_cmdset_0001.c | 14 ++++++++++++++ 1 file changed, 14 insertions(+) (limited to 'drivers/mtd/chips') diff --git a/drivers/mtd/chips/cfi_cmdset_0001.c b/drivers/mtd/chips/cfi_cmdset_0001.c index d923a2d88f9..94be67e880a 100644 --- a/drivers/mtd/chips/cfi_cmdset_0001.c +++ b/drivers/mtd/chips/cfi_cmdset_0001.c @@ -51,7 +51,9 @@ #define M50LPW080 0x002F #define M50FLW080A 0x0080 #define M50FLW080B 0x0081 +/* Atmel chips */ #define AT49BV640D 0x02de +#define AT49BV640DT 0x02db static int cfi_intelext_read (struct mtd_info *, loff_t, size_t, size_t *, u_char *); static int cfi_intelext_write_words(struct mtd_info *, loff_t, size_t, size_t *, const u_char *); @@ -199,6 +201,16 @@ static void fixup_convert_atmel_pri(struct mtd_info *mtd, void *param) cfi->cfiq->BufWriteTimeoutMax = 0; } +static void fixup_at49bv640dx_lock(struct mtd_info *mtd, void *param) +{ + struct map_info *map = mtd->priv; + struct cfi_private *cfi = map->fldrv_priv; + struct cfi_pri_intelext *cfip = cfi->cmdset_priv; + + cfip->FeatureSupport |= (1 << 5); + mtd->flags |= MTD_POWERUP_LOCK; +} + #ifdef CMDSET0001_DISABLE_ERASE_SUSPEND_ON_WRITE /* Some Intel Strata Flash prior to FPO revision C has bugs in this area */ static void fixup_intel_strataflash(struct mtd_info *mtd, void* param) @@ -283,6 +295,8 @@ static void fixup_unlock_powerup_lock(struct mtd_info *mtd, void *param) static struct cfi_fixup cfi_fixup_table[] = { { CFI_MFR_ATMEL, CFI_ID_ANY, fixup_convert_atmel_pri, NULL }, + { CFI_MFR_ATMEL, AT49BV640D, fixup_at49bv640dx_lock, NULL }, + { CFI_MFR_ATMEL, AT49BV640DT, fixup_at49bv640dx_lock, NULL }, #ifdef CMDSET0001_DISABLE_ERASE_SUSPEND_ON_WRITE { CFI_MFR_ANY, CFI_ID_ANY, fixup_intel_strataflash, NULL }, #endif -- cgit v1.2.3 From b2ef1a2bb2eb49cd7c75b22f1ea40ead0bdfdb8a Mon Sep 17 00:00:00 2001 From: Hans-Christian Egtvedt Date: Thu, 5 Nov 2009 15:53:43 +0100 Subject: mtd: move manufacturer to the common cfi.h header file This patch moves the MANUFACTURER_ST and MANUFACTURER_INTEL to the include/linux/mtd/cfi.h header file and renames them to CFI_MFR_ST and CFI_MFR_INTEL. CFI_MFR_ST was already present there. All references in drivers/mtd/chips/cfi_cmdset_0001.c are updated to reflect this. Signed-off-by: Hans-Christian Egtvedt Acked-by: Nicolas Pitre Signed-off-by: Artem Bityutskiy Signed-off-by: David Woodhouse --- drivers/mtd/chips/cfi_cmdset_0001.c | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) (limited to 'drivers/mtd/chips') diff --git a/drivers/mtd/chips/cfi_cmdset_0001.c b/drivers/mtd/chips/cfi_cmdset_0001.c index 94be67e880a..5fbf29e1e64 100644 --- a/drivers/mtd/chips/cfi_cmdset_0001.c +++ b/drivers/mtd/chips/cfi_cmdset_0001.c @@ -43,11 +43,11 @@ // debugging, turns off buffer write mode if set to 1 #define FORCE_WORD_WRITE 0 -#define MANUFACTURER_INTEL 0x0089 +/* Intel chips */ #define I82802AB 0x00ad #define I82802AC 0x00ac #define PF38F4476 0x881c -#define MANUFACTURER_ST 0x0020 +/* STMicroelectronics chips */ #define M50LPW080 0x002F #define M50FLW080A 0x0080 #define M50FLW080B 0x0081 @@ -308,16 +308,16 @@ static struct cfi_fixup cfi_fixup_table[] = { #endif { CFI_MFR_ST, 0x00ba, /* M28W320CT */ fixup_st_m28w320ct, NULL }, { CFI_MFR_ST, 0x00bb, /* M28W320CB */ fixup_st_m28w320cb, NULL }, - { MANUFACTURER_INTEL, CFI_ID_ANY, fixup_unlock_powerup_lock, NULL, }, + { CFI_MFR_INTEL, CFI_ID_ANY, fixup_unlock_powerup_lock, NULL, }, { 0, 0, NULL, NULL } }; static struct cfi_fixup jedec_fixup_table[] = { - { MANUFACTURER_INTEL, I82802AB, fixup_use_fwh_lock, NULL, }, - { MANUFACTURER_INTEL, I82802AC, fixup_use_fwh_lock, NULL, }, - { MANUFACTURER_ST, M50LPW080, fixup_use_fwh_lock, NULL, }, - { MANUFACTURER_ST, M50FLW080A, fixup_use_fwh_lock, NULL, }, - { MANUFACTURER_ST, M50FLW080B, fixup_use_fwh_lock, NULL, }, + { CFI_MFR_INTEL, I82802AB, fixup_use_fwh_lock, NULL, }, + { CFI_MFR_INTEL, I82802AC, fixup_use_fwh_lock, NULL, }, + { CFI_MFR_ST, M50LPW080, fixup_use_fwh_lock, NULL, }, + { CFI_MFR_ST, M50FLW080A, fixup_use_fwh_lock, NULL, }, + { CFI_MFR_ST, M50FLW080B, fixup_use_fwh_lock, NULL, }, { 0, 0, NULL, NULL } }; static struct cfi_fixup fixup_table[] = { @@ -333,7 +333,7 @@ static struct cfi_fixup fixup_table[] = { static void cfi_fixup_major_minor(struct cfi_private *cfi, struct cfi_pri_intelext *extp) { - if (cfi->mfr == MANUFACTURER_INTEL && + if (cfi->mfr == CFI_MFR_INTEL && cfi->id == PF38F4476 && extp->MinorVersion == '3') extp->MinorVersion = '1'; } @@ -2249,7 +2249,7 @@ static int cfi_intelext_otp_walk(struct mtd_info *mtd, loff_t from, size_t len, /* Some chips have OTP located in the _top_ partition only. For example: Intel 28F256L18T (T means top-parameter device) */ - if (cfi->mfr == MANUFACTURER_INTEL) { + if (cfi->mfr == CFI_MFR_INTEL) { switch (cfi->id) { case 0x880b: case 0x880c: -- cgit v1.2.3 From 2695eab964efaa382168e0351705967bd9deb7ea Mon Sep 17 00:00:00 2001 From: Joakim Tjernlund Date: Thu, 19 Nov 2009 12:01:58 +0100 Subject: mtd: CFI cmdset_0002: enable erase-suspend-program Erase-suspend for writing is required to avoid blocking applications that wish to write some data (to a NOR block other than the one being erased). Particularly, it solves some huge delays that an application (which writes to a UBIFS) will experience if UBI attaches to empty NOR flash. In this case the UBI background thread will erase a lot of blocks and the application can be blocked for minutes because of the "MTD/CFI chip lock". This feature has been disabled for years. Maybe this was because the old code turned it on for erase-suspend read-only chips also (cfip->EraseSuspend & 0x1). This is wrong and corrected now. This patch was tweaked by Norbert van Bolhuis. Signed-off-by: Norbert van Bolhuis Signed-off-by: Artem Bityutskiy Signed-off-by: David Woodhouse --- drivers/mtd/chips/cfi_cmdset_0002.c | 16 +++------------- 1 file changed, 3 insertions(+), 13 deletions(-) (limited to 'drivers/mtd/chips') diff --git a/drivers/mtd/chips/cfi_cmdset_0002.c b/drivers/mtd/chips/cfi_cmdset_0002.c index 94bb61e1904..1d49e18adbf 100644 --- a/drivers/mtd/chips/cfi_cmdset_0002.c +++ b/drivers/mtd/chips/cfi_cmdset_0002.c @@ -490,10 +490,6 @@ static struct mtd_info *cfi_amdstd_setup(struct mtd_info *mtd) } #endif - /* FIXME: erase-suspend-program is broken. See - http://lists.infradead.org/pipermail/linux-mtd/2003-December/009001.html */ - printk(KERN_NOTICE "cfi_cmdset_0002: Disabling erase-suspend-program due to code brokenness.\n"); - __module_get(THIS_MODULE); return mtd; @@ -589,15 +585,9 @@ static int get_chip(struct map_info *map, struct flchip *chip, unsigned long adr return 0; case FL_ERASING: - if (mode == FL_WRITING) /* FIXME: Erase-suspend-program appears broken. */ - goto sleep; - - if (!( mode == FL_READY - || mode == FL_POINT - || !cfip - || (mode == FL_WRITING && (cfip->EraseSuspend & 0x2)) - || (mode == FL_WRITING && (cfip->EraseSuspend & 0x1) - ))) + if (!cfip || !(cfip->EraseSuspend & (0x1|0x2)) || + !(mode == FL_READY || mode == FL_POINT || + (mode == FL_WRITING && (cfip->EraseSuspend & 0x2)))) goto sleep; /* We could check to see if we're trying to access the sector -- cgit v1.2.3 From db5432db81b1775f145945b21428490583ab3e2b Mon Sep 17 00:00:00 2001 From: Ladislav Michl Date: Mon, 23 Nov 2009 00:06:50 +0100 Subject: mtd: fix M29W800D dev_id and uaddr This one sits in my tree for more than two years... Using device code found on page 12 (http://www.btdesigner.com/pdfs/M29W800D.pdf) and unlock address from page 15 MTD subsytem happily detects ST M29W800DB in 16-bit mode. I do believe original author used only 8-bit mode and thus didn't hit this bug. Signed-off-by: Ladislav Michl Signed-off-by: David Woodhouse --- drivers/mtd/chips/jedec_probe.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'drivers/mtd/chips') diff --git a/drivers/mtd/chips/jedec_probe.c b/drivers/mtd/chips/jedec_probe.c index 736a3be265f..1bec5e1ce6a 100644 --- a/drivers/mtd/chips/jedec_probe.c +++ b/drivers/mtd/chips/jedec_probe.c @@ -142,8 +142,8 @@ /* ST - www.st.com */ #define M29F800AB 0x0058 -#define M29W800DT 0x00D7 -#define M29W800DB 0x005B +#define M29W800DT 0x22D7 +#define M29W800DB 0x225B #define M29W400DT 0x00EE #define M29W400DB 0x00EF #define M29W160DT 0x22C4 @@ -1575,7 +1575,7 @@ static const struct amd_flash_info jedec_table[] = { .dev_id = M29W800DT, .name = "ST M29W800DT", .devtypes = CFI_DEVICETYPE_X16|CFI_DEVICETYPE_X8, - .uaddr = MTD_UADDR_0x5555_0x2AAA, /* ???? */ + .uaddr = MTD_UADDR_0x0AAA_0x0555, .dev_size = SIZE_1MiB, .cmd_set = P_ID_AMD_STD, .nr_regions = 4, @@ -1590,7 +1590,7 @@ static const struct amd_flash_info jedec_table[] = { .dev_id = M29W800DB, .name = "ST M29W800DB", .devtypes = CFI_DEVICETYPE_X16|CFI_DEVICETYPE_X8, - .uaddr = MTD_UADDR_0x5555_0x2AAA, /* ???? */ + .uaddr = MTD_UADDR_0x0AAA_0x0555, .dev_size = SIZE_1MiB, .cmd_set = P_ID_AMD_STD, .nr_regions = 4, -- cgit v1.2.3 From 4a58948669702639db7acecfa2105c3172d85c93 Mon Sep 17 00:00:00 2001 From: Guillaume LECERF Date: Mon, 23 Nov 2009 02:10:49 +0100 Subject: mtd: add support for switching old SST chips into QRY mode SST 39VF160x/39VF320x and some old SST chips need a special command sequence to enter CFI QueRY mode [1]. This patch adds the relevant sequence to cfi_qry_mode_on(). Tested with 39VF3201. Signed-off-by: Guillaume LECERF Signed-off-by: David Woodhouse --- drivers/mtd/chips/cfi_util.c | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'drivers/mtd/chips') diff --git a/drivers/mtd/chips/cfi_util.c b/drivers/mtd/chips/cfi_util.c index c5a84fda541..ca584d0380b 100755 --- a/drivers/mtd/chips/cfi_util.c +++ b/drivers/mtd/chips/cfi_util.c @@ -69,6 +69,13 @@ int __xipram cfi_qry_mode_on(uint32_t base, struct map_info *map, /* ST M29DW chips */ cfi_send_gen_cmd(0xF0, 0, base, map, cfi, cfi->device_type, NULL); cfi_send_gen_cmd(0x98, 0x555, base, map, cfi, cfi->device_type, NULL); + if (cfi_qry_present(map, base, cfi)) + return 1; + /* some old SST chips, e.g. 39VF160x/39VF320x */ + cfi_send_gen_cmd(0xF0, 0, base, map, cfi, cfi->device_type, NULL); + cfi_send_gen_cmd(0xAA, 0x5555, base, map, cfi, cfi->device_type, NULL); + cfi_send_gen_cmd(0x55, 0x2AAA, base, map, cfi, cfi->device_type, NULL); + cfi_send_gen_cmd(0x98, 0x5555, base, map, cfi, cfi->device_type, NULL); if (cfi_qry_present(map, base, cfi)) return 1; /* QRY not found */ -- cgit v1.2.3 From caf0e8e028516253afce6e40c52f0c193a221f8a Mon Sep 17 00:00:00 2001 From: Jiri Slaby Date: Thu, 10 Dec 2009 14:23:57 +0100 Subject: mtd: cfi_cmdset_0002, fix lock imbalance Stanse found a double unlock in get_chip. get_chip is called with chip->mutex held and caller is responsible for unlocking it too. Do not unlock the lock in get_chip on a fail path. This would mean a double unlock. Signed-off-by: Jiri Slaby Signed-off-by: David Woodhouse --- drivers/mtd/chips/cfi_cmdset_0002.c | 1 - 1 file changed, 1 deletion(-) (limited to 'drivers/mtd/chips') diff --git a/drivers/mtd/chips/cfi_cmdset_0002.c b/drivers/mtd/chips/cfi_cmdset_0002.c index 1d49e18adbf..f3600e8d538 100644 --- a/drivers/mtd/chips/cfi_cmdset_0002.c +++ b/drivers/mtd/chips/cfi_cmdset_0002.c @@ -569,7 +569,6 @@ static int get_chip(struct map_info *map, struct flchip *chip, unsigned long adr if (time_after(jiffies, timeo)) { printk(KERN_ERR "Waiting for chip to be ready timed out.\n"); - spin_unlock(chip->mutex); return -EIO; } spin_unlock(chip->mutex); -- cgit v1.2.3