diff --git a/drivers/base/power/domain.c b/drivers/base/power/domain.c index 4a55f3c949ae..f209607e6eb5 100644 --- a/drivers/base/power/domain.c +++ b/drivers/base/power/domain.c @@ -1748,6 +1748,24 @@ int dev_pm_genpd_remove_notifier(struct device *dev) } EXPORT_SYMBOL_GPL(dev_pm_genpd_remove_notifier); +/** + * genpd_enable_next_wakeup - Enable genpd gov to use next_wakeup + * + * @genpd: The genpd to be updated + * @enable: Enable/disable genpd gov to use next wakeup + */ +void genpd_enable_next_wakeup(struct generic_pm_domain *genpd, bool enable) +{ + genpd_lock(genpd); + if (enable) + genpd->flags |= GENPD_FLAG_GOV_NEXT_WAKEUP; + else + genpd->flags &= ~GENPD_FLAG_GOV_NEXT_WAKEUP; + genpd->next_wakeup = KTIME_MAX; + genpd_unlock(genpd); +} +EXPORT_SYMBOL_GPL(genpd_enable_next_wakeup); + static int genpd_add_subdomain(struct generic_pm_domain *genpd, struct generic_pm_domain *subdomain) { diff --git a/include/linux/pm_domain.h b/include/linux/pm_domain.h index a8f93328daec..138c2704a3e0 100644 --- a/include/linux/pm_domain.h +++ b/include/linux/pm_domain.h @@ -55,13 +55,19 @@ * * GENPD_FLAG_RPM_ALWAYS_ON: Instructs genpd to always keep the PM domain * powered on except for system suspend. + * + * GENPD_FLAG_GOV_NEXT_WAKEUP: Enable the genpd governor to consider its + * components' next wakeup when determining the + * optimal idle state. This is setup only if the + * domain's idle state specifies a residency. */ -#define GENPD_FLAG_PM_CLK (1U << 0) -#define GENPD_FLAG_IRQ_SAFE (1U << 1) -#define GENPD_FLAG_ALWAYS_ON (1U << 2) -#define GENPD_FLAG_ACTIVE_WAKEUP (1U << 3) -#define GENPD_FLAG_CPU_DOMAIN (1U << 4) -#define GENPD_FLAG_RPM_ALWAYS_ON (1U << 5) +#define GENPD_FLAG_PM_CLK (1U << 0) +#define GENPD_FLAG_IRQ_SAFE (1U << 1) +#define GENPD_FLAG_ALWAYS_ON (1U << 2) +#define GENPD_FLAG_ACTIVE_WAKEUP (1U << 3) +#define GENPD_FLAG_CPU_DOMAIN (1U << 4) +#define GENPD_FLAG_RPM_ALWAYS_ON (1U << 5) +#define GENPD_FLAG_GOV_NEXT_WAKEUP (1U << 6) enum gpd_status { GENPD_STATE_ON = 0, /* PM domain is on */ @@ -205,6 +211,11 @@ static inline struct generic_pm_domain_data *dev_gpd_data(struct device *dev) return to_gpd_data(dev->power.subsys_data->domain_data); } +static inline bool genpd_may_use_next_wakeup(struct generic_pm_domain *genpd) +{ + return genpd->flags & GENPD_FLAG_GOV_NEXT_WAKEUP; +} + int pm_genpd_add_device(struct generic_pm_domain *genpd, struct device *dev); int pm_genpd_remove_device(struct device *dev); int pm_genpd_add_subdomain(struct generic_pm_domain *genpd, @@ -217,6 +228,7 @@ int pm_genpd_remove(struct generic_pm_domain *genpd); int dev_pm_genpd_set_performance_state(struct device *dev, unsigned int state); int dev_pm_genpd_add_notifier(struct device *dev, struct notifier_block *nb); int dev_pm_genpd_remove_notifier(struct device *dev); +void genpd_enable_next_wakeup(struct generic_pm_domain *genpd, bool enable); extern struct dev_power_governor simple_qos_governor; extern struct dev_power_governor pm_domain_always_on_gov; @@ -275,6 +287,10 @@ static inline int dev_pm_genpd_remove_notifier(struct device *dev) return -ENOTSUPP; } +static void genpd_enable_next_wakeup(struct generic_pm_domain *genpd, + bool enable) +{ } + #define simple_qos_governor (*(struct dev_power_governor *)(NULL)) #define pm_domain_always_on_gov (*(struct dev_power_governor *)(NULL)) #endif