|
@@ -239,6 +239,52 @@ trip_point_temp_show(struct device *dev, struct device_attribute *attr,
|
|
|
return sprintf(buf, "%ld\n", temperature);
|
|
|
}
|
|
|
|
|
|
+static ssize_t
|
|
|
+trip_point_hyst_store(struct device *dev, struct device_attribute *attr,
|
|
|
+ const char *buf, size_t count)
|
|
|
+{
|
|
|
+ struct thermal_zone_device *tz = to_thermal_zone(dev);
|
|
|
+ int trip, ret;
|
|
|
+ unsigned long temperature;
|
|
|
+
|
|
|
+ if (!tz->ops->set_trip_hyst)
|
|
|
+ return -EPERM;
|
|
|
+
|
|
|
+ if (!sscanf(attr->attr.name, "trip_point_%d_hyst", &trip))
|
|
|
+ return -EINVAL;
|
|
|
+
|
|
|
+ if (kstrtoul(buf, 10, &temperature))
|
|
|
+ return -EINVAL;
|
|
|
+
|
|
|
+ /*
|
|
|
+ * We are not doing any check on the 'temperature' value
|
|
|
+ * here. The driver implementing 'set_trip_hyst' has to
|
|
|
+ * take care of this.
|
|
|
+ */
|
|
|
+ ret = tz->ops->set_trip_hyst(tz, trip, temperature);
|
|
|
+
|
|
|
+ return ret ? ret : count;
|
|
|
+}
|
|
|
+
|
|
|
+static ssize_t
|
|
|
+trip_point_hyst_show(struct device *dev, struct device_attribute *attr,
|
|
|
+ char *buf)
|
|
|
+{
|
|
|
+ struct thermal_zone_device *tz = to_thermal_zone(dev);
|
|
|
+ int trip, ret;
|
|
|
+ unsigned long temperature;
|
|
|
+
|
|
|
+ if (!tz->ops->get_trip_hyst)
|
|
|
+ return -EPERM;
|
|
|
+
|
|
|
+ if (!sscanf(attr->attr.name, "trip_point_%d_hyst", &trip))
|
|
|
+ return -EINVAL;
|
|
|
+
|
|
|
+ ret = tz->ops->get_trip_hyst(tz, trip, &temperature);
|
|
|
+
|
|
|
+ return ret ? ret : sprintf(buf, "%ld\n", temperature);
|
|
|
+}
|
|
|
+
|
|
|
static ssize_t
|
|
|
passive_store(struct device *dev, struct device_attribute *attr,
|
|
|
const char *buf, size_t count)
|
|
@@ -1091,21 +1137,29 @@ EXPORT_SYMBOL(thermal_zone_device_update);
|
|
|
static int create_trip_attrs(struct thermal_zone_device *tz, int mask)
|
|
|
{
|
|
|
int indx;
|
|
|
+ int size = sizeof(struct thermal_attr) * tz->trips;
|
|
|
|
|
|
- tz->trip_type_attrs =
|
|
|
- kzalloc(sizeof(struct thermal_attr) * tz->trips, GFP_KERNEL);
|
|
|
+ tz->trip_type_attrs = kzalloc(size, GFP_KERNEL);
|
|
|
if (!tz->trip_type_attrs)
|
|
|
return -ENOMEM;
|
|
|
|
|
|
- tz->trip_temp_attrs =
|
|
|
- kzalloc(sizeof(struct thermal_attr) * tz->trips, GFP_KERNEL);
|
|
|
+ tz->trip_temp_attrs = kzalloc(size, GFP_KERNEL);
|
|
|
if (!tz->trip_temp_attrs) {
|
|
|
kfree(tz->trip_type_attrs);
|
|
|
return -ENOMEM;
|
|
|
}
|
|
|
|
|
|
- for (indx = 0; indx < tz->trips; indx++) {
|
|
|
+ if (tz->ops->get_trip_hyst) {
|
|
|
+ tz->trip_hyst_attrs = kzalloc(size, GFP_KERNEL);
|
|
|
+ if (!tz->trip_hyst_attrs) {
|
|
|
+ kfree(tz->trip_type_attrs);
|
|
|
+ kfree(tz->trip_temp_attrs);
|
|
|
+ return -ENOMEM;
|
|
|
+ }
|
|
|
+ }
|
|
|
|
|
|
+
|
|
|
+ for (indx = 0; indx < tz->trips; indx++) {
|
|
|
/* create trip type attribute */
|
|
|
snprintf(tz->trip_type_attrs[indx].name, THERMAL_NAME_LENGTH,
|
|
|
"trip_point_%d_type", indx);
|
|
@@ -1136,6 +1190,26 @@ static int create_trip_attrs(struct thermal_zone_device *tz, int mask)
|
|
|
|
|
|
device_create_file(&tz->device,
|
|
|
&tz->trip_temp_attrs[indx].attr);
|
|
|
+
|
|
|
+ /* create Optional trip hyst attribute */
|
|
|
+ if (!tz->ops->get_trip_hyst)
|
|
|
+ continue;
|
|
|
+ snprintf(tz->trip_hyst_attrs[indx].name, THERMAL_NAME_LENGTH,
|
|
|
+ "trip_point_%d_hyst", indx);
|
|
|
+
|
|
|
+ sysfs_attr_init(&tz->trip_hyst_attrs[indx].attr.attr);
|
|
|
+ tz->trip_hyst_attrs[indx].attr.attr.name =
|
|
|
+ tz->trip_hyst_attrs[indx].name;
|
|
|
+ tz->trip_hyst_attrs[indx].attr.attr.mode = S_IRUGO;
|
|
|
+ tz->trip_hyst_attrs[indx].attr.show = trip_point_hyst_show;
|
|
|
+ if (tz->ops->set_trip_hyst) {
|
|
|
+ tz->trip_hyst_attrs[indx].attr.attr.mode |= S_IWUSR;
|
|
|
+ tz->trip_hyst_attrs[indx].attr.store =
|
|
|
+ trip_point_hyst_store;
|
|
|
+ }
|
|
|
+
|
|
|
+ device_create_file(&tz->device,
|
|
|
+ &tz->trip_hyst_attrs[indx].attr);
|
|
|
}
|
|
|
return 0;
|
|
|
}
|
|
@@ -1149,9 +1223,13 @@ static void remove_trip_attrs(struct thermal_zone_device *tz)
|
|
|
&tz->trip_type_attrs[indx].attr);
|
|
|
device_remove_file(&tz->device,
|
|
|
&tz->trip_temp_attrs[indx].attr);
|
|
|
+ if (tz->ops->get_trip_hyst)
|
|
|
+ device_remove_file(&tz->device,
|
|
|
+ &tz->trip_hyst_attrs[indx].attr);
|
|
|
}
|
|
|
kfree(tz->trip_type_attrs);
|
|
|
kfree(tz->trip_temp_attrs);
|
|
|
+ kfree(tz->trip_hyst_attrs);
|
|
|
}
|
|
|
|
|
|
/**
|