Пример #1
0
/* 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;
}
Пример #2
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;
}
Пример #3
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;
	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;
}