From: Aman Kumar Pandey Date: Fri, 12 Jun 2026 11:18:09 +0000 (+0530) Subject: i3c: master: Expose the APIs to support I3C hub X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=8d8afa428318a623aa674c3f90550475ad3e6ccd;p=thirdparty%2Flinux.git 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 Signed-off-by: Lakshay Piplani Reviewed-by: Frank Li Link: https://patch.msgid.link/20260612111816.3688240-3-lakshay.piplani@nxp.com Signed-off-by: Alexandre Belloni --- diff --git a/drivers/i3c/master.c b/drivers/i3c/master.c index cf56865d875aa..372d911ecbadc 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) { diff --git a/include/linux/i3c/master.h b/include/linux/i3c/master.h index f73cede87d36a..27eeb598b3c52 100644 --- a/include/linux/i3c/master.h +++ b/include/linux/i3c/master.h @@ -625,6 +625,8 @@ void i3c_master_dma_unmap_single(struct i3c_dma *dma_xfer); DEFINE_FREE(i3c_master_dma_unmap_single, void *, if (_T) i3c_master_dma_unmap_single(_T)) +int i3c_master_reattach_i3c_dev_locked(struct i3c_dev_desc *dev, + u8 old_dyn_addr); int i3c_master_set_info(struct i3c_master_controller *master, const struct i3c_device_info *info);