Skip to content

Commit cab2d3f

Browse files
Loic Poulaingregkh
authored andcommitted
bus: mhi: core: Add support for forced PM resume
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 an API mhi_pm_resume_force(), to force resuming irrespective of the current MHI state. 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 Link: https://lore.kernel.org/regressions/871r5p0x2u.fsf@codeaurora.org/ Fixes: 020d3b2 ("bus: mhi: Early MHI resume failure in non M3 state") Cc: stable@vger.kernel.org #5.13 Reported-by: Kalle Valo <kvalo@codeaurora.org> Reported-by: Pengyu Ma <mapengyu@gmail.com> Tested-by: Kalle Valo <kvalo@kernel.org> Acked-by: Kalle Valo <kvalo@kernel.org> Signed-off-by: Loic Poulain <loic.poulain@linaro.org> [mani: Switched to API, added bug report, reported-by tags and CCed stable] Signed-off-by: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org> Link: https://lore.kernel.org/r/20211209131633.4168-1-manivannan.sadhasivam@linaro.org Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
1 parent 7c602f5 commit cab2d3f

File tree

3 files changed

+36
-4
lines changed

3 files changed

+36
-4
lines changed

drivers/bus/mhi/core/pm.c

Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -881,7 +881,7 @@ int mhi_pm_suspend(struct mhi_controller *mhi_cntrl)
881881
}
882882
EXPORT_SYMBOL_GPL(mhi_pm_suspend);
883883

884-
int mhi_pm_resume(struct mhi_controller *mhi_cntrl)
884+
static int __mhi_pm_resume(struct mhi_controller *mhi_cntrl, bool force)
885885
{
886886
struct mhi_chan *itr, *tmp;
887887
struct device *dev = &mhi_cntrl->mhi_dev->dev;
@@ -898,8 +898,12 @@ int mhi_pm_resume(struct mhi_controller *mhi_cntrl)
898898
if (MHI_PM_IN_ERROR_STATE(mhi_cntrl->pm_state))
899899
return -EIO;
900900

901-
if (mhi_get_mhi_state(mhi_cntrl) != MHI_STATE_M3)
902-
return -EINVAL;
901+
if (mhi_get_mhi_state(mhi_cntrl) != MHI_STATE_M3) {
902+
dev_warn(dev, "Resuming from non M3 state (%s)\n",
903+
TO_MHI_STATE_STR(mhi_get_mhi_state(mhi_cntrl)));
904+
if (!force)
905+
return -EINVAL;
906+
}
903907

904908
/* Notify clients about exiting LPM */
905909
list_for_each_entry_safe(itr, tmp, &mhi_cntrl->lpm_chans, node) {
@@ -940,8 +944,19 @@ int mhi_pm_resume(struct mhi_controller *mhi_cntrl)
940944

941945
return 0;
942946
}
947+
948+
int mhi_pm_resume(struct mhi_controller *mhi_cntrl)
949+
{
950+
return __mhi_pm_resume(mhi_cntrl, false);
951+
}
943952
EXPORT_SYMBOL_GPL(mhi_pm_resume);
944953

954+
int mhi_pm_resume_force(struct mhi_controller *mhi_cntrl)
955+
{
956+
return __mhi_pm_resume(mhi_cntrl, true);
957+
}
958+
EXPORT_SYMBOL_GPL(mhi_pm_resume_force);
959+
945960
int __mhi_device_get_sync(struct mhi_controller *mhi_cntrl)
946961
{
947962
int ret;

drivers/net/wireless/ath/ath11k/mhi.c

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -533,7 +533,11 @@ static int ath11k_mhi_set_state(struct ath11k_pci *ab_pci,
533533
ret = mhi_pm_suspend(ab_pci->mhi_ctrl);
534534
break;
535535
case ATH11K_MHI_RESUME:
536-
ret = mhi_pm_resume(ab_pci->mhi_ctrl);
536+
/* Do force MHI resume as some devices like QCA6390, WCN6855
537+
* are not in M3 state but they are functional. So just ignore
538+
* the MHI state while resuming.
539+
*/
540+
ret = mhi_pm_resume_force(ab_pci->mhi_ctrl);
537541
break;
538542
case ATH11K_MHI_TRIGGER_RDDM:
539543
ret = mhi_force_rddm_mode(ab_pci->mhi_ctrl);

include/linux/mhi.h

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -663,6 +663,19 @@ int mhi_pm_suspend(struct mhi_controller *mhi_cntrl);
663663
*/
664664
int mhi_pm_resume(struct mhi_controller *mhi_cntrl);
665665

666+
/**
667+
* mhi_pm_resume_force - Force resume MHI from suspended state
668+
* @mhi_cntrl: MHI controller
669+
*
670+
* Resume the device irrespective of its MHI state. As per the MHI spec, devices
671+
* has to be in M3 state during resume. But some devices seem to be in a
672+
* different MHI state other than M3 but they continue working fine if allowed.
673+
* This API is intented to be used for such devices.
674+
*
675+
* Return: 0 if the resume succeeds, a negative error code otherwise
676+
*/
677+
int mhi_pm_resume_force(struct mhi_controller *mhi_cntrl);
678+
666679
/**
667680
* mhi_download_rddm_image - Download ramdump image from device for
668681
* debugging purpose.

0 commit comments

Comments
 (0)