From 1149ca005a548aff8e65d44634d31db965ed66bd Mon Sep 17 00:00:00 2001 From: Naveen Krishna Chatradhi Date: Fri, 5 Apr 2013 15:21:38 -0700 Subject: power: exynos-tmu: fix warnings and clean up code This patch does the folowing 1. change the data types for unsigned int variable to unsigned 2. change the tmu_base type to struct exynos5_tmu_reg * 3. Add timer functionality for get_cur_temp() 4. error handling in the get_tmu_fdt_values() 5. Add check for curr_temp reading 6. some cosmotic changes. Signed-off-by: Naveen Krishna Chatradhi Reviewed-by: Vadim Bendebury Acked-by: Simon Glass Signed-off-by: Minkyu Kang --- drivers/power/exynos-tmu.c | 112 ++++++++++++++++++++++++++------------------- 1 file changed, 65 insertions(+), 47 deletions(-) (limited to 'drivers/power') diff --git a/drivers/power/exynos-tmu.c b/drivers/power/exynos-tmu.c index d4b3e65a3e..6d74bc74b5 100644 --- a/drivers/power/exynos-tmu.c +++ b/drivers/power/exynos-tmu.c @@ -50,15 +50,15 @@ /* Tmeperature threshold values for various thermal events */ struct temperature_params { /* minimum value in temperature code range */ - unsigned int min_val; + unsigned min_val; /* maximum value in temperature code range */ - unsigned int max_val; + unsigned max_val; /* temperature threshold to start warning */ - unsigned int start_warning; + unsigned start_warning; /* temperature threshold CPU tripping */ - unsigned int start_tripping; + unsigned start_tripping; /* temperature threshold for HW tripping */ - unsigned int hardware_tripping; + unsigned hardware_tripping; }; /* Pre-defined values and thresholds for calibration of current temperature */ @@ -66,25 +66,25 @@ struct tmu_data { /* pre-defined temperature thresholds */ struct temperature_params ts; /* pre-defined efuse range minimum value */ - unsigned int efuse_min_value; + unsigned efuse_min_value; /* pre-defined efuse value for temperature calibration */ - unsigned int efuse_value; + unsigned efuse_value; /* pre-defined efuse range maximum value */ - unsigned int efuse_max_value; + unsigned efuse_max_value; /* current temperature sensing slope */ - unsigned int slope; + unsigned slope; }; /* TMU device specific details and status */ struct tmu_info { /* base Address for the TMU */ - unsigned tmu_base; + struct exynos5_tmu_reg *tmu_base; /* pre-defined values for calibration and thresholds */ struct tmu_data data; /* value required for triminfo_25 calibration */ - unsigned int te1; + unsigned te1; /* value required for triminfo_85 calibration */ - unsigned int te2; + unsigned te2; /* Value for measured data calibration */ int dc_value; /* enum value indicating status of the TMU */ @@ -103,17 +103,24 @@ static struct tmu_info gbl_info; */ static int get_cur_temp(struct tmu_info *info) { - int cur_temp; - struct exynos5_tmu_reg *reg = (struct exynos5_tmu_reg *)info->tmu_base; + struct exynos5_tmu_reg *reg = info->tmu_base; + ulong start; + int cur_temp = 0; /* * Temperature code range between min 25 and max 125. * May run more than once for first call as initial sensing * has not yet happened. */ - do { - cur_temp = readl(®->current_temp) & 0xff; - } while (cur_temp == 0 && info->tmu_state == TMU_STATUS_NORMAL); + if (info->tmu_state == TMU_STATUS_NORMAL) { + start = get_timer(0); + do { + cur_temp = readl(®->current_temp) & 0xff; + } while ((cur_temp == 0) || (get_timer(start) > 100)); + } + + if (cur_temp == 0) + return cur_temp; /* Calibrate current temperature */ cur_temp = cur_temp - info->te1 + info->dc_value; @@ -137,23 +144,29 @@ enum tmu_status_t tmu_monitor(int *temp) /* Read current temperature of the SOC */ cur_temp = get_cur_temp(&gbl_info); + + if (!cur_temp) + goto out; + *temp = cur_temp; /* Temperature code lies between min 25 and max 125 */ - if (cur_temp >= data->ts.start_tripping && - cur_temp <= data->ts.max_val) { + if ((cur_temp >= data->ts.start_tripping) && + (cur_temp <= data->ts.max_val)) return TMU_STATUS_TRIPPED; - } else if (cur_temp >= data->ts.start_warning) { + + if (cur_temp >= data->ts.start_warning) return TMU_STATUS_WARNING; - } else if (cur_temp < data->ts.start_warning && - cur_temp >= data->ts.min_val) { + + if ((cur_temp < data->ts.start_warning) && + (cur_temp >= data->ts.min_val)) return TMU_STATUS_NORMAL; - } else { - /* Temperature code does not lie between min 25 and max 125 */ - gbl_info.tmu_state = TMU_STATUS_INIT; - debug("EXYNOS_TMU: Thermal reading failed\n"); - return TMU_STATUS_INIT; - } + + out: + /* Temperature code does not lie between min 25 and max 125 */ + gbl_info.tmu_state = TMU_STATUS_INIT; + debug("EXYNOS_TMU: Thermal reading failed\n"); + return TMU_STATUS_INIT; } /* @@ -166,6 +179,7 @@ enum tmu_status_t tmu_monitor(int *temp) static int get_tmu_fdt_values(struct tmu_info *info, const void *blob) { #ifdef CONFIG_OF_CONTROL + fdt_addr_t addr; int node; int error = 0; @@ -183,46 +197,51 @@ static int get_tmu_fdt_values(struct tmu_info *info, const void *blob) * miscalculation of register values in tmu_setup_parameters * may result in misleading current temperature. */ - info->tmu_base = fdtdec_get_addr(blob, node, "reg"); - if (info->tmu_base == FDT_ADDR_T_NONE) { + addr = fdtdec_get_addr(blob, node, "reg"); + if (addr == FDT_ADDR_T_NONE) { debug("%s: Missing tmu-base\n", __func__); return -1; } + info->tmu_base = (struct exynos5_tmu_reg *)addr; + info->data.ts.min_val = fdtdec_get_int(blob, node, "samsung,min-temp", -1); - error |= info->data.ts.min_val; + error |= (info->data.ts.min_val == -1); info->data.ts.max_val = fdtdec_get_int(blob, node, "samsung,max-temp", -1); - error |= info->data.ts.max_val; + error |= (info->data.ts.max_val == -1); info->data.ts.start_warning = fdtdec_get_int(blob, node, "samsung,start-warning", -1); - error |= info->data.ts.start_warning; + error |= (info->data.ts.start_warning == -1); info->data.ts.start_tripping = fdtdec_get_int(blob, node, "samsung,start-tripping", -1); - error |= info->data.ts.start_tripping; + error |= (info->data.ts.start_tripping == -1); info->data.ts.hardware_tripping = fdtdec_get_int(blob, node, "samsung,hw-tripping", -1); - error |= info->data.ts.hardware_tripping; + error |= (info->data.ts.hardware_tripping == -1); info->data.efuse_min_value = fdtdec_get_int(blob, node, "samsung,efuse-min-value", -1); - error |= info->data.efuse_min_value; + error |= (info->data.efuse_min_value == -1); info->data.efuse_value = fdtdec_get_int(blob, node, "samsung,efuse-value", -1); - error |= info->data.efuse_value; + error |= (info->data.efuse_value == -1); info->data.efuse_max_value = fdtdec_get_int(blob, node, "samsung,efuse-max-value", -1); - error |= info->data.efuse_max_value; + error |= (info->data.efuse_max_value == -1); info->data.slope = fdtdec_get_int(blob, node, "samsung,slope", -1); - error |= info->data.slope; + error |= (info->data.slope == -1); info->dc_value = fdtdec_get_int(blob, node, "samsung,dc-value", -1); - error |= info->dc_value; + error |= (info->dc_value == -1); - if (error == -1) { + if (error) { debug("fail to get tmu node properties\n"); return -1; } +#else + /* Non DT support may never be added. Just in case */ + return -1; #endif return 0; @@ -236,12 +255,12 @@ static int get_tmu_fdt_values(struct tmu_info *info, const void *blob) */ static void tmu_setup_parameters(struct tmu_info *info) { - unsigned int te_code, con; - unsigned int warning_code, trip_code, hwtrip_code; - unsigned int cooling_temp; - unsigned int rising_value; + unsigned te_code, con; + unsigned warning_code, trip_code, hwtrip_code; + unsigned cooling_temp; + unsigned rising_value; struct tmu_data *data = &info->data; - struct exynos5_tmu_reg *reg = (struct exynos5_tmu_reg *)info->tmu_base; + struct exynos5_tmu_reg *reg = info->tmu_base; /* Must reload for reading efuse value from triminfo register */ writel(TRIMINFO_RELOAD, ®->triminfo_control); @@ -314,6 +333,5 @@ int tmu_init(const void *blob) tmu_setup_parameters(&gbl_info); gbl_info.tmu_state = TMU_STATUS_NORMAL; ret: - return gbl_info.tmu_state; } -- cgit From eeb7d6a238f42c5c87892f9849cea00725f6d2d5 Mon Sep 17 00:00:00 2001 From: Naveen Krishna Chatradhi Date: Fri, 5 Apr 2013 15:21:39 -0700 Subject: power: exynos-tmu: use the mux_addr bit fields in tmu_control register This patch implements the mux_addr bit fields defined in tmu_control register (used for debugging purpose) Signed-off-by: Naveen Krishna Chatradhi Reviewed-by: Vadim Bendebury Signed-off-by: Minkyu Kang --- drivers/power/exynos-tmu.c | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) (limited to 'drivers/power') diff --git a/drivers/power/exynos-tmu.c b/drivers/power/exynos-tmu.c index 6d74bc74b5..9a093a5bdd 100644 --- a/drivers/power/exynos-tmu.c +++ b/drivers/power/exynos-tmu.c @@ -79,6 +79,8 @@ struct tmu_data { struct tmu_info { /* base Address for the TMU */ struct exynos5_tmu_reg *tmu_base; + /* mux Address for the TMU */ + int tmu_mux; /* pre-defined values for calibration and thresholds */ struct tmu_data data; /* value required for triminfo_25 calibration */ @@ -204,6 +206,13 @@ static int get_tmu_fdt_values(struct tmu_info *info, const void *blob) } info->tmu_base = (struct exynos5_tmu_reg *)addr; + /* Optional field. */ + info->tmu_mux = fdtdec_get_int(blob, + node, "samsung,mux", -1); + /* Take default value as per the user manual b(110) */ + if (info->tmu_mux == -1) + info->tmu_mux = 0x6; + info->data.ts.min_val = fdtdec_get_int(blob, node, "samsung,min-temp", -1); error |= (info->data.ts.min_val == -1); @@ -307,7 +316,7 @@ static void tmu_setup_parameters(struct tmu_info *info) /* TMU core enable */ con = readl(®->tmu_control); - con |= THERM_TRIP_EN | CORE_EN; + con |= THERM_TRIP_EN | CORE_EN | (info->tmu_mux << 20); writel(con, ®->tmu_control); -- cgit