Commit 65e81866 authored by Daniel Vetter's avatar Daniel Vetter

drm/i915: be more careful when returning -ENXIO in gmbus transfer

... flaky ddc hardware can cause a spurious NAK, resulting in the i2c
core and drm edid functions not trying to retry the edid transfer.

Luckily the gmbus quiescenting also times out for these cases, so we
can get out of this mess by returning -ETIMEDOUT for this specific
case. This way we keep the fast-fail of returning -ENXIO if there is
no device present, speeding up the boot process.

This regression has been introduced in

commit e646d577
Author: Daniel Kurtz <djkurtz@chromium.org>
Date:   Fri Mar 30 19:46:38 2012 +0800

    drm/i915/intel_i2c: always wait for IDLE before clearing NAK

v2: Return -ETIMEDOUT for this case and keep the -ENXIO for real NAKs,
suggested by Daniel Kurtz.

Cc: Daniel Kurtz <djkurtz@chromium.org>
Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=49518Reported-and-Tested-by: default avatarJulian Simioni <julian.simioni@gmail.com>
Acked-by: default avatarChris Wilson <chris@chris-wilson.co.uk>
Reviewed-by: default avatarDaniel Kurtz <djkurtz@chromium.org>
Signed-Off-by: default avatarDaniel Vetter <daniel.vetter@ffwll.ch>
parent f15b4ca2
...@@ -396,11 +396,22 @@ gmbus_xfer(struct i2c_adapter *adapter, ...@@ -396,11 +396,22 @@ gmbus_xfer(struct i2c_adapter *adapter,
* Wait for bus to IDLE before clearing NAK. * Wait for bus to IDLE before clearing NAK.
* If we clear the NAK while bus is still active, then it will stay * If we clear the NAK while bus is still active, then it will stay
* active and the next transaction may fail. * active and the next transaction may fail.
*
* If no ACK is received during the address phase of a transaction, the
* adapter must report -ENXIO. It is not clear what to return if no ACK
* is received at other times. But we have to be careful to not return
* spurious -ENXIO because that will prevent i2c and drm edid functions
* from retrying. So return -ENXIO only when gmbus properly quiescents -
* timing out seems to happen when there _is_ a ddc chip present, but
* it's slow responding and only answers on the 2nd retry.
*/ */
ret = -ENXIO;
if (wait_for((I915_READ(GMBUS2 + reg_offset) & GMBUS_ACTIVE) == 0, if (wait_for((I915_READ(GMBUS2 + reg_offset) & GMBUS_ACTIVE) == 0,
10)) 10)) {
DRM_DEBUG_KMS("GMBUS [%s] timed out after NAK\n", DRM_DEBUG_KMS("GMBUS [%s] timed out after NAK\n",
adapter->name); adapter->name);
ret = -ETIMEDOUT;
}
/* Toggle the Software Clear Interrupt bit. This has the effect /* Toggle the Software Clear Interrupt bit. This has the effect
* of resetting the GMBUS controller and so clearing the * of resetting the GMBUS controller and so clearing the
...@@ -414,14 +425,6 @@ gmbus_xfer(struct i2c_adapter *adapter, ...@@ -414,14 +425,6 @@ gmbus_xfer(struct i2c_adapter *adapter,
adapter->name, msgs[i].addr, adapter->name, msgs[i].addr,
(msgs[i].flags & I2C_M_RD) ? 'r' : 'w', msgs[i].len); (msgs[i].flags & I2C_M_RD) ? 'r' : 'w', msgs[i].len);
/*
* If no ACK is received during the address phase of a transaction,
* the adapter must report -ENXIO.
* It is not clear what to return if no ACK is received at other times.
* So, we always return -ENXIO in all NAK cases, to ensure we send
* it at least during the one case that is specified.
*/
ret = -ENXIO;
goto out; goto out;
timeout: timeout:
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment