Skip to content

Commit 46b2dfc

Browse files
vasilykh-aristaAndi Shyti
authored andcommitted
i2c: ismt: kill transaction in hardware on timeout
On Intel Denverton SoC ismt controller may enter weird state when transaction gets stuck. It times out in the driver, but unless transaction is explicitly killed in the controller, it won't be able to perform new transactions anymore. The issue is extremely difficult to reproduce and may take weeks of non- stop smbus traffic. Numerous hours with logic analyzer didn't yield any useful results, it looks like the controller stops toggling SCK line, i.e. the issue is likely in the controller, since device doesn't do clock stretching, so nothing is driving SCK except the host. Explicitly kill transaction on timeout to recover the controller from this state. Signed-off-by: Vasily Khoruzhick <[email protected]> Signed-off-by: Andi Shyti <[email protected]>
1 parent 66049b3 commit 46b2dfc

File tree

1 file changed

+10
-0
lines changed

1 file changed

+10
-0
lines changed

drivers/i2c/busses/i2c-ismt.c

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -381,6 +381,15 @@ static int ismt_process_desc(const struct ismt_desc *desc,
381381
return -EIO;
382382
}
383383

384+
/**
385+
* ismt_kill_transaction() - kill current transaction
386+
* @priv: iSMT private data
387+
*/
388+
static void ismt_kill_transaction(struct ismt_priv *priv)
389+
{
390+
writel(ISMT_GCTRL_KILL, priv->smba + ISMT_GR_GCTRL);
391+
}
392+
384393
/**
385394
* ismt_access() - process an SMBus command
386395
* @adap: the i2c host adapter
@@ -623,6 +632,7 @@ static int ismt_access(struct i2c_adapter *adap, u16 addr,
623632
dma_unmap_single(dev, dma_addr, dma_size, dma_direction);
624633

625634
if (unlikely(!time_left)) {
635+
ismt_kill_transaction(priv);
626636
ret = -ETIMEDOUT;
627637
goto out;
628638
}

0 commit comments

Comments
 (0)