aboutsummaryrefslogtreecommitdiff
path: root/drivers/i2c/bfin-twi_i2c.c
diff options
context:
space:
mode:
authorMike Frysinger2009-10-14 19:27:26 -0400
committerHeiko Schocher2009-10-30 15:10:58 +0100
commit3814ea4f0002536ac592480b2cdafa319a16e329 (patch)
tree0dc7c33077544e7e04729f15c925542ba2a40916 /drivers/i2c/bfin-twi_i2c.c
parentf2b4bc04d6aed6be712d236dab48ac4c4da22cbf (diff)
Blackfin: TWI/I2C: add timeout to transfer
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>
Diffstat (limited to 'drivers/i2c/bfin-twi_i2c.c')
-rw-r--r--drivers/i2c/bfin-twi_i2c.c15
1 files changed, 12 insertions, 3 deletions
diff --git a/drivers/i2c/bfin-twi_i2c.c b/drivers/i2c/bfin-twi_i2c.c
index e7906340799..5ef30beca76 100644
--- a/drivers/i2c/bfin-twi_i2c.c
+++ b/drivers/i2c/bfin-twi_i2c.c
@@ -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;
}