/* get states of the cooling device instance */ static int probe_cdev(struct cdev_info *cdi, char *path) { sysfs_get_string(path, "type", cdi->type); sysfs_get_ulong(path, "max_state", &cdi->max_state); sysfs_get_ulong(path, "cur_state", &cdi->cur_state); syslog(LOG_INFO, "%s: %s: type %s, max %lu, curr %lu inst %d\n", __func__, path, cdi->type, cdi->max_state, cdi->cur_state, cdi->instance); return 0; }
void get_ctrl_state(unsigned long *state) { char ctrl_cdev_path[256]; int ctrl_cdev_id = -1; int i; /* TODO: take average of all ctrl types. also consider change based on * uevent. Take the first reading for now. */ for (i = 0; i < ptdata.nr_cooling_dev; i++) { if (ptdata.cdi[i].flag & CDEV_FLAG_IN_CONTROL) { ctrl_cdev_id = ptdata.cdi[i].instance; syslog(LOG_INFO, "ctrl cdev %d get state\n", ptdata.cdi[i].instance); break; } } if (ctrl_cdev_id == -1) { *state = 0; return; } snprintf(ctrl_cdev_path, 256, "%s/%s%d", THERMAL_SYSFS, CDEV, ctrl_cdev_id); sysfs_get_ulong(ctrl_cdev_path, "cur_state", state); }
/* Find trip point info of a thermal zone */ static int find_tzone_tp(char *tz_name, char *d_name, struct tz_info *tzi, int tz_id) { int tp_id; unsigned long temp_ulong; if (strstr(d_name, "trip_point") && strstr(d_name, "temp")) { /* check if trip point temp is non-zero * ignore 0/invalid trip points */ sysfs_get_ulong(tz_name, d_name, &temp_ulong); if (temp_ulong < MAX_TEMP_KC) { tzi->nr_trip_pts++; /* found a valid trip point */ tp_id = get_instance_id(d_name, 2, 0); syslog(LOG_DEBUG, "tzone %s trip %d temp %lu tpnode %s", tz_name, tp_id, temp_ulong, d_name); if (tp_id < 0 || tp_id >= MAX_NR_TRIP) { syslog(LOG_ERR, "Failed to find TP inst %s\n", d_name); return -1; } get_trip_point_data(tz_name, tz_id, tp_id); tzi->tp[tp_id].temp = temp_ulong; } } return 0; }
/* check cooling devices for binding info. */ static int find_tzone_cdev(struct dirent *nl, char *tz_name, struct tz_info *tzi, int tz_id, int cid) { unsigned long trip_instance = 0; char cdev_name_linked[256]; char cdev_name[256]; char cdev_trip_name[256]; int cdev_id; if (nl->d_type == DT_LNK) { syslog(LOG_DEBUG, "TZ%d: cdev: %s cid %d\n", tz_id, nl->d_name, cid); tzi->nr_cdev++; if (tzi->nr_cdev > ptdata.nr_cooling_dev) { syslog(LOG_ERR, "Err: Too many cdev? %d\n", tzi->nr_cdev); return -EINVAL; } /* find the link to real cooling device record binding */ snprintf(cdev_name, 256, "%s/%s", tz_name, nl->d_name); memset(cdev_name_linked, 0, sizeof(cdev_name_linked)); if (readlink(cdev_name, cdev_name_linked, sizeof(cdev_name_linked) - 1) != -1) { cdev_id = get_instance_id(cdev_name_linked, 1, sizeof("device") - 1); syslog(LOG_DEBUG, "cdev %s linked to %s : %d\n", cdev_name, cdev_name_linked, cdev_id); tzi->cdev_binding |= (1 << cdev_id); /* find the trip point in which the cdev is binded to * in this tzone */ snprintf(cdev_trip_name, 256, "%s%s", nl->d_name, "_trip_point"); sysfs_get_ulong(tz_name, cdev_trip_name, &trip_instance); /* validate trip point range, e.g. trip could return -1 * when passive is enabled */ if (trip_instance > MAX_NR_TRIP) trip_instance = 0; tzi->trip_binding[cdev_id] |= 1 << trip_instance; syslog(LOG_DEBUG, "cdev %s -> trip:%lu: 0x%lx %d\n", cdev_name, trip_instance, tzi->trip_binding[cdev_id], cdev_id); } return 0; } return -ENODEV; }
/* read temperature of all thermal zones */ int update_thermal_data() { int i; int next_thermal_record = cur_thermal_record + 1; char tz_name[256]; static unsigned long samples; if (!ptdata.nr_tz_sensor) { syslog(LOG_ERR, "No thermal zones found!\n"); return -1; } /* circular buffer for keeping historic data */ if (next_thermal_record >= NR_THERMAL_RECORDS) next_thermal_record = 0; gettimeofday(&trec[next_thermal_record].tv, NULL); if (tmon_log) { fprintf(tmon_log, "%lu ", ++samples); fprintf(tmon_log, "%3.1f ", p_param.t_target); } for (i = 0; i < ptdata.nr_tz_sensor; i++) { memset(tz_name, 0, sizeof(tz_name)); snprintf(tz_name, 256, "%s/%s%d", THERMAL_SYSFS, TZONE, ptdata.tzi[i].instance); sysfs_get_ulong(tz_name, "temp", &trec[next_thermal_record].temp[i]); if (tmon_log) fprintf(tmon_log, "%lu ", trec[next_thermal_record].temp[i] / 1000); } cur_thermal_record = next_thermal_record; for (i = 0; i < ptdata.nr_cooling_dev; i++) { char cdev_name[256]; unsigned long val; snprintf(cdev_name, 256, "%s/%s%d", THERMAL_SYSFS, CDEV, ptdata.cdi[i].instance); probe_cdev(&ptdata.cdi[i], cdev_name); val = ptdata.cdi[i].cur_state; if (val > 1000000) val = 0; if (tmon_log) fprintf(tmon_log, "%lu ", val); } if (tmon_log) { fprintf(tmon_log, "\n"); fflush(tmon_log); } return 0; }