From: Sven Peter <s...@svenpeter.dev>

Add proper timeout handling for the interrupt path.
Previously, this was only correctly done for the polling path.
Note that we drop reg_write(smbus, REG_SMSTA, status) here which
will be done anyway whenever the next transaction starts via
pasemi_smb_clear.

Signed-off-by: Sven Peter <s...@svenpeter.dev>
---
 drivers/i2c/busses/i2c-pasemi-core.c | 24 +++++++++++++++++-------
 1 file changed, 17 insertions(+), 7 deletions(-)

diff --git a/drivers/i2c/busses/i2c-pasemi-core.c 
b/drivers/i2c/busses/i2c-pasemi-core.c
index 
df1b0087dcacb0a3b94196368137d5e20b0e6d7e..9b611dbdfef23e78a4ea75ac0311938d52b6ba96
 100644
--- a/drivers/i2c/busses/i2c-pasemi-core.c
+++ b/drivers/i2c/busses/i2c-pasemi-core.c
@@ -91,32 +91,42 @@ static void pasemi_smb_clear(struct pasemi_smbus *smbus)
 static int pasemi_smb_waitready(struct pasemi_smbus *smbus)
 {
        int timeout = 100;
+       int ret;
        unsigned int status;
 
        if (smbus->use_irq) {
                reinit_completion(&smbus->irq_completion);
                reg_write(smbus, REG_IMASK, SMSTA_XEN | SMSTA_MTN);
-               wait_for_completion_timeout(&smbus->irq_completion, 
msecs_to_jiffies(100));
+               ret = wait_for_completion_timeout(&smbus->irq_completion, 
msecs_to_jiffies(100));
                reg_write(smbus, REG_IMASK, 0);
                status = reg_read(smbus, REG_SMSTA);
+
+               if (ret < 0) {
+                       dev_err(smbus->dev,
+                               "Completion wait failed with %d, status 
0x%08x\n",
+                               ret, status);
+                       return ret;
+               } else if (ret == 0) {
+                       dev_warn(smbus->dev, "Timeout, status 0x%08x\n", 
status);
+                       return -ETIME;
+               }
        } else {
                status = reg_read(smbus, REG_SMSTA);
                while (!(status & SMSTA_XEN) && timeout--) {
                        msleep(1);
                        status = reg_read(smbus, REG_SMSTA);
                }
+
+               if (timeout < 0) {
+                       dev_warn(smbus->dev, "Timeout, status 0x%08x\n", 
status);
+                       return -ETIME;
+               }
        }
 
        /* Got NACK? */
        if (status & SMSTA_MTN)
                return -ENXIO;
 
-       if (timeout < 0) {
-               dev_warn(smbus->dev, "Timeout, status 0x%08x\n", status);
-               reg_write(smbus, REG_SMSTA, status);
-               return -ETIME;
-       }
-
        /* Clear XEN */
        reg_write(smbus, REG_SMSTA, SMSTA_XEN);
 

-- 
2.34.1



Reply via email to