Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 4966230a authored by Gauri Joshi's avatar Gauri Joshi
Browse files

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: default avatarSubramanian Ananthanarayanan <skananth@codeaurora.org>
Signed-off-by: default avatarGauri Joshi <gaurjosh@codeaurora.org>
parent 1e18bf1c
Loading
Loading
Loading
Loading
+43 −0
Original line number Diff line number Diff line
@@ -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,
	},
};