diff options
author | Daniel Vetter <daniel.vetter@ffwll.ch> | 2012-05-21 20:19:48 +0200 |
---|---|---|
committer | Daniel Vetter <daniel.vetter@ffwll.ch> | 2012-05-21 21:04:21 +0200 |
commit | 65e818660275ecda3702a4245f308923e3813a85 (patch) | |
tree | 35884f20a18fc66a4adf2eb1d229dff095c3ad98 /drivers/gpu/drm/i915/intel_i2c.c | |
parent | f15b4ca2ccbc0a4661c35a744d254e1e32dd1e15 (diff) |
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 e646d5773572bf52017983d758bdf05777dc5600
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=49518
Reported-and-Tested-by: Julian Simioni <julian.simioni@gmail.com>
Acked-by: Chris Wilson <chris@chris-wilson.co.uk>
Reviewed-by: Daniel Kurtz <djkurtz@chromium.org>
Signed-Off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
Diffstat (limited to 'drivers/gpu/drm/i915/intel_i2c.c')
-rw-r--r-- | drivers/gpu/drm/i915/intel_i2c.c | 21 |
1 files changed, 12 insertions, 9 deletions
diff --git a/drivers/gpu/drm/i915/intel_i2c.c b/drivers/gpu/drm/i915/intel_i2c.c index 4a9707dd0f9..1991a4408cf 100644 --- a/drivers/gpu/drm/i915/intel_i2c.c +++ b/drivers/gpu/drm/i915/intel_i2c.c @@ -396,11 +396,22 @@ clear_err: * Wait for bus to IDLE before clearing NAK. * If we clear the NAK while bus is still active, then it will stay * 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, - 10)) + 10)) { DRM_DEBUG_KMS("GMBUS [%s] timed out after NAK\n", adapter->name); + ret = -ETIMEDOUT; + } /* Toggle the Software Clear Interrupt bit. This has the effect * of resetting the GMBUS controller and so clearing the @@ -414,14 +425,6 @@ clear_err: adapter->name, msgs[i].addr, (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; timeout: |