@@ -482,6 +482,7 @@ intel_dp_i2c_aux_ch(struct i2c_adapter *adapter, int mode,
int msg_bytes;
int reply_bytes;
int ret;
+ unsigned retry;
/* Set up the command byte */
if (mode & MODE_I2C_READ)
@@ -513,7 +514,7 @@ intel_dp_i2c_aux_ch(struct i2c_adapter *adapter, int mode,
break;
}
- for (;;) {
+ for (retry = 5; retry; retry--) {
ret = intel_dp_aux_ch(intel_dp,
msg, msg_bytes,
reply, reply_bytes);
@@ -521,6 +522,21 @@ intel_dp_i2c_aux_ch(struct i2c_adapter *adapter, int mode,
DRM_DEBUG_KMS("aux_ch failed %d\n", ret);
return ret;
}
+ switch (reply[0] & AUX_NATIVE_REPLY_MASK) {
+ case AUX_NATIVE_REPLY_ACK:
+ /* I2C-over-AUX Reply field is only valid when paired with AUX ACK.*/
+ break;
+ case AUX_NATIVE_REPLY_NACK:
+ DRM_DEBUG_KMS("aux_ch nack\n");
+ return -EREMOTEIO;
+ case AUX_NATIVE_REPLY_DEFER:
+ udelay(100);
+ continue;
+ default:
+ DRM_ERROR("aux_ch invalid reply 0x%02x\n", reply[0]);
+ return -EREMOTEIO;
+ }
+
switch (reply[0] & AUX_I2C_REPLY_MASK) {
case AUX_I2C_REPLY_ACK:
if (mode == MODE_I2C_READ) {
@@ -528,17 +544,20 @@ intel_dp_i2c_aux_ch(struct i2c_adapter *adapter, int mode,
}
return reply_bytes - 1;
case AUX_I2C_REPLY_NACK:
- DRM_DEBUG_KMS("aux_ch nack\n");
+ DRM_DEBUG_KMS("aux_i2c nack\n");
return -EREMOTEIO;
case AUX_I2C_REPLY_DEFER:
- DRM_DEBUG_KMS("aux_ch defer\n");
+ DRM_DEBUG_KMS("aux_i2c defer\n");
udelay(100);
break;
default:
- DRM_ERROR("aux_ch invalid reply 0x%02x\n", reply[0]);
+ DRM_ERROR("aux_i2c invalid reply 0x%02x\n", reply[0]);
return -EREMOTEIO;
}
}
+
+ DRM_ERROR("too many retries, giving up\n");
+ return -EREMOTEIO;
}
static int