Usually EDID retrieval is fine. However, sometimes, especially when the machine is loaded, it fails, but succeeds after a few retries. Based on a patch by Michael Buesch. Reported-by: Michael Buesch <mb@xxxxxxxxx> Signed-off-by: Chris Wilson <chris@xxxxxxxxxxxxxxxxxx> --- I was going to suggest tuning the i2c_adapter.retries of the affected components, but that only covers EGAIN and not EREMOTEIO/ETIMEDOUT that afflicts us. With the alteration to only retry the transfer of the affected block, this looks to be a reasonable idea and complements the logic to retry corrupted transfers. -Chris --- drivers/gpu/drm/drm_edid.c | 44 ++++++++++++++++++++++++++------------------ 1 files changed, 26 insertions(+), 18 deletions(-) diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c index a245d17..ddc3da9 100644 --- a/drivers/gpu/drm/drm_edid.c +++ b/drivers/gpu/drm/drm_edid.c @@ -230,24 +230,32 @@ drm_do_probe_ddc_edid(struct i2c_adapter *adapter, unsigned char *buf, int block, int len) { unsigned char start = block * EDID_LENGTH; - struct i2c_msg msgs[] = { - { - .addr = DDC_ADDR, - .flags = 0, - .len = 1, - .buf = &start, - }, { - .addr = DDC_ADDR, - .flags = I2C_M_RD, - .len = len, - .buf = buf, - } - }; + int ret, retries = 5; - if (i2c_transfer(adapter, msgs, 2) == 2) - return 0; + /* The core i2c driver will automatically retry the transfer if the + * adapter reports EAGAIN. However, we find that bit-banging transfers + * are susceptible to errors under a heavily loaded machine and + * generate spurious NAKs and timeouts. Retrying the transfer + * of the individual block a few times seems to overcome this. + */ + do { + struct i2c_msg msgs[] = { + { + .addr = DDC_ADDR, + .flags = 0, + .len = 1, + .buf = &start, + }, { + .addr = DDC_ADDR, + .flags = I2C_M_RD, + .len = len, + .buf = buf, + } + }; + ret = i2c_transfer(adapter, msgs, 2); + } while (ret != 2 && --retries); - return -1; + return ret == 2 ? 0 : -1; } static u8 * -- 1.7.2.3 _______________________________________________ dri-devel mailing list dri-devel@xxxxxxxxxxxxxxxxxxxxx http://lists.freedesktop.org/mailman/listinfo/dri-devel