Commit e93cafe45fd74935e0aca2b79e533f0e3ed9640f
Committed by
David Woodhouse
1 parent
2e489e077a
Exists in
master
and in
7 other branches
[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>
Showing 2 changed files with 42 additions and 14 deletions Side-by-side Diff
drivers/mtd/chips/cfi_cmdset_0001.c
... | ... | @@ -478,6 +478,28 @@ |
478 | 478 | else |
479 | 479 | cfi->chips[i].erase_time = 2000000; |
480 | 480 | |
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 | + | |
481 | 503 | cfi->chips[i].ref_point_counter = 0; |
482 | 504 | init_waitqueue_head(&(cfi->chips[i].wq)); |
483 | 505 | } |
... | ... | @@ -1012,7 +1034,7 @@ |
1012 | 1034 | |
1013 | 1035 | static int __xipram xip_wait_for_operation( |
1014 | 1036 | 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) | |
1016 | 1038 | { |
1017 | 1039 | struct cfi_private *cfi = map->fldrv_priv; |
1018 | 1040 | struct cfi_pri_intelext *cfip = cfi->cmdset_priv; |
... | ... | @@ -1021,7 +1043,7 @@ |
1021 | 1043 | flstate_t oldstate, newstate; |
1022 | 1044 | |
1023 | 1045 | start = xip_currtime(); |
1024 | - usec = chip_op_time * 8; | |
1046 | + usec = chip_op_time_max; | |
1025 | 1047 | if (usec == 0) |
1026 | 1048 | usec = 500000; |
1027 | 1049 | done = 0; |
... | ... | @@ -1131,8 +1153,8 @@ |
1131 | 1153 | #define XIP_INVAL_CACHED_RANGE(map, from, size) \ |
1132 | 1154 | INVALIDATE_CACHED_RANGE(map, from, size) |
1133 | 1155 | |
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) | |
1136 | 1158 | |
1137 | 1159 | #else |
1138 | 1160 | |
... | ... | @@ -1144,7 +1166,7 @@ |
1144 | 1166 | static int inval_cache_and_wait_for_operation( |
1145 | 1167 | struct map_info *map, struct flchip *chip, |
1146 | 1168 | 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) | |
1148 | 1170 | { |
1149 | 1171 | struct cfi_private *cfi = map->fldrv_priv; |
1150 | 1172 | map_word status, status_OK = CMD(0x80); |
... | ... | @@ -1156,8 +1178,7 @@ |
1156 | 1178 | INVALIDATE_CACHED_RANGE(map, inval_adr, inval_len); |
1157 | 1179 | spin_lock(chip->mutex); |
1158 | 1180 | |
1159 | - /* set our timeout to 8 times the expected delay */ | |
1160 | - timeo = chip_op_time * 8; | |
1181 | + timeo = chip_op_time_max; | |
1161 | 1182 | if (!timeo) |
1162 | 1183 | timeo = 500000; |
1163 | 1184 | reset_timeo = timeo; |
... | ... | @@ -1217,8 +1238,8 @@ |
1217 | 1238 | |
1218 | 1239 | #endif |
1219 | 1240 | |
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); | |
1222 | 1243 | |
1223 | 1244 | |
1224 | 1245 | static int do_point_onechip (struct map_info *map, struct flchip *chip, loff_t adr, size_t len) |
... | ... | @@ -1452,7 +1473,8 @@ |
1452 | 1473 | |
1453 | 1474 | ret = INVAL_CACHE_AND_WAIT(map, chip, adr, |
1454 | 1475 | adr, map_bankwidth(map), |
1455 | - chip->word_write_time); | |
1476 | + chip->word_write_time, | |
1477 | + chip->word_write_time_max); | |
1456 | 1478 | if (ret) { |
1457 | 1479 | xip_enable(map, chip, adr); |
1458 | 1480 | printk(KERN_ERR "%s: word write error (status timeout)\n", map->name); |
... | ... | @@ -1623,7 +1645,7 @@ |
1623 | 1645 | |
1624 | 1646 | chip->state = FL_WRITING_TO_BUFFER; |
1625 | 1647 | 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); | |
1627 | 1649 | if (ret) { |
1628 | 1650 | /* Argh. Not ready for write to buffer */ |
1629 | 1651 | map_word Xstatus = map_read(map, cmd_adr); |
... | ... | @@ -1692,7 +1714,8 @@ |
1692 | 1714 | |
1693 | 1715 | ret = INVAL_CACHE_AND_WAIT(map, chip, cmd_adr, |
1694 | 1716 | initial_adr, initial_len, |
1695 | - chip->buffer_write_time); | |
1717 | + chip->buffer_write_time, | |
1718 | + chip->buffer_write_time_max); | |
1696 | 1719 | if (ret) { |
1697 | 1720 | map_write(map, CMD(0x70), cmd_adr); |
1698 | 1721 | chip->state = FL_STATUS; |
... | ... | @@ -1827,7 +1850,8 @@ |
1827 | 1850 | |
1828 | 1851 | ret = INVAL_CACHE_AND_WAIT(map, chip, adr, |
1829 | 1852 | adr, len, |
1830 | - chip->erase_time); | |
1853 | + chip->erase_time, | |
1854 | + chip->erase_time_max); | |
1831 | 1855 | if (ret) { |
1832 | 1856 | map_write(map, CMD(0x70), adr); |
1833 | 1857 | chip->state = FL_STATUS; |
... | ... | @@ -2006,7 +2030,7 @@ |
2006 | 2030 | */ |
2007 | 2031 | udelay = (!extp || !(extp->FeatureSupport & (1 << 5))) ? 1000000/HZ : 0; |
2008 | 2032 | |
2009 | - ret = WAIT_TIMEOUT(map, chip, adr, udelay); | |
2033 | + ret = WAIT_TIMEOUT(map, chip, adr, udelay, udelay * 100); | |
2010 | 2034 | if (ret) { |
2011 | 2035 | map_write(map, CMD(0x70), adr); |
2012 | 2036 | chip->state = FL_STATUS; |