aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJani Nikula <jani.nikula@intel.com>2015-12-01 09:29:26 -0500
committerJani Nikula <jani.nikula@intel.com>2015-12-02 06:29:41 -0500
commitbffce907d64042b5683ed3076e839d0249606264 (patch)
tree6bda4975b36467d0f4460f824ff201751e9eb7b2
parent0aeb904888f52f48ca0cc7dfec2c2f540d2a762a (diff)
drm/i915: abstract i2c bit banging fallback in gmbus xfer
Choose between i2c bit banging and gmbus in a new higher level function, and let the i2c core retry the first time we fall back to bit banging. The i2c core imposes a timeout on -EAGAIN, but it defaults to 1 second, and shouldn't be a problem for us. Reviewed-by: Ville Syrjälä <ville.syrjala@linux.intel.com> Signed-off-by: Jani Nikula <jani.nikula@intel.com> Link: http://patchwork.freedesktop.org/patch/msgid/1448980166-23055-2-git-send-email-jani.nikula@intel.com
-rw-r--r--drivers/gpu/drm/i915/intel_i2c.c39
1 files changed, 25 insertions, 14 deletions
diff --git a/drivers/gpu/drm/i915/intel_i2c.c b/drivers/gpu/drm/i915/intel_i2c.c
index ccb522c176bd..e26e22a72e3b 100644
--- a/drivers/gpu/drm/i915/intel_i2c.c
+++ b/drivers/gpu/drm/i915/intel_i2c.c
@@ -472,9 +472,7 @@ gmbus_xfer_index_read(struct drm_i915_private *dev_priv, struct i2c_msg *msgs)
472} 472}
473 473
474static int 474static int
475gmbus_xfer(struct i2c_adapter *adapter, 475do_gmbus_xfer(struct i2c_adapter *adapter, struct i2c_msg *msgs, int num)
476 struct i2c_msg *msgs,
477 int num)
478{ 476{
479 struct intel_gmbus *bus = container_of(adapter, 477 struct intel_gmbus *bus = container_of(adapter,
480 struct intel_gmbus, 478 struct intel_gmbus,
@@ -483,14 +481,6 @@ gmbus_xfer(struct i2c_adapter *adapter,
483 int i = 0, inc, try = 0; 481 int i = 0, inc, try = 0;
484 int ret = 0; 482 int ret = 0;
485 483
486 intel_display_power_get(dev_priv, POWER_DOMAIN_GMBUS);
487 mutex_lock(&dev_priv->gmbus_mutex);
488
489 if (bus->force_bit) {
490 ret = i2c_bit_algo.master_xfer(adapter, msgs, num);
491 goto out;
492 }
493
494retry: 484retry:
495 I915_WRITE(GMBUS0, bus->reg0); 485 I915_WRITE(GMBUS0, bus->reg0);
496 486
@@ -585,13 +575,34 @@ timeout:
585 bus->adapter.name, bus->reg0 & 0xff); 575 bus->adapter.name, bus->reg0 & 0xff);
586 I915_WRITE(GMBUS0, 0); 576 I915_WRITE(GMBUS0, 0);
587 577
588 /* Hardware may not support GMBUS over these pins? Try GPIO bitbanging instead. */ 578 /*
579 * Hardware may not support GMBUS over these pins? Try GPIO bitbanging
580 * instead. Use EAGAIN to have i2c core retry.
581 */
589 bus->force_bit = 1; 582 bus->force_bit = 1;
590 ret = i2c_bit_algo.master_xfer(adapter, msgs, num); 583 ret = -EAGAIN;
591 584
592out: 585out:
593 mutex_unlock(&dev_priv->gmbus_mutex); 586 return ret;
587}
588
589static int
590gmbus_xfer(struct i2c_adapter *adapter, struct i2c_msg *msgs, int num)
591{
592 struct intel_gmbus *bus = container_of(adapter, struct intel_gmbus,
593 adapter);
594 struct drm_i915_private *dev_priv = bus->dev_priv;
595 int ret;
596
597 intel_display_power_get(dev_priv, POWER_DOMAIN_GMBUS);
598 mutex_lock(&dev_priv->gmbus_mutex);
599
600 if (bus->force_bit)
601 ret = i2c_bit_algo.master_xfer(adapter, msgs, num);
602 else
603 ret = do_gmbus_xfer(adapter, msgs, num);
594 604
605 mutex_unlock(&dev_priv->gmbus_mutex);
595 intel_display_power_put(dev_priv, POWER_DOMAIN_GMBUS); 606 intel_display_power_put(dev_priv, POWER_DOMAIN_GMBUS);
596 607
597 return ret; 608 return ret;