diff options
author | Durgadoss R <dugardoss.r@intel.com> | 2012-07-24 22:10:58 -0400 |
---|---|---|
committer | Len Brown <len.brown@intel.com> | 2012-07-24 23:17:20 -0400 |
commit | c56f5c0342dfee11a1a13d2f5bb7618de5b17590 (patch) | |
tree | 4f5bae9424271e41d10d0c9d9fc17be6f63fba63 /drivers/thermal | |
parent | 28a33cbc24e4256c143dce96c7d93bf423229f92 (diff) |
Thermal: Make Thermal trip points writeable
Some of the thermal drivers using the Generic Thermal Framework
require (all/some) trip points to be writeable. This patch makes
the trip point temperatures writeable on a per-trip point basis,
and modifies the required function call in thermal.c. This patch
also updates the Documentation to reflect the new change.
Signed-off-by: Durgadoss R <durgadoss.r@intel.com>
Signed-off-by: Zhang Rui <rui.zhang@intel.com>
Signed-off-by: Len Brown <len.brown@intel.com>
Diffstat (limited to 'drivers/thermal')
-rw-r--r-- | drivers/thermal/spear_thermal.c | 2 | ||||
-rw-r--r-- | drivers/thermal/thermal_sys.c | 145 |
2 files changed, 102 insertions, 45 deletions
diff --git a/drivers/thermal/spear_thermal.c b/drivers/thermal/spear_thermal.c index c2e32df3b164..69a55d46aaa6 100644 --- a/drivers/thermal/spear_thermal.c +++ b/drivers/thermal/spear_thermal.c | |||
@@ -147,7 +147,7 @@ static int spear_thermal_probe(struct platform_device *pdev) | |||
147 | stdev->flags = pdata->thermal_flags; | 147 | stdev->flags = pdata->thermal_flags; |
148 | writel_relaxed(stdev->flags, stdev->thermal_base); | 148 | writel_relaxed(stdev->flags, stdev->thermal_base); |
149 | 149 | ||
150 | spear_thermal = thermal_zone_device_register("spear_thermal", 0, | 150 | spear_thermal = thermal_zone_device_register("spear_thermal", 0, 0, |
151 | stdev, &ops, 0, 0, 0, 0); | 151 | stdev, &ops, 0, 0, 0, 0); |
152 | if (IS_ERR(spear_thermal)) { | 152 | if (IS_ERR(spear_thermal)) { |
153 | dev_err(&pdev->dev, "thermal zone device is NULL\n"); | 153 | dev_err(&pdev->dev, "thermal zone device is NULL\n"); |
diff --git a/drivers/thermal/thermal_sys.c b/drivers/thermal/thermal_sys.c index 022bacb71a7e..5feb3353213f 100644 --- a/drivers/thermal/thermal_sys.c +++ b/drivers/thermal/thermal_sys.c | |||
@@ -196,6 +196,28 @@ trip_point_type_show(struct device *dev, struct device_attribute *attr, | |||
196 | } | 196 | } |
197 | 197 | ||
198 | static ssize_t | 198 | static ssize_t |
199 | trip_point_temp_store(struct device *dev, struct device_attribute *attr, | ||
200 | const char *buf, size_t count) | ||
201 | { | ||
202 | struct thermal_zone_device *tz = to_thermal_zone(dev); | ||
203 | int trip, ret; | ||
204 | unsigned long temperature; | ||
205 | |||
206 | if (!tz->ops->set_trip_temp) | ||
207 | return -EPERM; | ||
208 | |||
209 | if (!sscanf(attr->attr.name, "trip_point_%d_temp", &trip)) | ||
210 | return -EINVAL; | ||
211 | |||
212 | if (kstrtoul(buf, 10, &temperature)) | ||
213 | return -EINVAL; | ||
214 | |||
215 | ret = tz->ops->set_trip_temp(tz, trip, temperature); | ||
216 | |||
217 | return ret ? ret : count; | ||
218 | } | ||
219 | |||
220 | static ssize_t | ||
199 | trip_point_temp_show(struct device *dev, struct device_attribute *attr, | 221 | trip_point_temp_show(struct device *dev, struct device_attribute *attr, |
200 | char *buf) | 222 | char *buf) |
201 | { | 223 | { |
@@ -283,33 +305,6 @@ static DEVICE_ATTR(temp, 0444, temp_show, NULL); | |||
283 | static DEVICE_ATTR(mode, 0644, mode_show, mode_store); | 305 | static DEVICE_ATTR(mode, 0644, mode_show, mode_store); |
284 | static DEVICE_ATTR(passive, S_IRUGO | S_IWUSR, passive_show, passive_store); | 306 | static DEVICE_ATTR(passive, S_IRUGO | S_IWUSR, passive_show, passive_store); |
285 | 307 | ||
286 | static struct device_attribute trip_point_attrs[] = { | ||
287 | __ATTR(trip_point_0_type, 0444, trip_point_type_show, NULL), | ||
288 | __ATTR(trip_point_0_temp, 0444, trip_point_temp_show, NULL), | ||
289 | __ATTR(trip_point_1_type, 0444, trip_point_type_show, NULL), | ||
290 | __ATTR(trip_point_1_temp, 0444, trip_point_temp_show, NULL), | ||
291 | __ATTR(trip_point_2_type, 0444, trip_point_type_show, NULL), | ||
292 | __ATTR(trip_point_2_temp, 0444, trip_point_temp_show, NULL), | ||
293 | __ATTR(trip_point_3_type, 0444, trip_point_type_show, NULL), | ||
294 | __ATTR(trip_point_3_temp, 0444, trip_point_temp_show, NULL), | ||
295 | __ATTR(trip_point_4_type, 0444, trip_point_type_show, NULL), | ||
296 | __ATTR(trip_point_4_temp, 0444, trip_point_temp_show, NULL), | ||
297 | __ATTR(trip_point_5_type, 0444, trip_point_type_show, NULL), | ||
298 | __ATTR(trip_point_5_temp, 0444, trip_point_temp_show, NULL), | ||
299 | __ATTR(trip_point_6_type, 0444, trip_point_type_show, NULL), | ||
300 | __ATTR(trip_point_6_temp, 0444, trip_point_temp_show, NULL), | ||
301 | __ATTR(trip_point_7_type, 0444, trip_point_type_show, NULL), | ||
302 | __ATTR(trip_point_7_temp, 0444, trip_point_temp_show, NULL), | ||
303 | __ATTR(trip_point_8_type, 0444, trip_point_type_show, NULL), | ||
304 | __ATTR(trip_point_8_temp, 0444, trip_point_temp_show, NULL), | ||
305 | __ATTR(trip_point_9_type, 0444, trip_point_type_show, NULL), | ||
306 | __ATTR(trip_point_9_temp, 0444, trip_point_temp_show, NULL), | ||
307 | __ATTR(trip_point_10_type, 0444, trip_point_type_show, NULL), | ||
308 | __ATTR(trip_point_10_temp, 0444, trip_point_temp_show, NULL), | ||
309 | __ATTR(trip_point_11_type, 0444, trip_point_type_show, NULL), | ||
310 | __ATTR(trip_point_11_temp, 0444, trip_point_temp_show, NULL), | ||
311 | }; | ||
312 | |||
313 | /* sys I/F for cooling device */ | 308 | /* sys I/F for cooling device */ |
314 | #define to_cooling_device(_dev) \ | 309 | #define to_cooling_device(_dev) \ |
315 | container_of(_dev, struct thermal_cooling_device, device) | 310 | container_of(_dev, struct thermal_cooling_device, device) |
@@ -1089,9 +1084,81 @@ leave: | |||
1089 | EXPORT_SYMBOL(thermal_zone_device_update); | 1084 | EXPORT_SYMBOL(thermal_zone_device_update); |
1090 | 1085 | ||
1091 | /** | 1086 | /** |
1087 | * create_trip_attrs - create attributes for trip points | ||
1088 | * @tz: the thermal zone device | ||
1089 | * @mask: Writeable trip point bitmap. | ||
1090 | */ | ||
1091 | static int create_trip_attrs(struct thermal_zone_device *tz, int mask) | ||
1092 | { | ||
1093 | int indx; | ||
1094 | |||
1095 | tz->trip_type_attrs = | ||
1096 | kzalloc(sizeof(struct thermal_attr) * tz->trips, GFP_KERNEL); | ||
1097 | if (!tz->trip_type_attrs) | ||
1098 | return -ENOMEM; | ||
1099 | |||
1100 | tz->trip_temp_attrs = | ||
1101 | kzalloc(sizeof(struct thermal_attr) * tz->trips, GFP_KERNEL); | ||
1102 | if (!tz->trip_temp_attrs) { | ||
1103 | kfree(tz->trip_type_attrs); | ||
1104 | return -ENOMEM; | ||
1105 | } | ||
1106 | |||
1107 | for (indx = 0; indx < tz->trips; indx++) { | ||
1108 | |||
1109 | /* create trip type attribute */ | ||
1110 | snprintf(tz->trip_type_attrs[indx].name, THERMAL_NAME_LENGTH, | ||
1111 | "trip_point_%d_type", indx); | ||
1112 | |||
1113 | sysfs_attr_init(&tz->trip_type_attrs[indx].attr.attr); | ||
1114 | tz->trip_type_attrs[indx].attr.attr.name = | ||
1115 | tz->trip_type_attrs[indx].name; | ||
1116 | tz->trip_type_attrs[indx].attr.attr.mode = S_IRUGO; | ||
1117 | tz->trip_type_attrs[indx].attr.show = trip_point_type_show; | ||
1118 | |||
1119 | device_create_file(&tz->device, | ||
1120 | &tz->trip_type_attrs[indx].attr); | ||
1121 | |||
1122 | /* create trip temp attribute */ | ||
1123 | snprintf(tz->trip_temp_attrs[indx].name, THERMAL_NAME_LENGTH, | ||
1124 | "trip_point_%d_temp", indx); | ||
1125 | |||
1126 | sysfs_attr_init(&tz->trip_temp_attrs[indx].attr.attr); | ||
1127 | tz->trip_temp_attrs[indx].attr.attr.name = | ||
1128 | tz->trip_temp_attrs[indx].name; | ||
1129 | tz->trip_temp_attrs[indx].attr.attr.mode = S_IRUGO; | ||
1130 | tz->trip_temp_attrs[indx].attr.show = trip_point_temp_show; | ||
1131 | if (mask & (1 << indx)) { | ||
1132 | tz->trip_temp_attrs[indx].attr.attr.mode |= S_IWUSR; | ||
1133 | tz->trip_temp_attrs[indx].attr.store = | ||
1134 | trip_point_temp_store; | ||
1135 | } | ||
1136 | |||
1137 | device_create_file(&tz->device, | ||
1138 | &tz->trip_temp_attrs[indx].attr); | ||
1139 | } | ||
1140 | return 0; | ||
1141 | } | ||
1142 | |||
1143 | static void remove_trip_attrs(struct thermal_zone_device *tz) | ||
1144 | { | ||
1145 | int indx; | ||
1146 | |||
1147 | for (indx = 0; indx < tz->trips; indx++) { | ||
1148 | device_remove_file(&tz->device, | ||
1149 | &tz->trip_type_attrs[indx].attr); | ||
1150 | device_remove_file(&tz->device, | ||
1151 | &tz->trip_temp_attrs[indx].attr); | ||
1152 | } | ||
1153 | kfree(tz->trip_type_attrs); | ||
1154 | kfree(tz->trip_temp_attrs); | ||
1155 | } | ||
1156 | |||
1157 | /** | ||
1092 | * thermal_zone_device_register - register a new thermal zone device | 1158 | * thermal_zone_device_register - register a new thermal zone device |
1093 | * @type: the thermal zone device type | 1159 | * @type: the thermal zone device type |
1094 | * @trips: the number of trip points the thermal zone support | 1160 | * @trips: the number of trip points the thermal zone support |
1161 | * @mask: a bit string indicating the writeablility of trip points | ||
1095 | * @devdata: private device data | 1162 | * @devdata: private device data |
1096 | * @ops: standard thermal zone device callbacks | 1163 | * @ops: standard thermal zone device callbacks |
1097 | * @tc1: thermal coefficient 1 for passive calculations | 1164 | * @tc1: thermal coefficient 1 for passive calculations |
@@ -1107,7 +1174,7 @@ EXPORT_SYMBOL(thermal_zone_device_update); | |||
1107 | * section 11.1.5.1 of the ACPI specification 3.0. | 1174 | * section 11.1.5.1 of the ACPI specification 3.0. |
1108 | */ | 1175 | */ |
1109 | struct thermal_zone_device *thermal_zone_device_register(char *type, | 1176 | struct thermal_zone_device *thermal_zone_device_register(char *type, |
1110 | int trips, void *devdata, | 1177 | int trips, int mask, void *devdata, |
1111 | const struct thermal_zone_device_ops *ops, | 1178 | const struct thermal_zone_device_ops *ops, |
1112 | int tc1, int tc2, int passive_delay, int polling_delay) | 1179 | int tc1, int tc2, int passive_delay, int polling_delay) |
1113 | { | 1180 | { |
@@ -1121,7 +1188,7 @@ struct thermal_zone_device *thermal_zone_device_register(char *type, | |||
1121 | if (strlen(type) >= THERMAL_NAME_LENGTH) | 1188 | if (strlen(type) >= THERMAL_NAME_LENGTH) |
1122 | return ERR_PTR(-EINVAL); | 1189 | return ERR_PTR(-EINVAL); |
1123 | 1190 | ||
1124 | if (trips > THERMAL_MAX_TRIPS || trips < 0) | 1191 | if (trips > THERMAL_MAX_TRIPS || trips < 0 || mask >> trips) |
1125 | return ERR_PTR(-EINVAL); | 1192 | return ERR_PTR(-EINVAL); |
1126 | 1193 | ||
1127 | if (!ops || !ops->get_temp) | 1194 | if (!ops || !ops->get_temp) |
@@ -1175,15 +1242,11 @@ struct thermal_zone_device *thermal_zone_device_register(char *type, | |||
1175 | goto unregister; | 1242 | goto unregister; |
1176 | } | 1243 | } |
1177 | 1244 | ||
1245 | result = create_trip_attrs(tz, mask); | ||
1246 | if (result) | ||
1247 | goto unregister; | ||
1248 | |||
1178 | for (count = 0; count < trips; count++) { | 1249 | for (count = 0; count < trips; count++) { |
1179 | result = device_create_file(&tz->device, | ||
1180 | &trip_point_attrs[count * 2]); | ||
1181 | if (result) | ||
1182 | break; | ||
1183 | result = device_create_file(&tz->device, | ||
1184 | &trip_point_attrs[count * 2 + 1]); | ||
1185 | if (result) | ||
1186 | goto unregister; | ||
1187 | tz->ops->get_trip_type(tz, count, &trip_type); | 1250 | tz->ops->get_trip_type(tz, count, &trip_type); |
1188 | if (trip_type == THERMAL_TRIP_PASSIVE) | 1251 | if (trip_type == THERMAL_TRIP_PASSIVE) |
1189 | passive = 1; | 1252 | passive = 1; |
@@ -1232,7 +1295,6 @@ void thermal_zone_device_unregister(struct thermal_zone_device *tz) | |||
1232 | { | 1295 | { |
1233 | struct thermal_cooling_device *cdev; | 1296 | struct thermal_cooling_device *cdev; |
1234 | struct thermal_zone_device *pos = NULL; | 1297 | struct thermal_zone_device *pos = NULL; |
1235 | int count; | ||
1236 | 1298 | ||
1237 | if (!tz) | 1299 | if (!tz) |
1238 | return; | 1300 | return; |
@@ -1259,13 +1321,8 @@ void thermal_zone_device_unregister(struct thermal_zone_device *tz) | |||
1259 | device_remove_file(&tz->device, &dev_attr_temp); | 1321 | device_remove_file(&tz->device, &dev_attr_temp); |
1260 | if (tz->ops->get_mode) | 1322 | if (tz->ops->get_mode) |
1261 | device_remove_file(&tz->device, &dev_attr_mode); | 1323 | device_remove_file(&tz->device, &dev_attr_mode); |
1324 | remove_trip_attrs(tz); | ||
1262 | 1325 | ||
1263 | for (count = 0; count < tz->trips; count++) { | ||
1264 | device_remove_file(&tz->device, | ||
1265 | &trip_point_attrs[count * 2]); | ||
1266 | device_remove_file(&tz->device, | ||
1267 | &trip_point_attrs[count * 2 + 1]); | ||
1268 | } | ||
1269 | thermal_remove_hwmon_sysfs(tz); | 1326 | thermal_remove_hwmon_sysfs(tz); |
1270 | release_idr(&thermal_tz_idr, &thermal_idr_lock, tz->id); | 1327 | release_idr(&thermal_tz_idr, &thermal_idr_lock, tz->id); |
1271 | idr_destroy(&tz->idr); | 1328 | idr_destroy(&tz->idr); |