i2c: exynos5: Avoid transaction timeouts due TRANSFER_DONE_AUTO not set
After commit7999eecb7e
("i2c: exynos5: fix arbitration lost handling"), some I2C transactions are failing because the TRANSFER_DONE_AUTO field is not set in the I2C_TRANS_STATUS register so the i2c->status value is left to -EINVAL causing the i2c->msg_complete completion to never be signaled. For example, when reading the time of an I2C rtc on an Exynos5800 machine: $ cat /sys/class/rtc/rtc0/time [ 25.924594] exynos5-hsi2c 12e10000.i2c: rx timeout [ 65.028365] max77686-rtc max77802-rtc: Fail to read time reg(-22) cat: /sys/class/rtc/rtc0/time: Invalid argument The Exynos5422 manual states clearly that most I2C_TRANS_STATUS reg bits (including TRANSFER_DONE_AUTO) are cleared after the register is read. So reading has side effects and should only be done if HSI2C_INT_I2C was set. Fixes:7999eecb7e
("i2c: exynos5: fix arbitration lost handling") Signed-off-by: Javier Martinez Canillas <javier@osg.samsung.com> Reviewed-by: Andrzej Hajda <a.hajda@samsung.com> Signed-off-by: Wolfram Sang <wsa@the-dreams.de>
This commit is contained in:
parent
ab809fd81f
commit
9ad2247442
@ -457,7 +457,6 @@ static irqreturn_t exynos5_i2c_irq(int irqno, void *dev_id)
|
||||
|
||||
int_status = readl(i2c->regs + HSI2C_INT_STATUS);
|
||||
writel(int_status, i2c->regs + HSI2C_INT_STATUS);
|
||||
trans_status = readl(i2c->regs + HSI2C_TRANS_STATUS);
|
||||
|
||||
/* handle interrupt related to the transfer status */
|
||||
if (i2c->variant->hw == HSI2C_EXYNOS7) {
|
||||
@ -482,11 +481,13 @@ static irqreturn_t exynos5_i2c_irq(int irqno, void *dev_id)
|
||||
goto stop;
|
||||
}
|
||||
|
||||
trans_status = readl(i2c->regs + HSI2C_TRANS_STATUS);
|
||||
if ((trans_status & HSI2C_MASTER_ST_MASK) == HSI2C_MASTER_ST_LOSE) {
|
||||
i2c->state = -EAGAIN;
|
||||
goto stop;
|
||||
}
|
||||
} else if (int_status & HSI2C_INT_I2C) {
|
||||
trans_status = readl(i2c->regs + HSI2C_TRANS_STATUS);
|
||||
if (trans_status & HSI2C_NO_DEV_ACK) {
|
||||
dev_dbg(i2c->dev, "No ACK from device\n");
|
||||
i2c->state = -ENXIO;
|
||||
|
Loading…
Reference in New Issue
Block a user