diff options
author | Wolfram Sang <w.sang@pengutronix.de> | 2009-03-28 16:34:45 -0400 |
---|---|---|
committer | Jean Delvare <khali@linux-fr.org> | 2009-03-28 16:34:45 -0400 |
commit | 2378bc09b91b0702fac7823828a614fd8016a29f (patch) | |
tree | 26539b17077028baba2741cf0e78fc01225a7d36 /drivers/i2c/busses/i2c-pca-platform.c | |
parent | 8e99ada8deaa9033600cd2c7d0a9366b0e99ab68 (diff) |
i2c-algo-pca: Use timeout for checking the state machine
We now timeout also if the state machine does not change within the
given time. For that, the driver-specific completion-functions are
extended to return true or false depending on the timeout. This then
gets checked in the algorithm.
Signed-off-by: Wolfram Sang <w.sang@pengutronix.de>
Signed-off-by: Jean Delvare <khali@linux-fr.org>
Diffstat (limited to 'drivers/i2c/busses/i2c-pca-platform.c')
-rw-r--r-- | drivers/i2c/busses/i2c-pca-platform.c | 20 |
1 files changed, 10 insertions, 10 deletions
diff --git a/drivers/i2c/busses/i2c-pca-platform.c b/drivers/i2c/busses/i2c-pca-platform.c index 51d179bbddf9..df5e593a1d76 100644 --- a/drivers/i2c/busses/i2c-pca-platform.c +++ b/drivers/i2c/busses/i2c-pca-platform.c | |||
@@ -15,6 +15,7 @@ | |||
15 | #include <linux/init.h> | 15 | #include <linux/init.h> |
16 | #include <linux/slab.h> | 16 | #include <linux/slab.h> |
17 | #include <linux/delay.h> | 17 | #include <linux/delay.h> |
18 | #include <linux/jiffies.h> | ||
18 | #include <linux/errno.h> | 19 | #include <linux/errno.h> |
19 | #include <linux/i2c.h> | 20 | #include <linux/i2c.h> |
20 | #include <linux/interrupt.h> | 21 | #include <linux/interrupt.h> |
@@ -81,24 +82,23 @@ static void i2c_pca_pf_writebyte32(void *pd, int reg, int val) | |||
81 | static int i2c_pca_pf_waitforcompletion(void *pd) | 82 | static int i2c_pca_pf_waitforcompletion(void *pd) |
82 | { | 83 | { |
83 | struct i2c_pca_pf_data *i2c = pd; | 84 | struct i2c_pca_pf_data *i2c = pd; |
84 | int ret = 0; | 85 | long ret = ~0; |
86 | unsigned long timeout; | ||
85 | 87 | ||
86 | if (i2c->irq) { | 88 | if (i2c->irq) { |
87 | ret = wait_event_interruptible(i2c->wait, | 89 | ret = wait_event_interruptible_timeout(i2c->wait, |
88 | i2c->algo_data.read_byte(i2c, I2C_PCA_CON) | 90 | i2c->algo_data.read_byte(i2c, I2C_PCA_CON) |
89 | & I2C_PCA_CON_SI); | 91 | & I2C_PCA_CON_SI, i2c->adap.timeout); |
90 | } else { | 92 | } else { |
91 | /* | 93 | /* Do polling */ |
92 | * Do polling... | 94 | timeout = jiffies + i2c->adap.timeout; |
93 | * XXX: Could get stuck in extreme cases! | 95 | while (((i2c->algo_data.read_byte(i2c, I2C_PCA_CON) |
94 | * Maybe add timeout, but using irqs is preferred anyhow. | ||
95 | */ | ||
96 | while ((i2c->algo_data.read_byte(i2c, I2C_PCA_CON) | ||
97 | & I2C_PCA_CON_SI) == 0) | 96 | & I2C_PCA_CON_SI) == 0) |
97 | && (ret = time_before(jiffies, timeout))) | ||
98 | udelay(100); | 98 | udelay(100); |
99 | } | 99 | } |
100 | 100 | ||
101 | return ret; | 101 | return ret > 0; |
102 | } | 102 | } |
103 | 103 | ||
104 | static void i2c_pca_pf_dummyreset(void *pd) | 104 | static void i2c_pca_pf_dummyreset(void *pd) |