On Mon, Dec 06, 2021 at 09:40:59PM +0530, Manivannan Sadhasivam wrote: > From: Loic Poulain <loic.poulain@xxxxxxxxxx> > > For whatever reason, some devices like QCA6390, WCN6855 using ath11k > are not in M3 state during PM resume, but still functional. The > mhi_pm_resume should then not fail in those cases, and let the higher > level device specific stack continue resuming process. > > Add a new parameter to mhi_pm_resume, to force resuming, whatever the > current MHI state is. This fixes a regression with non functional > ath11k WiFi after suspend/resume cycle on some machines. > > Bug report: https://bugzilla.kernel.org/show_bug.cgi?id=214179 > > Cc: stable@xxxxxxxxxxxxxxx #5.13 > Fixes: 020d3b26c07a ("bus: mhi: Early MHI resume failure in non M3 state") > Reported-by: Kalle Valo <kvalo@xxxxxxxxxxxxxx> > Reported-by: Pengyu Ma <mapengyu@xxxxxxxxx> > Signed-off-by: Loic Poulain <loic.poulain@xxxxxxxxxx> > [mani: Added comment, bug report, added reported-by tags and CCed stable] > Signed-off-by: Manivannan Sadhasivam <manivannan.sadhasivam@xxxxxxxxxx> Applied to mhi-fixes! Will be submitted for v5.16-rcX. Thanks, Mani > --- > drivers/bus/mhi/core/pm.c | 10 +++++++--- > drivers/bus/mhi/pci_generic.c | 2 +- > drivers/net/wireless/ath/ath11k/mhi.c | 6 +++++- > include/linux/mhi.h | 3 ++- > 4 files changed, 15 insertions(+), 6 deletions(-) > > diff --git a/drivers/bus/mhi/core/pm.c b/drivers/bus/mhi/core/pm.c > index 7464f5d09973..4ddd266e042e 100644 > --- a/drivers/bus/mhi/core/pm.c > +++ b/drivers/bus/mhi/core/pm.c > @@ -881,7 +881,7 @@ int mhi_pm_suspend(struct mhi_controller *mhi_cntrl) > } > EXPORT_SYMBOL_GPL(mhi_pm_suspend); > > -int mhi_pm_resume(struct mhi_controller *mhi_cntrl) > +int mhi_pm_resume(struct mhi_controller *mhi_cntrl, bool force) > { > struct mhi_chan *itr, *tmp; > struct device *dev = &mhi_cntrl->mhi_dev->dev; > @@ -898,8 +898,12 @@ int mhi_pm_resume(struct mhi_controller *mhi_cntrl) > if (MHI_PM_IN_ERROR_STATE(mhi_cntrl->pm_state)) > return -EIO; > > - if (mhi_get_mhi_state(mhi_cntrl) != MHI_STATE_M3) > - return -EINVAL; > + if (mhi_get_mhi_state(mhi_cntrl) != MHI_STATE_M3) { > + dev_warn(dev, "Resuming from non M3 state (%s)\n", > + TO_MHI_STATE_STR(mhi_get_mhi_state(mhi_cntrl))); > + if (!force) > + return -EINVAL; > + } > > /* Notify clients about exiting LPM */ > list_for_each_entry_safe(itr, tmp, &mhi_cntrl->lpm_chans, node) { > diff --git a/drivers/bus/mhi/pci_generic.c b/drivers/bus/mhi/pci_generic.c > index 9ef41354237c..efd1da66fdf9 100644 > --- a/drivers/bus/mhi/pci_generic.c > +++ b/drivers/bus/mhi/pci_generic.c > @@ -959,7 +959,7 @@ static int __maybe_unused mhi_pci_runtime_resume(struct device *dev) > return 0; /* Nothing to do at MHI level */ > > /* Exit M3, transition to M0 state */ > - err = mhi_pm_resume(mhi_cntrl); > + err = mhi_pm_resume(mhi_cntrl, false); > if (err) { > dev_err(&pdev->dev, "failed to resume device: %d\n", err); > goto err_recovery; > diff --git a/drivers/net/wireless/ath/ath11k/mhi.c b/drivers/net/wireless/ath/ath11k/mhi.c > index 26c7ae242db6..f1f2fa2d690d 100644 > --- a/drivers/net/wireless/ath/ath11k/mhi.c > +++ b/drivers/net/wireless/ath/ath11k/mhi.c > @@ -533,7 +533,11 @@ static int ath11k_mhi_set_state(struct ath11k_pci *ab_pci, > ret = mhi_pm_suspend(ab_pci->mhi_ctrl); > break; > case ATH11K_MHI_RESUME: > - ret = mhi_pm_resume(ab_pci->mhi_ctrl); > + /* Do force MHI resume as some devices like QCA6390, WCN6855 > + * are not in M3 state but they are functional. So just ignore > + * the MHI state while resuming. > + */ > + ret = mhi_pm_resume(ab_pci->mhi_ctrl, true); > break; > case ATH11K_MHI_TRIGGER_RDDM: > ret = mhi_force_rddm_mode(ab_pci->mhi_ctrl); > diff --git a/include/linux/mhi.h b/include/linux/mhi.h > index 723985879035..102303288cee 100644 > --- a/include/linux/mhi.h > +++ b/include/linux/mhi.h > @@ -660,8 +660,9 @@ int mhi_pm_suspend(struct mhi_controller *mhi_cntrl); > /** > * mhi_pm_resume - Resume MHI from suspended state > * @mhi_cntrl: MHI controller > + * @force: Force resuming to M0 irrespective of the device MHI state > */ > -int mhi_pm_resume(struct mhi_controller *mhi_cntrl); > +int mhi_pm_resume(struct mhi_controller *mhi_cntrl, bool force); > > /** > * mhi_download_rddm_image - Download ramdump image from device for > -- > 2.25.1 >