Loading Documentation/devicetree/bindings/arm/msm/msm_thermal.txt +5 −0 Original line number Diff line number Diff line Loading @@ -105,6 +105,10 @@ Optional properties - qcom,disable-cx-phase-ctrl: If this property is defined, the feature cx phase control will be disabled. All other properties corresponding to this feature will be ignored. - qcom,therm-ddr-lm-info: If this optional property is defined, it enables DDR frequency restriction feature. It expects array of sensor id to be monitored, high threshold and low threshold for that sensor respectively. Optional child nodes - qcom,pmic-opt-curr-temp: Threshold temperature for requesting optimum current (request Loading Loading @@ -280,6 +284,7 @@ Example: qcom,cx-retention-min = <RPM_SMD_REGULATOR_LEVEL_RETENTION_PLUS>; vdd-cx-supply = <&pmd9635_s5_level>; qcom,online-hotplug-core; qcom,therm-ddr-lm-info = <1 90 75>; qcom,synchronous-cluster-id = <0 1>; /* Indicates cluster 0 and 1 are synchronous */ qcom,synchronous-cluster-map = <0 2 &CPU0 &CPU1>, <1 2 &CPU2 &CPU3>; Loading arch/arm/boot/dts/qcom/mdm9607.dtsi +1 −0 Original line number Diff line number Diff line Loading @@ -1224,6 +1224,7 @@ qcom,vdd-restriction-temp = <5>; qcom,vdd-restriction-temp-hysteresis = <10>; vdd-dig-supply = <&mdm9607_s3_floor_level>; qcom,therm-ddr-lm-info = <2 78 70>; qcom,vdd-dig-rstr{ qcom,vdd-rstr-reg = "vdd-dig"; Loading drivers/thermal/msm_thermal.c +246 −0 Original line number Diff line number Diff line Loading @@ -49,6 +49,7 @@ #include <linux/suspend.h> #include <linux/uaccess.h> #include <linux/uio_driver.h> #include <linux/msm-bus.h> #define CREATE_TRACE_POINTS #define TRACE_MSM_THERMAL Loading @@ -74,6 +75,9 @@ #define DEVM_NAME_MAX 30 #define HOTPLUG_RETRY_INTERVAL_MS 100 #define UIO_VERSION "1.0" #define THERM_DDR_MASTER_ID 1 #define THERM_DDR_SLAVE_ID 512 #define THERM_DDR_IB_VOTE_REQ 366000000 #define VALIDATE_AND_SET_MASK(_node, _key, _mask, _cpu) \ do { \ Loading Loading @@ -165,6 +169,7 @@ static bool gfx_warm_phase_ctrl_enabled; static bool cx_phase_ctrl_enabled; static bool vdd_mx_enabled; static bool therm_reset_enabled; static bool therm_ddr_lm_enabled; static bool online_core; static bool cluster_info_probed; static bool cluster_info_nodes_called; Loading Loading @@ -205,6 +210,12 @@ enum thermal_threshold { THRESHOLD_MAX_NR, }; enum therm_ddr_events { THERM_DDR_LOW_THRESH = 0, THERM_DDR_HIGH_THRESH, THERM_DDR_MAX_THRESH }; struct cluster_info { int cluster_id; uint32_t entity_count; Loading Loading @@ -287,6 +298,7 @@ enum msm_thresh_list { MSM_GFX_PHASE_CTRL_HOT, MSM_OCR, MSM_VDD_MX_RESTRICTION, MSM_THERM_DDR_LM, MSM_LIST_MAX_NR, }; Loading Loading @@ -348,6 +360,8 @@ static struct cluster_info *core_ptr; static struct msm_thermal_debugfs_entry *msm_therm_debugfs; static struct devmgr_devices *devices; static struct msm_thermal_debugfs_thresh_config *mit_config; static struct msm_bus_scale_pdata *therm_ddr_lm_data; static uint8_t therm_ddr_lm_handle; struct vdd_rstr_enable { struct kobj_attribute ko_attr; Loading Loading @@ -2776,6 +2790,78 @@ static void therm_reset_notify(struct therm_threshold *thresh_data) thresh_data->threshold); } static int therm_ddr_lm_apply_limit(bool enable) { static bool ddr_lm_applied; int ret = 0; if (ddr_lm_applied == enable) return 0; ret = msm_bus_scale_client_update_request(therm_ddr_lm_handle, enable); if (ret) { pr_err("Failed to %s ddr lm limit. ret:%d\n", enable ? "Apply" : "Clear", ret); return ret; } ddr_lm_applied = enable; pr_debug("Thermal DDR restriction is %s\n", enable ? "Applied" : "Cleared"); return 0; } static inline void cleanup_bus_data(struct msm_bus_scale_pdata *data, struct platform_device *pdev) { int i = 0; if (therm_ddr_lm_handle) { therm_ddr_lm_apply_limit(false); msm_bus_scale_unregister_client(therm_ddr_lm_handle); } if (data) { if (data->usecase) { for (; i < THERM_DDR_MAX_THRESH; i++) if (data->usecase[i].vectors) devm_kfree(&pdev->dev, data->usecase[i].vectors); devm_kfree(&pdev->dev, data->usecase); } devm_kfree(&pdev->dev, data); } } static void therm_ddr_lm_notify(struct therm_threshold *trig_thresh) { if (!therm_ddr_lm_enabled) return; if (!trig_thresh) { pr_err("Invalid input\n"); return; } switch (trig_thresh->trip_triggered) { case THERMAL_TRIP_CONFIGURABLE_HI: therm_ddr_lm_apply_limit(true); break; case THERMAL_TRIP_CONFIGURABLE_LOW: therm_ddr_lm_apply_limit(false); break; default: pr_err("Invalid trip type\n"); return; } if (trig_thresh->cur_state != trig_thresh->trip_triggered) { sensor_mgr_set_threshold(trig_thresh->sensor_id, trig_thresh->threshold); trig_thresh->cur_state = trig_thresh->trip_triggered; } } static void retry_hotplug(struct work_struct *work) { mutex_lock(&core_control_mutex); Loading Loading @@ -4391,6 +4477,8 @@ therm_set_exit: static void thermal_monitor_init(void) { int ret = 0; if (thermal_monitor_task) return; Loading Loading @@ -4436,6 +4524,15 @@ static void thermal_monitor_init(void) !(convert_to_zone_id(&thresh[MSM_VDD_MX_RESTRICTION]))) therm_set_threshold(&thresh[MSM_VDD_MX_RESTRICTION]); if (therm_ddr_lm_enabled && !(convert_to_zone_id(&thresh[MSM_THERM_DDR_LM]))) { thresh[MSM_THERM_DDR_LM].thresh_list->trip_triggered = -1; ret = sensor_mgr_set_threshold( thresh[MSM_THERM_DDR_LM].thresh_list->sensor_id, thresh[MSM_THERM_DDR_LM].thresh_list->threshold); if (!IS_HI_THRESHOLD_SET(ret)) therm_ddr_lm_apply_limit(true); } init_exit: return; } Loading Loading @@ -6106,6 +6203,128 @@ fetch_mitig_exit: return err; } static int msm_bus_data_init(struct platform_device *pdev) { struct msm_bus_scale_pdata *ddr_bus_data = NULL; int ret = 0, i = 0; ddr_bus_data = devm_kzalloc(&pdev->dev, sizeof(*ddr_bus_data), GFP_KERNEL); if (!ddr_bus_data) { ret = -ENOMEM; goto bus_exit; } ddr_bus_data->num_usecases = THERM_DDR_MAX_THRESH; ddr_bus_data->name = KBUILD_MODNAME; ddr_bus_data->usecase = devm_kcalloc(&pdev->dev, THERM_DDR_MAX_THRESH, sizeof(*(ddr_bus_data->usecase)), GFP_KERNEL); if (!ddr_bus_data->usecase) { ret = -ENOMEM; goto bus_exit; } for (i = 0; i < THERM_DDR_MAX_THRESH; i++) { ddr_bus_data->usecase[i].num_paths = 1; ddr_bus_data->usecase[i].vectors = devm_kzalloc(&pdev->dev, sizeof(*(ddr_bus_data->usecase[i].vectors)), GFP_KERNEL); if (!ddr_bus_data->usecase[i].vectors) { ret = -ENOMEM; goto bus_exit; } /* set common entry values */ ddr_bus_data->usecase[i].vectors->src = THERM_DDR_MASTER_ID; ddr_bus_data->usecase[i].vectors->dst = THERM_DDR_SLAVE_ID; ddr_bus_data->usecase[i].vectors->ab = 0; } ddr_bus_data->usecase[THERM_DDR_LOW_THRESH].vectors->ib = 0; ddr_bus_data->usecase[THERM_DDR_HIGH_THRESH].vectors->ib = THERM_DDR_IB_VOTE_REQ; therm_ddr_lm_handle = msm_bus_scale_register_client(ddr_bus_data); if (!therm_ddr_lm_handle) { pr_err("Failed to register with bus driver\n"); ret = -EINVAL; goto bus_exit; } therm_ddr_lm_data = ddr_bus_data; bus_exit: if (ret) cleanup_bus_data(ddr_bus_data, pdev); return ret; } static void thermal_ddr_lm_disable(void) { int ret = 0; THERM_MITIGATION_DISABLE(therm_ddr_lm_enabled, MSM_THERM_DDR_LM); ret = therm_ddr_lm_apply_limit(false); if (ret) pr_err("Disable ddr lm failed. err:%d\n", ret); } static int probe_therm_ddr_lm(struct platform_device *pdev) { char *key = NULL; int ret = 0, arr_size = 0; struct device_node *node = pdev->dev.of_node; enum ddr_therm_cfg { THERM_DDR_SENS_ID = 0, THERM_DDR_HIGH_TEMP, THERM_DDR_LOW_TEMP, THERM_DDR_MAX_ENTRY }; uint32_t therm_ddr_data[THERM_DDR_MAX_ENTRY] = {0}; key = "qcom,therm-ddr-lm-info"; if (!of_get_property(node, key, &arr_size) || arr_size <= 0) return 0; arr_size = arr_size / sizeof(__be32); if (arr_size != THERM_DDR_MAX_ENTRY) goto PROBE_DDR_LM_EXIT; ret = of_property_read_u32_array(node, key, therm_ddr_data, THERM_DDR_MAX_ENTRY); if (ret) goto PROBE_DDR_LM_EXIT; /* Initialize bus APIs */ ret = msm_bus_data_init(pdev); if (ret) goto PROBE_DDR_LM_EXIT; ret = sensor_mgr_init_threshold(&thresh[MSM_THERM_DDR_LM], therm_ddr_data[THERM_DDR_SENS_ID], therm_ddr_data[THERM_DDR_HIGH_TEMP], therm_ddr_data[THERM_DDR_LOW_TEMP], therm_ddr_lm_notify); if (ret) { pr_err("ddr lm sensor init failed\n"); goto PROBE_DDR_LM_EXIT; } therm_ddr_lm_enabled = true; snprintf(mit_config[MSM_THERM_DDR_LM].config_name, MAX_DEBUGFS_CONFIG_LEN, "ddr_lm"); mit_config[MSM_THERM_DDR_LM].disable_config = thermal_ddr_lm_disable; PROBE_DDR_LM_EXIT: if (ret) { dev_info(&pdev->dev, "%s:Failed reading node=%s, key=%s err=%d. KTM continues\n", __func__, node->full_name, key, ret); therm_ddr_lm_enabled = false; } return ret; } static void probe_sensor_info(struct device_node *node, struct msm_thermal_data *data, struct platform_device *pdev) { Loading Loading @@ -6823,6 +7042,21 @@ static void thermal_ocr_config_read(struct seq_file *m, void *data) } } static void therm_ddr_lm_config_read(struct seq_file *m, void *data) { if (therm_ddr_lm_enabled) { seq_puts(m, "\n-----DDR Restriction(DDR LM)-----\n"); seq_printf(m, "threshold:%ld degC\n", thresh[ MSM_THERM_DDR_LM].thresh_list->threshold[0].temp); seq_printf(m, "threshold clear:%ld degC\n", thresh[ MSM_THERM_DDR_LM].thresh_list->threshold[1].temp); seq_printf(m, "tsens sensor:tsens_tz_sensor%d\n", thresh[MSM_THERM_DDR_LM].thresh_list->sensor_id); } } static void thermal_phase_ctrl_config_read(struct seq_file *m, void *data) { if (cx_phase_ctrl_enabled) { Loading Loading @@ -6861,6 +7095,7 @@ static void thermal_disable_all_mitigation(void) thermal_vdd_mit_disable(); thermal_psm_mit_disable(); thermal_ocr_mit_disable(); thermal_ddr_lm_disable(); thermal_cx_phase_ctrl_mit_disable(); thermal_gfx_phase_warm_ctrl_mit_disable(); thermal_gfx_phase_crit_ctrl_mit_disable(); Loading Loading @@ -6890,6 +7125,9 @@ static void enable_config(int config_id) case MSM_VDD_MX_RESTRICTION: vdd_mx_enabled = 1; break; case MSM_THERM_DDR_LM: therm_ddr_lm_enabled = 1; break; case MSM_LIST_MAX_NR + HOTPLUG_CONFIG: hotplug_enabled = 1; break; Loading Loading @@ -6993,6 +7231,7 @@ static int thermal_config_debugfs_read(struct seq_file *m, void *data) thermal_psm_config_read(m, data); thermal_ocr_config_read(m, data); thermal_phase_ctrl_config_read(m, data); therm_ddr_lm_config_read(m, data); return 0; } Loading Loading @@ -7182,6 +7421,12 @@ static int msm_thermal_dev_exit(struct platform_device *inp_dev) &thresh[MSM_VDD_MX_RESTRICTION]); kfree(thresh[MSM_VDD_MX_RESTRICTION].thresh_list); } if (therm_ddr_lm_enabled) { sensor_mgr_remove_threshold( &thresh[MSM_THERM_DDR_LM]); cleanup_bus_data(therm_ddr_lm_data, inp_dev); } kfree(thresh); thresh = NULL; } Loading Loading @@ -7234,6 +7479,7 @@ int __init msm_thermal_late_init(void) if (!msm_thermal_probed) return 0; probe_therm_ddr_lm(msm_thermal_info.pdev); if (num_possible_cpus() > 1) msm_thermal_add_cc_nodes(); msm_thermal_add_psm_nodes(); Loading Loading
Documentation/devicetree/bindings/arm/msm/msm_thermal.txt +5 −0 Original line number Diff line number Diff line Loading @@ -105,6 +105,10 @@ Optional properties - qcom,disable-cx-phase-ctrl: If this property is defined, the feature cx phase control will be disabled. All other properties corresponding to this feature will be ignored. - qcom,therm-ddr-lm-info: If this optional property is defined, it enables DDR frequency restriction feature. It expects array of sensor id to be monitored, high threshold and low threshold for that sensor respectively. Optional child nodes - qcom,pmic-opt-curr-temp: Threshold temperature for requesting optimum current (request Loading Loading @@ -280,6 +284,7 @@ Example: qcom,cx-retention-min = <RPM_SMD_REGULATOR_LEVEL_RETENTION_PLUS>; vdd-cx-supply = <&pmd9635_s5_level>; qcom,online-hotplug-core; qcom,therm-ddr-lm-info = <1 90 75>; qcom,synchronous-cluster-id = <0 1>; /* Indicates cluster 0 and 1 are synchronous */ qcom,synchronous-cluster-map = <0 2 &CPU0 &CPU1>, <1 2 &CPU2 &CPU3>; Loading
arch/arm/boot/dts/qcom/mdm9607.dtsi +1 −0 Original line number Diff line number Diff line Loading @@ -1224,6 +1224,7 @@ qcom,vdd-restriction-temp = <5>; qcom,vdd-restriction-temp-hysteresis = <10>; vdd-dig-supply = <&mdm9607_s3_floor_level>; qcom,therm-ddr-lm-info = <2 78 70>; qcom,vdd-dig-rstr{ qcom,vdd-rstr-reg = "vdd-dig"; Loading
drivers/thermal/msm_thermal.c +246 −0 Original line number Diff line number Diff line Loading @@ -49,6 +49,7 @@ #include <linux/suspend.h> #include <linux/uaccess.h> #include <linux/uio_driver.h> #include <linux/msm-bus.h> #define CREATE_TRACE_POINTS #define TRACE_MSM_THERMAL Loading @@ -74,6 +75,9 @@ #define DEVM_NAME_MAX 30 #define HOTPLUG_RETRY_INTERVAL_MS 100 #define UIO_VERSION "1.0" #define THERM_DDR_MASTER_ID 1 #define THERM_DDR_SLAVE_ID 512 #define THERM_DDR_IB_VOTE_REQ 366000000 #define VALIDATE_AND_SET_MASK(_node, _key, _mask, _cpu) \ do { \ Loading Loading @@ -165,6 +169,7 @@ static bool gfx_warm_phase_ctrl_enabled; static bool cx_phase_ctrl_enabled; static bool vdd_mx_enabled; static bool therm_reset_enabled; static bool therm_ddr_lm_enabled; static bool online_core; static bool cluster_info_probed; static bool cluster_info_nodes_called; Loading Loading @@ -205,6 +210,12 @@ enum thermal_threshold { THRESHOLD_MAX_NR, }; enum therm_ddr_events { THERM_DDR_LOW_THRESH = 0, THERM_DDR_HIGH_THRESH, THERM_DDR_MAX_THRESH }; struct cluster_info { int cluster_id; uint32_t entity_count; Loading Loading @@ -287,6 +298,7 @@ enum msm_thresh_list { MSM_GFX_PHASE_CTRL_HOT, MSM_OCR, MSM_VDD_MX_RESTRICTION, MSM_THERM_DDR_LM, MSM_LIST_MAX_NR, }; Loading Loading @@ -348,6 +360,8 @@ static struct cluster_info *core_ptr; static struct msm_thermal_debugfs_entry *msm_therm_debugfs; static struct devmgr_devices *devices; static struct msm_thermal_debugfs_thresh_config *mit_config; static struct msm_bus_scale_pdata *therm_ddr_lm_data; static uint8_t therm_ddr_lm_handle; struct vdd_rstr_enable { struct kobj_attribute ko_attr; Loading Loading @@ -2776,6 +2790,78 @@ static void therm_reset_notify(struct therm_threshold *thresh_data) thresh_data->threshold); } static int therm_ddr_lm_apply_limit(bool enable) { static bool ddr_lm_applied; int ret = 0; if (ddr_lm_applied == enable) return 0; ret = msm_bus_scale_client_update_request(therm_ddr_lm_handle, enable); if (ret) { pr_err("Failed to %s ddr lm limit. ret:%d\n", enable ? "Apply" : "Clear", ret); return ret; } ddr_lm_applied = enable; pr_debug("Thermal DDR restriction is %s\n", enable ? "Applied" : "Cleared"); return 0; } static inline void cleanup_bus_data(struct msm_bus_scale_pdata *data, struct platform_device *pdev) { int i = 0; if (therm_ddr_lm_handle) { therm_ddr_lm_apply_limit(false); msm_bus_scale_unregister_client(therm_ddr_lm_handle); } if (data) { if (data->usecase) { for (; i < THERM_DDR_MAX_THRESH; i++) if (data->usecase[i].vectors) devm_kfree(&pdev->dev, data->usecase[i].vectors); devm_kfree(&pdev->dev, data->usecase); } devm_kfree(&pdev->dev, data); } } static void therm_ddr_lm_notify(struct therm_threshold *trig_thresh) { if (!therm_ddr_lm_enabled) return; if (!trig_thresh) { pr_err("Invalid input\n"); return; } switch (trig_thresh->trip_triggered) { case THERMAL_TRIP_CONFIGURABLE_HI: therm_ddr_lm_apply_limit(true); break; case THERMAL_TRIP_CONFIGURABLE_LOW: therm_ddr_lm_apply_limit(false); break; default: pr_err("Invalid trip type\n"); return; } if (trig_thresh->cur_state != trig_thresh->trip_triggered) { sensor_mgr_set_threshold(trig_thresh->sensor_id, trig_thresh->threshold); trig_thresh->cur_state = trig_thresh->trip_triggered; } } static void retry_hotplug(struct work_struct *work) { mutex_lock(&core_control_mutex); Loading Loading @@ -4391,6 +4477,8 @@ therm_set_exit: static void thermal_monitor_init(void) { int ret = 0; if (thermal_monitor_task) return; Loading Loading @@ -4436,6 +4524,15 @@ static void thermal_monitor_init(void) !(convert_to_zone_id(&thresh[MSM_VDD_MX_RESTRICTION]))) therm_set_threshold(&thresh[MSM_VDD_MX_RESTRICTION]); if (therm_ddr_lm_enabled && !(convert_to_zone_id(&thresh[MSM_THERM_DDR_LM]))) { thresh[MSM_THERM_DDR_LM].thresh_list->trip_triggered = -1; ret = sensor_mgr_set_threshold( thresh[MSM_THERM_DDR_LM].thresh_list->sensor_id, thresh[MSM_THERM_DDR_LM].thresh_list->threshold); if (!IS_HI_THRESHOLD_SET(ret)) therm_ddr_lm_apply_limit(true); } init_exit: return; } Loading Loading @@ -6106,6 +6203,128 @@ fetch_mitig_exit: return err; } static int msm_bus_data_init(struct platform_device *pdev) { struct msm_bus_scale_pdata *ddr_bus_data = NULL; int ret = 0, i = 0; ddr_bus_data = devm_kzalloc(&pdev->dev, sizeof(*ddr_bus_data), GFP_KERNEL); if (!ddr_bus_data) { ret = -ENOMEM; goto bus_exit; } ddr_bus_data->num_usecases = THERM_DDR_MAX_THRESH; ddr_bus_data->name = KBUILD_MODNAME; ddr_bus_data->usecase = devm_kcalloc(&pdev->dev, THERM_DDR_MAX_THRESH, sizeof(*(ddr_bus_data->usecase)), GFP_KERNEL); if (!ddr_bus_data->usecase) { ret = -ENOMEM; goto bus_exit; } for (i = 0; i < THERM_DDR_MAX_THRESH; i++) { ddr_bus_data->usecase[i].num_paths = 1; ddr_bus_data->usecase[i].vectors = devm_kzalloc(&pdev->dev, sizeof(*(ddr_bus_data->usecase[i].vectors)), GFP_KERNEL); if (!ddr_bus_data->usecase[i].vectors) { ret = -ENOMEM; goto bus_exit; } /* set common entry values */ ddr_bus_data->usecase[i].vectors->src = THERM_DDR_MASTER_ID; ddr_bus_data->usecase[i].vectors->dst = THERM_DDR_SLAVE_ID; ddr_bus_data->usecase[i].vectors->ab = 0; } ddr_bus_data->usecase[THERM_DDR_LOW_THRESH].vectors->ib = 0; ddr_bus_data->usecase[THERM_DDR_HIGH_THRESH].vectors->ib = THERM_DDR_IB_VOTE_REQ; therm_ddr_lm_handle = msm_bus_scale_register_client(ddr_bus_data); if (!therm_ddr_lm_handle) { pr_err("Failed to register with bus driver\n"); ret = -EINVAL; goto bus_exit; } therm_ddr_lm_data = ddr_bus_data; bus_exit: if (ret) cleanup_bus_data(ddr_bus_data, pdev); return ret; } static void thermal_ddr_lm_disable(void) { int ret = 0; THERM_MITIGATION_DISABLE(therm_ddr_lm_enabled, MSM_THERM_DDR_LM); ret = therm_ddr_lm_apply_limit(false); if (ret) pr_err("Disable ddr lm failed. err:%d\n", ret); } static int probe_therm_ddr_lm(struct platform_device *pdev) { char *key = NULL; int ret = 0, arr_size = 0; struct device_node *node = pdev->dev.of_node; enum ddr_therm_cfg { THERM_DDR_SENS_ID = 0, THERM_DDR_HIGH_TEMP, THERM_DDR_LOW_TEMP, THERM_DDR_MAX_ENTRY }; uint32_t therm_ddr_data[THERM_DDR_MAX_ENTRY] = {0}; key = "qcom,therm-ddr-lm-info"; if (!of_get_property(node, key, &arr_size) || arr_size <= 0) return 0; arr_size = arr_size / sizeof(__be32); if (arr_size != THERM_DDR_MAX_ENTRY) goto PROBE_DDR_LM_EXIT; ret = of_property_read_u32_array(node, key, therm_ddr_data, THERM_DDR_MAX_ENTRY); if (ret) goto PROBE_DDR_LM_EXIT; /* Initialize bus APIs */ ret = msm_bus_data_init(pdev); if (ret) goto PROBE_DDR_LM_EXIT; ret = sensor_mgr_init_threshold(&thresh[MSM_THERM_DDR_LM], therm_ddr_data[THERM_DDR_SENS_ID], therm_ddr_data[THERM_DDR_HIGH_TEMP], therm_ddr_data[THERM_DDR_LOW_TEMP], therm_ddr_lm_notify); if (ret) { pr_err("ddr lm sensor init failed\n"); goto PROBE_DDR_LM_EXIT; } therm_ddr_lm_enabled = true; snprintf(mit_config[MSM_THERM_DDR_LM].config_name, MAX_DEBUGFS_CONFIG_LEN, "ddr_lm"); mit_config[MSM_THERM_DDR_LM].disable_config = thermal_ddr_lm_disable; PROBE_DDR_LM_EXIT: if (ret) { dev_info(&pdev->dev, "%s:Failed reading node=%s, key=%s err=%d. KTM continues\n", __func__, node->full_name, key, ret); therm_ddr_lm_enabled = false; } return ret; } static void probe_sensor_info(struct device_node *node, struct msm_thermal_data *data, struct platform_device *pdev) { Loading Loading @@ -6823,6 +7042,21 @@ static void thermal_ocr_config_read(struct seq_file *m, void *data) } } static void therm_ddr_lm_config_read(struct seq_file *m, void *data) { if (therm_ddr_lm_enabled) { seq_puts(m, "\n-----DDR Restriction(DDR LM)-----\n"); seq_printf(m, "threshold:%ld degC\n", thresh[ MSM_THERM_DDR_LM].thresh_list->threshold[0].temp); seq_printf(m, "threshold clear:%ld degC\n", thresh[ MSM_THERM_DDR_LM].thresh_list->threshold[1].temp); seq_printf(m, "tsens sensor:tsens_tz_sensor%d\n", thresh[MSM_THERM_DDR_LM].thresh_list->sensor_id); } } static void thermal_phase_ctrl_config_read(struct seq_file *m, void *data) { if (cx_phase_ctrl_enabled) { Loading Loading @@ -6861,6 +7095,7 @@ static void thermal_disable_all_mitigation(void) thermal_vdd_mit_disable(); thermal_psm_mit_disable(); thermal_ocr_mit_disable(); thermal_ddr_lm_disable(); thermal_cx_phase_ctrl_mit_disable(); thermal_gfx_phase_warm_ctrl_mit_disable(); thermal_gfx_phase_crit_ctrl_mit_disable(); Loading Loading @@ -6890,6 +7125,9 @@ static void enable_config(int config_id) case MSM_VDD_MX_RESTRICTION: vdd_mx_enabled = 1; break; case MSM_THERM_DDR_LM: therm_ddr_lm_enabled = 1; break; case MSM_LIST_MAX_NR + HOTPLUG_CONFIG: hotplug_enabled = 1; break; Loading Loading @@ -6993,6 +7231,7 @@ static int thermal_config_debugfs_read(struct seq_file *m, void *data) thermal_psm_config_read(m, data); thermal_ocr_config_read(m, data); thermal_phase_ctrl_config_read(m, data); therm_ddr_lm_config_read(m, data); return 0; } Loading Loading @@ -7182,6 +7421,12 @@ static int msm_thermal_dev_exit(struct platform_device *inp_dev) &thresh[MSM_VDD_MX_RESTRICTION]); kfree(thresh[MSM_VDD_MX_RESTRICTION].thresh_list); } if (therm_ddr_lm_enabled) { sensor_mgr_remove_threshold( &thresh[MSM_THERM_DDR_LM]); cleanup_bus_data(therm_ddr_lm_data, inp_dev); } kfree(thresh); thresh = NULL; } Loading Loading @@ -7234,6 +7479,7 @@ int __init msm_thermal_late_init(void) if (!msm_thermal_probed) return 0; probe_therm_ddr_lm(msm_thermal_info.pdev); if (num_possible_cpus() > 1) msm_thermal_add_cc_nodes(); msm_thermal_add_psm_nodes(); Loading