Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit b3293c81 authored by Jeff Bernard's avatar Jeff Bernard Committed by Shiju Mathew
Browse files

msm: thermal: Restore hotplug cores started outside of thermal driver



Track cores onlined by system prior to registering for cpu notifier
callbacks by copying cpu online mask. Use core up and down notfiers to
track cores being previously online when registered via cpu notifier.
Cores enabled by thermal driver to read cpu freq table are not counted
as previously enabled unless they were enabled by some external driver
and this was previously detected by the methods described earlier.

CRs-fixed: 772172
Change-Id: I7f3a53544d336d44644ad00ac1728f5a89b9e056
Signed-off-by: default avatarJeff Bernard <jbernard@codeaurora.org>
parent ebf056a1
Loading
Loading
Loading
Loading
+58 −9
Original line number Diff line number Diff line
@@ -45,6 +45,7 @@
#include <linux/notifier.h>
#include <linux/reboot.h>
#include <soc/qcom/msm-core.h>
#include <linux/cpumask.h>

#define CREATE_TRACE_POINTS
#define TRACE_MSM_THERMAL
@@ -60,6 +61,7 @@
#define SENSOR_SCALING_FACTOR 1
#define MSM_THERMAL_NAME "msm_thermal"
#define MSM_TSENS_PRINT  "log_tsens_temperature"
#define CPU_BUF_SIZE 64

#define THERM_CREATE_DEBUGFS_DIR(_node, _name, _parent, _ret) \
	do { \
@@ -85,6 +87,7 @@ static struct msm_thermal_data msm_thermal_info;
static struct delayed_work check_temp_work;
static bool core_control_enabled;
static uint32_t cpus_offlined;
static cpumask_var_t cpus_previously_online;
static DEFINE_MUTEX(core_control_mutex);
static struct kobject *cc_kobj;
static struct kobject *mx_kobj;
@@ -419,6 +422,18 @@ uint32_t get_core_max_freq(uint32_t cpu)
	return max_freq;
}

static void cpus_previously_online_update(void)
{
	char buf[CPU_BUF_SIZE];

	get_online_cpus();
	cpumask_or(cpus_previously_online, cpus_previously_online,
		   cpu_online_mask);
	put_online_cpus();
	cpulist_scnprintf(buf, sizeof(buf), cpus_previously_online);
	pr_debug("%s\n", buf);
}

uint32_t get_core_min_freq(uint32_t cpu)
{
	int i;
@@ -844,7 +859,8 @@ static void update_cpu_topology(struct device *dev)
static int __ref init_cluster_freq_table(void)
{
	uint32_t _cluster = 0, _cpu = 0, table_len = 0, idx = 0;
	int ret = 0;
	int ret = 0, cpu_set;
	char buf[CPU_BUF_SIZE];
	struct cluster_info *cluster_ptr = NULL;
	struct cpufreq_policy *policy = NULL;
	struct cpufreq_frequency_table *freq_table_ptr = NULL;
@@ -876,10 +892,22 @@ static int __ref init_cluster_freq_table(void)
				cluster_ptr->cluster_id, _cpu);
			pending_cpu_freq = _cpu;
			if (!cpu_online(_cpu)) {
				cpu_set = cpumask_test_cpu(_cpu,
						cpus_previously_online);
#ifdef CONFIG_SMP
				cpu_up(_cpu);
				cpu_down(_cpu);
#endif
				/* Remove prev online bit if we are first to
				   put it online */
				if (!cpu_set) {
					cpumask_clear_cpu(_cpu,
						cpus_previously_online);
					cpumask_scnprintf(buf, sizeof(buf),
						cpus_previously_online);
					pr_debug("Reset prev online to %s\n",
						 buf);
				}
			}
			freq_table_ptr = pending_freq_table_ptr;
		}
@@ -2090,6 +2118,7 @@ static void __ref do_core_control(long temp)
				continue;
			pr_info("Set Offline: CPU%d Temp: %ld\n",
					i, temp);
			if (cpu_online(i)) {
				trace_thermal_pre_core_offline(i);
				ret = cpu_down(i);
				if (ret)
@@ -2097,6 +2126,7 @@ static void __ref do_core_control(long temp)
					       ret, i);
				trace_thermal_post_core_offline(i,
					cpumask_test_cpu(i, cpu_online_mask));
			}
			cpus_offlined |= BIT(i);
			break;
		}
@@ -2115,6 +2145,10 @@ static void __ref do_core_control(long temp)
			 */
			if (cpu_online(i))
				continue;
			/* If this core wasn't previously online don't put it
			   online */
			if (!(cpumask_test_cpu(i, cpus_previously_online)))
				continue;
			trace_thermal_pre_core_online(i);
			ret = cpu_up(i);
			if (ret)
@@ -2156,6 +2190,10 @@ static int __ref update_offline_cores(int val)
		} else if (online_core && (previous_cpus_offlined & BIT(cpu))) {
			if (cpu_online(cpu))
				continue;
			/* If this core wasn't previously online don't put it
			   online */
			if (!(cpumask_test_cpu(cpu, cpus_previously_online)))
				continue;
			trace_thermal_pre_core_online(cpu);
			ret = cpu_up(cpu);
			if (ret && ret == notifier_to_errno(NOTIFY_BAD))
@@ -2626,6 +2664,9 @@ static int __ref msm_thermal_cpu_callback(struct notifier_block *nfb,
	uint32_t cpu = (uintptr_t)hcpu;

	if (action == CPU_UP_PREPARE || action == CPU_UP_PREPARE_FROZEN) {
		if (!cpumask_test_and_set_cpu(cpu, cpus_previously_online))
			pr_debug("Total prev cores online tracked %u\n",
				cpumask_weight(cpus_previously_online));
		if (core_control_enabled &&
			(msm_thermal_info.core_control_mask & BIT(cpu)) &&
			(cpus_offlined & BIT(cpu))) {
@@ -2633,6 +2674,11 @@ static int __ref msm_thermal_cpu_callback(struct notifier_block *nfb,
				cpu);
			return NOTIFY_BAD;
		}
	} else if (action == CPU_DOWN_PREPARE ||
				action == CPU_DOWN_PREPARE_FROZEN) {
		if (!cpumask_test_and_set_cpu(cpu, cpus_previously_online))
			pr_debug("Total prev cores online tracked %u\n",
				cpumask_weight(cpus_previously_online));
	}

	pr_debug("voting for CPU%d to be online\n", cpu);
@@ -3744,6 +3790,7 @@ static ssize_t __ref store_cc_enabled(struct kobject *kobj,
	core_control_enabled = !!val;
	if (core_control_enabled) {
		pr_info("Core control enabled\n");
		cpus_previously_online_update();
		register_cpu_notifier(&msm_thermal_cpu_notifier);
		/*
		 * Re-evaluate thermal core condition, update current status
@@ -4041,8 +4088,10 @@ int msm_thermal_init(struct msm_thermal_data *pdata)
	INIT_DELAYED_WORK(&check_temp_work, check_temp);
	schedule_delayed_work(&check_temp_work, 0);

	if (num_possible_cpus() > 1)
	if (num_possible_cpus() > 1) {
		cpus_previously_online_update();
		register_cpu_notifier(&msm_thermal_cpu_notifier);
	}

	return ret;
}