PM / Domains: Support enter deepest state for multiple states domains
Currently the generic power domain will power off the domain if all devices in it have been stopped during system suspend. It is done by checking if the domain is active in genpd_sync_power_off, then disable it. However, for power domains supporting multiple low power states, it may have already entered an intermediate low power state by runtime PM before system suspend and the status is already GPD_STATE_POWER_OFF which results in then the power domain stay at an intermediate low power state during system suspend. Then genpd_sync_power_off will keep it at the low power state instead of completely gate off it. Let's give the power domain a chance to switch to the deepest state in case it's already off but in an intermediate low power state. Signed-off-by: Dong Aisheng <aisheng.dong@nxp.com>
This commit is contained in:
parent
070d55393a
commit
f93257d4e4
|
@ -957,7 +957,17 @@ static void genpd_sync_power_off(struct generic_pm_domain *genpd, bool use_lock,
|
|||
{
|
||||
struct gpd_link *link;
|
||||
|
||||
if (!genpd_status_on(genpd) || genpd_is_always_on(genpd))
|
||||
/*
|
||||
* Give the power domain a chance to switch to the deepest state in
|
||||
* case it's already off but in an intermediate low power state.
|
||||
*/
|
||||
genpd->state_idx_saved = genpd->state_idx;
|
||||
|
||||
if (genpd_is_always_on(genpd))
|
||||
return;
|
||||
|
||||
if (!genpd_status_on(genpd) &&
|
||||
genpd->state_idx == (genpd->state_count - 1))
|
||||
return;
|
||||
|
||||
if (genpd->suspended_count != genpd->device_count)
|
||||
|
@ -968,6 +978,9 @@ static void genpd_sync_power_off(struct generic_pm_domain *genpd, bool use_lock,
|
|||
if (_genpd_power_off(genpd, false))
|
||||
return;
|
||||
|
||||
if (genpd->status == GPD_STATE_POWER_OFF)
|
||||
return;
|
||||
|
||||
genpd->status = GPD_STATE_POWER_OFF;
|
||||
|
||||
list_for_each_entry(link, &genpd->slave_links, slave_node) {
|
||||
|
@ -1015,6 +1028,9 @@ static void genpd_sync_power_on(struct generic_pm_domain *genpd, bool use_lock,
|
|||
|
||||
_genpd_power_on(genpd, false);
|
||||
|
||||
/* restore save power domain state after resume */
|
||||
genpd->state_idx = genpd->state_idx_saved;
|
||||
|
||||
genpd->status = GPD_STATE_ACTIVE;
|
||||
}
|
||||
|
||||
|
|
|
@ -143,6 +143,7 @@ struct generic_pm_domain {
|
|||
};
|
||||
};
|
||||
|
||||
unsigned int state_idx_saved; /* saved power state for recovery after system suspend/resume */
|
||||
};
|
||||
|
||||
static inline struct generic_pm_domain *pd_to_genpd(struct dev_pm_domain *pd)
|
||||
|
|
Loading…
Reference in New Issue