static int exynos4210_tmu_initialize(struct platform_device *pdev) { struct exynos4_tmu_data *data = platform_get_drvdata(pdev); struct exynos4_tmu_platform_data *pdata = data->pdata; unsigned int status, trim_info; int ret = 0, threshold_code; mutex_lock(&data->lock); clk_enable(data->clk); status = readb(data->base + EXYNOS4_TMU_REG_STATUS); if (!status) { ret = -EBUSY; goto out; } /* Save trimming info in order to perform calibration */ trim_info = readl(data->base + EXYNOS4_TMU_REG_TRIMINFO); data->temp_error1 = trim_info & EXYNOS4_TMU_TRIM_TEMP_MASK; data->temp_error2 = ((trim_info >> 8) & EXYNOS4_TMU_TRIM_TEMP_MASK); /* Write temperature code for threshold */ threshold_code = temp_to_code(data, pdata->threshold); if (threshold_code < 0) { ret = threshold_code; goto out; } writeb(threshold_code, data->base + EXYNOS4_TMU_REG_THRESHOLD_TEMP); writeb(pdata->trigger_levels[0], data->base + EXYNOS4_TMU_REG_TRIG_LEVEL0); writeb(pdata->trigger_levels[1], data->base + EXYNOS4_TMU_REG_TRIG_LEVEL1); writeb(pdata->trigger_levels[2], data->base + EXYNOS4_TMU_REG_TRIG_LEVEL2); writeb(pdata->trigger_levels[3], data->base + EXYNOS4_TMU_REG_TRIG_LEVEL3); writel(EXYNOS4_TMU_INTCLEAR_VAL, data->base + EXYNOS4_TMU_REG_INTCLEAR); out: clk_disable(data->clk); mutex_unlock(&data->lock); return ret; }
static ssize_t exynos_tmu_emulation_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { struct platform_device *pdev = container_of(dev, struct platform_device, dev); struct exynos_tmu_data *data = platform_get_drvdata(pdev); unsigned int reg; int temp; if (data->soc == SOC_ARCH_EXYNOS4210) goto out; if (!sscanf(buf, "%d\n", &temp) || temp < 0) return -EINVAL; mutex_lock(&data->lock); clk_enable(data->clk); reg = readl(data->base + EXYNOS_EMUL_CON); if (temp) { /* Both CELSIUS and MCELSIUS type are available for input */ if (temp > MCELSIUS) temp /= MCELSIUS; reg = (EXYNOS_EMUL_TIME << EXYNOS_EMUL_TIME_SHIFT) | (temp_to_code(data, (temp / MCELSIUS)) << EXYNOS_EMUL_DATA_SHIFT) | EXYNOS_EMUL_ENABLE; } else { reg &= ~EXYNOS_EMUL_ENABLE; } writel(reg, data->base + EXYNOS_EMUL_CON); clk_disable(data->clk); mutex_unlock(&data->lock); out: return count; }
static int exynos_tmu_initialize(struct platform_device *pdev, int id) { struct exynos_tmu_data *data = platform_get_drvdata(pdev); struct exynos_tmu_platform_data *pdata = data->pdata; unsigned int status, trim_info, rising_threshold; int ret = 0, threshold_code; mutex_lock(&data->lock); clk_enable(data->clk); status = readb(data->base[id] + EXYNOS_TMU_REG_STATUS); if (!status) { ret = -EBUSY; goto out; } if (data->soc == SOC_ARCH_EXYNOS5) { __raw_writel(EXYNOS5_TRIMINFO_RELOAD, data->base[id] + EXYNOS5_TMU_TRIMINFO_CON); } /* Save trimming info in order to perform calibration */ trim_info = readl(data->base[id] + EXYNOS_TMU_REG_TRIMINFO); data->temp_error1[id] = trim_info & EXYNOS_TMU_TRIM_TEMP_MASK; data->temp_error2[id] = ((trim_info >> 8) & EXYNOS_TMU_TRIM_TEMP_MASK); if ((EFUSE_MIN_VALUE > data->temp_error1[id]) || (data->temp_error1[id] > EFUSE_MAX_VALUE) || (data->temp_error2[id] != 0)) data->temp_error1[id] = pdata->efuse_value; if (data->soc == SOC_ARCH_EXYNOS4) { /* Write temperature code for threshold */ threshold_code = temp_to_code(data, pdata->threshold, id); if (threshold_code < 0) { ret = threshold_code; goto out; } writeb(threshold_code, data->base[id] + EXYNOS4_TMU_REG_THRESHOLD_TEMP); writeb(pdata->trigger_levels[0], data->base[id] + EXYNOS4_TMU_REG_TRIG_LEVEL0); writeb(pdata->trigger_levels[1], data->base[id] + EXYNOS4_TMU_REG_TRIG_LEVEL1); writeb(pdata->trigger_levels[2], data->base[id] + EXYNOS4_TMU_REG_TRIG_LEVEL2); writeb(pdata->trigger_levels[3], data->base[id] + EXYNOS4_TMU_REG_TRIG_LEVEL3); writel(EXYNOS4_TMU_INTCLEAR_VAL, data->base[id] + EXYNOS_TMU_REG_INTCLEAR); } else if (data->soc == SOC_ARCH_EXYNOS5) { /* Write temperature code for threshold */ threshold_code = temp_to_code(data, pdata->trigger_levels[0], id); if (threshold_code < 0) { ret = threshold_code; goto out; } rising_threshold = threshold_code; threshold_code = temp_to_code(data, pdata->trigger_levels[1], id); if (threshold_code < 0) { ret = threshold_code; goto out; } rising_threshold |= (threshold_code << 8); threshold_code = temp_to_code(data, pdata->trigger_levels[2], id); if (threshold_code < 0) { ret = threshold_code; goto out; } rising_threshold |= (threshold_code << 16); threshold_code = temp_to_code(data, pdata->trigger_levels[3], id); if (threshold_code < 0) { ret = threshold_code; goto out; } rising_threshold |= (threshold_code << 24); writel(rising_threshold, data->base[id] + EXYNOS5_THD_TEMP_RISE); writel(0, data->base[id] + EXYNOS5_THD_TEMP_FALL); writel(EXYNOS5_TMU_CLEAR_RISE_INT|EXYNOS5_TMU_CLEAR_FALL_INT, data->base[id] + EXYNOS_TMU_REG_INTCLEAR); } out: clk_disable(data->clk); mutex_unlock(&data->lock); 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_tmu_initialize(struct platform_device *pdev, int id) { struct exynos_tmu_data *data = platform_get_drvdata(pdev); struct exynos_tmu_platform_data *pdata = data->pdata; unsigned int status, rising_threshold, falling_threshold; int ret = 0, threshold_code; mutex_lock(&data->lock); clk_enable(data->clk); status = readb(data->base[id] + EXYNOS_TMU_REG_STATUS); if (!status) { ret = -EBUSY; goto out; } if (data->soc == SOC_ARCH_EXYNOS4) { /* Write temperature code for threshold */ threshold_code = temp_to_code(data, pdata->threshold, id); if (threshold_code < 0) { ret = threshold_code; goto out; } writeb(threshold_code, data->base[id] + EXYNOS4_TMU_REG_THRESHOLD_TEMP); writeb(pdata->trigger_levels[0], data->base[id] + EXYNOS4_TMU_REG_TRIG_LEVEL0); writeb(pdata->trigger_levels[1], data->base[id] + EXYNOS4_TMU_REG_TRIG_LEVEL1); writeb(pdata->trigger_levels[2], data->base[id] + EXYNOS4_TMU_REG_TRIG_LEVEL2); writeb(pdata->trigger_levels[3], data->base[id] + EXYNOS4_TMU_REG_TRIG_LEVEL3); writel(EXYNOS4_TMU_INTCLEAR_VAL, data->base[id] + EXYNOS_TMU_REG_INTCLEAR); } else if (data->soc == SOC_ARCH_EXYNOS3) { /* Write temperature code for threshold */ threshold_code = temp_to_code(data, pdata->trigger_levels[0], id); if (threshold_code < 0) { ret = threshold_code; goto out; } rising_threshold = threshold_code; falling_threshold = threshold_code - GAP_WITH_RISE; threshold_code = temp_to_code(data, pdata->trigger_levels[1], id); if (threshold_code < 0) { ret = threshold_code; goto out; } rising_threshold |= (threshold_code << THRESH_LEVE1_SHIFT); falling_threshold |= ((threshold_code - GAP_WITH_RISE) << THRESH_LEVE1_SHIFT); threshold_code = temp_to_code(data, pdata->trigger_levels[2], id); if (threshold_code < 0) { ret = threshold_code; goto out; } rising_threshold |= (threshold_code << THRESH_LEVE2_SHIFT); falling_threshold |= ((threshold_code - GAP_WITH_RISE) << THRESH_LEVE2_SHIFT); threshold_code = temp_to_code(data, pdata->trigger_levels[3], id); if (threshold_code < 0) { ret = threshold_code; goto out; } rising_threshold |= (threshold_code << THRESH_LEVE3_SHIFT); writel(rising_threshold, data->base[id] + EXYNOS3_THD_TEMP_RISE); writel(falling_threshold, data->base[id] + EXYNOS3_THD_TEMP_FALL); writel(EXYNOS3_TMU_CLEAR_RISE_INT|EXYNOS3_TMU_CLEAR_FALL_INT, data->base[id] + EXYNOS_TMU_REG_INTCLEAR); } else if (data->soc == SOC_ARCH_EXYNOS5) { /* Write temperature code for threshold */ threshold_code = temp_to_code(data, pdata->trigger_levels[0], id); if (threshold_code < 0) { ret = threshold_code; goto out; } rising_threshold = threshold_code; falling_threshold = threshold_code - GAP_WITH_RISE; threshold_code = temp_to_code(data, pdata->trigger_levels[1], id); if (threshold_code < 0) { ret = threshold_code; goto out; } rising_threshold |= (threshold_code << THRESH_LEVE1_SHIFT); falling_threshold |= ((threshold_code - GAP_WITH_RISE) << THRESH_LEVE1_SHIFT); threshold_code = temp_to_code(data, pdata->trigger_levels[2], id); if (threshold_code < 0) { ret = threshold_code; goto out; } rising_threshold |= (threshold_code << THRESH_LEVE2_SHIFT); falling_threshold |= ((threshold_code - GAP_WITH_RISE) << THRESH_LEVE2_SHIFT); threshold_code = temp_to_code(data, pdata->trigger_levels[3], id); if (threshold_code < 0) { ret = threshold_code; goto out; } rising_threshold |= (threshold_code << THRESH_LEVE3_SHIFT); writel(rising_threshold, data->base[id] + EXYNOS5_THD_TEMP_RISE); writel(falling_threshold, data->base[id] + EXYNOS5_THD_TEMP_FALL); writel(EXYNOS5_TMU_CLEAR_RISE_INT|EXYNOS5_TMU_CLEAR_FALL_INT, data->base[id] + EXYNOS_TMU_REG_INTCLEAR); } out: clk_disable(data->clk); mutex_unlock(&data->lock); 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, 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; }
static int exynos4x12_tmu_initialize(struct platform_device *pdev) { struct exynos4_tmu_data *data = platform_get_drvdata(pdev); struct exynos4_tmu_platform_data *pdata = data->pdata; unsigned int trim_info; int ret = 0, threshold_code[4], interrupt_code, tmp; mutex_lock(&data->lock); clk_enable(data->clk); tmp = readl(data->base + EXYNOS4X12_TMU_REG_TRIMINFO_CONROL); tmp |= EXYNOS4X12_TMU_RELOAD; writel(tmp, data->base + EXYNOS4X12_TMU_REG_TRIMINFO_CONROL); mdelay(1); /* Save trimming info in order to perform calibration */ trim_info = readl(data->base + EXYNOS4_TMU_REG_TRIMINFO); data->temp_error1 = trim_info & EXYNOS4_TMU_TRIM_TEMP_MASK; /* In case of non e-fusing chip, s/w workaround */ if (trim_info == 0) data->temp_error1 = 0x37; pr_debug("%s: triminfo reg = 0x%08x, value = %d\n", __func__, trim_info, data->temp_error1); /* Write temperature code for threshold */ threshold_code[0] = temp_to_code(data, pdata->threshold + pdata->trigger_levels[0]); if (threshold_code[0] < 0) { ret = threshold_code[0]; goto out; } threshold_code[1] = temp_to_code(data, pdata->threshold + pdata->trigger_levels[1]); if (threshold_code[1] < 0) { ret = threshold_code[1]; goto out; } threshold_code[2] = temp_to_code(data, pdata->threshold + pdata->trigger_levels[2]); if (threshold_code[2] < 0) { ret = threshold_code[2]; goto out; } threshold_code[3] = temp_to_code(data, pdata->threshold + pdata->trigger_levels[3]); if (threshold_code[3] < 0) { ret = threshold_code[3]; goto out; } /* Set interrupt trigger level */ interrupt_code = ((threshold_code[3] << 24) | (threshold_code[2] << 16) | (threshold_code[1] << 8) | (threshold_code[0] << 0)); writel(interrupt_code, data->base + EXYNOS4X12_TMU_REG_TRESHOLD_TEMP_RISE); mdelay(2); writel(EXYNOS4X12_TMU_INTCLEAR_VAL, data->base + EXYNOS4_TMU_REG_INTCLEAR); out: clk_disable(data->clk); mutex_unlock(&data->lock); return ret; }
static int exynos_tmu_initialize(struct platform_device *pdev) { struct exynos_tmu_data *data = platform_get_drvdata(pdev); struct exynos_tmu_platform_data *pdata = data->pdata; unsigned int status, trim_info; unsigned int rising_threshold = 0, falling_threshold = 0; int ret = 0, threshold_code, i, trigger_levs = 0; mutex_lock(&data->lock); clk_enable(data->clk); status = readb(data->base + EXYNOS_TMU_REG_STATUS); if (!status) { ret = -EBUSY; goto out; } if (data->soc == SOC_ARCH_EXYNOS) { __raw_writel(EXYNOS_TRIMINFO_RELOAD, data->base + EXYNOS_TMU_TRIMINFO_CON); } /* Save trimming info in order to perform calibration */ trim_info = readl(data->base + EXYNOS_TMU_REG_TRIMINFO); data->temp_error1 = trim_info & EXYNOS_TMU_TRIM_TEMP_MASK; data->temp_error2 = ((trim_info >> 8) & EXYNOS_TMU_TRIM_TEMP_MASK); if ((EFUSE_MIN_VALUE > data->temp_error1) || (data->temp_error1 > EFUSE_MAX_VALUE) || (data->temp_error2 != 0)) data->temp_error1 = pdata->efuse_value; /* Count trigger levels to be enabled */ for (i = 0; i < MAX_THRESHOLD_LEVS; i++) if (pdata->trigger_levels[i]) trigger_levs++; if (data->soc == SOC_ARCH_EXYNOS4210) { /* Write temperature code for threshold */ threshold_code = temp_to_code(data, pdata->threshold); if (threshold_code < 0) { ret = threshold_code; goto out; } writeb(threshold_code, data->base + EXYNOS4210_TMU_REG_THRESHOLD_TEMP); for (i = 0; i < trigger_levs; i++) writeb(pdata->trigger_levels[i], data->base + EXYNOS4210_TMU_REG_TRIG_LEVEL0 + i * 4); writel(EXYNOS4210_TMU_INTCLEAR_VAL, data->base + EXYNOS_TMU_REG_INTCLEAR); } else if (data->soc == SOC_ARCH_EXYNOS) { /* Write temperature code for rising and falling threshold */ for (i = 0; i < trigger_levs; i++) { threshold_code = temp_to_code(data, pdata->trigger_levels[i]); if (threshold_code < 0) { ret = threshold_code; goto out; } rising_threshold |= threshold_code << 8 * i; if (pdata->threshold_falling) { threshold_code = temp_to_code(data, pdata->trigger_levels[i] - pdata->threshold_falling); if (threshold_code > 0) falling_threshold |= threshold_code << 8 * i; } } writel(rising_threshold, data->base + EXYNOS_THD_TEMP_RISE); writel(falling_threshold, data->base + EXYNOS_THD_TEMP_FALL); writel(EXYNOS_TMU_CLEAR_RISE_INT | EXYNOS_TMU_CLEAR_FALL_INT, data->base + EXYNOS_TMU_REG_INTCLEAR); } out: clk_disable(data->clk); mutex_unlock(&data->lock); return ret; }
static int exynos_tmu_initialize(struct platform_device *pdev, int id) { struct exynos_tmu_data *data = platform_get_drvdata(pdev); struct exynos_tmu_platform_data *pdata = data->pdata; unsigned int status, trim_info, rising_threshold, falling_threshold; int ret = 0, timeout =5, threshold_code; mutex_lock(&data->lock); clk_enable(data->clk); status = readb(data->base[id] + EXYNOS_TMU_REG_STATUS); if (!status) { ret = -EBUSY; goto out; } __raw_writel(EXYNOS_TRIMINFO_RELOAD1, data->base[id] + EXYNOS_TMU_TRIMINFO_CON1); __raw_writel(EXYNOS_TRIMINFO_RELOAD2, data->base[id] + EXYNOS_TMU_TRIMINFO_CON2); while(readl(data->base[id] + EXYNOS_TMU_TRIMINFO_CON2) & EXYNOS_TRIMINFO_RELOAD1) { if(!timeout) { pr_err("Thermal TRIMINFO register reload failed\n"); break; } timeout--; cpu_relax(); usleep_range(5,10); } /* Save trimming info in order to perform calibration */ trim_info = readl(data->base[id] + EXYNOS_TMU_REG_TRIMINFO); data->temp_error1 = trim_info & EXYNOS_TMU_TRIM_TEMP_MASK; data->temp_error2 = ((trim_info >> 8) & EXYNOS_TMU_TRIM_TEMP_MASK); if ((EFUSE_MIN_VALUE > data->temp_error1) || (data->temp_error1 > EFUSE_MAX_VALUE) || (data->temp_error2 != 0)) data->temp_error1 = pdata->efuse_value; /* Write temperature code for threshold */ threshold_code = temp_to_code(data, pdata->threshold + pdata->trigger_levels[0]); if (threshold_code < 0) { ret = threshold_code; goto out; } rising_threshold = threshold_code; falling_threshold = threshold_code - GAP_WITH_RISE; threshold_code = temp_to_code(data, pdata->threshold + pdata->trigger_levels[1]); if (threshold_code < 0) { ret = threshold_code; goto out; } rising_threshold |= (threshold_code << THRESH_LEVE1_SHIFT); falling_threshold |= ((threshold_code - GAP_WITH_RISE) << THRESH_LEVE1_SHIFT); threshold_code = temp_to_code(data, pdata->threshold + pdata->trigger_levels[2]); if (threshold_code < 0) { ret = threshold_code; goto out; } rising_threshold |= (threshold_code << THRESH_LEVE2_SHIFT); falling_threshold |= ((threshold_code - GAP_WITH_RISE) << THRESH_LEVE2_SHIFT); threshold_code = temp_to_code(data, pdata->threshold + pdata->trigger_levels[3]); if (threshold_code < 0) { ret = threshold_code; goto out; } rising_threshold |= (threshold_code << THRESH_LEVE3_SHIFT); writel(rising_threshold, data->base[0] + EXYNOS4270_TMU_THRESHOLD_TEMP_RISE); writel(falling_threshold, data->base[0] + EXYNOS4270_TMU_THRESHOLD_TEMP_FALL); writel(EXYNOS4270_TMU_CLEAR_RISE_INT | EXYNOS4270_TMU_CLEAR_FALL_INT, data->base[0] + EXYNOS_TMU_REG_INTCLEAR); out: clk_disable(data->clk); mutex_unlock(&data->lock); return ret; }