i2c: core: Pick i2c bus number from dt alias if present
This allows you to get the equivalent functionality of i2c_add_numbered_adapter() with all data in the device tree and no special case code in your driver. This is a common device tree technique. For quick reference, the FDT syntax for using an alias to provide an ID looks like: aliases { i2c0 = &i2c_0; i2c1 = &i2c_1; }; Signed-off-by: Doug Anderson <dianders@chromium.org> [wsa: removed one check from static function. We know our callers] Signed-off-by: Wolfram Sang <wsa@the-dreams.de>
This commit is contained in:
Родитель
8bb9660418
Коммит
ee5c27440c
|
@ -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);
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче