diff options
author | Shawn Nematbakhsh <shawnn@chromium.org> | 2015-11-24 16:04:25 -0800 |
---|---|---|
committer | chrome-bot <chrome-bot@chromium.org> | 2015-11-30 16:25:39 -0800 |
commit | 07bf28b77c7890f134e147baac0823a5c7a322f2 (patch) | |
tree | 8c8114cd3a6789ca156150c1f4b63d54f5548f83 /chip/mec1322 | |
parent | 1051a7e2d56ed23634f33a380236f370d70370c0 (diff) | |
download | chrome-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.c | 34 |
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); } |