Esempio n. 1
0
static int therm_est_get_trip_temp(struct thermal_zone_device *thz,
				   int trip, unsigned long *temp)
{
	struct therm_estimator *est = thz->devdata;
	struct therm_est_timer_trip_info *timer_info;
	int ret;

	ret = __get_trip_temp(thz, trip, temp);
	if (ret & (TIMER_TRIP_STATE_START | TIMER_TRIP_STATE_DOWN)) {
		timer_info = __find_timer_trip(est, trip);

		mutex_lock(&est->timer_trip_lock);
		timer_info->last_tripped = ktime_to_ms(ktime_get());

		if (ret & TIMER_TRIP_STATE_START) {
			timer_info->cur = TIMER_TRIP_INACTIVE + 1;
		} else if (ret & TIMER_TRIP_STATE_DOWN) {
			if (--timer_info->cur < TIMER_TRIP_INACTIVE)
				timer_info->cur = TIMER_TRIP_INACTIVE;
		}
		mutex_unlock(&est->timer_trip_lock);

		/* Update limits, because trip temp was changed by timer trip
		 * changing. */
		therm_est_update_limits(est);
	}

	return 0;
}
Esempio n. 2
0
static int therm_est_set_trip_temp(struct thermal_zone_device *thz,
				   int trip, unsigned long temp)
{
	struct therm_estimator *est = thz->devdata;

	est->trips[trip].trip_temp = temp;

	/* Update limits, because trip temp was changed. */
	therm_est_update_limits(est);
	return 0;
}
Esempio n. 3
0
static void therm_est_timer_trip_work_func(struct work_struct *work)
{
	struct therm_estimator *est = container_of(work, struct therm_estimator,
						   timer_trip_work.work);
	struct thermal_trip_info *trip_state;
	struct therm_est_timer_trip_info *timer_info;
	s64 now, delay;
	int timer_trip_state, i;

	mutex_lock(&est->timer_trip_lock);
	timer_trip_state = TIMER_TRIP_STATE_NONE;
	now = ktime_to_ms(ktime_get());

	for (i = 0; i < est->num_timer_trips; i++) {
		timer_info = &est->timer_trips[i];
		trip_state = &est->trips[timer_info->trip];

		pr_debug("%s: i %d, trip %d, tripped %d, cur %d\n",
			__func__, i, timer_info->trip, trip_state->tripped,
			timer_info->cur);
		if ((timer_info->cur == TIMER_TRIP_INACTIVE) ||
			(__get_timer_trip_delay(timer_info, now, &delay) < 0))
			continue;

		if (delay <= 0) { /* Timer on this trip has expired. */
			if (timer_info->cur + 1 < timer_info->num_timers) {
				timer_info->last_tripped = now;
				timer_info->cur++;
				timer_trip_state |= TIMER_TRIP_STATE_UP;
			}
		}

		/* If delay > 0, timer on this trip has not yet expired.
		 * So need to restart timer with remaining delay. */
		timer_trip_state |= TIMER_TRIP_STATE_START;
		pr_debug("%s: new_cur %d, delay %lld, timer_trip_state 0x%x\n",
			__func__, timer_info->cur, delay, timer_trip_state);
	}
	mutex_unlock(&est->timer_trip_lock);

	if (timer_trip_state & (TIMER_TRIP_STATE_START | TIMER_TRIP_STATE_UP)) {
		therm_est_update_timer_trips(est);
		therm_est_update_limits(est);
	}
}
Esempio n. 4
0
static void therm_est_work_func(struct work_struct *work)
{
	int i, j, index, sum = 0;
	long temp;
	struct delayed_work *dwork = container_of(work,
					struct delayed_work, work);
	struct therm_estimator *est = container_of(dwork,
					struct therm_estimator,
					therm_est_work);

	if ((est->ntemp == HIST_UNINIT) && therm_est_init_history(est)) {
		est->cur_temp = DEFAULT_TEMP;
		goto out;
	}

	for (i = 0; i < est->ndevs; i++) {
		if (therm_est_subdev_get_temp(est->devs[i].dev_data, &temp)) {
			index = (est->ntemp > 0) ? (est->ntemp - 1) : 0;
			temp = est->devs[i].hist[(index % HIST_LEN)];
		}
		est->devs[i].hist[(est->ntemp % HIST_LEN)] = temp;
	}

	for (i = 0; i < est->ndevs; i++) {
		for (j = 0; j < HIST_LEN; j++) {
			index = (est->ntemp - j + HIST_LEN) % HIST_LEN;
			sum += est->devs[i].hist[index] *
				est->devs[i].coeffs[j];
		}
	}

	est->cur_temp = sum / 100 + est->toffset;
	est->ntemp++;

out:
	if (est->thz && ((est->cur_temp < est->low_limit) ||
			(est->cur_temp >= est->high_limit))) {
		thermal_zone_device_update(est->thz);
		therm_est_update_timer_trips(est);
		therm_est_update_limits(est);
	}

	queue_delayed_work(est->workqueue, &est->therm_est_work,
				msecs_to_jiffies(est->polling_period));
}