summaryrefslogtreecommitdiff
path: root/chip/mec1322
diff options
context:
space:
mode:
authorShawn Nematbakhsh <shawnn@chromium.org>2015-11-24 16:04:25 -0800
committerchrome-bot <chrome-bot@chromium.org>2015-11-30 16:25:39 -0800
commit07bf28b77c7890f134e147baac0823a5c7a322f2 (patch)
tree8c8114cd3a6789ca156150c1f4b63d54f5548f83 /chip/mec1322
parent1051a7e2d56ed23634f33a380236f370d70370c0 (diff)
downloadchrome-ec-07bf28b77c7890f134e147baac0823a5c7a322f2.tar.gz
mec1322: i2c: Add hard-timeout for status wait
Add a hard timeout to wait_for_interrupt() so that we won't wait forever, even if we get into a state where interrupts fire yet our status is not as expected. BUG=chromium:561143 TEST=Verify "ectool i2cxfer 1 0x25 1 2" doesn't watchdog on glados BRANCH=None Signed-off-by: Shawn Nematbakhsh <shawnn@chromium.org> Change-Id: I39773370bb7e45a8f0c0cdb4a463904643f72587 Reviewed-on: https://chromium-review.googlesource.com/314253 Commit-Ready: Shawn N <shawnn@chromium.org> Tested-by: Shawn N <shawnn@chromium.org> Reviewed-by: Alec Berg <alecaberg@chromium.org>
Diffstat (limited to 'chip/mec1322')
-rw-r--r--chip/mec1322/i2c.c34
1 files changed, 19 insertions, 15 deletions
diff --git a/chip/mec1322/i2c.c b/chip/mec1322/i2c.c
index 8cf92cb860..cc8649cd10 100644
--- a/chip/mec1322/i2c.c
+++ b/chip/mec1322/i2c.c
@@ -122,16 +122,18 @@ static void reset_controller(int controller)
}
}
-static int wait_for_interrupt(int controller)
+static int wait_for_interrupt(int controller, int timeout)
{
int event;
+ if (timeout <= 0)
+ return EC_ERROR_TIMEOUT;
+
cdata[controller].task_waiting = task_get_current();
task_enable_irq(MEC1322_IRQ_I2C_0 + controller);
/* Wait until I2C interrupt or timeout. */
- event = task_wait_event_mask(TASK_EVENT_I2C_IDLE,
- cdata[controller].timeout_us);
+ event = task_wait_event_mask(TASK_EVENT_I2C_IDLE, timeout);
task_disable_irq(MEC1322_IRQ_I2C_0 + controller);
cdata[controller].task_waiting = TASK_ID_INVALID;
@@ -143,14 +145,15 @@ static int wait_idle(int controller)
{
uint8_t sts = MEC1322_I2C_STATUS(controller);
uint64_t block_timeout = get_time().val + I2C_WAIT_BLOCKING_TIMEOUT_US;
- int rv;
+ uint64_t task_timeout = block_timeout + cdata[controller].timeout_us;
+ int rv = 0;
while (!(sts & STS_NBB)) {
- if (get_time().val > block_timeout) {
- rv = wait_for_interrupt(controller);
- if (rv)
- return rv;
- }
+ if (rv)
+ return rv;
+ if (get_time().val > block_timeout)
+ rv = wait_for_interrupt(controller,
+ task_timeout - get_time().val);
sts = MEC1322_I2C_STATUS(controller);
}
@@ -163,14 +166,15 @@ static int wait_byte_done(int controller)
{
uint8_t sts = MEC1322_I2C_STATUS(controller);
uint64_t block_timeout = get_time().val + I2C_WAIT_BLOCKING_TIMEOUT_US;
- int rv;
+ uint64_t task_timeout = block_timeout + cdata[controller].timeout_us;
+ int rv = 0;
while (sts & STS_PIN) {
- if (get_time().val > block_timeout) {
- rv = wait_for_interrupt(controller);
- if (rv)
- return rv;
- }
+ if (rv)
+ return rv;
+ if (get_time().val > block_timeout)
+ rv = wait_for_interrupt(controller,
+ task_timeout - get_time().val);
sts = MEC1322_I2C_STATUS(controller);
}