diff options
Diffstat (limited to 'drivers/i3c/master.c')
| -rw-r--r-- | drivers/i3c/master.c | 36 | 
1 files changed, 26 insertions, 10 deletions
diff --git a/drivers/i3c/master.c b/drivers/i3c/master.c index 54e4c34b4a22..08aeb69a7800 100644 --- a/drivers/i3c/master.c +++ b/drivers/i3c/master.c @@ -21,6 +21,7 @@  static DEFINE_IDR(i3c_bus_idr);  static DEFINE_MUTEX(i3c_core_lock); +static int __i3c_first_dynamic_bus_num;  /**   * i3c_bus_maintenance_lock - Lock the bus for a maintenance operation @@ -419,9 +420,9 @@ static void i3c_bus_cleanup(struct i3c_bus *i3cbus)  	mutex_unlock(&i3c_core_lock);  } -static int i3c_bus_init(struct i3c_bus *i3cbus) +static int i3c_bus_init(struct i3c_bus *i3cbus, struct device_node *np)  { -	int ret; +	int ret, start, end, id = -1;  	init_rwsem(&i3cbus->lock);  	INIT_LIST_HEAD(&i3cbus->devs.i2c); @@ -429,8 +430,19 @@ static int i3c_bus_init(struct i3c_bus *i3cbus)  	i3c_bus_init_addrslots(i3cbus);  	i3cbus->mode = I3C_BUS_MODE_PURE; +	if (np) +		id = of_alias_get_id(np, "i3c"); +  	mutex_lock(&i3c_core_lock); -	ret = idr_alloc(&i3c_bus_idr, i3cbus, 0, 0, GFP_KERNEL); +	if (id >= 0) { +		start = id; +		end = start + 1; +	} else { +		start = __i3c_first_dynamic_bus_num; +		end = 0; +	} + +	ret = idr_alloc(&i3c_bus_idr, i3cbus, start, end, GFP_KERNEL);  	mutex_unlock(&i3c_core_lock);  	if (ret < 0) @@ -2606,7 +2618,7 @@ int i3c_master_register(struct i3c_master_controller *master,  	INIT_LIST_HEAD(&master->boardinfo.i2c);  	INIT_LIST_HEAD(&master->boardinfo.i3c); -	ret = i3c_bus_init(i3cbus); +	ret = i3c_bus_init(i3cbus, master->dev.of_node);  	if (ret)  		return ret; @@ -2695,17 +2707,13 @@ EXPORT_SYMBOL_GPL(i3c_master_register);   * @master: master used to send frames on the bus   *   * Basically undo everything done in i3c_master_register(). - * - * Return: 0 in case of success, a negative error code otherwise.   */ -int i3c_master_unregister(struct i3c_master_controller *master) +void i3c_master_unregister(struct i3c_master_controller *master)  {  	i3c_master_i2c_adapter_cleanup(master);  	i3c_master_unregister_i3c_devs(master);  	i3c_master_bus_cleanup(master);  	device_unregister(&master->dev); - -	return 0;  }  EXPORT_SYMBOL_GPL(i3c_master_unregister); @@ -2834,8 +2842,16 @@ void i3c_dev_free_ibi_locked(struct i3c_dev_desc *dev)  static int __init i3c_init(void)  { -	int res = bus_register_notifier(&i2c_bus_type, &i2cdev_notifier); +	int res; + +	res = of_alias_get_highest_id("i3c"); +	if (res >= 0) { +		mutex_lock(&i3c_core_lock); +		__i3c_first_dynamic_bus_num = res + 1; +		mutex_unlock(&i3c_core_lock); +	} +	res = bus_register_notifier(&i2c_bus_type, &i2cdev_notifier);  	if (res)  		return res;  |