From 66689230913bb151d3fb4422923beaa0c503e0ac Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Feb 27 2024 12:06:41 +0000 Subject: Update ath11k hibernation patches for v2 series (bsc#1207948) --- diff --git a/patches.suse/bus-mhi-host-add-mhi_power_down_no_destroy.patch b/patches.suse/bus-mhi-host-add-mhi_power_down_no_destroy.patch index 5fa5ce8..6e12a3e 100644 --- a/patches.suse/bus-mhi-host-add-mhi_power_down_no_destroy.patch +++ b/patches.suse/bus-mhi-host-add-mhi_power_down_no_destroy.patch @@ -1,7 +1,7 @@ From: Baochen Qiang -Subject: [PATCH 1/3] bus: mhi: host: add mhi_power_down_no_destroy() -Date: Wed, 21 Feb 2024 11:00:24 +0800 -Message-id: <20240221030026.10553-2-quic_bqiang@quicinc.com> +Subject: [PATCH v2 1/3] bus: mhi: host: add mhi_power_down_keep_dev() +Date: Tue, 27 Feb 2024 14:36:11 +0800 +Message-ID: <20240227063613.4478-2-quic_bqiang@quicinc.com> Patch-mainline: Submitted, linux-wireless ML References: bsc#1207948 @@ -31,36 +31,21 @@ So what this means that QRTR is not delivering messages and the QMI connection is not working between ath11k and the firmware, resulting a failure in firmware initialization. -To fix this add new function mhi_power_down_no_destroy() which doesn't destroy +To fix this add new function mhi_power_down_keep_dev() which doesn't destroy the devices for channels during power down. This way we avoid probe defer issue and finally can get ath11k hibernation working with the following patches. -Actually there is an RFC version of this change and it gets positive results -from multiple users. Firstly Mani doesn't like this idea and insists that an -MHI device should be destroyed when going to suspend/hibernation, see - -https://lore.kernel.org/mhi/20231127162022.518834-1-kvalo@kernel.org/ - -Then Mani changed his mind after a further discussion with kernel PM guys, -see - -https://lore.kernel.org/all/21cd2098-97e1-4947-a5bb-a97582902ead@quicinc.com/ - -So we come up with the regular version and it is almost identical with that RFC -version. - Tested-on: WCN6855 hw2.0 PCI WLAN.HSP.1.1-03125-QCAHSPSWPL_V1_V2_SILICONZ_LITE-3.6510.30 Signed-off-by: Kalle Valo Signed-off-by: Baochen Qiang Acked-by: Takashi Iwai - --- - drivers/bus/mhi/host/init.c | 1 + - drivers/bus/mhi/host/internal.h | 1 + - drivers/bus/mhi/host/pm.c | 36 ++++++++++++++++++++++++++++++------ - include/linux/mhi.h | 15 ++++++++++++++- - 4 files changed, 46 insertions(+), 7 deletions(-) + drivers/bus/mhi/host/init.c | 1 + drivers/bus/mhi/host/internal.h | 1 + drivers/bus/mhi/host/pm.c | 41 ++++++++++++++++++++++++++++++++++------ + include/linux/mhi.h | 18 ++++++++++++++++- + 4 files changed, 54 insertions(+), 7 deletions(-) --- a/drivers/bus/mhi/host/init.c +++ b/drivers/bus/mhi/host/init.c @@ -84,7 +69,7 @@ Acked-by: Takashi Iwai --- a/drivers/bus/mhi/host/pm.c +++ b/drivers/bus/mhi/host/pm.c -@@ -453,7 +453,8 @@ error_mission_mode: +@@ -458,7 +458,8 @@ error_mission_mode: } /* Handle shutdown transitions */ @@ -94,12 +79,17 @@ Acked-by: Takashi Iwai { enum mhi_pm_state cur_state; struct mhi_event *mhi_event; -@@ -515,8 +516,10 @@ skip_mhi_reset: +@@ -520,8 +521,15 @@ skip_mhi_reset: dev_dbg(dev, "Waiting for all pending threads to complete\n"); wake_up_all(&mhi_cntrl->state_event); - dev_dbg(dev, "Reset all active channels and remove MHI devices\n"); - device_for_each_child(&mhi_cntrl->mhi_dev->dev, NULL, mhi_destroy_device); ++ /** ++ * Some MHI controller drivers, ath11k as an example, would like to keep ++ * MHI deivces for channels during suspend/hibernation to avoid the ++ * probe defer issue. Add a check here to make it possible. ++ */ + if (destroy_device) { + dev_dbg(dev, "Reset all active channels and remove MHI devices\n"); + device_for_each_child(&mhi_cntrl->mhi_dev->dev, NULL, mhi_destroy_device); @@ -107,7 +97,7 @@ Acked-by: Takashi Iwai mutex_lock(&mhi_cntrl->pm_mutex); -@@ -801,7 +804,10 @@ void mhi_pm_st_worker(struct work_struct +@@ -806,7 +814,10 @@ void mhi_pm_st_worker(struct work_struct mhi_pm_sys_error_transition(mhi_cntrl); break; case DEV_ST_TRANSITION_DISABLE: @@ -119,7 +109,7 @@ Acked-by: Takashi Iwai break; default: break; -@@ -1154,7 +1160,8 @@ error_exit: +@@ -1160,7 +1171,8 @@ error_exit: } EXPORT_SYMBOL_GPL(mhi_async_power_up); @@ -129,7 +119,7 @@ Acked-by: Takashi Iwai { enum mhi_pm_state cur_state, transition_state; struct device *dev = &mhi_cntrl->mhi_dev->dev; -@@ -1190,15 +1197,32 @@ void mhi_power_down(struct mhi_controlle +@@ -1196,15 +1208,32 @@ void mhi_power_down(struct mhi_controlle write_unlock_irq(&mhi_cntrl->pm_lock); mutex_unlock(&mhi_cntrl->pm_mutex); @@ -153,41 +143,44 @@ Acked-by: Takashi Iwai +} EXPORT_SYMBOL_GPL(mhi_power_down); -+void mhi_power_down_no_destroy(struct mhi_controller *mhi_cntrl, ++void mhi_power_down_keep_dev(struct mhi_controller *mhi_cntrl, + bool graceful) +{ + __mhi_power_down(mhi_cntrl, graceful, false); +} -+EXPORT_SYMBOL_GPL(mhi_power_down_no_destroy); ++EXPORT_SYMBOL_GPL(mhi_power_down_keep_dev); + int mhi_sync_power_up(struct mhi_controller *mhi_cntrl) { int ret = mhi_async_power_up(mhi_cntrl); --- a/include/linux/mhi.h +++ b/include/linux/mhi.h -@@ -645,13 +645,26 @@ int mhi_async_power_up(struct mhi_contro +@@ -649,13 +649,29 @@ int mhi_async_power_up(struct mhi_contro int mhi_sync_power_up(struct mhi_controller *mhi_cntrl); /** - * mhi_power_down - Start MHI power down sequence -+ * mhi_power_down - Start MHI power down sequence. See also -+ * mhi_power_down_no_destroy() which is a variant of this for -+ * suspend/hibernation. -+ * ++ * mhi_power_down - Power down the MHI device and also destroy the ++ * 'struct device' for the channels associated with it. ++ * See also mhi_power_down_keep_dev() which is a variant ++ * of this API that keeps the 'struct device' for channels ++ * (useful during suspend/hibernation). * @mhi_cntrl: MHI controller * @graceful: Link is still accessible, so do a graceful shutdown process */ void mhi_power_down(struct mhi_controller *mhi_cntrl, bool graceful); /** -+ * mhi_power_down_no_destroy - Start MHI power down sequence but don't destroy -+ * struct devices for channels. This is a variant for mhi_power_down() and -+ * would be useful in suspend/hibernation. -+ * ++ * mhi_power_down_keep_dev - Power down the MHI device but keep the 'struct ++ * device' for the channels associated with it. ++ * This is a variant of 'mhi_power_down()' and ++ * useful in scenarios such as suspend/hibernation ++ * where destroying of the 'struct device' is not ++ * needed. + * @mhi_cntrl: MHI controller + * @graceful: Link is still accessible, so do a graceful shutdown process + */ -+void mhi_power_down_no_destroy(struct mhi_controller *mhi_cntrl, bool graceful); ++void mhi_power_down_keep_dev(struct mhi_controller *mhi_cntrl, bool graceful); + +/** * mhi_unprepare_after_power_down - Free any allocated memory after power down diff --git a/patches.suse/net-qrtr-support-suspend-hibernation.patch b/patches.suse/net-qrtr-support-suspend-hibernation.patch index fbf76d1..8f798cb 100644 --- a/patches.suse/net-qrtr-support-suspend-hibernation.patch +++ b/patches.suse/net-qrtr-support-suspend-hibernation.patch @@ -1,49 +1,35 @@ From: Baochen Qiang -Subject: [PATCH 2/3] net: qrtr: support suspend/hibernation -Date: Wed, 21 Feb 2024 11:00:25 +0800 -Message-id: <20240221030026.10553-3-quic_bqiang@quicinc.com> +Subject: [PATCH v2 2/3] net: qrtr: support suspend/hibernation +Date: Tue, 27 Feb 2024 14:36:12 +0800 +Message-ID: <20240227063613.4478-3-quic_bqiang@quicinc.com> Patch-mainline: Submitted, linux-wireless ML References: bsc#1207948 MHI devices may not be destroyed during suspend/hibernation, so need -to unprepare/prepare MHI channels throughout the transition. +to unprepare/prepare MHI channels throughout the transition, this is +done by adding suspend/resume callbacks. -The RFC version adds new API to MHI stack with which an MHI controller -driver can do unprepare/prepare directly by itself, see - -https://patchwork.kernel.org/project/linux-wireless/patch/20231127162022.518834-3-kvalo@kernel.org/ - -Although it works well Mani pointed out that the design is not good -because MHI channels are managed by MHI client driver thus should not -be touched by others. See the discussion - -https://lore.kernel.org/mhi/20231127162022.518834-1-kvalo@kernel.org/ - -This version changes to add suspend/resume callbacks to achieve the -same purpose. The suspend callback is called in the late suspend stage, -this means MHI channels are still alive at suspend stage, and that makes -it possible for an MHI controller driver to communicate with others over -those channels at suspend stage. While the resume callback is called in -the early resume stage, for a similar reason. +The suspend callback is called in the late suspend stage, this means +MHI channels are still alive at suspend stage, and that makes it +possible for an MHI controller driver to communicate with others over +those channels at suspend stage. While the resume callback is called +in the early resume stage, for a similar reason. Tested-on: WCN6855 hw2.0 PCI WLAN.HSP.1.1-03125-QCAHSPSWPL_V1_V2_SILICONZ_LITE-3.6510.30 Signed-off-by: Baochen Qiang Acked-by: Takashi Iwai - --- - net/qrtr/mhi.c | 29 +++++++++++++++++++++++++++++ - 1 file changed, 29 insertions(+) + net/qrtr/mhi.c | 27 +++++++++++++++++++++++++++ + 1 file changed, 27 insertions(+) -diff --git a/net/qrtr/mhi.c b/net/qrtr/mhi.c -index 9ced13c0627a..b54a6c2113e9 100644 --- a/net/qrtr/mhi.c +++ b/net/qrtr/mhi.c -@@ -118,6 +118,32 @@ static const struct mhi_device_id qcom_mhi_qrtr_id_table[] = { +@@ -118,6 +118,32 @@ static const struct mhi_device_id qcom_m }; MODULE_DEVICE_TABLE(mhi, qcom_mhi_qrtr_id_table); -+static int qcom_mhi_qrtr_pm_suspend_late(struct device *dev) ++static int __maybe_unused qcom_mhi_qrtr_pm_suspend_late(struct device *dev) +{ + struct mhi_device *mhi_dev = container_of(dev, struct mhi_device, dev); + @@ -52,7 +38,7 @@ index 9ced13c0627a..b54a6c2113e9 100644 + return 0; +} + -+static int qcom_mhi_qrtr_pm_resume_early(struct device *dev) ++static int __maybe_unused qcom_mhi_qrtr_pm_resume_early(struct device *dev) +{ + struct mhi_device *mhi_dev = container_of(dev, struct mhi_device, dev); + int rc; @@ -64,7 +50,7 @@ index 9ced13c0627a..b54a6c2113e9 100644 + return rc; +} + -+static const struct dev_pm_ops __maybe_unused qcom_mhi_qrtr_pm_ops = { ++static const struct dev_pm_ops qcom_mhi_qrtr_pm_ops = { + SET_LATE_SYSTEM_SLEEP_PM_OPS(qcom_mhi_qrtr_pm_suspend_late, + qcom_mhi_qrtr_pm_resume_early) +}; @@ -72,17 +58,11 @@ index 9ced13c0627a..b54a6c2113e9 100644 static struct mhi_driver qcom_mhi_qrtr_driver = { .probe = qcom_mhi_qrtr_probe, .remove = qcom_mhi_qrtr_remove, -@@ -126,6 +152,9 @@ static struct mhi_driver qcom_mhi_qrtr_driver = { +@@ -126,6 +152,7 @@ static struct mhi_driver qcom_mhi_qrtr_d .id_table = qcom_mhi_qrtr_id_table, .driver = { .name = "qcom_mhi_qrtr", -+#ifdef CONFIG_PM + .pm = &qcom_mhi_qrtr_pm_ops, -+#endif }, }; --- -2.25.1 - - diff --git a/patches.suse/wifi-ath11k-support-hibernation.patch b/patches.suse/wifi-ath11k-support-hibernation.patch index 81406aa..caf385f 100644 --- a/patches.suse/wifi-ath11k-support-hibernation.patch +++ b/patches.suse/wifi-ath11k-support-hibernation.patch @@ -1,7 +1,7 @@ From: Baochen Qiang -Subject: [PATCH 3/3] wifi: ath11k: support hibernation -Date: Wed, 21 Feb 2024 11:00:26 +0800 -Message-id: <20240221030026.10553-4-quic_bqiang@quicinc.com> +Subject: [PATCH v2 3/3] wifi: ath11k: support hibernation +Date: Tue, 27 Feb 2024 14:36:13 +0800 +Message-ID: <20240227063613.4478-4-quic_bqiang@quicinc.com> Patch-mainline: Submitted, linux-wireless ML References: bsc#1207948 @@ -43,7 +43,6 @@ Tested-by: Takashi Iwai Signed-off-by: Kalle Valo Signed-off-by: Baochen Qiang Acked-by: Takashi Iwai - --- drivers/net/wireless/ath/ath11k/ahb.c | 6 - drivers/net/wireless/ath/ath11k/core.c | 105 +++++++++++++++++++++++---------- @@ -340,12 +339,12 @@ Acked-by: Takashi Iwai +void ath11k_mhi_stop(struct ath11k_pci *ab_pci, bool is_suspend) { - mhi_power_down(ab_pci->mhi_ctrl, true); -+ /* During suspend we need to use mhi_power_down_no_destroy() ++ /* During suspend we need to use mhi_power_down_keep_dev() + * workaround, otherwise ath11k_core_resume() will timeout + * during resume. + */ + if (is_suspend) -+ mhi_power_down_no_destroy(ab_pci->mhi_ctrl, true); ++ mhi_power_down_keep_dev(ab_pci->mhi_ctrl, true); + else + mhi_power_down(ab_pci->mhi_ctrl, true); +