mirror of
https://github.com/Telecominfraproject/OpenCellular.git
synced 2026-01-03 21:49:32 +00:00
snow: i2c: Reset i2c if we get a timeout in slave mode
This is important to do because if we don't reset we could leave the i2c bus in a wedged state (it's possible that whoever was mastering us could have reset halfway through a transaction). BUG=chrome-os-partner:14430 BRANCH=snow TEST=From vt2 type: "echo bug > /proc/breakme" several times and see good reboots. Check scope trace and see that reset of i2c bus helped (SDA low for 100ms and then fixed). TEST=Run hacky "repro" script from bug see that i2c doesn't get wedged. Change-Id: I57010dcc5f4baa63278b6a025d44f10f00eb9e9d Signed-off-by: Doug Anderson <dianders@chromium.org> Reviewed-on: https://gerrit.chromium.org/gerrit/35115 Reviewed-by: Simon Glass <sjg@chromium.org> Reviewed-by: Vincent Palatin <vpalatin@chromium.org> Reviewed-by: Charlie Mooney <charliemooney@chromium.org>
This commit is contained in:
@@ -132,9 +132,12 @@ void __board_i2c_release(int port)
|
||||
void board_i2c_release(int port)
|
||||
__attribute__((weak, alias("__board_i2c_release")));
|
||||
|
||||
static int i2c_init_port(unsigned int port);
|
||||
|
||||
static int i2c_write_raw_slave(int port, void *buf, int len)
|
||||
{
|
||||
struct dma_channel *chan;
|
||||
int rv;
|
||||
|
||||
/* we don't want to race with TxE interrupt event */
|
||||
disable_i2c_interrupt(port);
|
||||
@@ -157,8 +160,13 @@ static int i2c_write_raw_slave(int port, void *buf, int len)
|
||||
} else {
|
||||
/* Wait for the transmission complete Interrupt */
|
||||
dma_enable_tc_interrupt(DMAC_I2C_TX);
|
||||
task_wait_event(DMA_TRANSFER_TIMEOUT_US);
|
||||
rv = task_wait_event(DMA_TRANSFER_TIMEOUT_US);
|
||||
dma_disable_tc_interrupt(DMAC_I2C_TX);
|
||||
|
||||
if (!(rv & TASK_EVENT_WAKE)) {
|
||||
CPRINTF("[%T Slave timeout, resetting i2c]\n");
|
||||
i2c_init_port(port);
|
||||
}
|
||||
}
|
||||
|
||||
dma_disable(DMAC_I2C_TX);
|
||||
|
||||
Reference in New Issue
Block a user