/* Get trip temperature callback functions for thermal zone */ static int exynos_get_trip_temp(struct thermal_zone_device *thermal, int trip, unsigned long *temp) { if (trip < GET_TRIP(MONITOR_ZONE) || trip > GET_TRIP(PANIC_ZONE)) return -EINVAL; *temp = th_zone->sensor_conf->trip_data.trip_val[trip]; /* convert the temperature into millicelsius */ *temp = *temp * MCELSIUS; return 0; }
/* Get critical temperature callback functions for thermal zone */ static int exynos_get_crit_temp(struct thermal_zone_device *thermal, unsigned long *temp) { int ret; /* Panic zone */ ret = exynos_get_trip_temp(thermal, GET_TRIP(PANIC_ZONE), temp); return ret; }
static int exynos_set_trip_temp(struct thermal_zone_device *thermal, int trip, unsigned long temp) { struct exynos_tmu_platform_data *pdata; struct exynos_tmu_data *data; unsigned int interrupt_en = 0, rising_threshold = 0; int threshold_code, i; int boost_mode = th_zone->sensor_conf->cooling_data.boost_mode; if (trip < GET_TRIP(MONITOR_ZONE) || trip > GET_TRIP(PANIC_ZONE)) return -EINVAL; if (boost_mode) { pr_info("Boost mode now, cannot change trigger level"); return 0; } data = th_zone->sensor_conf->private_data; pdata = data->pdata; clk_enable(data->clk); th_zone->sensor_conf->trip_data.trip_val[trip] = temp; for (i = 0; i < EXYNOS_TMU_COUNT; i++) { rising_threshold = readl(data->base[i] + EXYNOS5_THD_TEMP_RISE); threshold_code = temp_to_code(data, temp, i); switch (trip) { case 0: rising_threshold &= ~0xff; rising_threshold |= threshold_code; interrupt_en |= pdata->trigger_level0_en; break; case 1: rising_threshold &= ~(0xff << 8); rising_threshold |= (threshold_code << 8); interrupt_en |= pdata->trigger_level1_en << 4; break; case 2: rising_threshold &= ~(0xff << 16); rising_threshold |= (threshold_code << 16); interrupt_en |= pdata->trigger_level2_en << 8; break; default: return -EINVAL; } /* Save same trip info in all tmu sensors */ writel(rising_threshold, data->base[i] + EXYNOS5_THD_TEMP_RISE); writel(interrupt_en, data->base[i] + EXYNOS_TMU_REG_INTEN); } clk_disable(data->clk); printk(KERN_INFO "sysfs : set_trip_temp temp=%d regval=0x%x id=%d\n", th_zone->sensor_conf->trip_data.trip_val[trip], rising_threshold, trip); return 0; }
static int exynos_set_trip_temp(struct thermal_zone_device *thermal, int trip, unsigned long temp) { struct exynos_tmu_platform_data *pdata; struct exynos_tmu_data *data; unsigned int interrupt_en = 0, rising_threshold = 0, falling_threshold; int threshold_code, i, con; data = th_zone->sensor_conf->private_data; pdata = data->pdata; clk_enable(data->clk); th_zone->sensor_conf->trip_data.trip_val[trip] = temp; for (i = 0; i < EXYNOS_TMU_COUNT; i++) { /* TMU core disable */ if (i <= GET_TRIP(PANIC_ZONE)) writel(0, data->base[i] + EXYNOS_TMU_REG_INTEN); con = readl(data->base[i] + EXYNOS_TMU_REG_CONTROL); con &= ~(0x3); con |= EXYNOS_TMU_CORE_OFF; writel(con, data->base[i] + EXYNOS_TMU_REG_CONTROL); /* Interrupt pending clear */ writel(EXYNOS5_TMU_CLEAR_RISE_INT|EXYNOS5_TMU_CLEAR_FALL_INT, data->base[i] + EXYNOS_TMU_REG_INTCLEAR); /* Change the trigger levels */ rising_threshold = readl(data->base[i] + EXYNOS5_THD_TEMP_RISE); falling_threshold = readl(data->base[i] + EXYNOS5_THD_TEMP_FALL); threshold_code = temp_to_code(data, temp, i); switch (trip) { case 0: rising_threshold &= ~0xff; falling_threshold &= ~0xff; rising_threshold |= threshold_code; falling_threshold |= threshold_code - GAP_WITH_RISE; interrupt_en |= pdata->trigger_level0_en; interrupt_en |= pdata->trigger_level0_en << FALL_LEVEL0_SHIFT; break; case 1: rising_threshold &= ~(0xff << THRESH_LEVE1_SHIFT); falling_threshold &= ~(0xff << THRESH_LEVE1_SHIFT); rising_threshold |= (threshold_code << THRESH_LEVE1_SHIFT); falling_threshold |= ((threshold_code - GAP_WITH_RISE) << THRESH_LEVE1_SHIFT); interrupt_en |= pdata->trigger_level1_en << RISE_LEVEL1_SHIFT; interrupt_en |= pdata->trigger_level1_en << FALL_LEVEL1_SHIFT; break; case 2: rising_threshold &= ~(0xff << THRESH_LEVE2_SHIFT); falling_threshold &= ~(0xff << THRESH_LEVE2_SHIFT); rising_threshold |= (threshold_code << THRESH_LEVE2_SHIFT); falling_threshold |= ((threshold_code - GAP_WITH_RISE) << THRESH_LEVE2_SHIFT); interrupt_en |= pdata->trigger_level2_en << RISE_LEVEL2_SHIFT; interrupt_en |= pdata->trigger_level2_en << FALL_LEVEL2_SHIFT; break; case 3: rising_threshold &= ~(0xff << THRESH_LEVE3_SHIFT); rising_threshold |= (threshold_code << THRESH_LEVE3_SHIFT); break; } writel(rising_threshold, data->base[i] + EXYNOS5_THD_TEMP_RISE); writel(falling_threshold, data->base[i] + EXYNOS5_THD_TEMP_FALL); /* TMU core enable */ if (i <= GET_TRIP(PANIC_ZONE)) writel(interrupt_en, data->base[i] + EXYNOS_TMU_REG_INTEN); con = readl(data->base[i] + EXYNOS_TMU_REG_CONTROL); con &= ~(0x3 | (0x1 << 12)); con |= (EXYNOS_TMU_CORE_ON | EXYNOS_THERM_TRIP_EN); writel(con, data->base[i] + EXYNOS_TMU_REG_CONTROL); } clk_disable(data->clk); printk(KERN_INFO "sysfs : set trip temp[%d] : %d\n", trip, th_zone->sensor_conf->trip_data.trip_val[trip]); return 0; }