aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/thermal
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/thermal')
-rw-r--r--drivers/thermal/Kconfig1
-rw-r--r--drivers/thermal/spear_thermal.c28
-rw-r--r--drivers/thermal/thermal_sys.c223
3 files changed, 197 insertions, 55 deletions
diff --git a/drivers/thermal/Kconfig b/drivers/thermal/Kconfig
index 514a691abea..3ab2bd540b5 100644
--- a/drivers/thermal/Kconfig
+++ b/drivers/thermal/Kconfig
@@ -23,6 +23,7 @@ config SPEAR_THERMAL
23 bool "SPEAr thermal sensor driver" 23 bool "SPEAr thermal sensor driver"
24 depends on THERMAL 24 depends on THERMAL
25 depends on PLAT_SPEAR 25 depends on PLAT_SPEAR
26 depends on OF
26 help 27 help
27 Enable this to plug the SPEAr thermal sensor driver into the Linux 28 Enable this to plug the SPEAr thermal sensor driver into the Linux
28 thermal framework 29 thermal framework
diff --git a/drivers/thermal/spear_thermal.c b/drivers/thermal/spear_thermal.c
index c2e32df3b16..5f8ee39f200 100644
--- a/drivers/thermal/spear_thermal.c
+++ b/drivers/thermal/spear_thermal.c
@@ -20,9 +20,9 @@
20#include <linux/err.h> 20#include <linux/err.h>
21#include <linux/io.h> 21#include <linux/io.h>
22#include <linux/kernel.h> 22#include <linux/kernel.h>
23#include <linux/of.h>
23#include <linux/module.h> 24#include <linux/module.h>
24#include <linux/platform_device.h> 25#include <linux/platform_device.h>
25#include <linux/platform_data/spear_thermal.h>
26#include <linux/thermal.h> 26#include <linux/thermal.h>
27 27
28#define MD_FACTOR 1000 28#define MD_FACTOR 1000
@@ -103,21 +103,20 @@ static int spear_thermal_probe(struct platform_device *pdev)
103{ 103{
104 struct thermal_zone_device *spear_thermal = NULL; 104 struct thermal_zone_device *spear_thermal = NULL;
105 struct spear_thermal_dev *stdev; 105 struct spear_thermal_dev *stdev;
106 struct spear_thermal_pdata *pdata; 106 struct device_node *np = pdev->dev.of_node;
107 int ret = 0;
108 struct resource *stres = platform_get_resource(pdev, IORESOURCE_MEM, 0); 107 struct resource *stres = platform_get_resource(pdev, IORESOURCE_MEM, 0);
108 int ret = 0, val;
109
110 if (!np || !of_property_read_u32(np, "st,thermal-flags", &val)) {
111 dev_err(&pdev->dev, "Failed: DT Pdata not passed\n");
112 return -EINVAL;
113 }
109 114
110 if (!stres) { 115 if (!stres) {
111 dev_err(&pdev->dev, "memory resource missing\n"); 116 dev_err(&pdev->dev, "memory resource missing\n");
112 return -ENODEV; 117 return -ENODEV;
113 } 118 }
114 119
115 pdata = dev_get_platdata(&pdev->dev);
116 if (!pdata) {
117 dev_err(&pdev->dev, "platform data is NULL\n");
118 return -EINVAL;
119 }
120
121 stdev = devm_kzalloc(&pdev->dev, sizeof(*stdev), GFP_KERNEL); 120 stdev = devm_kzalloc(&pdev->dev, sizeof(*stdev), GFP_KERNEL);
122 if (!stdev) { 121 if (!stdev) {
123 dev_err(&pdev->dev, "kzalloc fail\n"); 122 dev_err(&pdev->dev, "kzalloc fail\n");
@@ -144,10 +143,10 @@ static int spear_thermal_probe(struct platform_device *pdev)
144 goto put_clk; 143 goto put_clk;
145 } 144 }
146 145
147 stdev->flags = pdata->thermal_flags; 146 stdev->flags = val;
148 writel_relaxed(stdev->flags, stdev->thermal_base); 147 writel_relaxed(stdev->flags, stdev->thermal_base);
149 148
150 spear_thermal = thermal_zone_device_register("spear_thermal", 0, 149 spear_thermal = thermal_zone_device_register("spear_thermal", 0, 0,
151 stdev, &ops, 0, 0, 0, 0); 150 stdev, &ops, 0, 0, 0, 0);
152 if (IS_ERR(spear_thermal)) { 151 if (IS_ERR(spear_thermal)) {
153 dev_err(&pdev->dev, "thermal zone device is NULL\n"); 152 dev_err(&pdev->dev, "thermal zone device is NULL\n");
@@ -189,6 +188,12 @@ static int spear_thermal_exit(struct platform_device *pdev)
189 return 0; 188 return 0;
190} 189}
191 190
191static const struct of_device_id spear_thermal_id_table[] = {
192 { .compatible = "st,thermal-spear1340" },
193 {}
194};
195MODULE_DEVICE_TABLE(of, spear_thermal_id_table);
196
192static struct platform_driver spear_thermal_driver = { 197static struct platform_driver spear_thermal_driver = {
193 .probe = spear_thermal_probe, 198 .probe = spear_thermal_probe,
194 .remove = spear_thermal_exit, 199 .remove = spear_thermal_exit,
@@ -196,6 +201,7 @@ static struct platform_driver spear_thermal_driver = {
196 .name = "spear_thermal", 201 .name = "spear_thermal",
197 .owner = THIS_MODULE, 202 .owner = THIS_MODULE,
198 .pm = &spear_thermal_pm_ops, 203 .pm = &spear_thermal_pm_ops,
204 .of_match_table = of_match_ptr(spear_thermal_id_table),
199 }, 205 },
200}; 206};
201 207
diff --git a/drivers/thermal/thermal_sys.c b/drivers/thermal/thermal_sys.c
index 022bacb71a7..2d7a9fe8f36 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{
@@ -218,6 +240,52 @@ trip_point_temp_show(struct device *dev, struct device_attribute *attr,
218} 240}
219 241
220static ssize_t 242static ssize_t
243trip_point_hyst_store(struct device *dev, struct device_attribute *attr,
244 const char *buf, size_t count)
245{
246 struct thermal_zone_device *tz = to_thermal_zone(dev);
247 int trip, ret;
248 unsigned long temperature;
249
250 if (!tz->ops->set_trip_hyst)
251 return -EPERM;
252
253 if (!sscanf(attr->attr.name, "trip_point_%d_hyst", &trip))
254 return -EINVAL;
255
256 if (kstrtoul(buf, 10, &temperature))
257 return -EINVAL;
258
259 /*
260 * We are not doing any check on the 'temperature' value
261 * here. The driver implementing 'set_trip_hyst' has to
262 * take care of this.
263 */
264 ret = tz->ops->set_trip_hyst(tz, trip, temperature);
265
266 return ret ? ret : count;
267}
268
269static ssize_t
270trip_point_hyst_show(struct device *dev, struct device_attribute *attr,
271 char *buf)
272{
273 struct thermal_zone_device *tz = to_thermal_zone(dev);
274 int trip, ret;
275 unsigned long temperature;
276
277 if (!tz->ops->get_trip_hyst)
278 return -EPERM;
279
280 if (!sscanf(attr->attr.name, "trip_point_%d_hyst", &trip))
281 return -EINVAL;
282
283 ret = tz->ops->get_trip_hyst(tz, trip, &temperature);
284
285 return ret ? ret : sprintf(buf, "%ld\n", temperature);
286}
287
288static ssize_t
221passive_store(struct device *dev, struct device_attribute *attr, 289passive_store(struct device *dev, struct device_attribute *attr,
222 const char *buf, size_t count) 290 const char *buf, size_t count)
223{ 291{
@@ -283,33 +351,6 @@ static DEVICE_ATTR(temp, 0444, temp_show, NULL);
283static DEVICE_ATTR(mode, 0644, mode_show, mode_store); 351static DEVICE_ATTR(mode, 0644, mode_show, mode_store);
284static DEVICE_ATTR(passive, S_IRUGO | S_IWUSR, passive_show, passive_store); 352static DEVICE_ATTR(passive, S_IRUGO | S_IWUSR, passive_show, passive_store);
285 353
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 */ 354/* sys I/F for cooling device */
314#define to_cooling_device(_dev) \ 355#define to_cooling_device(_dev) \
315 container_of(_dev, struct thermal_cooling_device, device) 356 container_of(_dev, struct thermal_cooling_device, device)
@@ -1089,9 +1130,113 @@ leave:
1089EXPORT_SYMBOL(thermal_zone_device_update); 1130EXPORT_SYMBOL(thermal_zone_device_update);
1090 1131
1091/** 1132/**
1133 * create_trip_attrs - create attributes for trip points
1134 * @tz: the thermal zone device
1135 * @mask: Writeable trip point bitmap.
1136 */
1137static int create_trip_attrs(struct thermal_zone_device *tz, int mask)
1138{
1139 int indx;
1140 int size = sizeof(struct thermal_attr) * tz->trips;
1141
1142 tz->trip_type_attrs = kzalloc(size, GFP_KERNEL);
1143 if (!tz->trip_type_attrs)
1144 return -ENOMEM;
1145
1146 tz->trip_temp_attrs = kzalloc(size, GFP_KERNEL);
1147 if (!tz->trip_temp_attrs) {
1148 kfree(tz->trip_type_attrs);
1149 return -ENOMEM;
1150 }
1151
1152 if (tz->ops->get_trip_hyst) {
1153 tz->trip_hyst_attrs = kzalloc(size, GFP_KERNEL);
1154 if (!tz->trip_hyst_attrs) {
1155 kfree(tz->trip_type_attrs);
1156 kfree(tz->trip_temp_attrs);
1157 return -ENOMEM;
1158 }
1159 }
1160
1161
1162 for (indx = 0; indx < tz->trips; indx++) {
1163 /* create trip type attribute */
1164 snprintf(tz->trip_type_attrs[indx].name, THERMAL_NAME_LENGTH,
1165 "trip_point_%d_type", indx);
1166
1167 sysfs_attr_init(&tz->trip_type_attrs[indx].attr.attr);
1168 tz->trip_type_attrs[indx].attr.attr.name =
1169 tz->trip_type_attrs[indx].name;
1170 tz->trip_type_attrs[indx].attr.attr.mode = S_IRUGO;
1171 tz->trip_type_attrs[indx].attr.show = trip_point_type_show;
1172
1173 device_create_file(&tz->device,
1174 &tz->trip_type_attrs[indx].attr);
1175
1176 /* create trip temp attribute */
1177 snprintf(tz->trip_temp_attrs[indx].name, THERMAL_NAME_LENGTH,
1178 "trip_point_%d_temp", indx);
1179
1180 sysfs_attr_init(&tz->trip_temp_attrs[indx].attr.attr);
1181 tz->trip_temp_attrs[indx].attr.attr.name =
1182 tz->trip_temp_attrs[indx].name;
1183 tz->trip_temp_attrs[indx].attr.attr.mode = S_IRUGO;
1184 tz->trip_temp_attrs[indx].attr.show = trip_point_temp_show;
1185 if (mask & (1 << indx)) {
1186 tz->trip_temp_attrs[indx].attr.attr.mode |= S_IWUSR;
1187 tz->trip_temp_attrs[indx].attr.store =
1188 trip_point_temp_store;
1189 }
1190
1191 device_create_file(&tz->device,
1192 &tz->trip_temp_attrs[indx].attr);
1193
1194 /* create Optional trip hyst attribute */
1195 if (!tz->ops->get_trip_hyst)
1196 continue;
1197 snprintf(tz->trip_hyst_attrs[indx].name, THERMAL_NAME_LENGTH,
1198 "trip_point_%d_hyst", indx);
1199
1200 sysfs_attr_init(&tz->trip_hyst_attrs[indx].attr.attr);
1201 tz->trip_hyst_attrs[indx].attr.attr.name =
1202 tz->trip_hyst_attrs[indx].name;
1203 tz->trip_hyst_attrs[indx].attr.attr.mode = S_IRUGO;
1204 tz->trip_hyst_attrs[indx].attr.show = trip_point_hyst_show;
1205 if (tz->ops->set_trip_hyst) {
1206 tz->trip_hyst_attrs[indx].attr.attr.mode |= S_IWUSR;
1207 tz->trip_hyst_attrs[indx].attr.store =
1208 trip_point_hyst_store;
1209 }
1210
1211 device_create_file(&tz->device,
1212 &tz->trip_hyst_attrs[indx].attr);
1213 }
1214 return 0;
1215}
1216
1217static void remove_trip_attrs(struct thermal_zone_device *tz)
1218{
1219 int indx;
1220
1221 for (indx = 0; indx < tz->trips; indx++) {
1222 device_remove_file(&tz->device,
1223 &tz->trip_type_attrs[indx].attr);
1224 device_remove_file(&tz->device,
1225 &tz->trip_temp_attrs[indx].attr);
1226 if (tz->ops->get_trip_hyst)
1227 device_remove_file(&tz->device,
1228 &tz->trip_hyst_attrs[indx].attr);
1229 }
1230 kfree(tz->trip_type_attrs);
1231 kfree(tz->trip_temp_attrs);
1232 kfree(tz->trip_hyst_attrs);
1233}
1234
1235/**
1092 * thermal_zone_device_register - register a new thermal zone device 1236 * thermal_zone_device_register - register a new thermal zone device
1093 * @type: the thermal zone device type 1237 * @type: the thermal zone device type
1094 * @trips: the number of trip points the thermal zone support 1238 * @trips: the number of trip points the thermal zone support
1239 * @mask: a bit string indicating the writeablility of trip points
1095 * @devdata: private device data 1240 * @devdata: private device data
1096 * @ops: standard thermal zone device callbacks 1241 * @ops: standard thermal zone device callbacks
1097 * @tc1: thermal coefficient 1 for passive calculations 1242 * @tc1: thermal coefficient 1 for passive calculations
@@ -1107,7 +1252,7 @@ EXPORT_SYMBOL(thermal_zone_device_update);
1107 * section 11.1.5.1 of the ACPI specification 3.0. 1252 * section 11.1.5.1 of the ACPI specification 3.0.
1108 */ 1253 */
1109struct thermal_zone_device *thermal_zone_device_register(char *type, 1254struct thermal_zone_device *thermal_zone_device_register(char *type,
1110 int trips, void *devdata, 1255 int trips, int mask, void *devdata,
1111 const struct thermal_zone_device_ops *ops, 1256 const struct thermal_zone_device_ops *ops,
1112 int tc1, int tc2, int passive_delay, int polling_delay) 1257 int tc1, int tc2, int passive_delay, int polling_delay)
1113{ 1258{
@@ -1121,7 +1266,7 @@ struct thermal_zone_device *thermal_zone_device_register(char *type,
1121 if (strlen(type) >= THERMAL_NAME_LENGTH) 1266 if (strlen(type) >= THERMAL_NAME_LENGTH)
1122 return ERR_PTR(-EINVAL); 1267 return ERR_PTR(-EINVAL);
1123 1268
1124 if (trips > THERMAL_MAX_TRIPS || trips < 0) 1269 if (trips > THERMAL_MAX_TRIPS || trips < 0 || mask >> trips)
1125 return ERR_PTR(-EINVAL); 1270 return ERR_PTR(-EINVAL);
1126 1271
1127 if (!ops || !ops->get_temp) 1272 if (!ops || !ops->get_temp)
@@ -1175,15 +1320,11 @@ struct thermal_zone_device *thermal_zone_device_register(char *type,
1175 goto unregister; 1320 goto unregister;
1176 } 1321 }
1177 1322
1323 result = create_trip_attrs(tz, mask);
1324 if (result)
1325 goto unregister;
1326
1178 for (count = 0; count < trips; count++) { 1327 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); 1328 tz->ops->get_trip_type(tz, count, &trip_type);
1188 if (trip_type == THERMAL_TRIP_PASSIVE) 1329 if (trip_type == THERMAL_TRIP_PASSIVE)
1189 passive = 1; 1330 passive = 1;
@@ -1232,7 +1373,6 @@ void thermal_zone_device_unregister(struct thermal_zone_device *tz)
1232{ 1373{
1233 struct thermal_cooling_device *cdev; 1374 struct thermal_cooling_device *cdev;
1234 struct thermal_zone_device *pos = NULL; 1375 struct thermal_zone_device *pos = NULL;
1235 int count;
1236 1376
1237 if (!tz) 1377 if (!tz)
1238 return; 1378 return;
@@ -1259,13 +1399,8 @@ void thermal_zone_device_unregister(struct thermal_zone_device *tz)
1259 device_remove_file(&tz->device, &dev_attr_temp); 1399 device_remove_file(&tz->device, &dev_attr_temp);
1260 if (tz->ops->get_mode) 1400 if (tz->ops->get_mode)
1261 device_remove_file(&tz->device, &dev_attr_mode); 1401 device_remove_file(&tz->device, &dev_attr_mode);
1402 remove_trip_attrs(tz);
1262 1403
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); 1404 thermal_remove_hwmon_sysfs(tz);
1270 release_idr(&thermal_tz_idr, &thermal_idr_lock, tz->id); 1405 release_idr(&thermal_tz_idr, &thermal_idr_lock, tz->id);
1271 idr_destroy(&tz->idr); 1406 idr_destroy(&tz->idr);