Re: [PATCH V2 08/17] i3c: mipi-i3c-hci: Fix runtime PM violation in i3c_hci_free_ibi()
From: Frank Li
Date: Thu Sep 17 2026 - 17:32:19 EST
On Thu, Sep 17, 2026 at 10:13:47PM +0300, Adrian Hunter wrote:
> i3c_hci_free_ibi() calls __i3c_hci_disable_ibi(), but the latter
> requires runtime PM to be resumed. The ->free_ibi() callback does not
> guarantee that condition.
>
> The cases where ->free_ibi() may be called without a preceding
> ->disable_ibi() do not require re-enabling runtime PM handling:
>
> - runtime resume failed in i3c_dev_free_ibi_locked(), so it skips the
> IBI disable but still proceeds to call ->free_ibi()
> - the device has been re-enumerated under a new dynamic address in
> __i3c_master_add_i3c_dev_locked(), which tears down the old device
> descriptor and deliberately clears olddev->ibi->enabled (to avoid
> sending a DISEC to the stale old address) before calling
> i3c_dev_free_ibi_locked(). As a result ->free_ibi() is reached with
> neither a hardware IBI disable nor runtime PM resumed.
>
> In both cases the important requirement is to prevent further IBI
> processing for the device. That can be done without accessing hardware
> by removing the device from the ibi_devs[] table.
>
> Replace the call to __i3c_hci_disable_ibi() with clearing the
> corresponding ibi_devs[] entry under the controller lock.
>
> Fixes: 650716f23eac4 ("i3c: mipi-i3c-hci: Fix race in i3c_hci_addr_to_dev()")
> Signed-off-by: Adrian Hunter <adrian.hunter@xxxxxxxxx>
> ---
Reviewed-by: Frank Li <Frank.Li@xxxxxxx>
>
>
> Changes in V2:
>
> None
>
>
> drivers/i3c/master/mipi-i3c-hci/core.c | 6 ++++--
> 1 file changed, 4 insertions(+), 2 deletions(-)
>
> diff --git a/drivers/i3c/master/mipi-i3c-hci/core.c b/drivers/i3c/master/mipi-i3c-hci/core.c
> index f6a34ce7a295..b9b20797d045 100644
> --- a/drivers/i3c/master/mipi-i3c-hci/core.c
> +++ b/drivers/i3c/master/mipi-i3c-hci/core.c
> @@ -675,11 +675,13 @@ static void __i3c_hci_disable_ibi(struct i3c_hci *hci, struct i3c_dev_desc *dev)
>
> static void i3c_hci_free_ibi(struct i3c_dev_desc *dev)
> {
> + struct i3c_hci_dev_data *dev_data = i3c_dev_get_master_data(dev);
> struct i3c_master_controller *m = i3c_dev_get_master(dev);
> struct i3c_hci *hci = to_i3c_hci(m);
>
> - /* Must ensure the IBI has been disabled */
> - __i3c_hci_disable_ibi(hci, dev);
> + /* Must ensure IBIs for this device will no longer be processed */
> + scoped_guard(spinlock_irqsave, &hci->lock)
> + hci->ibi_devs[dev_data->dat_idx] = NULL;
> hci->io->free_ibi(hci, dev);
> }
>
> --
> 2.53.0
>