@@ -868,8 +868,11 @@ void i2c_lock_adapter(struct i2c_adapter *adapter)
if (parent)
i2c_lock_adapter(parent);
- else
+ else {
rt_mutex_lock(&adapter->bus_lock);
+ if (adapter->hardware_lock)
+ adapter->hardware_lock(adapter);
+ }
}
EXPORT_SYMBOL_GPL(i2c_lock_adapter);
@@ -880,11 +883,19 @@ EXPORT_SYMBOL_GPL(i2c_lock_adapter);
static int i2c_trylock_adapter(struct i2c_adapter *adapter)
{
struct i2c_adapter *parent = i2c_parent_is_i2c_adapter(adapter);
+ int ret = 0;
if (parent)
return i2c_trylock_adapter(parent);
- else
- return rt_mutex_trylock(&adapter->bus_lock);
+ else {
+ ret = rt_mutex_trylock(&adapter->bus_lock);
+ if (ret && adapter->hardware_trylock) {
+ ret = adapter->hardware_trylock(adapter);
+ if (!ret)
+ i2c_unlock_adapter(adapter);
+ }
+ return ret;
+ }
}
/**
@@ -897,8 +908,11 @@ void i2c_unlock_adapter(struct i2c_adapter *adapter)
if (parent)
i2c_unlock_adapter(parent);
- else
+ else {
+ if (adapter->hardware_unlock)
+ adapter->hardware_unlock(adapter);
rt_mutex_unlock(&adapter->bus_lock);
+ }
}
EXPORT_SYMBOL_GPL(i2c_unlock_adapter);
@@ -504,6 +504,11 @@ struct i2c_adapter {
/* data fields that are valid for all devices */
struct rt_mutex bus_lock;
+ /* if hardware lock feature provided */
+ void (*hardware_lock)(struct i2c_adapter *);
+ void (*hardware_unlock)(struct i2c_adapter *);
+ int (*hardware_trylock)(struct i2c_adapter *);
+
int timeout; /* in jiffies */
int retries;
struct device dev; /* the adapter device */