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

Commit afd226a8 authored by Linux Build Service Account's avatar Linux Build Service Account Committed by Gerrit - the friendly Code Review server
Browse files

Merge "msm: thermal: Retry on failure to hotplug"

parents ac869dd9 f2947cbf
Loading
Loading
Loading
Loading
+48 −11
Original line number Diff line number Diff line
@@ -71,6 +71,7 @@
#define MSM_THERMAL_THRESH_CLR    "thresh_clr_degc"
#define MSM_THERMAL_THRESH_UPDATE "update"
#define DEVM_NAME_MAX 30
#define HOTPLUG_RETRY_INTERVAL_MS 100

#define VALIDATE_AND_SET_MASK(_node, _key, _mask, _cpu) \
	do { \
@@ -115,7 +116,7 @@
	} while (0)

static struct msm_thermal_data msm_thermal_info;
static struct delayed_work check_temp_work;
static struct delayed_work check_temp_work, retry_hotplug_work;
static bool core_control_enabled;
static uint32_t cpus_offlined;
static cpumask_var_t cpus_previously_online;
@@ -166,6 +167,7 @@ static bool therm_reset_enabled;
static bool online_core;
static bool cluster_info_probed;
static bool cluster_info_nodes_called;
static bool in_suspend, retry_in_progress;
static int *tsens_id_map;
static int *zone_id_tsens_map;
static DEFINE_MUTEX(vdd_rstr_mutex);
@@ -581,11 +583,19 @@ static int msm_thermal_suspend_callback(
	case PM_HIBERNATION_PREPARE:
	case PM_SUSPEND_PREPARE:
		msm_thermal_update_freq(false, true);
		in_suspend = true;
		retry_in_progress = false;
		cancel_delayed_work_sync(&retry_hotplug_work);
		break;

	case PM_POST_HIBERNATION:
	case PM_POST_SUSPEND:
		msm_thermal_update_freq(false, false);
		in_suspend = false;
		if (hotplug_task)
			complete(&hotplug_notify_complete);
		else
			pr_debug("Hotplug task not initialized\n");
		break;

	default:
@@ -2640,6 +2650,17 @@ static void therm_reset_notify(struct therm_threshold *thresh_data)
					thresh_data->threshold);
}

static void retry_hotplug(struct work_struct *work)
{
	mutex_lock(&core_control_mutex);
	if (retry_in_progress) {
		pr_debug("Retrying hotplug\n");
		retry_in_progress = false;
		complete(&hotplug_notify_complete);
	}
	mutex_unlock(&core_control_mutex);
}

#ifdef CONFIG_SMP
static void __ref do_core_control(long temp)
{
@@ -2708,6 +2729,7 @@ static int __ref update_offline_cores(int val)
	uint32_t cpu = 0;
	int ret = 0;
	uint32_t previous_cpus_offlined = 0;
	bool pend_hotplug_req = false;

	if (!core_control_enabled)
		return 0;
@@ -2721,11 +2743,14 @@ static int __ref update_offline_cores(int val)
				continue;
			trace_thermal_pre_core_offline(cpu);
			ret = cpu_down(cpu);
			if (ret)
				pr_err("Unable to offline CPU%d. err:%d\n",
			if (ret) {
				pr_err_ratelimited(
					"Unable to offline CPU%d. err:%d\n",
					cpu, ret);
			else
				pend_hotplug_req = true;
			} else {
				pr_debug("Offlined CPU%d\n", cpu);
			}
			trace_thermal_post_core_offline(cpu,
				cpumask_test_cpu(cpu, cpu_online_mask));
		} else if (online_core && (previous_cpus_offlined & BIT(cpu))) {
@@ -2737,17 +2762,28 @@ static int __ref update_offline_cores(int val)
				continue;
			trace_thermal_pre_core_online(cpu);
			ret = cpu_up(cpu);
			if (ret && ret == notifier_to_errno(NOTIFY_BAD))
			if (ret && ret == notifier_to_errno(NOTIFY_BAD)) {
				pr_debug("Onlining CPU%d is vetoed\n", cpu);
			else if (ret)
				pr_err("Unable to online CPU%d. err:%d\n",
			} else if (ret) {
				cpus_offlined |= BIT(cpu);
				pend_hotplug_req = true;
				pr_err_ratelimited(
					"Unable to online CPU%d. err:%d\n",
					cpu, ret);
			else
			} else {
				pr_debug("Onlined CPU%d\n", cpu);
				trace_thermal_post_core_online(cpu,
					cpumask_test_cpu(cpu, cpu_online_mask));
			}
		}
	}

	if (pend_hotplug_req && !in_suspend && !retry_in_progress) {
		retry_in_progress = true;
		schedule_delayed_work(&retry_hotplug_work,
			msecs_to_jiffies(HOTPLUG_RETRY_INTERVAL_MS));
	}

	return ret;
}

@@ -4875,6 +4911,7 @@ int msm_thermal_init(struct msm_thermal_data *pdata)

	register_reboot_notifier(&msm_thermal_reboot_notifier);
	pm_notifier(msm_thermal_suspend_callback, 0);
	INIT_DELAYED_WORK(&retry_hotplug_work, retry_hotplug);
	INIT_DELAYED_WORK(&check_temp_work, check_temp);
	schedule_delayed_work(&check_temp_work, 0);