drivers: thermal: cpu_cooling: Add a notifier for max level transitions

Add a blocking notifier to send a notification when a CPU enters or
leaves the max cooling level state. Also add an API to retrieve
the cpumask that contains all CPUs that are in max cooling state.

Interested clients like core_ctl subscribe to these notifications
and manage CPUs accordingly.

Change-Id: I4828ed572fa965b5bfce8184ef813fddfb246cb1
Signed-off-by: Pavankumar Kondeti <pkondeti@codeaurora.org>
[satyap@codeaurora.org: resolve trivial merge conflicts]
Signed-off-by: Satya Durga Srinivasu Prabhala <satyap@codeaurora.org>
This commit is contained in:
Pavankumar Kondeti
2018-08-27 08:35:39 +05:30
committed by Gerrit - the friendly Code Review server
parent eee86f2a17
commit 547ecd3b02
2 changed files with 43 additions and 0 deletions

View File

@@ -129,6 +129,24 @@ static DEFINE_IDA(cpufreq_ida);
static DEFINE_MUTEX(cooling_list_lock);
static LIST_HEAD(cpufreq_cdev_list);
static struct cpumask cpus_in_max_cooling_level;
static BLOCKING_NOTIFIER_HEAD(cpu_max_cooling_level_notifer);
void cpu_cooling_max_level_notifier_register(struct notifier_block *n)
{
blocking_notifier_chain_register(&cpu_max_cooling_level_notifer, n);
}
void cpu_cooling_max_level_notifier_unregister(struct notifier_block *n)
{
blocking_notifier_chain_unregister(&cpu_max_cooling_level_notifer, n);
}
const struct cpumask *cpu_cooling_get_max_level_cpumask(void)
{
return &cpus_in_max_cooling_level;
}
/* Below code defines functions to be used for cpufreq as cooling device */
/**
@@ -621,6 +639,9 @@ static int cpufreq_set_cur_state(struct thermal_cooling_device *cdev,
cpumask_clear_cpu(cpu,
&cpus_isolated_by_thermal);
}
cpumask_set_cpu(cpu, &cpus_in_max_cooling_level);
blocking_notifier_call_chain(&cpu_max_cooling_level_notifer,
1, (void *)(long)cpu);
return ret;
} else if ((prev_state == cpufreq_cdev->max_level)
&& (state < cpufreq_cdev->max_level)) {
@@ -634,6 +655,9 @@ static int cpufreq_set_cur_state(struct thermal_cooling_device *cdev,
&cpus_isolated_by_thermal)) {
sched_unisolate_cpu(cpu);
}
cpumask_clear_cpu(cpu, &cpus_in_max_cooling_level);
blocking_notifier_call_chain(&cpu_max_cooling_level_notifer,
0, (void *)(long)cpu);
}
update_frequency:
clip_freq = cpufreq_cdev->freq_table[state].frequency;
@@ -990,6 +1014,7 @@ __cpufreq_cooling_register(struct device_node *np,
register_pm_notifier(&cpufreq_cooling_pm_nb);
cpumask_clear(&cpus_pending_online);
cpumask_clear(&cpus_isolated_by_thermal);
cpumask_clear(&cpus_in_max_cooling_level);
INIT_WORK(&cpuhp_register_work, register_cdev);
queue_work(system_wq, &cpuhp_register_work);
}

View File

@@ -54,6 +54,9 @@ cpufreq_platform_cooling_register(const struct cpumask *clip_cpus,
*/
void cpufreq_cooling_unregister(struct thermal_cooling_device *cdev);
extern void cpu_cooling_max_level_notifier_register(struct notifier_block *n);
extern void cpu_cooling_max_level_notifier_unregister(struct notifier_block *n);
extern const struct cpumask *cpu_cooling_get_max_level_cpumask(void);
#else /* !CONFIG_CPU_THERMAL */
static inline struct thermal_cooling_device *
cpufreq_cooling_register(struct cpufreq_policy *policy)
@@ -88,6 +91,21 @@ cpufreq_platform_cooling_register(const struct cpumask *clip_cpus,
{
return NULL;
}
static inline
void cpu_cooling_max_level_notifier_register(struct notifier_block *n)
{
}
static inline
void cpu_cooling_max_level_notifier_unregister(struct notifier_block *n)
{
}
static inline const struct cpumask *cpu_cooling_get_max_level_cpumask(void)
{
return cpu_none_mask;
}
#endif /* defined(CONFIG_THERMAL_OF) && defined(CONFIG_CPU_THERMAL) */
#endif /* __CPU_COOLING_H__ */