Commit b9c532c1 authored by Alex Elder's avatar Alex Elder Committed by David S. Miller
Browse files

net: ipa: distinguish system from runtime suspend



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: default avatarAlex Elder <elder@linaro.org>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent d430fe4b
Loading
Loading
Loading
Loading
+31 −7
Original line number Diff line number Diff line
@@ -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,11 +322,12 @@ 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))
	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 */
@@ -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,