eeprom/at25: bugfix "not ready" timeout after write
authorSebastian Heutling <heutling@who-ing.de>
Wed, 29 Jul 2009 22:04:05 +0000 (15:04 -0700)
committerLinus Torvalds <torvalds@linux-foundation.org>
Thu, 30 Jul 2009 02:10:35 +0000 (19:10 -0700)
Under certain circumstances msleep(1) within the loop, which waits for the
EEPROM to be finished, might take longer than the timeout.  On the next
loop the status register might now return to be ready and therefore the
loop finishes.  The following check now tests if a timeout occurred and if
so returns an error although the device reported it was ready.

This fix replaces testing the occurrence of the timeout by testing the
"not ready" bit in the status register.

Signed-off-by: Sebastian Heutling <heutling@who-ing.de>
Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
drivers/misc/eeprom/at25.c

index b34cb5f79eea94ce1c23a82f2f33205a93451313..2e535a0ccd5e274c1fc46b700a07a45953022ba8 100644 (file)
@@ -173,6 +173,7 @@ at25_ee_write(struct at25_data *at25, const char *buf, loff_t off,
                unsigned        segment;
                unsigned        offset = (unsigned) off;
                u8              *cp = bounce + 1;
+               int             sr;
 
                *cp = AT25_WREN;
                status = spi_write(at25->spi, cp, 1);
@@ -214,7 +215,6 @@ at25_ee_write(struct at25_data *at25, const char *buf, loff_t off,
                timeout = jiffies + msecs_to_jiffies(EE_TIMEOUT);
                retries = 0;
                do {
-                       int     sr;
 
                        sr = spi_w8r8(at25->spi, AT25_RDSR);
                        if (sr < 0 || (sr & AT25_SR_nRDY)) {
@@ -228,7 +228,7 @@ at25_ee_write(struct at25_data *at25, const char *buf, loff_t off,
                                break;
                } while (retries++ < 3 || time_before_eq(jiffies, timeout));
 
-               if (time_after(jiffies, timeout)) {
+               if ((sr < 0) || (sr & AT25_SR_nRDY)) {
                        dev_err(&at25->spi->dev,
                                "write %d bytes offset %d, "
                                "timeout after %u msecs\n",