From 2feb9398a178195cdda1cd2f71ab51268bee6a64 Mon Sep 17 00:00:00 2001 From: Daniel Vetter Date: Sat, 1 Dec 2012 13:53:46 +0100 Subject: [PATCH] --- yaml --- r: 357895 b: refs/heads/master c: 2c438c0273b76d6cb158f8bdd0aa3ebf66e48a28 h: refs/heads/master i: 357893: b5a36166259a139a32004009a962565f9c6fe2e8 357891: 6d178145aeb356a22c88c207f1fdc7bbfccbcca7 357887: 39060d6c853344568e172c506ef3657dd28626e4 v: v3 --- [refs] | 2 +- trunk/drivers/gpu/drm/i915/intel_i2c.c | 32 ++++++++++++++++++++++---- 2 files changed, 29 insertions(+), 5 deletions(-) diff --git a/[refs] b/[refs] index ccb68fb41eff..bb3368472fb1 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: 28c70f162a315bdcfbe0bf940a740ef8bfb918d6 +refs/heads/master: 2c438c0273b76d6cb158f8bdd0aa3ebf66e48a28 diff --git a/trunk/drivers/gpu/drm/i915/intel_i2c.c b/trunk/drivers/gpu/drm/i915/intel_i2c.c index 8b7189253cb4..1fc31191b910 100644 --- a/trunk/drivers/gpu/drm/i915/intel_i2c.c +++ b/trunk/drivers/gpu/drm/i915/intel_i2c.c @@ -203,6 +203,7 @@ intel_gpio_setup(struct intel_gmbus *bus, u32 pin) algo->data = bus; } +#define HAS_GMBUS_IRQ(dev) (INTEL_INFO(dev)->gen >= 4) static int gmbus_wait_hw_status(struct drm_i915_private *dev_priv, u32 gmbus2_status, @@ -239,6 +240,31 @@ gmbus_wait_hw_status(struct drm_i915_private *dev_priv, return -ETIMEDOUT; } +static int +gmbus_wait_idle(struct drm_i915_private *dev_priv) +{ + int ret; + int reg_offset = dev_priv->gpio_mmio_base; + +#define C ((I915_READ(GMBUS2 + reg_offset) & GMBUS_ACTIVE) == 0) + + if (!HAS_GMBUS_IRQ(dev_priv->dev)) + return wait_for(C, 10); + + /* Important: The hw handles only the first bit, so set only one! */ + I915_WRITE(GMBUS4 + reg_offset, GMBUS_IDLE_EN); + + ret = wait_event_timeout(dev_priv->gmbus_wait_queue, C, 10); + + I915_WRITE(GMBUS4 + reg_offset, 0); + + if (ret) + return 0; + else + return -ETIMEDOUT; +#undef C +} + static int gmbus_xfer_read(struct drm_i915_private *dev_priv, struct i2c_msg *msg, u32 gmbus1_index) @@ -406,8 +432,7 @@ gmbus_xfer(struct i2c_adapter *adapter, * We will re-enable it at the start of the next xfer, * till then let it sleep. */ - if (wait_for((I915_READ(GMBUS2 + reg_offset) & GMBUS_ACTIVE) == 0, - 10)) { + if (gmbus_wait_idle(dev_priv)) { DRM_DEBUG_KMS("GMBUS [%s] timed out waiting for idle\n", adapter->name); ret = -ETIMEDOUT; @@ -431,8 +456,7 @@ gmbus_xfer(struct i2c_adapter *adapter, * 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)) { + if (gmbus_wait_idle(dev_priv)) { DRM_DEBUG_KMS("GMBUS [%s] timed out after NAK\n", adapter->name); ret = -ETIMEDOUT;