From 4966230ae8ebdcdce177c1e45fee63fa62078d4c Mon Sep 17 00:00:00 2001 From: Gauri Joshi Date: Fri, 14 Aug 2020 12:31:57 +0530 Subject: [PATCH] msm: ep_pcie: Acquire wakelock as part of D0 event During bootup scenario, there will not be any PERST de-assert interrupt. So if host send mhi suspend event followed by D3 hot and D0 event, then the PCIE link will be in an enabled state but there will not be any wake lock to prevent system suspend scenario. To prevent the above scenario we will acquire wakelock as part of D0 during bootup scenario and from PERST-deassert for subsequent cases. The change also involves to prevent system suspend if there is PERST de-assertion during system suspend scenario. Registering for suspend_noirq(), as this guarantees that there can be no wakeup interrupts(PERST assertion) during this call. Change-Id: I19051df46cc8353492e34175a47665ab89dc86af Signed-off-by: Subramanian Ananthanarayanan Signed-off-by: Gauri Joshi --- drivers/platform/msm/ep_pcie/ep_pcie_core.c | 43 +++++++++++++++++++++ 1 file changed, 43 insertions(+) diff --git a/drivers/platform/msm/ep_pcie/ep_pcie_core.c b/drivers/platform/msm/ep_pcie/ep_pcie_core.c index 7e4f8bcecf4f..be8d1f5d644f 100644 --- a/drivers/platform/msm/ep_pcie/ep_pcie_core.c +++ b/drivers/platform/msm/ep_pcie/ep_pcie_core.c @@ -2208,6 +2208,16 @@ static irqreturn_t ep_pcie_handle_dstate_change_irq(int irq, void *data) EP_PCIE_DBG(dev, "PCIe V%d: No. %ld change to D0 state\n", dev->rev, dev->d0_counter); + /* + * During device bootup, there will not be any PERT-deassert, + * so aquire wakelock from D0 event + */ + if (!atomic_read(&dev->ep_pcie_dev_wake)) { + pm_stay_awake(&dev->pdev->dev); + atomic_set(&dev->ep_pcie_dev_wake, 1); + EP_PCIE_DBG(dev, "PCIe V%d: Acquired wakelock in D0\n", + dev->rev); + } ep_pcie_notify_event(dev, EP_PCIE_EVENT_PM_D0); } else { EP_PCIE_ERR(dev, @@ -3334,11 +3344,44 @@ static const struct of_device_id ep_pcie_match[] = { {} }; +static int ep_pcie_suspend_noirq(struct device *pdev) +{ + struct ep_pcie_dev_t *dev = &ep_pcie_dev; + + + /* Allow suspend if autonomous M2 is enabled */ + if (dev->m2_autonomous) { + EP_PCIE_DBG(dev, + "PCIe V%d: Autonomous M2 is enabled, allow suspend\n", + dev->rev); + return 0; + } + + /* Allow suspend only after D3 cold is received */ + if (atomic_read(&dev->perst_deast)) { + EP_PCIE_DBG(dev, + "PCIe V%d: Perst not asserted, fail suspend\n", + dev->rev); + return -EBUSY; + } + + EP_PCIE_DBG(dev, + "PCIe V%d: Perst asserted, allow suspend\n", + dev->rev); + + return 0; +} + +static const struct dev_pm_ops ep_pcie_pm_ops = { + .suspend_noirq = ep_pcie_suspend_noirq, +}; + static struct platform_driver ep_pcie_driver = { .probe = ep_pcie_probe, .remove = ep_pcie_remove, .driver = { .name = "pcie-ep", + .pm = &ep_pcie_pm_ops, .of_match_table = ep_pcie_match, }, };