summaryrefslogtreecommitdiff
path: root/drivers/i3c
diff options
context:
space:
mode:
authorAman Kumar Pandey <aman.kumarpandey@nxp.com>2026-06-12 16:48:09 +0530
committerAlexandre Belloni <alexandre.belloni@bootlin.com>2026-06-16 01:27:25 +0200
commit8d8afa428318a623aa674c3f90550475ad3e6ccd (patch)
tree4e5e7acd80586a5d9adf7bfd4daa5814aea14785 /drivers/i3c
parent79c41666b397df9218b6e7555663b298a88e2b56 (diff)
downloadlinux-next-8d8afa428318a623aa674c3f90550475ad3e6ccd.tar.gz
linux-next-8d8afa428318a623aa674c3f90550475ad3e6ccd.zip
i3c: master: Expose the APIs to support I3C hub
Change the below internal static functions to APIs to allow new I3C hub driver to use them 1) i3c_dev_enable_ibi_locked() 2) i3c_dev_disable_ibi_locked() 3) i3c_dev_request_ibi_locked() 4) i3c_dev_free_ibi_locked() 5) i3c_master_reattach_i3c_dev_locked() Signed-off-by: Aman Kumar Pandey <aman.kumarpandey@nxp.com> Signed-off-by: Lakshay Piplani <lakshay.piplani@nxp.com> Reviewed-by: Frank Li <Frank.Li@nxp.com> Link: https://patch.msgid.link/20260612111816.3688240-3-lakshay.piplani@nxp.com Signed-off-by: Alexandre Belloni <alexandre.belloni@bootlin.com>
Diffstat (limited to 'drivers/i3c')
-rw-r--r--drivers/i3c/master.c70
1 files changed, 68 insertions, 2 deletions
diff --git a/drivers/i3c/master.c b/drivers/i3c/master.c
index cf56865d875a..372d911ecbad 100644
--- a/drivers/i3c/master.c
+++ b/drivers/i3c/master.c
@@ -1765,8 +1765,23 @@ static int i3c_master_attach_i3c_dev(struct i3c_master_controller *master,
return 0;
}
-static int i3c_master_reattach_i3c_dev_locked(struct i3c_dev_desc *dev,
- u8 old_dyn_addr)
+/**
+ * i3c_master_reattach_i3c_dev_locked() - reattach an I3C device with a new address
+ * @dev: I3C device descriptor to reattach
+ * @old_dyn_addr: previous dynamic address of the device
+ *
+ * This function reattaches an existing I3C device to the bus when its dynamic
+ * address has changed. It updates the bus address slot status accordingly:
+ * - Marks the new dynamic address as occupied by an I3C device.
+ * - Frees the old dynamic address slot if applicable.
+ *
+ * This function must be called with the bus lock held in write mode.
+ *
+ * Return: 0 on success, or a negative error code if reattachment fails
+ * (e.g. -EBUSY if the new address slot is not free).
+ */
+int i3c_master_reattach_i3c_dev_locked(struct i3c_dev_desc *dev,
+ u8 old_dyn_addr)
{
struct i3c_master_controller *master = i3c_dev_get_master(dev);
int ret;
@@ -1790,6 +1805,7 @@ static int i3c_master_reattach_i3c_dev_locked(struct i3c_dev_desc *dev,
return 0;
}
+EXPORT_SYMBOL_GPL(i3c_master_reattach_i3c_dev_locked);
static void i3c_master_detach_i3c_dev(struct i3c_dev_desc *dev)
{
@@ -3387,6 +3403,16 @@ int i3c_dev_do_xfers_locked(struct i3c_dev_desc *dev, struct i3c_xfer *xfers,
return master->ops->i3c_xfers(dev, xfers, nxfers, mode);
}
+/**
+ * i3c_dev_disable_ibi_locked() - Disable IBIs coming from a specific device
+ * @dev: device on which IBIs should be disabled
+ *
+ * This function disable IBIs coming from a specific device and wait for
+ * all pending IBIs to be processed.
+ *
+ * Context: Must be called with mutex_lock(&dev->desc->ibi_lock) held.
+ * Return: 0 in case of success, a negative error core otherwise.
+ */
int i3c_dev_disable_ibi_locked(struct i3c_dev_desc *dev)
{
struct i3c_master_controller *master;
@@ -3408,7 +3434,22 @@ int i3c_dev_disable_ibi_locked(struct i3c_dev_desc *dev)
return 0;
}
+EXPORT_SYMBOL_GPL(i3c_dev_disable_ibi_locked);
+/**
+ * i3c_dev_enable_ibi_locked() - Enable IBIs from a specific device (lock held)
+ * @dev: device on which IBIs should be enabled
+ *
+ * This function enable IBIs coming from a specific device and wait for
+ * all pending IBIs to be processed. This should be called on a device
+ * where i3c_device_request_ibi() has succeeded.
+ *
+ * Note that IBIs from this device might be received before this function
+ * returns to its caller.
+ *
+ * Context: Must be called with mutex_lock(&dev->desc->ibi_lock) held.
+ * Return: 0 on success, or a negative error code on failure.
+ */
int i3c_dev_enable_ibi_locked(struct i3c_dev_desc *dev)
{
struct i3c_master_controller *master = i3c_dev_get_master(dev);
@@ -3423,7 +3464,20 @@ int i3c_dev_enable_ibi_locked(struct i3c_dev_desc *dev)
return ret;
}
+EXPORT_SYMBOL_GPL(i3c_dev_enable_ibi_locked);
+/**
+ * i3c_dev_request_ibi_locked() - Request an IBI
+ * @dev: device for which we should enable IBIs
+ * @req: setup requested for this IBI
+ *
+ * This function is responsible for pre-allocating all resources needed to
+ * process IBIs coming from @dev. When this function returns, the IBI is not
+ * enabled until i3c_device_enable_ibi() is called.
+ *
+ * Context: Must be called with mutex_lock(&dev->desc->ibi_lock) held.
+ * Return: 0 in case of success, a negative error core otherwise.
+ */
int i3c_dev_request_ibi_locked(struct i3c_dev_desc *dev,
const struct i3c_ibi_setup *req)
{
@@ -3462,7 +3516,18 @@ int i3c_dev_request_ibi_locked(struct i3c_dev_desc *dev,
return ret;
}
+EXPORT_SYMBOL_GPL(i3c_dev_request_ibi_locked);
+/**
+ * i3c_dev_free_ibi_locked() - Free all resources needed for IBI handling
+ * @dev: device on which you want to release IBI resources
+ *
+ * This function is responsible for de-allocating resources previously
+ * allocated by i3c_device_request_ibi(). It should be called after disabling
+ * IBIs with i3c_device_disable_ibi().
+ *
+ * Context: Must be called with mutex_lock(&dev->desc->ibi_lock) held.
+ */
void i3c_dev_free_ibi_locked(struct i3c_dev_desc *dev)
{
struct i3c_master_controller *master = i3c_dev_get_master(dev);
@@ -3493,6 +3558,7 @@ void i3c_dev_free_ibi_locked(struct i3c_dev_desc *dev)
kfree(dev->ibi);
dev->ibi = NULL;
}
+EXPORT_SYMBOL_GPL(i3c_dev_free_ibi_locked);
static int __init i3c_init(void)
{