Skip to content

Commit e93cafe

Browse files
Anders GrafströmDavid Woodhouse
authored andcommitted
[MTD] [NOR] cfi_cmdset_0001: Timeouts for erase, write and unlock operations
Timeouts are currently given by the typical operation time times 8. It works in the general well-behaved case but not when an erase block is failing. For erase operations, it seems that a failing erase block will keep the device state machine in erasing state until the vendor specified maximum timeout period has passed. By this time the driver would have long since timed out, left erasing state and attempted further operations which all fail. This patch implements timeouts using values from the CFI Query structure when available. The patch also sets a longer timeout for locking operations. The current value used for locking/unlocking given by 1000000/HZ microseconds is too short for devices like J3 and J5 Strataflash which have a typical clear lock-bits time of 0.5 seconds. Signed-off-by: Anders Grafström <grfstrm@users.sourceforge.net> Signed-off-by: David Woodhouse <David.Woodhouse@intel.com>
1 parent 2e489e0 commit e93cafe

File tree

2 files changed

+42
-14
lines changed

2 files changed

+42
-14
lines changed

drivers/mtd/chips/cfi_cmdset_0001.c

Lines changed: 38 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -478,6 +478,28 @@ struct mtd_info *cfi_cmdset_0001(struct map_info *map, int primary)
478478
else
479479
cfi->chips[i].erase_time = 2000000;
480480

481+
if (cfi->cfiq->WordWriteTimeoutTyp &&
482+
cfi->cfiq->WordWriteTimeoutMax)
483+
cfi->chips[i].word_write_time_max =
484+
1<<(cfi->cfiq->WordWriteTimeoutTyp +
485+
cfi->cfiq->WordWriteTimeoutMax);
486+
else
487+
cfi->chips[i].word_write_time_max = 50000 * 8;
488+
489+
if (cfi->cfiq->BufWriteTimeoutTyp &&
490+
cfi->cfiq->BufWriteTimeoutMax)
491+
cfi->chips[i].buffer_write_time_max =
492+
1<<(cfi->cfiq->BufWriteTimeoutTyp +
493+
cfi->cfiq->BufWriteTimeoutMax);
494+
495+
if (cfi->cfiq->BlockEraseTimeoutTyp &&
496+
cfi->cfiq->BlockEraseTimeoutMax)
497+
cfi->chips[i].erase_time_max =
498+
1000<<(cfi->cfiq->BlockEraseTimeoutTyp +
499+
cfi->cfiq->BlockEraseTimeoutMax);
500+
else
501+
cfi->chips[i].erase_time_max = 2000000 * 8;
502+
481503
cfi->chips[i].ref_point_counter = 0;
482504
init_waitqueue_head(&(cfi->chips[i].wq));
483505
}
@@ -1012,7 +1034,7 @@ static void __xipram xip_enable(struct map_info *map, struct flchip *chip,
10121034

10131035
static int __xipram xip_wait_for_operation(
10141036
struct map_info *map, struct flchip *chip,
1015-
unsigned long adr, unsigned int chip_op_time )
1037+
unsigned long adr, unsigned int chip_op_time_max)
10161038
{
10171039
struct cfi_private *cfi = map->fldrv_priv;
10181040
struct cfi_pri_intelext *cfip = cfi->cmdset_priv;
@@ -1021,7 +1043,7 @@ static int __xipram xip_wait_for_operation(
10211043
flstate_t oldstate, newstate;
10221044

10231045
start = xip_currtime();
1024-
usec = chip_op_time * 8;
1046+
usec = chip_op_time_max;
10251047
if (usec == 0)
10261048
usec = 500000;
10271049
done = 0;
@@ -1131,8 +1153,8 @@ static int __xipram xip_wait_for_operation(
11311153
#define XIP_INVAL_CACHED_RANGE(map, from, size) \
11321154
INVALIDATE_CACHED_RANGE(map, from, size)
11331155

1134-
#define INVAL_CACHE_AND_WAIT(map, chip, cmd_adr, inval_adr, inval_len, usec) \
1135-
xip_wait_for_operation(map, chip, cmd_adr, usec)
1156+
#define INVAL_CACHE_AND_WAIT(map, chip, cmd_adr, inval_adr, inval_len, usec, usec_max) \
1157+
xip_wait_for_operation(map, chip, cmd_adr, usec_max)
11361158

11371159
#else
11381160

@@ -1144,7 +1166,7 @@ static int __xipram xip_wait_for_operation(
11441166
static int inval_cache_and_wait_for_operation(
11451167
struct map_info *map, struct flchip *chip,
11461168
unsigned long cmd_adr, unsigned long inval_adr, int inval_len,
1147-
unsigned int chip_op_time)
1169+
unsigned int chip_op_time, unsigned int chip_op_time_max)
11481170
{
11491171
struct cfi_private *cfi = map->fldrv_priv;
11501172
map_word status, status_OK = CMD(0x80);
@@ -1156,8 +1178,7 @@ static int inval_cache_and_wait_for_operation(
11561178
INVALIDATE_CACHED_RANGE(map, inval_adr, inval_len);
11571179
spin_lock(chip->mutex);
11581180

1159-
/* set our timeout to 8 times the expected delay */
1160-
timeo = chip_op_time * 8;
1181+
timeo = chip_op_time_max;
11611182
if (!timeo)
11621183
timeo = 500000;
11631184
reset_timeo = timeo;
@@ -1217,8 +1238,8 @@ static int inval_cache_and_wait_for_operation(
12171238

12181239
#endif
12191240

1220-
#define WAIT_TIMEOUT(map, chip, adr, udelay) \
1221-
INVAL_CACHE_AND_WAIT(map, chip, adr, 0, 0, udelay);
1241+
#define WAIT_TIMEOUT(map, chip, adr, udelay, udelay_max) \
1242+
INVAL_CACHE_AND_WAIT(map, chip, adr, 0, 0, udelay, udelay_max);
12221243

12231244

12241245
static int do_point_onechip (struct map_info *map, struct flchip *chip, loff_t adr, size_t len)
@@ -1452,7 +1473,8 @@ static int __xipram do_write_oneword(struct map_info *map, struct flchip *chip,
14521473

14531474
ret = INVAL_CACHE_AND_WAIT(map, chip, adr,
14541475
adr, map_bankwidth(map),
1455-
chip->word_write_time);
1476+
chip->word_write_time,
1477+
chip->word_write_time_max);
14561478
if (ret) {
14571479
xip_enable(map, chip, adr);
14581480
printk(KERN_ERR "%s: word write error (status timeout)\n", map->name);
@@ -1623,7 +1645,7 @@ static int __xipram do_write_buffer(struct map_info *map, struct flchip *chip,
16231645

16241646
chip->state = FL_WRITING_TO_BUFFER;
16251647
map_write(map, write_cmd, cmd_adr);
1626-
ret = WAIT_TIMEOUT(map, chip, cmd_adr, 0);
1648+
ret = WAIT_TIMEOUT(map, chip, cmd_adr, 0, 0);
16271649
if (ret) {
16281650
/* Argh. Not ready for write to buffer */
16291651
map_word Xstatus = map_read(map, cmd_adr);
@@ -1692,7 +1714,8 @@ static int __xipram do_write_buffer(struct map_info *map, struct flchip *chip,
16921714

16931715
ret = INVAL_CACHE_AND_WAIT(map, chip, cmd_adr,
16941716
initial_adr, initial_len,
1695-
chip->buffer_write_time);
1717+
chip->buffer_write_time,
1718+
chip->buffer_write_time_max);
16961719
if (ret) {
16971720
map_write(map, CMD(0x70), cmd_adr);
16981721
chip->state = FL_STATUS;
@@ -1827,7 +1850,8 @@ static int __xipram do_erase_oneblock(struct map_info *map, struct flchip *chip,
18271850

18281851
ret = INVAL_CACHE_AND_WAIT(map, chip, adr,
18291852
adr, len,
1830-
chip->erase_time);
1853+
chip->erase_time,
1854+
chip->erase_time_max);
18311855
if (ret) {
18321856
map_write(map, CMD(0x70), adr);
18331857
chip->state = FL_STATUS;
@@ -2006,7 +2030,7 @@ static int __xipram do_xxlock_oneblock(struct map_info *map, struct flchip *chip
20062030
*/
20072031
udelay = (!extp || !(extp->FeatureSupport & (1 << 5))) ? 1000000/HZ : 0;
20082032

2009-
ret = WAIT_TIMEOUT(map, chip, adr, udelay);
2033+
ret = WAIT_TIMEOUT(map, chip, adr, udelay, udelay * 100);
20102034
if (ret) {
20112035
map_write(map, CMD(0x70), adr);
20122036
chip->state = FL_STATUS;

include/linux/mtd/flashchip.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,10 @@ struct flchip {
7373
int buffer_write_time;
7474
int erase_time;
7575

76+
int word_write_time_max;
77+
int buffer_write_time_max;
78+
int erase_time_max;
79+
7680
void *priv;
7781
};
7882

0 commit comments

Comments
 (0)