Re: [PATCH] bus: mhi: host: pci_generic: Switch to async power up to avoid boot delays
From: Qiang Yu
Date: Mon Mar 02 2026 - 05:13:41 EST
On Mon, Mar 02, 2026 at 01:37:38PM +0530, Manivannan Sadhasivam wrote:
> On Thu, Jan 22, 2026 at 12:53:48AM -0800, Qiang Yu wrote:
> > Some modem devices can take significant time (up to 20 secs for sdx75) to
> > enter mission mode during initialization. Currently, mhi_sync_power_up()
> > waits for this entire process to complete, blocking other driver probes
> > and delaying system boot.
> >
> > Switch to mhi_async_power_up() so probe can return immediately while MHI
> > initialization continues in the background. This eliminates lengthy boot
> > delays and allows other drivers to probe in parallel, improving overall
> > system boot performance.
> >
>
> This part is fine.
>
> > Add pm_runtime_forbid() in remove path to prevent device suspend during
> > driver reinstallation. This issue is specific to async power up: with
> > sync power up, pm_runtime_put_noidle() is called after mission mode is
> > reached because mhi_sync_power_up() waits for mission mode event. With
> > async power up, pm_runtime_put_noidle() is called immediately while power
> > up process continues in background, which can cause the device to
> > suspend and mhi init fail if pm_runtime_allow() from a previous probe
> > is still active.
> >
>
> pm_runtime_forbid() should be called at the start of the remove() callback to
> prevent the device from auto suspending during cleanup and to fix the issue you
> described above.
>
> So do in a separate patch and add a Fixes tag pointing to the commit that added
> the Runtime PM support.
>
I can implement this in a separate patch as it also serves as a cleanup to
call pm_runtime_forbid() in the remove callback, since we call
pm_runtime_allow() in our driver. However, I cannot call it at the start
of the remove() callback. Before the remove callback is invoked,
pci_device_remove() calls pm_runtime_get_sync(dev) first, so we don't need
to worry about auto-suspend during removal.
Since we use mhi_async_power_up(), there's a race condition where the
mhi_pci_generic driver could be removed after mission mode is reached but
before pm_runtime_allow() is called as part of mhi_status_cb(). In this
scenario, the pm_runtime_forbid() operation would be ineffective, and when
the driver is reinstalled next time, MHI read operations will fail during
initialization because the previous pm_runtime_allow() state was not
properly cleared.
- Qiang Yu
> - Mani
>
> > Fixes: 5571519009d0 ("bus: mhi: host: pci_generic: Add SDX75 based modem support")
> > Cc: stable@xxxxxxxxxxxxxxx
> > Signed-off-by: Qiang Yu <qiang.yu@xxxxxxxxxxxxxxxx>
> > ---
> > drivers/bus/mhi/host/pci_generic.c | 3 ++-
> > 1 file changed, 2 insertions(+), 1 deletion(-)
> >
> > diff --git a/drivers/bus/mhi/host/pci_generic.c b/drivers/bus/mhi/host/pci_generic.c
> > index 0884a384b77fc3f56fa62a12351933132ffc9293..fc0952e46ae5e4854c7165ed60b850729843d458 100644
> > --- a/drivers/bus/mhi/host/pci_generic.c
> > +++ b/drivers/bus/mhi/host/pci_generic.c
> > @@ -1393,7 +1393,7 @@ static int mhi_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id)
> > goto err_unregister;
> > }
> >
> > - err = mhi_sync_power_up(mhi_cntrl);
> > + err = mhi_async_power_up(mhi_cntrl);
> > if (err) {
> > dev_err(&pdev->dev, "failed to power up MHI controller\n");
> > goto err_unprepare;
> > @@ -1447,6 +1447,7 @@ static void mhi_pci_remove(struct pci_dev *pdev)
> > mhi_soc_reset(mhi_cntrl);
> >
> > mhi_unregister_controller(mhi_cntrl);
> > + pm_runtime_forbid(&pdev->dev);
> > }
> >
> > static void mhi_pci_shutdown(struct pci_dev *pdev)
> >
> > ---
> > base-commit: 91a0b0dce350766675961892ba4431363c4e29f7
> > change-id: 20260113-mhi_async_probe-a7b0867b6e2e
> >
> > Best regards,
> > --
> > Qiang Yu <qiang.yu@xxxxxxxxxxxxxxxx>
> >
>
> --
> மணிவண்ணன் சதாசிவம்