summaryrefslogtreecommitdiff
path: root/drivers/pmdomain
diff options
context:
space:
mode:
authorUlf Hansson <ulf.hansson@linaro.org>2025-11-25 12:26:43 +0100
committerRafael J. Wysocki <rafael.j.wysocki@intel.com>2025-11-25 19:01:29 +0100
commit8e7de6dc420979f4e4443807b71dcc8b72d8c4a9 (patch)
tree173dd1908a95158de1ae0c192addce2ea8a2e36e /drivers/pmdomain
parenta4e6512a79d8486dccf3e8b066e5d6bd5ff95446 (diff)
pmdomain: Respect the CPU system wakeup QoS limit for s2idle
A CPU system wakeup QoS limit may have been requested by user space. To avoid breaking this constraint when entering a low power state during s2idle through genpd, let's extend the corresponding genpd governor for CPUs. More precisely, during s2idle let the genpd governor select a suitable domain idle state, by taking into account the QoS limit. Reviewed-by: Dhruva Gole <d-gole@ti.com> Reviewed-by: Kevin Hilman (TI) <khilman@baylibre.com> Tested-by: Kevin Hilman (TI) <khilman@baylibre.com> Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org> Link: https://patch.msgid.link/20251125112650.329269-3-ulf.hansson@linaro.org Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
Diffstat (limited to 'drivers/pmdomain')
-rw-r--r--drivers/pmdomain/core.c10
-rw-r--r--drivers/pmdomain/governor.c27
2 files changed, 35 insertions, 2 deletions
diff --git a/drivers/pmdomain/core.c b/drivers/pmdomain/core.c
index 61c2277c9ce3..4fd546ef0448 100644
--- a/drivers/pmdomain/core.c
+++ b/drivers/pmdomain/core.c
@@ -1425,8 +1425,14 @@ static void genpd_sync_power_off(struct generic_pm_domain *genpd, bool use_lock,
return;
}
- /* Choose the deepest state when suspending */
- genpd->state_idx = genpd->state_count - 1;
+ if (genpd->gov && genpd->gov->system_power_down_ok) {
+ if (!genpd->gov->system_power_down_ok(&genpd->domain))
+ return;
+ } else {
+ /* Default to the deepest state. */
+ genpd->state_idx = genpd->state_count - 1;
+ }
+
if (_genpd_power_off(genpd, false)) {
genpd->states[genpd->state_idx].rejected++;
return;
diff --git a/drivers/pmdomain/governor.c b/drivers/pmdomain/governor.c
index 39359811a930..bd1b9d66d4a5 100644
--- a/drivers/pmdomain/governor.c
+++ b/drivers/pmdomain/governor.c
@@ -415,9 +415,36 @@ static bool cpu_power_down_ok(struct dev_pm_domain *pd)
return false;
}
+static bool cpu_system_power_down_ok(struct dev_pm_domain *pd)
+{
+ s64 constraint_ns = cpu_wakeup_latency_qos_limit() * NSEC_PER_USEC;
+ struct generic_pm_domain *genpd = pd_to_genpd(pd);
+ int state_idx = genpd->state_count - 1;
+
+ if (!(genpd->flags & GENPD_FLAG_CPU_DOMAIN)) {
+ genpd->state_idx = state_idx;
+ return true;
+ }
+
+ /* Find the deepest state for the latency constraint. */
+ while (state_idx >= 0) {
+ s64 latency_ns = genpd->states[state_idx].power_off_latency_ns +
+ genpd->states[state_idx].power_on_latency_ns;
+
+ if (latency_ns <= constraint_ns) {
+ genpd->state_idx = state_idx;
+ return true;
+ }
+ state_idx--;
+ }
+
+ return false;
+}
+
struct dev_power_governor pm_domain_cpu_gov = {
.suspend_ok = default_suspend_ok,
.power_down_ok = cpu_power_down_ok,
+ .system_power_down_ok = cpu_system_power_down_ok,
};
#endif