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)); }
static int therm_est_init_history(struct therm_estimator *est) { int i, j; struct therm_est_subdevice *dev; long temp; for (i = 0; i < est->ndevs; i++) { dev = &est->devs[i]; if (therm_est_subdev_get_temp(dev->dev_data, &temp)) return -EINVAL; for (j = 0; j < HIST_LEN; j++) dev->hist[j] = temp; } return 0; }
static int therm_est_init_history(struct therm_estimator *est) { int i, j; struct therm_est_subdevice *dev; long temp; int ret; for (i = 0; i < est->ndevs; i++) { dev = &est->devs[i]; ret = therm_est_subdev_get_temp(dev->dev_data, &temp); if (ret < 0) return ret; for (j = 0; j < HIST_LEN; j++) dev->hist[j] = temp; } est->ntemp = 0; return 0; }