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

Commit 554cd52a authored by Mukesh Kumar Savaliya's avatar Mukesh Kumar Savaliya
Browse files

i3c: i3c-master-qcom-geni: Manage driver suspend in late PM stage



While executing suspend_noirq callbacks non-wakeup interrupts are
disabled, wake-up interrupts are enabled but their handling is
deferred till the completion of suspend_noirq stage and gets handled
when resume starts again immediately after suspend_late.

GENI I3C driver unvotes the resources in the suspend_noirq stage.
There is no issue wrt managing clk and pinctrl resources at noirq
tage however ICC BW voting can't be done at noirq stage.

ICC request to RPM needs an ACK from RPM driver, the ack here is
nothing but interrupt from IPCC driver and it can't be processed
at noirq stage, hence flow is indefinitely stuck in I3C suspend_noirq
callback.

This issue primarily occurs for platforms using IPCC driver but  also
there is no harm making driver to suspend during late suspend. This is
by design of all buses drivers for now.

Change-Id: Icdbba72f431da321a3343364400c180f325ac369
Signed-off-by: default avatarMukesh Kumar Savaliya <msavaliy@codeaurora.org>
parent 1f9fc6d2
Loading
Loading
Loading
Loading
+9 −5
Original line number Diff line number Diff line
@@ -2164,7 +2164,7 @@ static int geni_i3c_remove(struct platform_device *pdev)
	return ret;
}

static int geni_i3c_resume_noirq(struct device *dev)
static int geni_i3c_resume_early(struct device *dev)
{
	return 0;
}
@@ -2194,9 +2194,13 @@ static int geni_i3c_runtime_resume(struct device *dev)
	return 0;
}

static int geni_i3c_suspend_noirq(struct device *dev)
static int geni_i3c_suspend_late(struct device *dev)
{
	struct geni_i3c_dev *gi3c = dev_get_drvdata(dev);

	if (!pm_runtime_status_suspended(dev)) {
		GENI_SE_DBG(gi3c->ipcl, false, gi3c->se.dev,
				"%s: Forced suspend\n", __func__);
		geni_i3c_runtime_suspend(dev);
		pm_runtime_disable(dev);
		pm_runtime_put_noidle(dev);
@@ -2216,15 +2220,15 @@ static int geni_i3c_runtime_resume(struct device *dev)
	return 0;
}

static int geni_i3c_suspend_noirq(struct device *dev)
static int geni_i3c_suspend_late(struct device *dev)
{
	return 0;
}
#endif

static const struct dev_pm_ops geni_i3c_pm_ops = {
	.suspend_noirq = geni_i3c_suspend_noirq,
	.resume_noirq = geni_i3c_resume_noirq,
	.suspend_late = geni_i3c_suspend_late,
	.resume_early = geni_i3c_resume_early,
	.runtime_suspend = geni_i3c_runtime_suspend,
	.runtime_resume  = geni_i3c_runtime_resume,
};