|
@@ -233,11 +233,15 @@ gmbus_xfer(struct i2c_adapter *adapter,
|
|
|
struct intel_gmbus,
|
|
|
adapter);
|
|
|
struct drm_i915_private *dev_priv = adapter->algo_data;
|
|
|
- int i, reg_offset;
|
|
|
+ int i, reg_offset, ret;
|
|
|
|
|
|
- if (bus->force_bit)
|
|
|
- return intel_i2c_quirk_xfer(dev_priv,
|
|
|
+ mutex_lock(&dev_priv->gmbus_mutex);
|
|
|
+
|
|
|
+ if (bus->force_bit) {
|
|
|
+ ret = intel_i2c_quirk_xfer(dev_priv,
|
|
|
bus->force_bit, msgs, num);
|
|
|
+ goto out;
|
|
|
+ }
|
|
|
|
|
|
reg_offset = HAS_PCH_SPLIT(dev_priv->dev) ? PCH_GMBUS0 - GMBUS0 : 0;
|
|
|
|
|
@@ -321,7 +325,8 @@ done:
|
|
|
* start of the next xfer, till then let it sleep.
|
|
|
*/
|
|
|
I915_WRITE(GMBUS0 + reg_offset, 0);
|
|
|
- return i;
|
|
|
+ ret = i;
|
|
|
+ goto out;
|
|
|
|
|
|
timeout:
|
|
|
DRM_INFO("GMBUS timed out, falling back to bit banging on pin %d [%s]\n",
|
|
@@ -331,9 +336,12 @@ timeout:
|
|
|
/* Hardware may not support GMBUS over these pins? Try GPIO bitbanging instead. */
|
|
|
bus->force_bit = intel_gpio_create(dev_priv, bus->reg0 & 0xff);
|
|
|
if (!bus->force_bit)
|
|
|
- return -ENOMEM;
|
|
|
-
|
|
|
- return intel_i2c_quirk_xfer(dev_priv, bus->force_bit, msgs, num);
|
|
|
+ ret = -ENOMEM;
|
|
|
+ else
|
|
|
+ ret = intel_i2c_quirk_xfer(dev_priv, bus->force_bit, msgs, num);
|
|
|
+out:
|
|
|
+ mutex_unlock(&dev_priv->gmbus_mutex);
|
|
|
+ return ret;
|
|
|
}
|
|
|
|
|
|
static u32 gmbus_func(struct i2c_adapter *adapter)
|
|
@@ -380,6 +388,8 @@ int intel_setup_gmbus(struct drm_device *dev)
|
|
|
if (dev_priv->gmbus == NULL)
|
|
|
return -ENOMEM;
|
|
|
|
|
|
+ mutex_init(&dev_priv->gmbus_mutex);
|
|
|
+
|
|
|
for (i = 0; i < GMBUS_NUM_PORTS; i++) {
|
|
|
struct intel_gmbus *bus = &dev_priv->gmbus[i];
|
|
|
|