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>
This commit is contained in:
Aman Kumar Pandey 2026-06-12 16:48:09 +05:30 committed by Alexandre Belloni
parent 79c41666b3
commit 8d8afa4283
2 changed files with 70 additions and 2 deletions

View File

@ -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)
{

View File

@ -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);