From: Daniel Kurtz Date: Tue, 24 Jul 2012 12:13:58 +0000 (+0200) Subject: i2c-i801: Check and return errors during byte-by-byte transfers X-Git-Url: https://git.stricted.de/?a=commitdiff_plain;h=70a1cc1952355404a5746c88757f5a444df52b04;p=GitHub%2FLineageOS%2FG12%2Fandroid_kernel_amlogic_linux-4.9.git i2c-i801: Check and return errors during byte-by-byte transfers If an error is detected in the polling loop, abort the transaction and return an error code. * DEV_ERR is set if the device does not respond with an acknowledge, and the SMBus controller times out (minimum 25ms). * BUS_ERR is set if a bus arbitration collision is detected. In other words, when the SMBus controller tries to generate a START condition, but detects that the SMBDATA is being held low, usually by another SMBus/I2C master. * FAILED is only set if a transaction is stopped by software (using the SMBHSTCNT KILL bit). Signed-off-by: Daniel Kurtz Signed-off-by: Jean Delvare --- diff --git a/drivers/i2c/busses/i2c-i801.c b/drivers/i2c/busses/i2c-i801.c index 05f394938b82..40a50f780972 100644 --- a/drivers/i2c/busses/i2c-i801.c +++ b/drivers/i2c/busses/i2c-i801.c @@ -131,9 +131,11 @@ #define SMBHSTSTS_INTR 0x02 #define SMBHSTSTS_HOST_BUSY 0x01 -#define STATUS_FLAGS (SMBHSTSTS_BYTE_DONE | SMBHSTSTS_FAILED | \ - SMBHSTSTS_BUS_ERR | SMBHSTSTS_DEV_ERR | \ - SMBHSTSTS_INTR) +#define STATUS_ERROR_FLAGS (SMBHSTSTS_FAILED | SMBHSTSTS_BUS_ERR | \ + SMBHSTSTS_DEV_ERR) + +#define STATUS_FLAGS (SMBHSTSTS_BYTE_DONE | SMBHSTSTS_INTR | \ + STATUS_ERROR_FLAGS) /* Older devices have their ID defined in */ #define PCI_DEVICE_ID_INTEL_COUGARPOINT_SMBUS 0x1c22 @@ -384,7 +386,7 @@ static int i801_block_transaction_byte_by_byte(struct i801_priv *priv, do { usleep_range(250, 500); status = inb_p(SMBHSTSTS(priv)); - } while ((!(status & SMBHSTSTS_BYTE_DONE)) + } while (!(status & (SMBHSTSTS_BYTE_DONE | STATUS_ERROR_FLAGS)) && (timeout++ < MAX_RETRIES)); result = i801_check_post(priv, status, timeout > MAX_RETRIES);