Hello guys,
Here are a couple of fixes and clean ups on the omap thermal code.
These are trivial I'd say.
There is one question about the location of the BG sensor code. Looking to the existing code under drivers/thermal/, looks like it is practice to keep the sensor driver code there as well. So, I was wondering if same needs to be done for OMAP code, because as of today the sensor code is residing under drivers/mfd. I will cook something and send it across to see how it looks like.
Eduardo Valentin (4): thermal: omap: fix get mode function MFD: omap scm: remove all references to TI THERMAL_FRAMEWORK config MFD: omap temp sensor: rework initialization sequence omap thermal: fix off by one issue
drivers/mfd/omap4460plus_temp_sensor.c | 272 +++++++++----------------------- drivers/mfd/omap4plus_scm.c | 9 - drivers/thermal/omap_thermal.c | 14 +- include/linux/mfd/omap4_scm.h | 4 +- 4 files changed, 80 insertions(+), 219 deletions(-)
This patch changes the behavior of omap thermal zone so that if the data structures are not setup, it will always return 'disabled' while if data structures are set, then it will return the actual state.
Signed-off-by: Eduardo Valentin eduardo.valentin@ti.com --- drivers/thermal/omap_thermal.c | 8 +++++--- 1 files changed, 5 insertions(+), 3 deletions(-)
diff --git a/drivers/thermal/omap_thermal.c b/drivers/thermal/omap_thermal.c index cd5baa5..2d0fbc2 100644 --- a/drivers/thermal/omap_thermal.c +++ b/drivers/thermal/omap_thermal.c @@ -14,11 +14,13 @@ static int omap_get_mode(struct thermal_zone_device *thermal, { struct omap_thermal_zone *th_zone = thermal->devdata;
- if (th_zone->sensor_conf) { + if (!th_zone->sensor_conf) { pr_info("Temperature sensor not initialised\n"); *mode = THERMAL_DEVICE_DISABLED; - } else - *mode = THERMAL_DEVICE_ENABLED; + } else { + *mode = th_zone->mode; + } + return 0; }
The TI thermal framework is a non existing entity in mainline kernel. It is a framework present inside TI android tree. This patch removes references to this config entry from the SCM driver code.
Signed-off-by: Eduardo Valentin eduardo.valentin@ti.com --- drivers/mfd/omap4460plus_temp_sensor.c | 153 +------------------------------ drivers/mfd/omap4plus_scm.c | 9 -- include/linux/mfd/omap4_scm.h | 4 +- 3 files changed, 6 insertions(+), 160 deletions(-)
diff --git a/drivers/mfd/omap4460plus_temp_sensor.c b/drivers/mfd/omap4460plus_temp_sensor.c index acf8c10..18140b7 100644 --- a/drivers/mfd/omap4460plus_temp_sensor.c +++ b/drivers/mfd/omap4460plus_temp_sensor.c @@ -40,9 +40,7 @@ #include <linux/mfd/omap4_scm.h> #include <mach/ctrl_module_core_44xx.h>
-#ifdef CONFIG_THERMAL_FRAMEWORK -#include <linux/thermal_framework.h> -#elif defined(CONFIG_CPU_THERMAL) +#if defined(CONFIG_CPU_THERMAL) #include <linux/thermal.h> #include <linux/omap_thermal.h> #include <linux/platform_data/omap4_thermal_data.h> @@ -810,90 +808,7 @@ int omap4460_tshut_init(struct scm *scm_ptr) return 0; }
-#ifdef CONFIG_THERMAL_FRAMEWORK -static int omap_report_temp(struct thermal_dev *tdev) -{ - struct platform_device *pdev = to_platform_device(tdev->dev); - struct scm *scm_ptr = platform_get_drvdata(pdev); - int id = tdev->sen_id; - - scm_ptr->therm_fw[id]->current_temp = - omap4460plus_scm_read_temp(scm_ptr, id); - - if (scm_ptr->therm_fw[id]->current_temp != -EINVAL) { - thermal_sensor_set_temp(scm_ptr->therm_fw[id]); - kobject_uevent(&scm_ptr->tsh_ptr[id].pdev->dev.kobj, - KOBJ_CHANGE); - } - - return scm_ptr->therm_fw[id]->current_temp; -} - -static int omap_set_temp_thresh(struct thermal_dev *tdev, int min, int max) -{ - struct platform_device *pdev = to_platform_device(tdev->dev); - struct scm *scm_ptr = platform_get_drvdata(pdev); - int ret, t_cold, t_hot, thresh_val, hot, cold; - int id = tdev->sen_id; - struct omap4460plus_temp_sensor_registers *tsr; - - tsr = scm_ptr->registers[id]; - t_cold = temp_to_adc_conversion(min, scm_ptr, id); - t_hot = temp_to_adc_conversion(max, scm_ptr, id); - - thresh_val = omap4plus_scm_readl(scm_ptr, tsr->bgap_threshold); - hot = (thresh_val & tsr->threshold_thot_mask) >> - __ffs(tsr->threshold_thot_mask); - cold = (thresh_val & tsr->threshold_tcold_mask) >> - __ffs(tsr->threshold_tcold_mask); - - if (t_hot < cold) { - ret = omap4460plus_scm_set_temp_max_hyst(scm_ptr, id, min); - ret = omap4460plus_scm_set_temp_max(scm_ptr, id, max); - } else { - ret = omap4460plus_scm_set_temp_max(scm_ptr, id, max); - ret = omap4460plus_scm_set_temp_max_hyst(scm_ptr, id, min); - } - - return ret; -} - -static int omap_set_measuring_rate(struct thermal_dev *tdev, int rate) -{ - struct platform_device *pdev = to_platform_device(tdev->dev); - struct scm *scm_ptr = platform_get_drvdata(pdev); - int id = tdev->sen_id; - - omap4460plus_scm_set_update_interval(scm_ptr, rate, id); - - return rate; -} - -static int omap_report_slope(struct thermal_dev *tdev) -{ - struct platform_device *pdev = to_platform_device(tdev->dev); - struct scm *scm_ptr = platform_get_drvdata(pdev); - int id = tdev->sen_id; - return scm_ptr->therm_fw[id]->slope; -} - -static int omap_report_offset(struct thermal_dev *tdev) -{ - struct platform_device *pdev = to_platform_device(tdev->dev); - struct scm *scm_ptr = platform_get_drvdata(pdev); - int id = tdev->sen_id; - - return scm_ptr->therm_fw[id]->constant_offset; -} - -static struct thermal_dev_ops omap_sensor_ops = { - .report_temp = omap_report_temp, - .set_temp_thresh = omap_set_temp_thresh, - .set_temp_report_rate = omap_set_measuring_rate, - .init_slope = omap_report_slope, - .init_offset = omap_report_offset -}; -#elif defined(CONFIG_CPU_THERMAL) +#if defined(CONFIG_CPU_THERMAL)
struct omap_thermal_zone *omap_zones[3];
@@ -1020,14 +935,7 @@ int omap4460plus_temp_sensor_init(struct scm *scm_ptr) goto fail_alloc; }
-#ifdef CONFIG_THERMAL_FRAMEWORK - scm_ptr->therm_fw = kzalloc(sizeof(struct thermal_dev *) - * scm_ptr->cnt, GFP_KERNEL); - if (!scm_ptr->therm_fw) { - pr_err("Unable to allocate memory for ts data\n"); - return -ENOMEM; - } -#elif defined(CONFIG_CPU_THERMAL) +#if defined(CONFIG_CPU_THERMAL) scm_ptr->cpu_therm = kzalloc(sizeof(struct thermal_sensor_conf) * scm_ptr->cnt, GFP_KERNEL); if (!scm_ptr->cpu_therm) { @@ -1037,10 +945,6 @@ int omap4460plus_temp_sensor_init(struct scm *scm_ptr) #endif
for (i = 0; i < scm_ptr->cnt; i++) { -#ifdef CONFIG_THERMAL_FRAMEWORK - scm_ptr->therm_fw[i] = - kzalloc(sizeof(struct thermal_dev), GFP_KERNEL); -#endif scm_ptr->regval[i] = kzalloc(sizeof(struct scm_regval), GFP_KERNEL); } @@ -1057,22 +961,7 @@ int omap4460plus_temp_sensor_init(struct scm *scm_ptr) if (!omap4plus_scm_readl(scm_ptr, scm_ptr->registers[0]->bgap_efuse)) pr_info("Non-trimmed BGAP, Temp not accurate\n"); -#ifdef CONFIG_THERMAL_FRAMEWORK - if (scm_ptr->therm_fw) { - scm_ptr->therm_fw[0]->name = "omap_ondie_sensor"; - scm_ptr->therm_fw[0]->domain_name = "cpu"; - scm_ptr->therm_fw[0]->dev = scm_ptr->dev; - scm_ptr->therm_fw[0]->dev_ops = &omap_sensor_ops; - scm_ptr->therm_fw[0]->sen_id = 0; - scm_ptr->therm_fw[0]->slope = 376; - scm_ptr->therm_fw[0]->constant_offset = -16000; - thermal_sensor_dev_register(scm_ptr->therm_fw[0]); - } else { - pr_err("%s:Cannot alloc memory for thermal fw\n", - __func__); - ret = -ENOMEM; - } -#elif defined(CONFIG_CPU_THERMAL) +#if defined(CONFIG_CPU_THERMAL) strncpy(scm_ptr->cpu_therm[0].name, "omap_ondie_sensor", SENSOR_NAME_LEN); scm_ptr->cpu_therm[0].private_data = scm_ptr; @@ -1093,39 +982,7 @@ int omap4460plus_temp_sensor_init(struct scm *scm_ptr) scm_ptr->registers[2] = &omap5430_core_temp_sensor_registers; scm_ptr->ts_data[2] = &omap5430_core_temp_sensor_data; scm_ptr->conv_table = omap5430_adc_to_temp; -#ifdef CONFIG_THERMAL_FRAMEWORK - if (scm_ptr->therm_fw) { - scm_ptr->therm_fw[0]->name = "omap_ondie_mpu_sensor"; - scm_ptr->therm_fw[0]->domain_name = "cpu"; - scm_ptr->therm_fw[0]->dev = scm_ptr->dev; - scm_ptr->therm_fw[0]->dev_ops = &omap_sensor_ops; - scm_ptr->therm_fw[0]->sen_id = 0; - scm_ptr->therm_fw[0]->slope = 196; - scm_ptr->therm_fw[0]->constant_offset = -6822; - thermal_sensor_dev_register(scm_ptr->therm_fw[0]); - scm_ptr->therm_fw[1]->name = "omap_ondie_gpu_sensor"; - scm_ptr->therm_fw[1]->domain_name = "gpu"; - scm_ptr->therm_fw[1]->dev = scm_ptr->dev; - scm_ptr->therm_fw[1]->dev_ops = &omap_sensor_ops; - scm_ptr->therm_fw[1]->sen_id = 1; - scm_ptr->therm_fw[1]->slope = 0; - scm_ptr->therm_fw[1]->constant_offset = 7000; - thermal_sensor_dev_register(scm_ptr->therm_fw[1]); - scm_ptr->therm_fw[2]->name = "omap_ondie_core_sensor"; - scm_ptr->therm_fw[2]->domain_name = "core"; - scm_ptr->therm_fw[2]->dev = scm_ptr->dev; - scm_ptr->therm_fw[2]->dev_ops = &omap_sensor_ops; - scm_ptr->therm_fw[2]->sen_id = 2; - scm_ptr->therm_fw[2]->slope = 0; - scm_ptr->therm_fw[2]->constant_offset = 0; - thermal_sensor_dev_register(scm_ptr->therm_fw[2]); - /*TO DO: Add for GPU and core */ - } else { - pr_err("%s:Cannot alloc memory for thermal fw\n", - __func__); - ret = -ENOMEM; - } -#elif defined(CONFIG_CPU_THERMAL) +#if defined(CONFIG_CPU_THERMAL) strncpy(scm_ptr->cpu_therm[0].name, "omap_ondie_sensor", SENSOR_NAME_LEN); scm_ptr->cpu_therm[0].private_data = scm_ptr; diff --git a/drivers/mfd/omap4plus_scm.c b/drivers/mfd/omap4plus_scm.c index 20df540..a54d3fe 100644 --- a/drivers/mfd/omap4plus_scm.c +++ b/drivers/mfd/omap4plus_scm.c @@ -39,10 +39,6 @@ #include <plat/scm.h> #include <linux/mfd/omap4_scm.h>
-#ifdef CONFIG_THERMAL_FRAMEWORK -#include <linux/thermal_framework.h> -#endif - #ifdef CONFIG_CPU_THERMAL #include <linux/thermal.h> #include <linux/omap_thermal.h> @@ -124,11 +120,6 @@ static irqreturn_t talert_irq_handler(int irq, void *data) temp &= tsr->bgap_dtemp_mask;
if (t_hot || t_cold) { -#ifdef CONFIG_THERMAL_FRAMEWORK - scm_ptr->therm_fw[i]->current_temp = - adc_to_temp_conversion(scm_ptr, i, temp); - thermal_sensor_set_temp(scm_ptr->therm_fw[i]); -#endif #ifdef CONFIG_CPU_THERMAL if (omap_zones[0]) omap4_report_trigger(omap_zones[0]); diff --git a/include/linux/mfd/omap4_scm.h b/include/linux/mfd/omap4_scm.h index 43db7a3..9a700de 100644 --- a/include/linux/mfd/omap4_scm.h +++ b/include/linux/mfd/omap4_scm.h @@ -133,9 +133,7 @@ struct scm { struct device *dev; struct omap4460plus_temp_sensor_data **ts_data; struct omap4460plus_temp_sensor_registers **registers; -#if defined(CONFIG_THERMAL_FRAMEWORK) - struct thermal_dev **therm_fw; -#elif defined(CONFIG_CPU_THERMAL) +#if defined(CONFIG_CPU_THERMAL) struct thermal_sensor_conf *cpu_therm; #endif struct scm_regval **regval;
This is a simplification of the initialization sequence of the omap temp sensor. Now all code related to cpu cooling is concentrated in only one place. This patch also properly handle the fail path, by freeing the right resources, in case the initialization fails.
Signed-off-by: Eduardo Valentin eduardo.valentin@ti.com --- drivers/mfd/omap4460plus_temp_sensor.c | 125 ++++++++++++++++++-------------- 1 files changed, 69 insertions(+), 56 deletions(-)
diff --git a/drivers/mfd/omap4460plus_temp_sensor.c b/drivers/mfd/omap4460plus_temp_sensor.c index 18140b7..ef2b091 100644 --- a/drivers/mfd/omap4460plus_temp_sensor.c +++ b/drivers/mfd/omap4460plus_temp_sensor.c @@ -904,13 +904,57 @@ static int omap_read_temp(void *private_data) return temp; }
+static int omap4460plus_cpu_cooling_init(struct scm *scm_ptr) +{ + scm_ptr->cpu_therm = kzalloc(sizeof(struct thermal_sensor_conf) * + scm_ptr->cnt, GFP_KERNEL); + if (!scm_ptr->cpu_therm) { + pr_err("Unable to allocate memory for ts data\n"); + + return -ENOMEM; + } + + if (scm_ptr->rev == 1) { + strncpy(scm_ptr->cpu_therm[0].name, "omap_ondie_sensor", + SENSOR_NAME_LEN); + scm_ptr->cpu_therm[0].private_data = scm_ptr; + scm_ptr->cpu_therm[0].read_temperature = omap_read_temp; + if (omap4_has_mpu_1_5ghz()) + scm_ptr->cpu_therm[0].sensor_data = + &omap4_1500mhz_bandgap_data; + else + scm_ptr->cpu_therm[0].sensor_data = + &omap4_1200mhz_bandgap_data; + omap_zones[0] = omap4_register_thermal(scm_ptr->cpu_therm); + } else if (scm_ptr->rev == 2) { + strncpy(scm_ptr->cpu_therm[0].name, "omap_ondie_sensor", + SENSOR_NAME_LEN); + scm_ptr->cpu_therm[0].private_data = scm_ptr; + scm_ptr->cpu_therm[0].read_temperature = omap_read_temp; + scm_ptr->cpu_therm[0].sensor_data = &omap5_1500mhz_bandgap_data; + omap_zones[0] = omap4_register_thermal(&scm_ptr->cpu_therm[0]); + strncpy(scm_ptr->cpu_therm[1].name, "omap_ondie_gpu_sensor", + SENSOR_NAME_LEN); + scm_ptr->cpu_therm[1].private_data = scm_ptr; + scm_ptr->cpu_therm[1].read_temperature = omap_read_temp; + scm_ptr->cpu_therm[1].sensor_data = &omap5_1500mhz_bandgap_data; + strncpy(scm_ptr->cpu_therm[2].name, "omap_ondie_core_sensor", + SENSOR_NAME_LEN); + scm_ptr->cpu_therm[2].private_data = scm_ptr; + scm_ptr->cpu_therm[2].read_temperature = omap_read_temp; + scm_ptr->cpu_therm[2].sensor_data = &omap5_1500mhz_bandgap_data; + } + + return 0; +} +#else +static int omap4460plus_cpu_cooling_init(struct scm *scm_ptr) { return 0; } #endif
int omap4460plus_temp_sensor_init(struct scm *scm_ptr) { struct omap_temp_sensor_registers *reg_ptr; struct omap4460plus_temp_sensor_data *ts_ptr; - struct scm_regval *regval_ptr; int clk_rate, ret, i;
scm_ptr->registers = kzalloc(sizeof(reg_ptr) * @@ -924,29 +968,25 @@ int omap4460plus_temp_sensor_init(struct scm *scm_ptr) if (!scm_ptr->ts_data) { pr_err("Unable to allocate memory for ts data\n"); ret = -ENOMEM; - goto fail_alloc; + goto free_registers; }
- scm_ptr->regval = kzalloc(sizeof(regval_ptr) * scm_ptr->cnt, + scm_ptr->regval = kzalloc(scm_ptr->cnt * sizeof(struct scm_regval *), GFP_KERNEL); if (!scm_ptr->regval) { pr_err("Unable to allocate memory for regval\n"); ret = -ENOMEM; - goto fail_alloc; + goto free_ts_data; }
-#if defined(CONFIG_CPU_THERMAL) - scm_ptr->cpu_therm = kzalloc(sizeof(struct thermal_sensor_conf) - * scm_ptr->cnt, GFP_KERNEL); - if (!scm_ptr->cpu_therm) { - pr_err("Unable to allocate memory for ts data\n"); - goto clk_err; - } -#endif - for (i = 0; i < scm_ptr->cnt; i++) { scm_ptr->regval[i] = kzalloc(sizeof(struct scm_regval), GFP_KERNEL); + if (!scm_ptr->regval[i]) { + pr_err("Unable to allocate memory for regval\n"); + ret = -ENOMEM; + goto free_regval; + } }
if (scm_ptr->rev == 1) { @@ -961,19 +1001,6 @@ int omap4460plus_temp_sensor_init(struct scm *scm_ptr) if (!omap4plus_scm_readl(scm_ptr, scm_ptr->registers[0]->bgap_efuse)) pr_info("Non-trimmed BGAP, Temp not accurate\n"); -#if defined(CONFIG_CPU_THERMAL) - strncpy(scm_ptr->cpu_therm[0].name, "omap_ondie_sensor", - SENSOR_NAME_LEN); - scm_ptr->cpu_therm[0].private_data = scm_ptr; - scm_ptr->cpu_therm[0].read_temperature = omap_read_temp; - if (omap4_has_mpu_1_5ghz()) - scm_ptr->cpu_therm[0].sensor_data = - &omap4_1500mhz_bandgap_data; - else - scm_ptr->cpu_therm[0].sensor_data = - &omap4_1200mhz_bandgap_data; - omap_zones[0] = omap4_register_thermal(scm_ptr->cpu_therm); -#endif } else if (scm_ptr->rev == 2) { scm_ptr->registers[0] = &omap5430_mpu_temp_sensor_registers; scm_ptr->ts_data[0] = &omap5430_mpu_temp_sensor_data; @@ -982,24 +1009,6 @@ int omap4460plus_temp_sensor_init(struct scm *scm_ptr) scm_ptr->registers[2] = &omap5430_core_temp_sensor_registers; scm_ptr->ts_data[2] = &omap5430_core_temp_sensor_data; scm_ptr->conv_table = omap5430_adc_to_temp; -#if defined(CONFIG_CPU_THERMAL) - strncpy(scm_ptr->cpu_therm[0].name, "omap_ondie_sensor", - SENSOR_NAME_LEN); - scm_ptr->cpu_therm[0].private_data = scm_ptr; - scm_ptr->cpu_therm[0].read_temperature = omap_read_temp; - scm_ptr->cpu_therm[0].sensor_data = &omap5_1500mhz_bandgap_data; - omap_zones[0] = omap4_register_thermal(&scm_ptr->cpu_therm[0]); - strncpy(scm_ptr->cpu_therm[1].name, "omap_ondie_gpu_sensor", - SENSOR_NAME_LEN); - scm_ptr->cpu_therm[1].private_data = scm_ptr; - scm_ptr->cpu_therm[1].read_temperature = omap_read_temp; - scm_ptr->cpu_therm[1].sensor_data = &omap5_1500mhz_bandgap_data; - strncpy(scm_ptr->cpu_therm[2].name, "omap_ondie_core_sensor", - SENSOR_NAME_LEN); - scm_ptr->cpu_therm[2].private_data = scm_ptr; - scm_ptr->cpu_therm[2].read_temperature = omap_read_temp; - scm_ptr->cpu_therm[2].sensor_data = &omap5_1500mhz_bandgap_data; -#endif }
if (scm_ptr->rev == 1) { @@ -1009,40 +1018,39 @@ int omap4460plus_temp_sensor_init(struct scm *scm_ptr) if (clk_rate < scm_ptr->ts_data[0]->min_freq || clk_rate == 0xffffffff) { ret = -ENODEV; - goto clk_err; + goto free_regval; }
ret = clk_set_rate(scm_ptr->div_clk, clk_rate); if (ret) { pr_err("Cannot set clock rate\n"); - goto clk_err; + goto free_regval; }
scm_ptr->clk_rate = clk_rate; } else if (scm_ptr->rev == 2) { - /* add clock rate code for omap5430 */ -#ifdef CONFIG_MACH_OMAP_5430ZEBU - scm_ptr->clk_rate = 1200; -#else - + /* add clock rate code for omap5430 */ clk_rate = clk_round_rate(scm_ptr->fclock, scm_ptr->ts_data[0]->max_freq);
if (clk_rate < scm_ptr->ts_data[0]->min_freq || clk_rate == 0xffffffff) { ret = -ENODEV; - goto clk_err; + goto free_regval; }
ret = clk_set_rate(scm_ptr->fclock, clk_rate); if (ret) { pr_err("Cannot set clock rate\n"); - goto clk_err; + goto free_regval; } scm_ptr->clk_rate = clk_rate; -#endif }
+ ret = omap4460plus_cpu_cooling_init(scm_ptr); + if (ret) + goto free_regval; + clk_enable(scm_ptr->fclock); /* 1 clk cycle */ for (i = 0; i < scm_ptr->cnt; i++) @@ -1067,9 +1075,14 @@ int omap4460plus_temp_sensor_init(struct scm *scm_ptr) }
return 0; -clk_err: + +free_regval: + for (i = scm_ptr->cnt - 1; i >= 0; i--) + kfree(scm_ptr->regval[i]); + kfree(scm_ptr->regval); +free_ts_data: kfree(scm_ptr->ts_data); -fail_alloc: +free_registers: kfree(scm_ptr->registers); return ret; }
As of now, the function to check what have triggered a thermal event is accessing wrong data area.
This patch changes the way to match the trip point triggering the thermal event. Now it won't access the memory out of its usable range.
Signed-off-by: Eduardo Valentin eduardo.valentin@ti.com --- drivers/thermal/omap_thermal.c | 6 +++--- 1 files changed, 3 insertions(+), 3 deletions(-)
diff --git a/drivers/thermal/omap_thermal.c b/drivers/thermal/omap_thermal.c index 2d0fbc2..45c4989 100644 --- a/drivers/thermal/omap_thermal.c +++ b/drivers/thermal/omap_thermal.c @@ -172,14 +172,14 @@ void omap4_report_trigger(struct omap_thermal_zone *th_zone) /* Find the level for which trip happened */ for (i = 0; i < th_zone->therm_dev->trips; i++) { if (th_zone->therm_dev->last_temperature < - th_zone->sensor_data->trigger_levels[i - 1]) + th_zone->sensor_data->trigger_levels[i]) break; }
if (th_zone->mode == THERMAL_DEVICE_ENABLED) { - if (i > 0) + if (i < th_zone->therm_dev->trips) th_zone->therm_dev->polling_delay = - th_zone->sensor_data->freq_tab[i - 1].polling_interval; + th_zone->sensor_data->freq_tab[i].polling_interval; else th_zone->therm_dev->polling_delay = th_zone->idle_interval;