Loading drivers/thermal/msm_thermal.c +65 −0 Original line number Diff line number Diff line Loading @@ -41,6 +41,8 @@ #include <soc/qcom/scm.h> #include <linux/debugfs.h> #include <linux/pm_opp.h> #include <linux/notifier.h> #include <linux/reboot.h> #define CREATE_TRACE_POINTS #define TRACE_MSM_THERMAL Loading Loading @@ -191,6 +193,7 @@ struct cpu_info { struct sensor_threshold threshold[THRESHOLD_MAX_NR]; bool max_freq; uint32_t user_max_freq; uint32_t reboot_max_freq; uint32_t user_min_freq; uint32_t limited_max_freq; uint32_t limited_min_freq; Loading Loading @@ -370,6 +373,62 @@ enum ocr_request { sysfs_attr_init(&ko_attr.attr); \ _attr_gp.attrs[0] = &ko_attr.attr; uint32_t get_core_min_freq(uint32_t cpu) { int i; uint32_t min_freq = UINT_MAX; if (core_ptr) { for (i = 0; i < core_ptr->entity_count; i++) { struct cluster_info *cluster_ptr = &core_ptr->child_entity_ptr[i]; if (*cluster_ptr->cluster_cores.bits & BIT(cpu)) { if (cluster_ptr->freq_table) min_freq = cluster_ptr->freq_table[0].frequency; break; } } } else { if (table) min_freq = table[0].frequency; } return min_freq; } static int msm_thermal_reboot_callback( struct notifier_block *nfb, unsigned long val, void *data) { if (val == SYS_RESTART) { uint32_t cpu; for_each_possible_cpu(cpu) { if (msm_thermal_info.freq_mitig_control_mask & BIT(cpu)) { cpus[cpu].reboot_max_freq = get_core_min_freq(cpu); if (cpus[cpu].reboot_max_freq == UINT_MAX) continue; cpus[cpu].max_freq = true; if (freq_mitigation_task) { cpus[cpu].freq_thresh_clear = true; complete(&freq_mitigation_complete); } else { pr_err( "Freq mit task is not initialized\n"); } } } } return NOTIFY_DONE; } static struct notifier_block msm_thermal_reboot_notifier = { .notifier_call = msm_thermal_reboot_callback, }; static int msm_thermal_cpufreq_callback(struct notifier_block *nfb, unsigned long event, void *data) { Loading Loading @@ -2651,6 +2710,9 @@ static __ref int do_freq_mitigation(void *data) max_freq_req = min(max_freq_req, cpus[cpu].user_max_freq); max_freq_req = min(max_freq_req, cpus[cpu].reboot_max_freq); min_freq_req = max(min_freq_limit, cpus[cpu].user_min_freq); Loading Loading @@ -3889,6 +3951,7 @@ int msm_thermal_init(struct msm_thermal_data *pdata) cpus[cpu].hotplug_thresh_clear = false; cpus[cpu].max_freq = false; cpus[cpu].user_max_freq = UINT_MAX; cpus[cpu].reboot_max_freq = UINT_MAX; cpus[cpu].user_min_freq = 0; cpus[cpu].limited_max_freq = UINT_MAX; cpus[cpu].limited_min_freq = 0; Loading @@ -3910,6 +3973,7 @@ int msm_thermal_init(struct msm_thermal_data *pdata) if (ret) pr_err("cannot register cpufreq notifier. err:%d\n", ret); register_reboot_notifier(&msm_thermal_reboot_notifier); INIT_DELAYED_WORK(&check_temp_work, check_temp); schedule_delayed_work(&check_temp_work, 0); Loading Loading @@ -5215,6 +5279,7 @@ static int msm_thermal_dev_exit(struct platform_device *inp_dev) { int i = 0; unregister_reboot_notifier(&msm_thermal_reboot_notifier); if (msm_therm_debugfs && msm_therm_debugfs->parent) debugfs_remove_recursive(msm_therm_debugfs->parent); msm_thermal_ioctl_cleanup(); Loading Loading
drivers/thermal/msm_thermal.c +65 −0 Original line number Diff line number Diff line Loading @@ -41,6 +41,8 @@ #include <soc/qcom/scm.h> #include <linux/debugfs.h> #include <linux/pm_opp.h> #include <linux/notifier.h> #include <linux/reboot.h> #define CREATE_TRACE_POINTS #define TRACE_MSM_THERMAL Loading Loading @@ -191,6 +193,7 @@ struct cpu_info { struct sensor_threshold threshold[THRESHOLD_MAX_NR]; bool max_freq; uint32_t user_max_freq; uint32_t reboot_max_freq; uint32_t user_min_freq; uint32_t limited_max_freq; uint32_t limited_min_freq; Loading Loading @@ -370,6 +373,62 @@ enum ocr_request { sysfs_attr_init(&ko_attr.attr); \ _attr_gp.attrs[0] = &ko_attr.attr; uint32_t get_core_min_freq(uint32_t cpu) { int i; uint32_t min_freq = UINT_MAX; if (core_ptr) { for (i = 0; i < core_ptr->entity_count; i++) { struct cluster_info *cluster_ptr = &core_ptr->child_entity_ptr[i]; if (*cluster_ptr->cluster_cores.bits & BIT(cpu)) { if (cluster_ptr->freq_table) min_freq = cluster_ptr->freq_table[0].frequency; break; } } } else { if (table) min_freq = table[0].frequency; } return min_freq; } static int msm_thermal_reboot_callback( struct notifier_block *nfb, unsigned long val, void *data) { if (val == SYS_RESTART) { uint32_t cpu; for_each_possible_cpu(cpu) { if (msm_thermal_info.freq_mitig_control_mask & BIT(cpu)) { cpus[cpu].reboot_max_freq = get_core_min_freq(cpu); if (cpus[cpu].reboot_max_freq == UINT_MAX) continue; cpus[cpu].max_freq = true; if (freq_mitigation_task) { cpus[cpu].freq_thresh_clear = true; complete(&freq_mitigation_complete); } else { pr_err( "Freq mit task is not initialized\n"); } } } } return NOTIFY_DONE; } static struct notifier_block msm_thermal_reboot_notifier = { .notifier_call = msm_thermal_reboot_callback, }; static int msm_thermal_cpufreq_callback(struct notifier_block *nfb, unsigned long event, void *data) { Loading Loading @@ -2651,6 +2710,9 @@ static __ref int do_freq_mitigation(void *data) max_freq_req = min(max_freq_req, cpus[cpu].user_max_freq); max_freq_req = min(max_freq_req, cpus[cpu].reboot_max_freq); min_freq_req = max(min_freq_limit, cpus[cpu].user_min_freq); Loading Loading @@ -3889,6 +3951,7 @@ int msm_thermal_init(struct msm_thermal_data *pdata) cpus[cpu].hotplug_thresh_clear = false; cpus[cpu].max_freq = false; cpus[cpu].user_max_freq = UINT_MAX; cpus[cpu].reboot_max_freq = UINT_MAX; cpus[cpu].user_min_freq = 0; cpus[cpu].limited_max_freq = UINT_MAX; cpus[cpu].limited_min_freq = 0; Loading @@ -3910,6 +3973,7 @@ int msm_thermal_init(struct msm_thermal_data *pdata) if (ret) pr_err("cannot register cpufreq notifier. err:%d\n", ret); register_reboot_notifier(&msm_thermal_reboot_notifier); INIT_DELAYED_WORK(&check_temp_work, check_temp); schedule_delayed_work(&check_temp_work, 0); Loading Loading @@ -5215,6 +5279,7 @@ static int msm_thermal_dev_exit(struct platform_device *inp_dev) { int i = 0; unregister_reboot_notifier(&msm_thermal_reboot_notifier); if (msm_therm_debugfs && msm_therm_debugfs->parent) debugfs_remove_recursive(msm_therm_debugfs->parent); msm_thermal_ioctl_cleanup(); Loading