History

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

Loic Poulain committed 4 years ago

Commit cab2d3f1 parent 7c602f53 files · +36 −4Browse files

Unified · Split

3 files
  1. drivers/bus/mhi/core/pm.c +18 −3
  2. drivers/net/wireless/ath/ath11k/mhi.c +5 −1
  3. include/linux/mhi.h +13 −0
drivers/bus/mhi/core/pm.c+18−3
@@ -881,7 +881,7 @@ int mhi_pm_suspend(struct mhi_controller *mhi_cntrl) · 880 unmodified lines
881}881}
882EXPORT_SYMBOL_GPL(mhi_pm_suspend);882EXPORT_SYMBOL_GPL(mhi_pm_suspend);
883 883
884int mhi_pm_resume(struct mhi_controller *mhi_cntrl)884static int __mhi_pm_resume(struct mhi_controller *mhi_cntrl, bool force)
885{885{
886 struct mhi_chan *itr, *tmp;886 struct mhi_chan *itr, *tmp;
887 struct device *dev = &mhi_cntrl->mhi_dev->dev;887 struct device *dev = &mhi_cntrl->mhi_dev->dev;
@@ -898,8 +898,12 @@ int mhi_pm_resume(struct mhi_controller *mhi_cntrl) · 10 unmodified lines
898 if (MHI_PM_IN_ERROR_STATE(mhi_cntrl->pm_state))898 if (MHI_PM_IN_ERROR_STATE(mhi_cntrl->pm_state))
899 return -EIO;899 return -EIO;
900 900
901 if (mhi_get_mhi_state(mhi_cntrl) != MHI_STATE_M3)901 if (mhi_get_mhi_state(mhi_cntrl) != MHI_STATE_M3) {
902 return -EINVAL;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 }
903 907
904 /* Notify clients about exiting LPM */908 /* Notify clients about exiting LPM */
905 list_for_each_entry_safe(itr, tmp, &mhi_cntrl->lpm_chans, node) {909 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) · 34 unmodified lines
940 944
941 return 0;945 return 0;
942}946}
947
948int mhi_pm_resume(struct mhi_controller *mhi_cntrl)
949{
950 return __mhi_pm_resume(mhi_cntrl, false);
951}
943EXPORT_SYMBOL_GPL(mhi_pm_resume);952EXPORT_SYMBOL_GPL(mhi_pm_resume);
944 953
954int mhi_pm_resume_force(struct mhi_controller *mhi_cntrl)
955{
956 return __mhi_pm_resume(mhi_cntrl, true);
957}
958EXPORT_SYMBOL_GPL(mhi_pm_resume_force);
959
945int __mhi_device_get_sync(struct mhi_controller *mhi_cntrl)960int __mhi_device_get_sync(struct mhi_controller *mhi_cntrl)
946{961{
947 int ret;962 int ret;
drivers/net/wireless/ath/ath11k/mhi.c+5−1
@@ -533,7 +533,11 @@ static int ath11k_mhi_set_state(struct ath11k_pci *ab_pci, · 532 unmodified lines
533 ret = mhi_pm_suspend(ab_pci->mhi_ctrl);533 ret = mhi_pm_suspend(ab_pci->mhi_ctrl);
534 break;534 break;
535 case ATH11K_MHI_RESUME:535 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);
537 break;541 break;
538 case ATH11K_MHI_TRIGGER_RDDM:542 case ATH11K_MHI_TRIGGER_RDDM:
539 ret = mhi_force_rddm_mode(ab_pci->mhi_ctrl);543 ret = mhi_force_rddm_mode(ab_pci->mhi_ctrl);
include/linux/mhi.h+13−0
@@ -663,6 +663,19 @@ int mhi_pm_suspend(struct mhi_controller *mhi_cntrl); · 662 unmodified lines
663 */663 */
664int mhi_pm_resume(struct mhi_controller *mhi_cntrl);664int mhi_pm_resume(struct mhi_controller *mhi_cntrl);
665 665
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 */
677int mhi_pm_resume_force(struct mhi_controller *mhi_cntrl);
678
666/**679/**
667 * mhi_download_rddm_image - Download ramdump image from device for680 * mhi_download_rddm_image - Download ramdump image from device for
668 * debugging purpose.681 * debugging purpose.