drm/i915: Rework sdvo proxy i2c locking
lockdep complaints about a locking recursion for the i2c bus lock because both the sdvo ddc proxy bus and the gmbus nested within use the same locking class. It's not really a deadlock since we never nest the other way round, but it's annoying. Fix it by pulling the gmbus locking into the i2c lock_ops for both i2c_adapater and making sure that the ddc_proxy_xfer function is entirely lockless. Re-layouting the extracted function resulted in some whitespace cleanups, I figured we might as well keep them. v2: Review from Chris: - s/locked/unlocked/ since I got the naming backwards - Use the vfuncs of the proxied adatper instead of re-rolling copies. That's more consistent with the other proxying we're doing. Cc: Chris Wilson <chris@chris-wilson.co.uk> Reviewed-by: Chris Wilson <chris@chris-wilson.co.uk> Signed-off-by: Daniel Vetter <daniel.vetter@intel.com> Link: https://patchwork.freedesktop.org/patch/msgid/20170726132647.31833-1-daniel.vetter@ffwll.ch
This commit is contained in:
@@ -592,7 +592,6 @@ gmbus_xfer(struct i2c_adapter *adapter, struct i2c_msg *msgs, int num)
|
||||
int ret;
|
||||
|
||||
intel_display_power_get(dev_priv, POWER_DOMAIN_GMBUS);
|
||||
mutex_lock(&dev_priv->gmbus_mutex);
|
||||
|
||||
if (bus->force_bit) {
|
||||
ret = i2c_bit_algo.master_xfer(adapter, msgs, num);
|
||||
@@ -604,7 +603,6 @@ gmbus_xfer(struct i2c_adapter *adapter, struct i2c_msg *msgs, int num)
|
||||
bus->force_bit |= GMBUS_FORCE_BIT_RETRY;
|
||||
}
|
||||
|
||||
mutex_unlock(&dev_priv->gmbus_mutex);
|
||||
intel_display_power_put(dev_priv, POWER_DOMAIN_GMBUS);
|
||||
|
||||
return ret;
|
||||
@@ -624,6 +622,39 @@ static const struct i2c_algorithm gmbus_algorithm = {
|
||||
.functionality = gmbus_func
|
||||
};
|
||||
|
||||
static void gmbus_lock_bus(struct i2c_adapter *adapter,
|
||||
unsigned int flags)
|
||||
{
|
||||
struct intel_gmbus *bus = to_intel_gmbus(adapter);
|
||||
struct drm_i915_private *dev_priv = bus->dev_priv;
|
||||
|
||||
mutex_lock(&dev_priv->gmbus_mutex);
|
||||
}
|
||||
|
||||
static int gmbus_trylock_bus(struct i2c_adapter *adapter,
|
||||
unsigned int flags)
|
||||
{
|
||||
struct intel_gmbus *bus = to_intel_gmbus(adapter);
|
||||
struct drm_i915_private *dev_priv = bus->dev_priv;
|
||||
|
||||
return mutex_trylock(&dev_priv->gmbus_mutex);
|
||||
}
|
||||
|
||||
static void gmbus_unlock_bus(struct i2c_adapter *adapter,
|
||||
unsigned int flags)
|
||||
{
|
||||
struct intel_gmbus *bus = to_intel_gmbus(adapter);
|
||||
struct drm_i915_private *dev_priv = bus->dev_priv;
|
||||
|
||||
mutex_unlock(&dev_priv->gmbus_mutex);
|
||||
}
|
||||
|
||||
const struct i2c_lock_operations gmbus_lock_ops = {
|
||||
.lock_bus = gmbus_lock_bus,
|
||||
.trylock_bus = gmbus_trylock_bus,
|
||||
.unlock_bus = gmbus_unlock_bus,
|
||||
};
|
||||
|
||||
/**
|
||||
* intel_gmbus_setup - instantiate all Intel i2c GMBuses
|
||||
* @dev_priv: i915 device private
|
||||
@@ -665,6 +696,7 @@ int intel_setup_gmbus(struct drm_i915_private *dev_priv)
|
||||
bus->dev_priv = dev_priv;
|
||||
|
||||
bus->adapter.algo = &gmbus_algorithm;
|
||||
bus->adapter.lock_ops = &gmbus_lock_ops;
|
||||
|
||||
/*
|
||||
* We wish to retry with bit banging
|
||||
|
Reference in New Issue
Block a user