i3c: export SETDASA method
authorJack Chen <zenghuchen@google.com>
Wed, 7 Dec 2022 20:50:59 +0000 (15:50 -0500)
committerAlexandre Belloni <alexandre.belloni@bootlin.com>
Sun, 11 Dec 2022 20:25:58 +0000 (21:25 +0100)
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.

Signed-off-by: Jack Chen <zenghuchen@google.com>
Link: https://lore.kernel.org/r/20221207205059.3848851-1-zenghuchen@google.com
Signed-off-by: Alexandre Belloni <alexandre.belloni@bootlin.com>
drivers/i3c/device.c
drivers/i3c/internals.h
drivers/i3c/master.c
include/linux/i3c/device.h

index e92d3e9a52bd55dedc1cd4b3f83d6721a1c97025..9762630b917ea55f86a4241d35974c23892bd77a 100644 (file)
@@ -50,6 +50,26 @@ int i3c_device_do_priv_xfers(struct i3c_device *dev,
 }
 EXPORT_SYMBOL_GPL(i3c_device_do_priv_xfers);
 
+/**
+ * i3c_device_do_setdasa() - do I3C dynamic address assignement with
+ *                           static address
+ *
+ * @dev: device with which the DAA should be done
+ *
+ * Return: 0 in case of success, a negative error core otherwise.
+ */
+int i3c_device_do_setdasa(struct i3c_device *dev)
+{
+       int ret;
+
+       i3c_bus_normaluse_lock(dev->bus);
+       ret = i3c_dev_setdasa_locked(dev->desc);
+       i3c_bus_normaluse_unlock(dev->bus);
+
+       return ret;
+}
+EXPORT_SYMBOL_GPL(i3c_device_do_setdasa);
+
 /**
  * i3c_device_get_info() - get I3C device information
  *
index 86b7b44cfca28be75fdc028f0c5a7460dd552d25..908a807badaf9c0266bc33756d66091b1ee8368c 100644 (file)
@@ -15,6 +15,7 @@ extern struct bus_type i3c_bus_type;
 void i3c_bus_normaluse_lock(struct i3c_bus *bus);
 void i3c_bus_normaluse_unlock(struct i3c_bus *bus);
 
+int i3c_dev_setdasa_locked(struct i3c_dev_desc *dev);
 int i3c_dev_do_priv_xfers_locked(struct i3c_dev_desc *dev,
                                 struct i3c_priv_xfer *xfers,
                                 int nxfers);
index 351c81a929a6c914b21d153d7587fe40dc695c0b..d7e6f6c99aea558f7781de8c34f354aeb0add48b 100644 (file)
@@ -2708,6 +2708,25 @@ int i3c_master_unregister(struct i3c_master_controller *master)
 }
 EXPORT_SYMBOL_GPL(i3c_master_unregister);
 
+int i3c_dev_setdasa_locked(struct i3c_dev_desc *dev)
+{
+       struct i3c_master_controller *master;
+
+       if (!dev)
+               return -ENOENT;
+
+       master = i3c_dev_get_master(dev);
+       if (!master)
+               return -EINVAL;
+
+       if (!dev->boardinfo || !dev->boardinfo->init_dyn_addr ||
+               !dev->boardinfo->static_addr)
+               return -EINVAL;
+
+       return i3c_master_setdasa_locked(master, dev->info.static_addr,
+                                               dev->boardinfo->init_dyn_addr);
+}
+
 int i3c_dev_do_priv_xfers_locked(struct i3c_dev_desc *dev,
                                 struct i3c_priv_xfer *xfers,
                                 int nxfers)
index 419192b5cc4d35c531944f92f26b9510ce5cb30c..1c997abe868c60c360cbeec6dc726d6e01d0dd9d 100644 (file)
@@ -294,6 +294,8 @@ int i3c_device_do_priv_xfers(struct i3c_device *dev,
                             struct i3c_priv_xfer *xfers,
                             int nxfers);
 
+int i3c_device_do_setdasa(struct i3c_device *dev);
+
 void i3c_device_get_info(struct i3c_device *dev, struct i3c_device_info *info);
 
 struct i3c_ibi_payload {