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
Unified · Split
| @@ -881,7 +881,7 @@ int mhi_pm_suspend(struct mhi_controller *mhi_cntrl) · 880 unmodified lines | ||
| 881 | 881 | } |
| 882 | 882 | EXPORT_SYMBOL_GPL(mhi_pm_suspend); |
| 883 | 883 | |
| 884 | −int mhi_pm_resume(struct mhi_controller *mhi_cntrl) | |
| 884 | +static int __mhi_pm_resume(struct mhi_controller *mhi_cntrl, bool force) | |
| 885 | 885 | { |
| 886 | 886 | struct mhi_chan *itr, *tmp; |
| 887 | 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 | 898 | if (MHI_PM_IN_ERROR_STATE(mhi_cntrl->pm_state)) |
| 899 | 899 | return -EIO; |
| 900 | 900 | |
| 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 | + } | |
| 903 | 907 | |
| 904 | 908 | /* Notify clients about exiting LPM */ |
| 905 | 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 | 945 | return 0; |
| 942 | 946 | } |
| 947 | + | |
| 948 | +int mhi_pm_resume(struct mhi_controller *mhi_cntrl) | |
| 949 | +{ | |
| 950 | + return __mhi_pm_resume(mhi_cntrl, false); | |
| 951 | +} | |
| 943 | 952 | EXPORT_SYMBOL_GPL(mhi_pm_resume); |
| 944 | 953 | |
| 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 | + | |
| 945 | 960 | int __mhi_device_get_sync(struct mhi_controller *mhi_cntrl) |
| 946 | 961 | { |
| 947 | 962 | int ret; |
| @@ -533,7 +533,11 @@ static int ath11k_mhi_set_state(struct ath11k_pci *ab_pci, · 532 unmodified lines | ||
| 533 | 533 | ret = mhi_pm_suspend(ab_pci->mhi_ctrl); |
| 534 | 534 | break; |
| 535 | 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 | 541 | break; |
| 538 | 542 | case ATH11K_MHI_TRIGGER_RDDM: |
| 539 | 543 | ret = mhi_force_rddm_mode(ab_pci->mhi_ctrl); |
| @@ -663,6 +663,19 @@ int mhi_pm_suspend(struct mhi_controller *mhi_cntrl); · 662 unmodified lines | ||
| 663 | 663 | */ |
| 664 | 664 | int 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 | + */ | |
| 677 | +int mhi_pm_resume_force(struct mhi_controller *mhi_cntrl); | |
| 678 | + | |
| 666 | 679 | /** |
| 667 | 680 | * mhi_download_rddm_image - Download ramdump image from device for |
| 668 | 681 | * debugging purpose. |