Expose notifier registration for the system-wide CPU latency and wakeup latency QoS constraints so listeners can react when the aggregate target value changes. pm_qos_update_target() already invokes constraint notifiers when the effective value changes.
Signed-off-by: Yaxiong Tian <[email protected]> --- include/linux/pm_qos.h | 23 +++++++++++++++++++ kernel/power/qos.c | 50 ++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 73 insertions(+) diff --git a/include/linux/pm_qos.h b/include/linux/pm_qos.h index 6cea4455f867..3759b453c6d6 100644 --- a/include/linux/pm_qos.h +++ b/include/linux/pm_qos.h @@ -149,6 +149,8 @@ bool cpu_latency_qos_request_active(struct pm_qos_request *req); void cpu_latency_qos_add_request(struct pm_qos_request *req, s32 value); void cpu_latency_qos_update_request(struct pm_qos_request *req, s32 new_value); void cpu_latency_qos_remove_request(struct pm_qos_request *req); +int cpu_latency_qos_add_notifier(struct notifier_block *notifier); +int cpu_latency_qos_remove_notifier(struct notifier_block *notifier); #else static inline s32 cpu_latency_qos_limit(void) { return INT_MAX; } static inline bool cpu_latency_qos_request_active(struct pm_qos_request *req) @@ -160,15 +162,36 @@ static inline void cpu_latency_qos_add_request(struct pm_qos_request *req, static inline void cpu_latency_qos_update_request(struct pm_qos_request *req, s32 new_value) {} static inline void cpu_latency_qos_remove_request(struct pm_qos_request *req) {} +static inline int cpu_latency_qos_add_notifier(struct notifier_block *notifier) +{ + return 0; +} +static inline int +cpu_latency_qos_remove_notifier(struct notifier_block *notifier) +{ + return 0; +} #endif #ifdef CONFIG_PM_QOS_CPU_SYSTEM_WAKEUP s32 cpu_wakeup_latency_qos_limit(void); +int cpu_wakeup_latency_qos_add_notifier(struct notifier_block *notifier); +int cpu_wakeup_latency_qos_remove_notifier(struct notifier_block *notifier); #else static inline s32 cpu_wakeup_latency_qos_limit(void) { return PM_QOS_RESUME_LATENCY_NO_CONSTRAINT; } +static inline int +cpu_wakeup_latency_qos_add_notifier(struct notifier_block *notifier) +{ + return 0; +} +static inline int +cpu_wakeup_latency_qos_remove_notifier(struct notifier_block *notifier) +{ + return 0; +} #endif #ifdef CONFIG_PM diff --git a/kernel/power/qos.c b/kernel/power/qos.c index 1944dbeb0d4c..392ab3dbb923 100644 --- a/kernel/power/qos.c +++ b/kernel/power/qos.c @@ -212,12 +212,15 @@ bool pm_qos_update_flags(struct pm_qos_flags *pqf, #ifdef CONFIG_CPU_IDLE /* Definitions related to the CPU latency QoS. */ +static BLOCKING_NOTIFIER_HEAD(cpu_latency_qos_notifiers); + static struct pm_qos_constraints cpu_latency_constraints = { .list = PLIST_HEAD_INIT(cpu_latency_constraints.list), .target_value = PM_QOS_CPU_LATENCY_DEFAULT_VALUE, .default_value = PM_QOS_CPU_LATENCY_DEFAULT_VALUE, .no_constraint_value = PM_QOS_CPU_LATENCY_DEFAULT_VALUE, .type = PM_QOS_MIN, + .notifiers = &cpu_latency_qos_notifiers, }; static inline bool cpu_latency_qos_value_invalid(s32 value) @@ -335,6 +338,28 @@ void cpu_latency_qos_remove_request(struct pm_qos_request *req) } EXPORT_SYMBOL_GPL(cpu_latency_qos_remove_request); +/** + * cpu_latency_qos_add_notifier - Add CPU latency QoS change notifier. + * @notifier: Notifier block managed by the caller. + */ +int cpu_latency_qos_add_notifier(struct notifier_block *notifier) +{ + return blocking_notifier_chain_register(&cpu_latency_qos_notifiers, + notifier); +} +EXPORT_SYMBOL_GPL(cpu_latency_qos_add_notifier); + +/** + * cpu_latency_qos_remove_notifier - Remove CPU latency QoS change notifier. + * @notifier: Notifier block previously registered. + */ +int cpu_latency_qos_remove_notifier(struct notifier_block *notifier) +{ + return blocking_notifier_chain_unregister(&cpu_latency_qos_notifiers, + notifier); +} +EXPORT_SYMBOL_GPL(cpu_latency_qos_remove_notifier); + /* User space interface to the CPU latency QoS via misc device. */ static int cpu_latency_qos_open(struct inode *inode, struct file *filp) @@ -417,12 +442,15 @@ static struct miscdevice cpu_latency_qos_miscdev = { #ifdef CONFIG_PM_QOS_CPU_SYSTEM_WAKEUP /* The CPU system wakeup latency QoS. */ +static BLOCKING_NOTIFIER_HEAD(cpu_wakeup_latency_qos_notifiers); + static struct pm_qos_constraints cpu_wakeup_latency_constraints = { .list = PLIST_HEAD_INIT(cpu_wakeup_latency_constraints.list), .target_value = PM_QOS_RESUME_LATENCY_NO_CONSTRAINT, .default_value = PM_QOS_RESUME_LATENCY_NO_CONSTRAINT, .no_constraint_value = PM_QOS_RESUME_LATENCY_NO_CONSTRAINT, .type = PM_QOS_MIN, + .notifiers = &cpu_wakeup_latency_qos_notifiers, }; /** @@ -436,6 +464,28 @@ s32 cpu_wakeup_latency_qos_limit(void) return pm_qos_read_value(&cpu_wakeup_latency_constraints); } +/** + * cpu_wakeup_latency_qos_add_notifier - Add wakeup latency QoS notifier. + * @notifier: Notifier block managed by the caller. + */ +int cpu_wakeup_latency_qos_add_notifier(struct notifier_block *notifier) +{ + return blocking_notifier_chain_register(&cpu_wakeup_latency_qos_notifiers, + notifier); +} +EXPORT_SYMBOL_GPL(cpu_wakeup_latency_qos_add_notifier); + +/** + * cpu_wakeup_latency_qos_remove_notifier - Remove wakeup latency QoS notifier. + * @notifier: Notifier block previously registered. + */ +int cpu_wakeup_latency_qos_remove_notifier(struct notifier_block *notifier) +{ + return blocking_notifier_chain_unregister(&cpu_wakeup_latency_qos_notifiers, + notifier); +} +EXPORT_SYMBOL_GPL(cpu_wakeup_latency_qos_remove_notifier); + static int cpu_wakeup_latency_qos_open(struct inode *inode, struct file *filp) { struct pm_qos_request *req; -- 2.43.0

