Because not all I3C drivers have the hot-join feature ready, and especially not all I3C devices support hot-join feature, exporting SETDASA method could be useful. With this function, the I3C controller could perform a DAA to I3C devices when users decide to turn these I3C devices off and on again during run-time. Tested: This change has been tested with turnning off an I3C device and turning on it again during run-time. The device driver calls SETDASA method to perform DAA to the device. And communication between I3C controller and device is set up again correctly.
Unified · Split
| @@ -50,6 +50,26 @@ int i3c_device_do_priv_xfers(struct i3c_device *dev, · 49 unmodified lines | ||
| 50 | 50 | } |
| 51 | 51 | EXPORT_SYMBOL_GPL(i3c_device_do_priv_xfers); |
| 52 | 52 | |
| 53 | +/** | |
| 54 | + * i3c_device_do_setdasa() - do I3C dynamic address assignement with | |
| 55 | + * static address | |
| 56 | + * | |
| 57 | + * @dev: device with which the DAA should be done | |
| 58 | + * | |
| 59 | + * Return: 0 in case of success, a negative error core otherwise. | |
| 60 | + */ | |
| 61 | +int i3c_device_do_setdasa(struct i3c_device *dev) | |
| 62 | +{ | |
| 63 | + int ret; | |
| 64 | + | |
| 65 | + i3c_bus_normaluse_lock(dev->bus); | |
| 66 | + ret = i3c_dev_setdasa_locked(dev->desc); | |
| 67 | + i3c_bus_normaluse_unlock(dev->bus); | |
| 68 | + | |
| 69 | + return ret; | |
| 70 | +} | |
| 71 | +EXPORT_SYMBOL_GPL(i3c_device_do_setdasa); | |
| 72 | + | |
| 53 | 73 | /** |
| 54 | 74 | * i3c_device_get_info() - get I3C device information |
| 55 | 75 | * |
| @@ -15,6 +15,7 @@ extern struct bus_type i3c_bus_type; · 14 unmodified lines | ||
| 15 | 15 | void i3c_bus_normaluse_lock(struct i3c_bus *bus); |
| 16 | 16 | void i3c_bus_normaluse_unlock(struct i3c_bus *bus); |
| 17 | 17 | |
| 18 | +int i3c_dev_setdasa_locked(struct i3c_dev_desc *dev); | |
| 18 | 19 | int i3c_dev_do_priv_xfers_locked(struct i3c_dev_desc *dev, |
| 19 | 20 | struct i3c_priv_xfer *xfers, |
| 20 | 21 | int nxfers); |
| @@ -2708,6 +2708,25 @@ int i3c_master_unregister(struct i3c_master_controller *master) · 2707 unmodified lines | ||
| 2708 | 2708 | } |
| 2709 | 2709 | EXPORT_SYMBOL_GPL(i3c_master_unregister); |
| 2710 | 2710 | |
| 2711 | +int i3c_dev_setdasa_locked(struct i3c_dev_desc *dev) | |
| 2712 | +{ | |
| 2713 | + struct i3c_master_controller *master; | |
| 2714 | + | |
| 2715 | + if (!dev) | |
| 2716 | + return -ENOENT; | |
| 2717 | + | |
| 2718 | + master = i3c_dev_get_master(dev); | |
| 2719 | + if (!master) | |
| 2720 | + return -EINVAL; | |
| 2721 | + | |
| 2722 | + if (!dev->boardinfo || !dev->boardinfo->init_dyn_addr || | |
| 2723 | + !dev->boardinfo->static_addr) | |
| 2724 | + return -EINVAL; | |
| 2725 | + | |
| 2726 | + return i3c_master_setdasa_locked(master, dev->info.static_addr, | |
| 2727 | + dev->boardinfo->init_dyn_addr); | |
| 2728 | +} | |
| 2729 | + | |
| 2711 | 2730 | int i3c_dev_do_priv_xfers_locked(struct i3c_dev_desc *dev, |
| 2712 | 2731 | struct i3c_priv_xfer *xfers, |
| 2713 | 2732 | int nxfers) |
| @@ -294,6 +294,8 @@ int i3c_device_do_priv_xfers(struct i3c_device *dev, · 293 unmodified lines | ||
| 294 | 294 | struct i3c_priv_xfer *xfers, |
| 295 | 295 | int nxfers); |
| 296 | 296 | |
| 297 | +int i3c_device_do_setdasa(struct i3c_device *dev); | |
| 298 | + | |
| 297 | 299 | void i3c_device_get_info(struct i3c_device *dev, struct i3c_device_info *info); |
| 298 | 300 | |
| 299 | 301 | struct i3c_ibi_payload { |