From d68dc25527bc0a0cfaa7a3f8150a15e300f15357 Mon Sep 17 00:00:00 2001 From: Elaine Zhang Date: Thu, 12 Jan 2017 16:12:31 +0800 Subject: [PATCH] PM / Domains: Keep the pd status during system PM phases If a PM domain is powered off before system suspend, we hope do nothing in system runtime suspend noirq phase and system runtime resume noirq phase. Change-Id: Id72b1f92e10449c48006aced0d49612637402210 Signed-off-by: Elaine Zhang --- drivers/base/power/domain.c | 10 +++++++--- include/linux/pm_domain.h | 1 + 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/drivers/base/power/domain.c b/drivers/base/power/domain.c index bf5be0bfaf77..376ac78bcc82 100644 --- a/drivers/base/power/domain.c +++ b/drivers/base/power/domain.c @@ -1003,8 +1003,10 @@ static int genpd_prepare(struct device *dev) genpd_lock(genpd); - if (genpd->prepared_count++ == 0) + if (genpd->prepared_count++ == 0) { genpd->suspended_count = 0; + genpd->suspend_power_off = genpd->status == GPD_STATE_POWER_OFF; + } genpd_unlock(genpd); @@ -1046,7 +1048,8 @@ static int genpd_finish_suspend(struct device *dev, bool poweroff) if (ret) return ret; - if (dev->power.wakeup_path && genpd_is_active_wakeup(genpd)) + if (genpd->suspend_power_off || + (dev->power.wakeup_path && genpd_is_active_wakeup(genpd))) return 0; if (genpd->dev_ops.stop && genpd->dev_ops.start && @@ -1100,7 +1103,8 @@ static int genpd_resume_noirq(struct device *dev) if (IS_ERR(genpd)) return -EINVAL; - if (dev->power.wakeup_path && genpd_is_active_wakeup(genpd)) + if (genpd->suspend_power_off || + (dev->power.wakeup_path && genpd_is_active_wakeup(genpd))) return pm_generic_resume_noirq(dev); genpd_lock(genpd); diff --git a/include/linux/pm_domain.h b/include/linux/pm_domain.h index 776c546d581a..0970e3f34a1e 100644 --- a/include/linux/pm_domain.h +++ b/include/linux/pm_domain.h @@ -67,6 +67,7 @@ struct generic_pm_domain { unsigned int suspended_count; /* System suspend device counter */ unsigned int prepared_count; /* Suspend counter of prepared devices */ unsigned int performance_state; /* Aggregated max performance state */ + bool suspend_power_off; /* Power status before system suspend */ int (*power_off)(struct generic_pm_domain *domain); int (*power_on)(struct generic_pm_domain *domain); unsigned int (*opp_to_performance_state)(struct generic_pm_domain *genpd,