From ccba394a902e9a076a84f46667a2b2837f772910 Mon Sep 17 00:00:00 2001 From: Sai Chaitanya Kaveti Date: Fri, 15 Dec 2023 14:33:19 +0530 Subject: [PATCH] msm: ep_pcie: Avoid setting host wake pending flag for D0 In current implementation, when host wake request is received in D0 and M3 states, the following sequence of events are happening causing next host wake request from IPA/ client to fail. Sequence of events: 1. Device is in waking up process in D0, M3 states and expecting M0 next. 2. Wake up request received as device in M3. 3. Host wake API is executed setting host_wake_pending flag as well. 4. M0 received as part of wake up from 1. 5. Device in D0, M0 states. 6. Device again went to suspend state as no transfers are happening. 7. Device in D3cold, M3 states 8. Wake up request received from IPA. 9. Host wake API is called again but its returning without any operation as host_wake_pending flag is set. wake toggle is not done. 10. host_wake_pending flag is cleared only on receiving next D0. 11. Host wake requests are failing because of 9. To handle this, avoiding setting of host_wake_pending flag when the host wake request is received in D0 state. Change-Id: I83acde55e6c116653c3ed00e6b4560e3db6390bd Signed-off-by: Sai Chaitanya Kaveti --- drivers/platform/msm/ep_pcie/ep_pcie_core.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/drivers/platform/msm/ep_pcie/ep_pcie_core.c b/drivers/platform/msm/ep_pcie/ep_pcie_core.c index f330e21ac46f..07f605af0254 100644 --- a/drivers/platform/msm/ep_pcie/ep_pcie_core.c +++ b/drivers/platform/msm/ep_pcie/ep_pcie_core.c @@ -3236,8 +3236,10 @@ 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)) + if (atomic_read(&dev->host_wake_pending)) { + EP_PCIE_DBG(dev, "PCIe V%d: Host wake is already pending, returning\n", dev->rev); return 0; + } if (!atomic_read(&dev->perst_deast)) { /*D3 cold handling*/ @@ -3249,12 +3251,14 @@ static int ep_pcie_core_wakeup_host_internal(enum ep_pcie_event event) */ dev->wake_from_d3cold = true; } + atomic_set(&dev->host_wake_pending, 1); } else if (dev->l23_ready) { EP_PCIE_ERR(dev, "PCIe V%d: request to assert WAKE# when in D3hot\n", dev->rev); /*D3 hot handling*/ ep_pcie_core_issue_inband_pme(); + atomic_set(&dev->host_wake_pending, 1); } else { /*D0 handling*/ EP_PCIE_ERR(dev, @@ -3262,7 +3266,6 @@ static int ep_pcie_core_wakeup_host_internal(enum ep_pcie_event event) dev->rev); } - atomic_set(&dev->host_wake_pending, 1); EP_PCIE_DBG(dev, "PCIe V%d: Set wake pending : %d and return ; perst is %s de-asserted; D3hot is %s set\n", dev->rev, atomic_read(&dev->host_wake_pending),