/* Adjust cpus offlined bit based on temperature reading. */ static int hotplug_init_cpu_offlined(void) { struct tsens_device tsens_dev; long temp = 0; int cpu = 0; mutex_lock(&core_control_mutex); for_each_possible_cpu(cpu) { if (!(msm_thermal_info.core_control_mask & BIT(cpus[cpu].cpu))) continue; tsens_dev.sensor_num = sensor_get_id(\ (char *)cpus[cpu].sensor_type); if (tsens_get_temp(&tsens_dev, &temp)) { pr_err("%s: Unable to read TSENS sensor %d\n", KBUILD_MODNAME, tsens_dev.sensor_num); return -EINVAL; } if (temp >= msm_thermal_info.hotplug_temp_degC) cpus[cpu].offline = 1; else if (temp <= (msm_thermal_info.hotplug_temp_degC - msm_thermal_info.hotplug_temp_hysteresis_degC)) cpus[cpu].offline = 0; } mutex_unlock(&core_control_mutex); if (hotplug_task) complete(&hotplug_notify_complete); else { pr_err("%s: Hotplug task is not initialized\n", KBUILD_MODNAME); return -EINVAL; } return 0; }
static void __ref check_temp(struct work_struct *work) { static int limit_init; struct tsens_device tsens_dev; long temp = 0; int ret = 0; tsens_dev.sensor_num = msm_thermal_info.sensor_id; ret = tsens_get_temp(&tsens_dev, &temp); if (ret) { pr_debug("%s: Unable to read TSENS sensor %d\n", KBUILD_MODNAME, tsens_dev.sensor_num); goto reschedule; } if (!limit_init) { ret = msm_thermal_get_freq_table(); if (ret) goto reschedule; else limit_init = 1; } do_core_control(temp); do_vdd_restriction(); do_psm(); do_freq_control(temp); reschedule: if (enabled) schedule_delayed_work(&check_temp_work, msecs_to_jiffies(msm_thermal_info.poll_ms)); }
static void check_temp(struct work_struct *work) { struct cpufreq_policy *cpu_policy = NULL; struct tsens_device tsens_dev; unsigned long temp = 0; unsigned int max_freq = 0; int update_policy = 0; int cpu = 0; int ret = 0; tsens_dev.sensor_num = DEF_TEMP_SENSOR; ret = tsens_get_temp(&tsens_dev, &temp); if (ret) { pr_debug("msm_thermal: Unable to read TSENS sensor %d\n", tsens_dev.sensor_num); goto reschedule; } else pr_info("msm_thermal: TSENS sensor %d (%ld C)\n", tsens_dev.sensor_num, temp); for_each_possible_cpu(cpu) { update_policy = 0; cpu_policy = cpufreq_cpu_get(cpu); if (!cpu_policy) { pr_debug("msm_thermal: NULL policy on cpu %d\n", cpu); continue; } if (temp >= allowed_max_high) { if (cpu_policy->max > allowed_max_freq) { update_policy = 1; max_freq = allowed_max_freq; } else { pr_debug("msm_thermal: policy max for cpu %d " "already < allowed_max_freq\n", cpu); } } else if (temp < allowed_max_low) { if (cpu_policy->max < cpu_policy->cpuinfo.max_freq) { max_freq = cpu_policy->cpuinfo.max_freq; update_policy = 1; } else { pr_debug("msm_thermal: policy max for cpu %d " "already at max allowed\n", cpu); } } if (update_policy) update_cpu_max_freq(cpu_policy, cpu, max_freq); cpufreq_cpu_put(cpu_policy); } reschedule: if (enabled) schedule_delayed_work(&check_temp_work, msecs_to_jiffies(check_interval_ms)); }
static ssize_t show_temp(struct device *dev, struct device_attribute *attr, char *buf) { struct tsens_device dev_temp; unsigned long temp = 0; dev_temp.sensor_num = 0; tsens_get_temp(&dev_temp, &temp); return snprintf(buf, 4, "%ld\n", temp*10); }
static void check_temp(struct work_struct *work) { struct cpufreq_policy *cpu_policy = NULL; struct tsens_device tsens_dev; unsigned long temp = 0; unsigned int max_freq = 0; int update_policy = 0; int cpu = 0; int ret = 0; mutex_lock(&policy_mutex); tsens_dev.sensor_num = DEF_TEMP_SENSOR; ret = tsens_get_temp(&tsens_dev, &temp); if (ret) { pr_debug("msm_thermal: Unable to read TSENS sensor %d\n", tsens_dev.sensor_num); goto reschedule; } /* lock hotplug when updating CPUfreq policy */ get_online_cpus(); for_each_online_cpu(cpu) { update_policy = 0; cpu_policy = per_cpu(policy, cpu); if (!cpu_policy) { pr_debug("msm_thermal: No CPUFreq policy found for " "cpu %d\n", cpu); continue; } if (temp >= allowed_max_high) { if (cpu_policy->max > allowed_max_freq) { update_policy = 1; max_freq = allowed_max_freq; } } else if (temp < allowed_max_low) { if (cpu_policy->max < cpu_policy->cpuinfo.max_freq) { max_freq = cpu_policy->cpuinfo.max_freq; update_policy = 1; } } if (update_policy) update_cpu_max_freq(cpu, max_freq); } put_online_cpus(); reschedule: if (enabled) schedule_delayed_work(&check_temp_work, msecs_to_jiffies(check_interval_ms)); mutex_unlock(&policy_mutex); }
static int do_vdd_restriction(void) { struct tsens_device tsens_dev; long temp = 0; int ret = 0; int i = 0; int dis_cnt = 0; if (!vdd_rstr_enabled) return ret; if (usefreq && !freq_table_get) { if (check_freq_table()) return ret; } mutex_lock(&vdd_rstr_mutex); for (i = 0; i < max_tsens_num; i++) { tsens_dev.sensor_num = i; ret = tsens_get_temp(&tsens_dev, &temp); if (ret) { pr_debug("%s: Unable to read TSENS sensor %d\n", __func__, tsens_dev.sensor_num); dis_cnt++; continue; } if (temp <= msm_thermal_info.vdd_rstr_temp_hyst_degC && vdd_rstr_en.enabled == 0) { ret = vdd_restriction_apply_all(1); if (ret) { pr_err( \ "Enable vdd rstr votlage for all failed\n"); goto exit; } vdd_rstr_en.enabled = 1; goto exit; } else if (temp > msm_thermal_info.vdd_rstr_temp_degC && vdd_rstr_en.enabled == 1) dis_cnt++; } if (dis_cnt == max_tsens_num) { ret = vdd_restriction_apply_all(0); if (ret) { pr_err("Disable vdd rstr votlage for all failed\n"); goto exit; } vdd_rstr_en.enabled = 0; } exit: mutex_unlock(&vdd_rstr_mutex); return ret; }
static int do_psm(void) { struct tsens_device tsens_dev; long temp = 0; int ret = 0; int i = 0; int auto_cnt = 0; mutex_lock(&psm_mutex); for (i = 0; i < max_tsens_num; i++) { tsens_dev.sensor_num = tsens_id_map[i]; ret = tsens_get_temp(&tsens_dev, &temp); if (ret) { pr_debug("%s: Unable to read TSENS sensor %d\n", __func__, tsens_dev.sensor_num); auto_cnt++; continue; } /* * As long as one sensor is above the threshold, set PWM mode * on all rails, and loop stops. Set auto mode when all rails * are below thershold */ if (temp > msm_thermal_info.psm_temp_degC) { ret = psm_set_mode_all(PMIC_PWM_MODE); if (ret) { pr_err("Set pwm mode for all failed\n"); goto exit; } break; } else if (temp <= msm_thermal_info.psm_temp_hyst_degC) auto_cnt++; } if (auto_cnt == max_tsens_num) { ret = psm_set_mode_all(PMIC_AUTO_MODE); if (ret) { pr_err("Set auto mode for all failed\n"); goto exit; } } exit: mutex_unlock(&psm_mutex); return ret; }
static void check_temp(struct work_struct *work) { struct tsens_device tsens_dev; unsigned long temp = 0; uint32_t max_freq = limited_max_freq; int cpu = 0; int ret = 0; tsens_dev.sensor_num = msm_thermal_info.sensor_id; ret = tsens_get_temp(&tsens_dev, &temp); if (ret) { pr_debug("msm_thermal: Unable to read TSENS sensor %d\n", tsens_dev.sensor_num); goto reschedule; } else pr_info("msm_thermal: TSENS sensor %d (%ld C)\n", tsens_dev.sensor_num, temp); if (temp >= msm_thermal_info.limit_temp) { max_freq = msm_thermal_info.limit_freq; #ifdef CONFIG_PERFLOCK_BOOT_LOCK release_boot_lock(); #endif } else if (temp < msm_thermal_info.limit_temp - msm_thermal_info.temp_hysteresis) max_freq = MSM_CPUFREQ_NO_LIMIT; if (max_freq == limited_max_freq) goto reschedule; for_each_possible_cpu(cpu) { ret = update_cpu_max_freq(cpu, max_freq); if (ret) pr_debug("Unable to limit cpu%d max freq to %d\n", cpu, max_freq); } reschedule: if (enabled) schedule_delayed_work(&check_temp_work, msecs_to_jiffies(msm_thermal_info.poll_ms)); }
static void check_temp(struct work_struct *work) { struct cpufreq_policy *cpu_policy = NULL; struct tsens_device tsens_dev; unsigned long temp = 0; unsigned int max_freq = 0; int update_policy = 0; int cpu = 0; int ret = 0; tsens_dev.sensor_num = DEF_TEMP_SENSOR; ret = tsens_get_temp(&tsens_dev, &temp); if (ret) { pr_debug("msm_thermal: Unable to read TSENS sensor %d\n", tsens_dev.sensor_num); goto reschedule; } else pr_info("msm_thermal: TSENS sensor %d (%ld C)\n", tsens_dev.sensor_num, temp); for_each_possible_cpu(cpu) { update_policy = 0; cpu_policy = cpufreq_cpu_get(cpu); if (!cpu_policy) { pr_debug("msm_thermal: NULL policy on cpu %d\n", cpu); continue; } if (temp >= allowed_max_high) { if (cpu_policy->max > allowed_max_freq) { update_policy = 1; /* save pre-throttled max freq value */ pre_throttled_max = cpu_policy->max; max_freq = allowed_max_freq; thermal_throttled = 1; pr_warn("Thermal Throttled! Set max freq to: \ %u\n", max_freq); } else { pr_debug("msm_thermal: policy max for cpu %d " "already < allowed_max_freq\n", cpu); } } else if (temp < allowed_max_low) {
static void __ref msm_therm_temp_log(struct work_struct *work) { struct tsens_device tsens_dev; long temp = 0; uint32_t max_sensors = 0; if(!(tsens_get_max_sensor_num(&max_sensors))) { int i ,added = 0; char buffer[500]; for (i = 0 ; i< max_sensors;i++) { int ret = 0; tsens_dev.sensor_num = i; tsens_get_temp(&tsens_dev,&temp); ret = sprintf(buffer + added , "(%d --- %ld)", i ,temp ); added += ret; } pr_debug("%s: Debug Temp for Sensors %s",KBUILD_MODNAME,buffer); } schedule_delayed_work(&temp_log_work, HZ*5); }
static void check_temp_and_throttle_if_needed(struct work_struct *work) { struct tsens_device tsens_dev; unsigned long temp_ul = 0; unsigned temp; int new_bin; int ret; tsens_dev.sensor_num = msm_thermal_info.sensor_id; ret = tsens_get_temp(&tsens_dev, &temp_ul); if (ret) { pr_warn("msm_thermal: Unable to read TSENS sensor %d\n", tsens_dev.sensor_num); return; } temp = (unsigned) temp_ul; new_bin = select_throttled_bin(temp); pr_debug("msm_thermal: TSENS sensor %d is %u degC old-bin %d new-bin %d\n", tsens_dev.sensor_num, temp, throttled_bin, new_bin); update_all_cpus_max_freq_if_changed(new_bin, temp); }
static void __cpuinit check_temp(struct work_struct *work) { static int limit_init; struct tsens_device tsens_dev; long temp = 0; uint32_t max_freq = limited_max_freq; int cpu = 0; int ret = 0; tsens_dev.sensor_num = msm_thermal_info.sensor_id; ret = tsens_get_temp(&tsens_dev, &temp); current_temp = temp; if (ret) { pr_debug("%s: Unable to read TSENS sensor %d\n", KBUILD_MODNAME, tsens_dev.sensor_num); goto reschedule; } if (!limit_init) { ret = msm_thermal_get_freq_table(); if (ret) goto reschedule; else limit_init = 1; } do_core_control(temp); if (temp >= msm_thermal_info.limit_temp_degC) { if (limit_idx == limit_idx_low) goto reschedule; limit_idx -= msm_thermal_info.freq_step; if (limit_idx < limit_idx_low) limit_idx = limit_idx_low; max_freq = table[limit_idx].frequency; } else if (temp < msm_thermal_info.limit_temp_degC - msm_thermal_info.temp_hysteresis_degC) { if (limit_idx == limit_idx_high) goto reschedule; limit_idx += msm_thermal_info.freq_step; if (limit_idx >= limit_idx_high) { limit_idx = limit_idx_high; max_freq = MSM_CPUFREQ_NO_LIMIT; } else max_freq = table[limit_idx].frequency; } if (max_freq == limited_max_freq) goto reschedule; /* Update new limits */ for_each_possible_cpu(cpu) { ret = update_cpu_max_freq(cpu, max_freq); if (ret) pr_debug( "%s: Unable to limit cpu%d max freq to %d\n", KBUILD_MODNAME, cpu, max_freq); } reschedule: if (enabled) schedule_delayed_work(&check_temp_work, msecs_to_jiffies(msm_thermal_info.poll_ms)); }
static void check_temp(struct work_struct *work) { static int limit_init; struct tsens_device tsens_dev; unsigned long temp = 0; uint32_t max_freq = limited_max_freq; int cpu = 0; int ret = 0; policy = cpufreq_cpu_get(0); tsens_dev.sensor_num = msm_thermal_info.sensor_id; ret = tsens_get_temp(&tsens_dev, &temp); if (ret) { pr_debug("msm_thermal: Unable to read TSENS sensor %d\n", tsens_dev.sensor_num); goto reschedule; } if (!limit_init) { ret = msm_thermal_get_freq_table(); if (ret) goto reschedule; else limit_init = 1; } if (temp >= temp_threshold) { if (!throttling) { max_frequency = policy->max; throttling = true; } if (limit_idx == limit_idx_low) goto reschedule; limit_idx = limit_idx_low; if (limit_idx < limit_idx_low) limit_idx = limit_idx_low; max_freq = table[limit_idx].frequency; } else if (temp < (temp_threshold - 5)) { if (limit_idx == limit_idx_high) goto reschedule; limit_idx = limit_idx_high; max_freq = max_frequency; } if (max_freq == limited_max_freq) goto reschedule; /* Update new limits */ for_each_possible_cpu(cpu) { ret = update_cpu_max_freq(cpu, max_freq); if (ret) pr_debug("Unable to limit cpu%d max freq to %d\n", cpu, max_freq); } reschedule: if (enabled) schedule_delayed_work(&check_temp_work, msecs_to_jiffies(POLLING_DELAY)); }
static void __cpuinit check_tempk(struct work_struct *work) { unsigned int new_freq; struct tsens_device tsens_dev; long temp = 0; int ret = 0; tsens_dev.sensor_num = kmsm_thermal_info.sensor_id; ret = tsens_get_temp(&tsens_dev, &temp); if (ret) { pr_debug("%s: Unable to read TSENS sensor %d\n", KBUILD_MODNAME, tsens_dev.sensor_num); goto reschedule; } //pr_alert("CHECK TEMP %lu-%d-%d\n", temp, kmsm_thermal_info.temp_limit_degC_start, kmsm_thermal_info.temp_limit_degC_stop); kmsm_thermal_info.current_temp = temp; if (temp >= kmsm_thermal_info.temp_limit_degC_start) { unsigned int i; if (!kmsm_thermal_info.isthrottling) { //prev_freq = cpufreq_get(0); thermal_get_freq_table(); pr_alert("START KTHROTTLING - current temp = %lu - set point = %d\n", temp, kmsm_thermal_info.temp_limit_degC_start); } kmsm_thermal_info.isthrottling = 1; //policy = cpufreq_cpu_get(0); //__cpufreq_driver_target(policy, 1296000, CPUFREQ_RELATION_H); limit_idx -= kmsm_thermal_info.freq_steps_while_throttling; if (limit_idx < limit_idx_low) limit_idx = limit_idx_low; for (i = 0; i < num_online_cpus(); i++) { //pr_alert("KTHROTTLING LOOP - current temp = %lu - set point = %d\n", temp, kmsm_thermal_info.temp_limit_degC_start); if (cpu_online(i) && cpufreq_get(i) != table[limit_idx].frequency) { //pr_alert("KTHROTTLING LOOP IN IF - current temp = %lu - set point = %d\n", temp, kmsm_thermal_info.temp_limit_degC_start); //policy = NULL; //policy = cpufreq_cpu_get(i); //if (policy != NULL) // __cpufreq_driver_target(policy, 1296000, CPUFREQ_RELATION_H); new_freq = table[limit_idx].frequency; do_kthermal(i, new_freq); } } } else if (kmsm_thermal_info.isthrottling && temp > kmsm_thermal_info.temp_limit_degC_stop && temp < kmsm_thermal_info.temp_limit_degC_start) { unsigned int i; for (i = 0; i < num_online_cpus(); i++) { if (cpu_online(i) && cpufreq_get(i) != table[limit_idx].frequency) { new_freq = table[limit_idx].frequency; do_kthermal(i, new_freq); } } } else if (kmsm_thermal_info.isthrottling && temp <= kmsm_thermal_info.temp_limit_degC_stop) { unsigned int i; bool stopThrottle = false; //policy = cpufreq_cpu_get(0); //if (prev_freq > 0) // __cpufreq_driver_target(policy, prev_freq, CPUFREQ_RELATION_H); limit_idx += kmsm_thermal_info.freq_steps_while_throttling; if (limit_idx >= limit_idx_high) { limit_idx = limit_idx_high; kmsm_thermal_info.isthrottling = 0; stopThrottle = true; pr_alert("STOP KTHROTTLING - current temp = %lu\n", temp); } for (i = 0; i < num_online_cpus(); i++) { if (cpu_online(i)) { //policy = NULL; //policy = cpufreq_cpu_get(i); //if (prev_freq > 0 && policy != NULL) // __cpufreq_driver_target(policy, prev_freq, CPUFREQ_RELATION_H); //do_thermal(i, prev_freq); new_freq = table[limit_idx].frequency; do_kthermal(i, new_freq); } } if (stopThrottle) do_kthermal(0, 0); } reschedule: schedule_delayed_work_on(0, &check_temp_workk, msecs_to_jiffies(kmsm_thermal_info.poll_speed)); }
static void __cpuinit check_temp(struct work_struct *work) { static int limit_init; struct tsens_device tsens_dev; long temp = 0; uint32_t max_freq = limited_max_freq; int cpu = 0; int ret = 0; tsens_dev.sensor_num = msm_thermal_info.sensor_id; ret = tsens_get_temp(&tsens_dev, &temp); if (ret) { pr_debug("%s: Unable to read TSENS sensor %d\n", KBUILD_MODNAME, tsens_dev.sensor_num); goto reschedule; } if (!limit_init) { ret = msm_thermal_get_freq_table(); if (ret) goto reschedule; else limit_init = 1; } #if defined(CONFIG_MACH_APQ8064_GK_KR) || defined(CONFIG_MACH_APQ8064_GKATT)\ || defined(CONFIG_MACH_APQ8064_GVDCM) || defined(CONFIG_MACH_APQ8064_GV_KR) || defined(CONFIG_MACH_APQ8064_GKGLOBAL) || defined(CONFIG_MACH_APQ8064_OMEGAR_KR) || defined(CONFIG_MACH_APQ8064_OMEGA_KR) if (lge_get_factory_boot()) return; do_core_control(temp); if (temp >= msm_thermal_info.limit_temp_degC || temp <= msm_thermal_info.limit_temp_degC_low) { max_freq = DEF_ALLOWED_MAX_FREQ_1; pr_info("msm_thermal: tsens_temp %ld\n", temp); } else if ( (temp < msm_thermal_info.limit_temp_degC - msm_thermal_info.temp_hysteresis_degC) && (temp > msm_thermal_info.limit_temp_degC_low)) { max_freq = DEF_ALLOWED_MAX_FREQ_2; } else { if(limited_max_freq == MSM_CPUFREQ_NO_LIMIT) max_freq = DEF_ALLOWED_MAX_FREQ_2; } #else do_core_control(temp); if (temp >= msm_thermal_info.limit_temp_degC #if defined(CONFIG_MACH_APQ8064_GVAR_CMCC) // || temp <= msm_thermal_info.limit_temp_degC_low #endif ) { if (limit_idx == limit_idx_low) goto reschedule; limit_idx -= msm_thermal_info.freq_step; if (limit_idx < limit_idx_low) limit_idx = limit_idx_low; max_freq = table[limit_idx].frequency; #ifdef CONFIG_LGE_PM if(max_freq >= 1026000) max_freq = DEF_ALLOWED_MAX_FREQ; pr_info("msm_thermal: tsens_temp %ld\n", temp); #endif } else if ( (temp < msm_thermal_info.limit_temp_degC - msm_thermal_info.temp_hysteresis_degC) #if defined(CONFIG_MACH_APQ8064_GVAR_CMCC) // && (temp > msm_thermal_info.limit_temp_degC_low) #endif ) { if (limit_idx == limit_idx_high) goto reschedule; limit_idx += msm_thermal_info.freq_step; if (limit_idx >= limit_idx_high) { limit_idx = limit_idx_high; max_freq = MSM_CPUFREQ_NO_LIMIT; } else max_freq = table[limit_idx].frequency; } #endif if (max_freq == limited_max_freq) goto reschedule; /* Update new limits */ for_each_possible_cpu(cpu) { ret = update_cpu_max_freq(cpu, max_freq); if (ret) pr_debug( "%s: Unable to limit cpu%d max freq to %d\n", KBUILD_MODNAME, cpu, max_freq); } reschedule: if (enabled) schedule_delayed_work(&check_temp_work, msecs_to_jiffies(msm_thermal_info.poll_ms)); }