[PATCH net-next 2/6] net: ipa: distinguish system from runtime suspend
flat view
STALE1879d
From: Alex Elder <hidden>
Date: 2021-08-12 19:50:53
Also in:
lkml
Subsystem:
networking drivers, qcom ipa driver, the rest · Maintainers:
Andrew Lunn, "David S. Miller", Eric Dumazet, Jakub Kicinski, Paolo Abeni, Alex Elder, Linus Torvalds
Add a new flag that is set when the hardware is suspended due to a system suspend operation, distingishing it from runtime suspend. Use it in the SUSPEND IPA interrupt handler to determine whether to trigger a system resume because of the event. Define new suspend and resume power management callback functions to set and clear the new flag, respectively. Signed-off-by: Alex Elder <redacted> --- drivers/net/ipa/ipa_clock.c | 38 ++++++++++++++++++++++++++++++------- 1 file changed, 31 insertions(+), 7 deletions(-)
diff --git a/drivers/net/ipa/ipa_clock.c b/drivers/net/ipa/ipa_clock.c
index cdbaba6618e9e..8f25107c1f1e7 100644
--- a/drivers/net/ipa/ipa_clock.c
+++ b/drivers/net/ipa/ipa_clock.c@@ -47,10 +47,12 @@ struct ipa_interconnect { /** * enum ipa_power_flag - IPA power flags * @IPA_POWER_FLAG_RESUMED: Whether resume from suspend has been signaled + * @IPA_POWER_FLAG_SYSTEM: Hardware is system (not runtime) suspended * @IPA_POWER_FLAG_COUNT: Number of defined power flags */ enum ipa_power_flag { IPA_POWER_FLAG_RESUMED, + IPA_POWER_FLAG_SYSTEM, IPA_POWER_FLAG_COUNT, /* Last; not a flag */ };
@@ -281,6 +283,27 @@ int ipa_clock_put(struct ipa *ipa) return pm_runtime_put(&ipa->pdev->dev); } +static int ipa_suspend(struct device *dev) +{ + struct ipa *ipa = dev_get_drvdata(dev); + + __set_bit(IPA_POWER_FLAG_SYSTEM, ipa->clock->flags); + + return pm_runtime_force_suspend(dev); +} + +static int ipa_resume(struct device *dev) +{ + struct ipa *ipa = dev_get_drvdata(dev); + int ret; + + ret = pm_runtime_force_resume(dev); + + __clear_bit(IPA_POWER_FLAG_SYSTEM, ipa->clock->flags); + + return ret; +} + /* Return the current IPA core clock rate */ u32 ipa_clock_rate(struct ipa *ipa) {
@@ -299,12 +322,13 @@ u32 ipa_clock_rate(struct ipa *ipa) */ static void ipa_suspend_handler(struct ipa *ipa, enum ipa_irq_id irq_id) { - /* Just report the event, and let system resume handle the rest. - * More than one endpoint could signal this; if so, ignore - * all but the first. + /* To handle an IPA interrupt we will have resumed the hardware + * just to handle the interrupt, so we're done. If we are in a + * system suspend, trigger a system resume. */ - if (!test_and_set_bit(IPA_POWER_FLAG_RESUMED, ipa->clock->flags)) - pm_wakeup_dev_event(&ipa->pdev->dev, 0, true); + if (!__test_and_set_bit(IPA_POWER_FLAG_RESUMED, ipa->clock->flags)) + if (test_bit(IPA_POWER_FLAG_SYSTEM, ipa->clock->flags)) + pm_wakeup_dev_event(&ipa->pdev->dev, 0, true); /* Acknowledge/clear the suspend interrupt on all endpoints */ ipa_interrupt_suspend_clear_all(ipa->interrupt);
@@ -390,8 +414,8 @@ void ipa_clock_exit(struct ipa_clock *clock) } const struct dev_pm_ops ipa_pm_ops = { - .suspend = pm_runtime_force_suspend, - .resume = pm_runtime_force_resume, + .suspend = ipa_suspend, + .resume = ipa_resume, .runtime_suspend = ipa_runtime_suspend, .runtime_resume = ipa_runtime_resume, .runtime_idle = ipa_runtime_idle,
--
2.27.0