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

This commit is contained in:
Linux Build Service Account 2015-05-03 04:50:26 -07:00 committed by Gerrit - the friendly Code Review server
commit d664e9ccb8
1 changed files with 40 additions and 5 deletions

View File

@ -61,6 +61,7 @@
#define MSM_TSENS_PRINT "log_tsens_temperature"
#define CPU_BUF_SIZE 64
#define CPU_DEVICE "cpu%d"
#define HOTPLUG_RETRY_INTERVAL_MS 100
#define THERM_CREATE_DEBUGFS_DIR(_node, _name, _parent, _ret) \
do { \
@ -80,7 +81,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;
@ -131,6 +132,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);
@ -505,8 +507,16 @@ static int msm_thermal_suspend_callback(
struct notifier_block *nfb, unsigned long action, void *data)
{
switch (action) {
case PM_HIBERNATION_PREPARE:
case PM_SUSPEND_PREPARE:
in_suspend = true;
retry_in_progress = false;
cancel_delayed_work_sync(&retry_hotplug_work);
break;
case PM_POST_HIBERNATION:
case PM_POST_SUSPEND:
in_suspend = false;
if (hotplug_task)
complete(&hotplug_notify_complete);
else
@ -2480,6 +2490,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)
{
@ -2548,6 +2569,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;
@ -2561,11 +2583,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))) {
@ -2581,7 +2606,9 @@ static int __ref update_offline_cores(int val)
pr_debug("Onlining CPU%d is vetoed\n", cpu);
} else if (ret) {
cpus_offlined |= BIT(cpu);
pr_err("Unable to online CPU%d. err:%d\n",
pend_hotplug_req = true;
pr_err_ratelimited(
"Unable to online CPU%d. err:%d\n",
cpu, ret);
} else {
pr_debug("Onlined CPU%d\n", cpu);
@ -2590,6 +2617,13 @@ static int __ref update_offline_cores(int val)
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;
}
@ -4669,6 +4703,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);