if (!genpd->power_on)
return 0;
+ pr_debug("%s: Power-%s (idle state %d timed %s)\n", genpd->name, "on",
+ state_idx, timed ? "true" : "false");
+
if (!timed)
return genpd->power_on(genpd);
if (!genpd->power_off)
return 0;
+ pr_debug("%s: Power-%s (idle state %d timed %s)\n", genpd->name, "off",
+ state_idx, timed ? "true" : "false");
+
if (!timed)
return genpd->power_off(genpd);
{
struct gpd_link *link;
- if (genpd->status == GPD_STATE_POWER_OFF)
+ /*
+ * 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.
+ * Due to power domain is alway off, so no need to check device wakeup
+ * here anymore
+ */
+
+ genpd->state_idx_saved = genpd->state_idx;
+
+ if (genpd->status == GPD_STATE_POWER_OFF &&
+ genpd->state_idx == (genpd->state_count - 1))
return;
if (genpd->suspended_count != genpd->device_count
genpd->state_idx = genpd->state_count - 1;
genpd_power_off(genpd, false);
+ if (genpd->status == GPD_STATE_POWER_OFF)
+ return;
+
genpd->status = GPD_STATE_POWER_OFF;
list_for_each_entry(link, &genpd->slave_links, slave_node) {
genpd_power_on(genpd, false);
+ /* restore save power domain state after resume */
+ genpd->state_idx = genpd->state_idx_saved;
genpd->status = GPD_STATE_ACTIVE;
}
struct genpd_power_state states[GENPD_MAX_NUM_STATES];
unsigned int state_count; /* number of states */
unsigned int state_idx; /* state that genpd will go to when off */
-
+ 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)