.get_trip_type: get the type of certain trip point.
.get_trip_temp: get the temperature above which the certain trip point
will be fired.
+ .set_emul_temp: set the emulation temperature which helps in debugging
+ different threshold temperature points.
1.1.2 void thermal_zone_device_unregister(struct thermal_zone_device *tz)
|---trip_point_[0-*]_temp: Trip point temperature
|---trip_point_[0-*]_type: Trip point type
|---trip_point_[0-*]_hyst: Hysteresis value for this trip point
+ |---emul_temp: Emulated temperature set node
Thermal cooling device sys I/F, created once it's registered:
/sys/class/thermal/cooling_device[0-*]:
Valid values: 0 (disabled) or greater than 1000
RW, Optional
+emul_temp
+ Interface to set the emulated temperature method in thermal zone
+ (sensor). After setting this temperature, the thermal zone may pass
+ this temperature to platform emulation function if registered or
+ cache it locally. This is useful in debugging different temperature
+ threshold and its associated cooling action. This is write only node
+ and writing 0 on this node should disable emulation.
+ Unit: millidegree Celsius
+ WO, Optional
+
*****************************
* Cooling device attributes *
*****************************
monitor_thermal_zone(tz);
}
+static int thermal_zone_get_temp(struct thermal_zone_device *tz,
+ unsigned long *temp)
+{
+ int ret = 0, count;
+ unsigned long crit_temp = -1UL;
+ enum thermal_trip_type type;
+
+ mutex_lock(&tz->lock);
+
+ ret = tz->ops->get_temp(tz, temp);
+#ifdef CONFIG_THERMAL_EMULATION
+ if (!tz->emul_temperature)
+ goto skip_emul;
+
+ for (count = 0; count < tz->trips; count++) {
+ ret = tz->ops->get_trip_type(tz, count, &type);
+ if (!ret && type == THERMAL_TRIP_CRITICAL) {
+ ret = tz->ops->get_trip_temp(tz, count, &crit_temp);
+ break;
+ }
+ }
+
+ if (ret)
+ goto skip_emul;
+
+ if (*temp < crit_temp)
+ *temp = tz->emul_temperature;
+skip_emul:
+#endif
+ mutex_unlock(&tz->lock);
+ return ret;
+}
+
static void update_temperature(struct thermal_zone_device *tz)
{
long temp;
int ret;
- mutex_lock(&tz->lock);
-
- ret = tz->ops->get_temp(tz, &temp);
+ ret = thermal_zone_get_temp(tz, &temp);
if (ret) {
dev_warn(&tz->device, "failed to read out thermal zone %d\n",
tz->id);
- goto exit;
+ return;
}
+ mutex_lock(&tz->lock);
tz->last_temperature = tz->temperature;
tz->temperature = temp;
-
-exit:
mutex_unlock(&tz->lock);
}
long temperature;
int ret;
- if (!tz->ops->get_temp)
- return -EPERM;
-
- ret = tz->ops->get_temp(tz, &temperature);
+ ret = thermal_zone_get_temp(tz, &temperature);
if (ret)
return ret;
return sprintf(buf, "%s\n", tz->governor->name);
}
+#ifdef CONFIG_THERMAL_EMULATION
+static ssize_t
+emul_temp_store(struct device *dev, struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ struct thermal_zone_device *tz = to_thermal_zone(dev);
+ int ret = 0;
+ unsigned long temperature;
+
+ if (kstrtoul(buf, 10, &temperature))
+ return -EINVAL;
+
+ if (!tz->ops->set_emul_temp) {
+ mutex_lock(&tz->lock);
+ tz->emul_temperature = temperature;
+ mutex_unlock(&tz->lock);
+ } else {
+ ret = tz->ops->set_emul_temp(tz, temperature);
+ }
+
+ return ret ? ret : count;
+}
+static DEVICE_ATTR(emul_temp, S_IWUSR, NULL, emul_temp_store);
+#endif/*CONFIG_THERMAL_EMULATION*/
+
static DEVICE_ATTR(type, 0444, type_show, NULL);
static DEVICE_ATTR(temp, 0444, temp_show, NULL);
static DEVICE_ATTR(mode, 0644, mode_show, mode_store);
temp_input);
struct thermal_zone_device *tz = temp->tz;
- ret = tz->ops->get_temp(tz, &temperature);
+ ret = thermal_zone_get_temp(tz, &temperature);
if (ret)
return ret;
goto unregister;
}
+#ifdef CONFIG_THERMAL_EMULATION
+ result = device_create_file(&tz->device, &dev_attr_emul_temp);
+ if (result)
+ goto unregister;
+#endif
/* Create policy attribute */
result = device_create_file(&tz->device, &dev_attr_policy);
if (result)