|
@@ -920,14 +920,36 @@ out_list:
|
|
|
return res;
|
|
|
}
|
|
|
|
|
|
+/**
|
|
|
+ * __i2c_add_numbered_adapter - i2c_add_numbered_adapter where nr is never -1
|
|
|
+ * @adap: the adapter to register (with adap->nr initialized)
|
|
|
+ * Context: can sleep
|
|
|
+ *
|
|
|
+ * See i2c_add_numbered_adapter() for details.
|
|
|
+ */
|
|
|
+static int __i2c_add_numbered_adapter(struct i2c_adapter *adap)
|
|
|
+{
|
|
|
+ int id;
|
|
|
+
|
|
|
+ mutex_lock(&core_lock);
|
|
|
+ id = idr_alloc(&i2c_adapter_idr, adap, adap->nr, adap->nr + 1,
|
|
|
+ GFP_KERNEL);
|
|
|
+ mutex_unlock(&core_lock);
|
|
|
+ if (id < 0)
|
|
|
+ return id == -ENOSPC ? -EBUSY : id;
|
|
|
+
|
|
|
+ return i2c_register_adapter(adap);
|
|
|
+}
|
|
|
+
|
|
|
/**
|
|
|
* i2c_add_adapter - declare i2c adapter, use dynamic bus number
|
|
|
* @adapter: the adapter to add
|
|
|
* Context: can sleep
|
|
|
*
|
|
|
* This routine is used to declare an I2C adapter when its bus number
|
|
|
- * doesn't matter. Examples: for I2C adapters dynamically added by
|
|
|
- * USB links or PCI plugin cards.
|
|
|
+ * doesn't matter or when its bus number is specified by an dt alias.
|
|
|
+ * Examples of bases when the bus number doesn't matter: I2C adapters
|
|
|
+ * dynamically added by USB links or PCI plugin cards.
|
|
|
*
|
|
|
* When this returns zero, a new bus number was allocated and stored
|
|
|
* in adap->nr, and the specified adapter became available for clients.
|
|
@@ -935,8 +957,17 @@ out_list:
|
|
|
*/
|
|
|
int i2c_add_adapter(struct i2c_adapter *adapter)
|
|
|
{
|
|
|
+ struct device *dev = &adapter->dev;
|
|
|
int id;
|
|
|
|
|
|
+ if (dev->of_node) {
|
|
|
+ id = of_alias_get_id(dev->of_node, "i2c");
|
|
|
+ if (id >= 0) {
|
|
|
+ adapter->nr = id;
|
|
|
+ return __i2c_add_numbered_adapter(adapter);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
mutex_lock(&core_lock);
|
|
|
id = idr_alloc(&i2c_adapter_idr, adapter,
|
|
|
__i2c_first_dynamic_bus_num, 0, GFP_KERNEL);
|
|
@@ -975,18 +1006,10 @@ EXPORT_SYMBOL(i2c_add_adapter);
|
|
|
*/
|
|
|
int i2c_add_numbered_adapter(struct i2c_adapter *adap)
|
|
|
{
|
|
|
- int id;
|
|
|
-
|
|
|
if (adap->nr == -1) /* -1 means dynamically assign bus id */
|
|
|
return i2c_add_adapter(adap);
|
|
|
|
|
|
- mutex_lock(&core_lock);
|
|
|
- id = idr_alloc(&i2c_adapter_idr, adap, adap->nr, adap->nr + 1,
|
|
|
- GFP_KERNEL);
|
|
|
- mutex_unlock(&core_lock);
|
|
|
- if (id < 0)
|
|
|
- return id == -ENOSPC ? -EBUSY : id;
|
|
|
- return i2c_register_adapter(adap);
|
|
|
+ return __i2c_add_numbered_adapter(adap);
|
|
|
}
|
|
|
EXPORT_SYMBOL_GPL(i2c_add_numbered_adapter);
|
|
|
|