diff --git a/drivers/thermal/cpu_cooling.c b/drivers/thermal/cpu_cooling.c index 33b535a9026b..40dc23261c00 100644 --- a/drivers/thermal/cpu_cooling.c +++ b/drivers/thermal/cpu_cooling.c @@ -85,6 +85,8 @@ static LIST_HEAD(cpufreq_dev_list); static BLOCKING_NOTIFIER_HEAD(cpu_notifier); +static enum tmu_noti_state_t cpu_tstate = TMU_NORMAL; + /** * get_idr - function to get a unique id. * @idr: struct idr * handle used to create a id. @@ -160,13 +162,17 @@ static unsigned long get_level(struct cpufreq_cooling_device *cpufreq_dev, unsigned long cpufreq_cooling_get_level(unsigned int cpu, unsigned int freq) { struct cpufreq_cooling_device *cpufreq_dev; + unsigned long level = 0; mutex_lock(&cooling_list_lock); list_for_each_entry(cpufreq_dev, &cpufreq_dev_list, node) { if (cpumask_test_cpu(cpu, &cpufreq_dev->allowed_cpus)) { - unsigned long level = get_level(cpufreq_dev, freq); - mutex_unlock(&cooling_list_lock); + level = get_level(cpufreq_dev, freq); + + if (level == THERMAL_CSTATE_INVALID && freq > cpufreq_dev->freq_table[0]) + level = 0; + return level; } } @@ -874,6 +880,30 @@ static int cpufreq_power2state(struct thermal_cooling_device *cdev, return 0; } +static int cpufreq_set_cur_temp(struct thermal_cooling_device *cdev, + bool suspended, int temp) +{ + enum tmu_noti_state_t tstate; + unsigned int on; + + if (suspended || temp < EXYNOS_COLD_TEMP) { + tstate = TMU_COLD; + on = 1; + } else { + tstate = TMU_NORMAL; + on = 0; + } + + if (cpu_tstate == tstate) + return 0; + + cpu_tstate = tstate; + + blocking_notifier_call_chain(&cpu_notifier, TMU_COLD, &on); + + return 0; +} + /* Bind cpufreq callbacks to thermal cooling device ops */ static struct thermal_cooling_device_ops cpufreq_cooling_ops = { .get_max_state = cpufreq_get_max_state, @@ -1015,6 +1045,9 @@ __cpufreq_cooling_register(struct device_node *np, pr_debug("%s: freq:%u KHz\n", __func__, freq); } + if (cpufreq_dev->id == 0) + cpufreq_cooling_ops.set_cur_temp = cpufreq_set_cur_temp; + snprintf(dev_name, sizeof(dev_name), "thermal-cpufreq-%d", cpufreq_dev->id);