Blackfin: TWI/I2C: add timeout to transfer
authorMike Frysinger <vapier@gentoo.org>
Wed, 14 Oct 2009 23:27:26 +0000 (19:27 -0400)
committerHeiko Schocher <hs@denx.de>
Fri, 30 Oct 2009 14:10:58 +0000 (15:10 +0100)
The current transfer code relies on ctrlc() to abort transfers, but this
requires user interactivity.  Naturalize the process with a timeout.

Signed-off-by: Mike Frysinger <vapier@gentoo.org>
drivers/i2c/bfin-twi_i2c.c

index e7906340799b9072553ff6d15ac9c53526e5dbf0..5ef30beca76d143c21ba821219fa706b23b4d3c9 100644 (file)
@@ -60,6 +60,9 @@ struct i2c_msg {
        u8 *abuf;               /* addr buffer */
 };
 
+/* Allow msec timeout per ~byte transfer */
+#define I2C_TIMEOUT 10
+
 /**
  * wait_for_completion - manage the actual i2c transfer
  *     @msg: the i2c msg
@@ -67,8 +70,9 @@ struct i2c_msg {
 static int wait_for_completion(struct i2c_msg *msg)
 {
        uint16_t int_stat;
+       ulong timebase = get_timer(0);
 
-       while (!ctrlc()) {
+       do {
                int_stat = bfin_read_TWI_INT_STAT();
 
                if (int_stat & XMTSERV) {
@@ -103,7 +107,7 @@ static int wait_for_completion(struct i2c_msg *msg)
                        debugi("processing MERR");
                        bfin_write_TWI_INT_STAT(MERR);
                        SSYNC();
-                       break;
+                       return msg->len;
                }
                if (int_stat & MCOMP) {
                        debugi("processing MCOMP");
@@ -116,7 +120,12 @@ static int wait_for_completion(struct i2c_msg *msg)
                        } else
                                break;
                }
-       }
+
+               /* If we were able to do something, reset timeout */
+               if (int_stat)
+                       timebase = get_timer(0);
+
+       } while (get_timer(timebase) < I2C_TIMEOUT);
 
        return msg->len;
 }