From ba1e78a1dc0ca3e92f0be82279e6ba24177af7d6 Mon Sep 17 00:00:00 2001 From: "Rafael J. Wysocki" Date: Thu, 21 Nov 2019 19:41:51 +0100 Subject: cpuidle: Drop disabled field from struct cpuidle_state After recent cpuidle updates the "disabled" field in struct cpuidle_state is only used by two drivers (intel_idle and shmobile cpuidle) for marking unusable idle states, but that may as well be achieved with the help of a state flag, so define an "unusable" idle state flag, CPUIDLE_FLAG_UNUSABLE, make the drivers in question use it instead of the "disabled" field and make the core set CPUIDLE_STATE_DISABLED_BY_DRIVER for the idle states with that flag set. After the above changes, the "disabled" field in struct cpuidle_state is not used any more, so drop it. No intentional functional impact. Signed-off-by: Rafael J. Wysocki --- include/linux/cpuidle.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'include') diff --git a/include/linux/cpuidle.h b/include/linux/cpuidle.h index 2dbe46b7c213..1dabe36bd011 100644 --- a/include/linux/cpuidle.h +++ b/include/linux/cpuidle.h @@ -54,7 +54,6 @@ struct cpuidle_state { unsigned int exit_latency; /* in US */ int power_usage; /* in mW */ unsigned int target_residency; /* in US */ - bool disabled; /* disabled on all CPUs */ int (*enter) (struct cpuidle_device *dev, struct cpuidle_driver *drv, @@ -77,6 +76,7 @@ struct cpuidle_state { #define CPUIDLE_FLAG_POLLING BIT(0) /* polling state */ #define CPUIDLE_FLAG_COUPLED BIT(1) /* state applies to multiple cpus */ #define CPUIDLE_FLAG_TIMER_STOP BIT(2) /* timer is stopped on this state */ +#define CPUIDLE_FLAG_UNUSABLE BIT(3) /* avoid using this state */ struct cpuidle_device_kobj; struct cpuidle_state_kobj; -- cgit v1.2.3 From c6a3aea93571a5393602256d8f74772bd64c8225 Mon Sep 17 00:00:00 2001 From: Leonard Crestez Date: Tue, 26 Nov 2019 17:17:11 +0200 Subject: PM / QoS: Redefine FREQ_QOS_MAX_DEFAULT_VALUE to S32_MAX QOS requests for DEFAULT_VALUE are supposed to be ignored but this is not the case for FREQ_QOS_MAX. Adding one request for MAX_DEFAULT_VALUE and one for a real value will cause freq_qos_read_value to unexpectedly return MAX_DEFAULT_VALUE (-1). This happens because freq_qos max value is aggregated with PM_QOS_MIN but FREQ_QOS_MAX_DEFAULT_VALUE is (-1) so it's smaller than other values. Fix this by redefining FREQ_QOS_MAX_DEFAULT_VALUE to S32_MAX. Looking at current users for freq_qos it seems that none of them create requests for FREQ_QOS_MAX_DEFAULT_VALUE. Fixes: 77751a466ebd ("PM: QoS: Introduce frequency QoS") Signed-off-by: Leonard Crestez Reported-by: Matthias Kaehlcke Reviewed-by: Matthias Kaehlcke Cc: 5.4+ # 5.4+ Signed-off-by: Rafael J. Wysocki --- include/linux/pm_qos.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'include') diff --git a/include/linux/pm_qos.h b/include/linux/pm_qos.h index ebf5ef17cc2a..24a6263c9931 100644 --- a/include/linux/pm_qos.h +++ b/include/linux/pm_qos.h @@ -256,7 +256,7 @@ static inline s32 dev_pm_qos_raw_resume_latency(struct device *dev) #endif #define FREQ_QOS_MIN_DEFAULT_VALUE 0 -#define FREQ_QOS_MAX_DEFAULT_VALUE (-1) +#define FREQ_QOS_MAX_DEFAULT_VALUE S32_MAX enum freq_qos_req_type { FREQ_QOS_MIN = 1, -- cgit v1.2.3 From 342035f66c866f4ad750477b21b210e98d1f6818 Mon Sep 17 00:00:00 2001 From: Leonard Crestez Date: Tue, 26 Nov 2019 17:17:12 +0200 Subject: PM / QoS: Reorder pm_qos/freq_qos/dev_pm_qos structs This allows dev_pm_qos to embed freq_qos structs, which is done in the next patch. Separate commit to make it easier to review. Signed-off-by: Leonard Crestez Reviewed-by: Matthias Kaehlcke Signed-off-by: Rafael J. Wysocki --- include/linux/pm_qos.h | 74 ++++++++++++++++++++++++++------------------------ 1 file changed, 38 insertions(+), 36 deletions(-) (limited to 'include') diff --git a/include/linux/pm_qos.h b/include/linux/pm_qos.h index 24a6263c9931..678fec6da5b9 100644 --- a/include/linux/pm_qos.h +++ b/include/linux/pm_qos.h @@ -49,21 +49,6 @@ struct pm_qos_flags_request { s32 flags; /* Do not change to 64 bit */ }; -enum dev_pm_qos_req_type { - DEV_PM_QOS_RESUME_LATENCY = 1, - DEV_PM_QOS_LATENCY_TOLERANCE, - DEV_PM_QOS_FLAGS, -}; - -struct dev_pm_qos_request { - enum dev_pm_qos_req_type type; - union { - struct plist_node pnode; - struct pm_qos_flags_request flr; - } data; - struct device *dev; -}; - enum pm_qos_type { PM_QOS_UNITIALIZED, PM_QOS_MAX, /* return the largest value */ @@ -90,6 +75,44 @@ struct pm_qos_flags { s32 effective_flags; /* Do not change to 64 bit */ }; + +#define FREQ_QOS_MIN_DEFAULT_VALUE 0 +#define FREQ_QOS_MAX_DEFAULT_VALUE S32_MAX + +enum freq_qos_req_type { + FREQ_QOS_MIN = 1, + FREQ_QOS_MAX, +}; + +struct freq_constraints { + struct pm_qos_constraints min_freq; + struct blocking_notifier_head min_freq_notifiers; + struct pm_qos_constraints max_freq; + struct blocking_notifier_head max_freq_notifiers; +}; + +struct freq_qos_request { + enum freq_qos_req_type type; + struct plist_node pnode; + struct freq_constraints *qos; +}; + + +enum dev_pm_qos_req_type { + DEV_PM_QOS_RESUME_LATENCY = 1, + DEV_PM_QOS_LATENCY_TOLERANCE, + DEV_PM_QOS_FLAGS, +}; + +struct dev_pm_qos_request { + enum dev_pm_qos_req_type type; + union { + struct plist_node pnode; + struct pm_qos_flags_request flr; + } data; + struct device *dev; +}; + struct dev_pm_qos { struct pm_qos_constraints resume_latency; struct pm_qos_constraints latency_tolerance; @@ -255,27 +278,6 @@ static inline s32 dev_pm_qos_raw_resume_latency(struct device *dev) } #endif -#define FREQ_QOS_MIN_DEFAULT_VALUE 0 -#define FREQ_QOS_MAX_DEFAULT_VALUE S32_MAX - -enum freq_qos_req_type { - FREQ_QOS_MIN = 1, - FREQ_QOS_MAX, -}; - -struct freq_constraints { - struct pm_qos_constraints min_freq; - struct blocking_notifier_head min_freq_notifiers; - struct pm_qos_constraints max_freq; - struct blocking_notifier_head max_freq_notifiers; -}; - -struct freq_qos_request { - enum freq_qos_req_type type; - struct plist_node pnode; - struct freq_constraints *qos; -}; - static inline int freq_qos_request_active(struct freq_qos_request *req) { return !IS_ERR_OR_NULL(req->qos); -- cgit v1.2.3 From 36a8015f89e40f7c9c91cc7e6d028fa288dad27b Mon Sep 17 00:00:00 2001 From: Leonard Crestez Date: Tue, 26 Nov 2019 17:17:13 +0200 Subject: PM / QoS: Restore DEV_PM_QOS_MIN/MAX_FREQUENCY Support for adding per-device frequency limits was removed in commit 2aac8bdf7a0f ("PM: QoS: Drop frequency QoS types from device PM QoS") after cpufreq switched to use a new "freq_constraints" construct. Restore support for per-device freq limits but base this upon freq_constraints. This is primarily meant to be used by the devfreq subsystem. This removes the "static" marking on freq_qos_apply but does not export it for modules. Signed-off-by: Leonard Crestez Reviewed-by: Matthias Kaehlcke Tested-by: Matthias Kaehlcke Signed-off-by: Rafael J. Wysocki --- include/linux/pm_qos.h | 12 ++++++++++++ 1 file changed, 12 insertions(+) (limited to 'include') diff --git a/include/linux/pm_qos.h b/include/linux/pm_qos.h index 678fec6da5b9..19eafca5680e 100644 --- a/include/linux/pm_qos.h +++ b/include/linux/pm_qos.h @@ -34,6 +34,8 @@ enum pm_qos_flags_status { #define PM_QOS_RESUME_LATENCY_NO_CONSTRAINT PM_QOS_LATENCY_ANY #define PM_QOS_RESUME_LATENCY_NO_CONSTRAINT_NS PM_QOS_LATENCY_ANY_NS #define PM_QOS_LATENCY_TOLERANCE_DEFAULT_VALUE 0 +#define PM_QOS_MIN_FREQUENCY_DEFAULT_VALUE 0 +#define PM_QOS_MAX_FREQUENCY_DEFAULT_VALUE FREQ_QOS_MAX_DEFAULT_VALUE #define PM_QOS_LATENCY_TOLERANCE_NO_CONSTRAINT (-1) #define PM_QOS_FLAG_NO_POWER_OFF (1 << 0) @@ -101,6 +103,8 @@ struct freq_qos_request { enum dev_pm_qos_req_type { DEV_PM_QOS_RESUME_LATENCY = 1, DEV_PM_QOS_LATENCY_TOLERANCE, + DEV_PM_QOS_MIN_FREQUENCY, + DEV_PM_QOS_MAX_FREQUENCY, DEV_PM_QOS_FLAGS, }; @@ -109,6 +113,7 @@ struct dev_pm_qos_request { union { struct plist_node pnode; struct pm_qos_flags_request flr; + struct freq_qos_request freq; } data; struct device *dev; }; @@ -116,6 +121,7 @@ struct dev_pm_qos_request { struct dev_pm_qos { struct pm_qos_constraints resume_latency; struct pm_qos_constraints latency_tolerance; + struct freq_constraints freq; struct pm_qos_flags flags; struct dev_pm_qos_request *resume_latency_req; struct dev_pm_qos_request *latency_tolerance_req; @@ -214,6 +220,10 @@ static inline s32 dev_pm_qos_read_value(struct device *dev, switch (type) { case DEV_PM_QOS_RESUME_LATENCY: return PM_QOS_RESUME_LATENCY_NO_CONSTRAINT; + case DEV_PM_QOS_MIN_FREQUENCY: + return PM_QOS_MIN_FREQUENCY_DEFAULT_VALUE; + case DEV_PM_QOS_MAX_FREQUENCY: + return PM_QOS_MAX_FREQUENCY_DEFAULT_VALUE; default: WARN_ON(1); return 0; @@ -293,6 +303,8 @@ int freq_qos_add_request(struct freq_constraints *qos, enum freq_qos_req_type type, s32 value); int freq_qos_update_request(struct freq_qos_request *req, s32 new_value); int freq_qos_remove_request(struct freq_qos_request *req); +int freq_qos_apply(struct freq_qos_request *req, + enum pm_qos_req_action action, s32 value); int freq_qos_add_notifier(struct freq_constraints *qos, enum freq_qos_req_type type, -- cgit v1.2.3