Re: [PATCH V2 01/16] i3c: mipi-i3c-hci: Fix suspend behavior when bus disable falls back to software reset

From: Frank Li

Date: Wed Apr 22 2026 - 00:05:33 EST


On Tue, Apr 21, 2026 at 08:54:20PM +0300, Adrian Hunter wrote:
> Software reset was introduced as a fallback if bus disable failed. The
> change was made in 2 places: the cleanup path and the suspend path.
>
> For the cleanup path (i3c_hci_bus_cleanup()), after software reset the
> function continues to do cleanup for the current I/O mode. For the
> suspend path (i3c_hci_rpm_suspend()), after software reset the function
> returns early. However software reset does not reset any Ring Headers in
> the Host Controller, so returning early is not the right thing to do.
>
> Instead, continue to call suspend for the current I/O mode, which for DMA
> mode will reset any Ring Headers.
>
> Note, although Ring Headers should not be active at this stage, performing
> this reset follows the procedure defined by the specification and keeps
> the suspend path consistent with the cleanup path.
>
> Note also, i3c_hci_sync_irq_inactive() is still called via the PIO and DMA
> hci->io->suspend() callbacks.
>
> Always return 0 because the device is quiesced as much as possible and
> returning a negative error code would unnecessarily prevent system suspend.
>
> Fixes: 9a258d1336f7 ("i3c: mipi-i3c-hci: Fallback to software reset when bus disable fails")
> Signed-off-by: Adrian Hunter <adrian.hunter@xxxxxxxxx>
> ---

Reviewed-by: Frank Li <Frank.Li@xxxxxxx>
>
>
> Changes in V2:
>
> Always return 0 from suspend callback
> Amend commit message
>
>
> drivers/i3c/master/mipi-i3c-hci/core.c | 11 +++--------
> 1 file changed, 3 insertions(+), 8 deletions(-)
>
> diff --git a/drivers/i3c/master/mipi-i3c-hci/core.c b/drivers/i3c/master/mipi-i3c-hci/core.c
> index b781dbed2165..afb0764b5e1f 100644
> --- a/drivers/i3c/master/mipi-i3c-hci/core.c
> +++ b/drivers/i3c/master/mipi-i3c-hci/core.c
> @@ -762,15 +762,10 @@ static int i3c_hci_reset_and_init(struct i3c_hci *hci)
> int i3c_hci_rpm_suspend(struct device *dev)
> {
> struct i3c_hci *hci = dev_get_drvdata(dev);
> - int ret;
>
> - ret = i3c_hci_bus_disable(hci);
> - if (ret) {
> - /* Fall back to software reset to disable the bus */
> - ret = i3c_hci_software_reset(hci);
> - i3c_hci_sync_irq_inactive(hci);
> - return ret;
> - }
> + /* Fall back to software reset to disable the bus */
> + if (i3c_hci_bus_disable(hci))
> + i3c_hci_software_reset(hci);
>
> hci->io->suspend(hci);
>
> --
> 2.51.0
>