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

Commit f2947cbf authored by Ram Chandrasekar's avatar Ram Chandrasekar
Browse files

msm: thermal: Retry on failure to hotplug



Add support in thermal driver to retry hotplug
request on failure to fulfill the request.

This retrying will be disabled when the device
enters suspend and will resume after the device
exits from suspend.

Change-Id: I9e2c305754465eb458566c0224804c5ad4bda240
Signed-off-by: default avatarRam Chandrasekar <rkumbako@codeaurora.org>
parent 729ef8ff
Loading
Loading
Loading
Loading
+48 −11
Original line number Original line Diff line number Diff line
@@ -71,6 +71,7 @@
#define MSM_THERMAL_THRESH_CLR    "thresh_clr_degc"
#define MSM_THERMAL_THRESH_CLR    "thresh_clr_degc"
#define MSM_THERMAL_THRESH_UPDATE "update"
#define MSM_THERMAL_THRESH_UPDATE "update"
#define DEVM_NAME_MAX 30
#define DEVM_NAME_MAX 30
#define HOTPLUG_RETRY_INTERVAL_MS 100


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


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


	case PM_POST_HIBERNATION:
	case PM_POST_HIBERNATION:
	case PM_POST_SUSPEND:
	case PM_POST_SUSPEND:
		msm_thermal_update_freq(false, false);
		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;
		break;


	default:
	default:
@@ -2640,6 +2650,17 @@ static void therm_reset_notify(struct therm_threshold *thresh_data)
					thresh_data->threshold);
					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
#ifdef CONFIG_SMP
static void __ref do_core_control(long temp)
static void __ref do_core_control(long temp)
{
{
@@ -2708,6 +2729,7 @@ static int __ref update_offline_cores(int val)
	uint32_t cpu = 0;
	uint32_t cpu = 0;
	int ret = 0;
	int ret = 0;
	uint32_t previous_cpus_offlined = 0;
	uint32_t previous_cpus_offlined = 0;
	bool pend_hotplug_req = false;


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


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


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