From d62bca7bf4f05954fd7006f79d166b7be1d27bff Mon Sep 17 00:00:00 2001 From: Qiang Yu Date: Fri, 28 Jul 2023 09:46:33 +0800 Subject: [PATCH] msm: ep_pcie: Prevent repetitive wake operation if wake is in process Sometimes, device receives two consecutive wake-up events, added into a workqueue. Then device assert WAKE# and host deassert PERST# if device in D3cold state, triggering deassert perst IRQ. In IRQ thread, device flush the workqueue to make sure previous d3cold process has completed before enable endpoint. commit 43917f862f7d ("msm: mhi_dev: Flush workqueue before processing PERST deassert"). However, the second wake event is also in the workqueue, so ep_pcie_core_wakeup_host_internal is invoked and seeing dev->perst_deast is true, setted by deassert PERST# IRQ. Then device goes to access MHI register to issue inband PME, leading to NOC error because endpoint is still disabled. So add a check to prevent wake operation if a previous wake has completed. 10567.834470: [0x8219195 mhi_sm_dev_event_manager] Handling MHI_DEV_EVENT_CORE_WAKEUP event, current states: M3 & D3_COLD_STATE 10567.834498: ep_pcie_core_toggle_wake_gpio: PCIe V1711211: No. 115 to assert PCIe WAKE#; perst is asserted; D3hot is received, WAKE GPIO state:0 10567.834507: ep_pcie_core_wakeup_host_internal: PCIe V1711211: Set wake pending : 1 and return ; perst is not de-asserted; D3hot is set 10567.849704: [0x8219195 mhi_dev_notify_sm_event] received: MHI_DEV_EVENT_HW_ACC_WAKEUP 10567.849976: ep_pcie_handle_perst_irq: PCIe V1711211: No. 1018 PERST deassertion 10567.850053: [0x8219195 mhi_sm_dev_event_manager] Handling MHI_DEV_EVENT_HW_ACC_WAKEUP event, current states: M3 & D3_COLD_STATE 10567.850071: ep_pcie_core_wakeup_host_internal: PCIe V1711211: request to assert WAKE# when in D3hot 10567.860093: ep_pcie_core_issue_inband_pme: PCIe V1711211: request to assert inband wake. Change-Id: I85fb37c4171c5ef4974c573f0abba199cb718a84 Signed-off-by: Qiang Yu --- drivers/platform/msm/ep_pcie/ep_pcie_core.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/platform/msm/ep_pcie/ep_pcie_core.c b/drivers/platform/msm/ep_pcie/ep_pcie_core.c index d0b8e3f386a3..f330e21ac46f 100644 --- a/drivers/platform/msm/ep_pcie/ep_pcie_core.c +++ b/drivers/platform/msm/ep_pcie/ep_pcie_core.c @@ -3236,6 +3236,9 @@ static int ep_pcie_core_wakeup_host_internal(enum ep_pcie_event event) { struct ep_pcie_dev_t *dev = &ep_pcie_dev; + if (atomic_read(&dev->host_wake_pending)) + return 0; + if (!atomic_read(&dev->perst_deast)) { /*D3 cold handling*/ ep_pcie_core_toggle_wake_gpio(true);