diff options
author | Gerrit <chrome-bot@google.com> | 2012-05-29 10:31:35 -0700 |
---|---|---|
committer | Gerrit Code Review <gerrit@gerrit.golo.chromium.org> | 2012-05-29 10:31:35 -0700 |
commit | 63da7ee73011e625d5a79603183341d5a1eb39a3 (patch) | |
tree | f161b30dcd6db23fbdffcb2a2bac753dccaf416b | |
parent | 7f66786b76464298a8fc92b2b2377d3652fda914 (diff) | |
parent | d42877300ac6deb988d351493ed23a79f662cb8c (diff) | |
download | chrome-ec-63da7ee73011e625d5a79603183341d5a1eb39a3.tar.gz |
Merge "Use correct EEPROM timeout"
-rw-r--r-- | chip/lm4/eeprom.c | 25 |
1 files changed, 18 insertions, 7 deletions
diff --git a/chip/lm4/eeprom.c b/chip/lm4/eeprom.c index dc3a17a36b..03768d2c13 100644 --- a/chip/lm4/eeprom.c +++ b/chip/lm4/eeprom.c @@ -8,7 +8,9 @@ #include "eeprom.h" #include "console.h" #include "registers.h" +#include "timer.h" #include "util.h" +#include "watchdog.h" /* Size of EEPROM block in bytes */ #define EEPROM_BLOCK_SIZE 64 @@ -17,12 +19,13 @@ static int block_count; -/* Waits for the current EEPROM operation to finish. */ +/* Waits for the current EEPROM operation to finish; all operations but write + * should normally finish in 4 system clocks. eeprom_write() has its own + * delay loop for the longer delay. */ static int wait_for_done(void) { - /* TODO: how long is a reasonable timeout? */ int i; - for (i = 0; i < 1000000; i++) { + for (i = 0; i < 1000; i++) { if (!(LM4_EEPROM_EEDONE & 0x01)) return EC_SUCCESS; } @@ -72,7 +75,7 @@ int eeprom_read(int block, int offset, int size, char *data) int eeprom_write(int block, int offset, int size, const char *data) { uint32_t *d = (uint32_t *)data; - int rv; + int rv, i; if (block < 0 || block >= block_count || offset < 0 || offset > EEPROM_BLOCK_SIZE || offset & 3 || @@ -92,9 +95,17 @@ int eeprom_write(int block, int offset, int size, const char *data) /* Write 32 bits at a time; wait for each write to complete */ for ( ; size; size -= sizeof(uint32_t)) { LM4_EEPROM_EERDWRINC = *(d++); - rv = wait_for_done(); - if (rv) - return rv; + + /* Writes nominally take ~110us, but can take up to 1800 ms + * worst-case (near endurance limit and need erase/copy). */ + for (i = 0; i < 2000 && (LM4_EEPROM_EEDONE & 0x01); i++) { + /* First few delays are smaller for nominal case */ + usleep(i < 20 ? 100 : 1000); + /* Reload the watchdog timer in case we're called + * before task scheduling starts. */ + watchdog_reload(); + } + if (LM4_EEPROM_EEDONE) return EC_ERROR_UNKNOWN; } |