aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/thermal
diff options
context:
space:
mode:
authorDurgadoss R <dugardoss.r@intel.com>2012-07-24 22:10:58 -0400
committerLen Brown <len.brown@intel.com>2012-07-24 23:17:20 -0400
commitc56f5c0342dfee11a1a13d2f5bb7618de5b17590 (patch)
tree4f5bae9424271e41d10d0c9d9fc17be6f63fba63 /drivers/thermal
parent28a33cbc24e4256c143dce96c7d93bf423229f92 (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.c2
-rw-r--r--drivers/thermal/thermal_sys.c145
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
198static ssize_t 198static ssize_t
199trip_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
220static ssize_t
199trip_point_temp_show(struct device *dev, struct device_attribute *attr, 221trip_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);
283static DEVICE_ATTR(mode, 0644, mode_show, mode_store); 305static DEVICE_ATTR(mode, 0644, mode_show, mode_store);
284static DEVICE_ATTR(passive, S_IRUGO | S_IWUSR, passive_show, passive_store); 306static DEVICE_ATTR(passive, S_IRUGO | S_IWUSR, passive_show, passive_store);
285 307
286static 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:
1089EXPORT_SYMBOL(thermal_zone_device_update); 1084EXPORT_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 */
1091static 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
1143static 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 */
1109struct thermal_zone_device *thermal_zone_device_register(char *type, 1176struct 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);