diff --git a/drivers/cpuidle/cpuidle.c b/drivers/cpuidle/cpuidle.c index 0db65cda298b..5a4566cfc23c 100644 --- a/drivers/cpuidle/cpuidle.c +++ b/drivers/cpuidle/cpuidle.c @@ -19,6 +19,7 @@ #include #include #include +#include #include #include #include @@ -128,6 +129,32 @@ void cpuidle_use_deepest_state(bool enable) preempt_enable(); } +static void set_uds_callback(void *info) +{ + bool enable = *(bool *)info; + + cpuidle_use_deepest_state(enable); +} + +/** + * cpuidle_use_deepest_state_mask - Set use_deepest_state on specific CPUs. + * @target: cpumask of CPUs to update use_deepest_state on. + * @enable: whether to enforce the deepest idle state on those CPUs. + */ +int cpuidle_use_deepest_state_mask(const struct cpumask *target, bool enable) +{ + bool *info = kmalloc(sizeof(bool), GFP_KERNEL); + + if (!info) + return -ENOMEM; + + *info = enable; + on_each_cpu_mask(target, set_uds_callback, info, 1); + kfree(info); + + return 0; +} + /** * cpuidle_find_deepest_state - Find the deepest available idle state. * @drv: cpuidle driver for the given CPU. diff --git a/include/linux/cpuidle.h b/include/linux/cpuidle.h index 0b14da79e9af..aba806908a38 100644 --- a/include/linux/cpuidle.h +++ b/include/linux/cpuidle.h @@ -198,7 +198,9 @@ extern int cpuidle_find_deepest_state(struct cpuidle_driver *drv, struct cpuidle_device *dev); extern int cpuidle_enter_freeze(struct cpuidle_driver *drv, struct cpuidle_device *dev); -extern void cpuidle_use_deepest_state(bool enable); +extern void cpuidle_use_deepest_state(bool enable); +extern int cpuidle_use_deepest_state_mask(const struct cpumask *target, + bool enable); #else static inline int cpuidle_find_deepest_state(struct cpuidle_driver *drv, struct cpuidle_device *dev) @@ -209,6 +211,11 @@ static inline int cpuidle_enter_freeze(struct cpuidle_driver *drv, static inline void cpuidle_use_deepest_state(bool enable) { } +static inline int cpuidle_use_deepest_state_mask(const struct cpumask *target, + bool enable) +{ + return -ENODEV; +} #endif /* kernel/sched/idle.c */