xref: /openbmc/linux/drivers/thermal/thermal_sysfs.c (revision 5ef12cb4a3a78ffb331c03a795a15eea4ae35155)
1 /*
2  *  thermal.c - sysfs interface of thermal devices
3  *
4  *  Copyright (C) 2016 Eduardo Valentin <edubezval@gmail.com>
5  *
6  *  Highly based on original thermal_core.c
7  *  Copyright (C) 2008 Intel Corp
8  *  Copyright (C) 2008 Zhang Rui <rui.zhang@intel.com>
9  *  Copyright (C) 2008 Sujith Thomas <sujith.thomas@intel.com>
10  *
11  *  This program is free software; you can redistribute it and/or modify
12  *  it under the terms of the GNU General Public License as published by
13  *  the Free Software Foundation; version 2 of the License.
14  */
15 
16 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
17 
18 #include <linux/sysfs.h>
19 #include <linux/device.h>
20 #include <linux/err.h>
21 #include <linux/slab.h>
22 #include <linux/string.h>
23 #include <linux/jiffies.h>
24 
25 #include "thermal_core.h"
26 
27 /* sys I/F for thermal zone */
28 
29 static ssize_t
30 type_show(struct device *dev, struct device_attribute *attr, char *buf)
31 {
32 	struct thermal_zone_device *tz = to_thermal_zone(dev);
33 
34 	return sprintf(buf, "%s\n", tz->type);
35 }
36 
37 static ssize_t
38 temp_show(struct device *dev, struct device_attribute *attr, char *buf)
39 {
40 	struct thermal_zone_device *tz = to_thermal_zone(dev);
41 	int temperature, ret;
42 
43 	ret = thermal_zone_get_temp(tz, &temperature);
44 
45 	if (ret)
46 		return ret;
47 
48 	return sprintf(buf, "%d\n", temperature);
49 }
50 
51 static ssize_t
52 mode_show(struct device *dev, struct device_attribute *attr, char *buf)
53 {
54 	struct thermal_zone_device *tz = to_thermal_zone(dev);
55 	enum thermal_device_mode mode;
56 	int result;
57 
58 	if (!tz->ops->get_mode)
59 		return -EPERM;
60 
61 	result = tz->ops->get_mode(tz, &mode);
62 	if (result)
63 		return result;
64 
65 	return sprintf(buf, "%s\n", mode == THERMAL_DEVICE_ENABLED ? "enabled"
66 		       : "disabled");
67 }
68 
69 static ssize_t
70 mode_store(struct device *dev, struct device_attribute *attr,
71 	   const char *buf, size_t count)
72 {
73 	struct thermal_zone_device *tz = to_thermal_zone(dev);
74 	int result;
75 
76 	if (!tz->ops->set_mode)
77 		return -EPERM;
78 
79 	if (!strncmp(buf, "enabled", sizeof("enabled") - 1))
80 		result = tz->ops->set_mode(tz, THERMAL_DEVICE_ENABLED);
81 	else if (!strncmp(buf, "disabled", sizeof("disabled") - 1))
82 		result = tz->ops->set_mode(tz, THERMAL_DEVICE_DISABLED);
83 	else
84 		result = -EINVAL;
85 
86 	if (result)
87 		return result;
88 
89 	return count;
90 }
91 
92 static ssize_t
93 trip_point_type_show(struct device *dev, struct device_attribute *attr,
94 		     char *buf)
95 {
96 	struct thermal_zone_device *tz = to_thermal_zone(dev);
97 	enum thermal_trip_type type;
98 	int trip, result;
99 
100 	if (!tz->ops->get_trip_type)
101 		return -EPERM;
102 
103 	if (sscanf(attr->attr.name, "trip_point_%d_type", &trip) != 1)
104 		return -EINVAL;
105 
106 	result = tz->ops->get_trip_type(tz, trip, &type);
107 	if (result)
108 		return result;
109 
110 	switch (type) {
111 	case THERMAL_TRIP_CRITICAL:
112 		return sprintf(buf, "critical\n");
113 	case THERMAL_TRIP_HOT:
114 		return sprintf(buf, "hot\n");
115 	case THERMAL_TRIP_PASSIVE:
116 		return sprintf(buf, "passive\n");
117 	case THERMAL_TRIP_ACTIVE:
118 		return sprintf(buf, "active\n");
119 	default:
120 		return sprintf(buf, "unknown\n");
121 	}
122 }
123 
124 static ssize_t
125 trip_point_temp_store(struct device *dev, struct device_attribute *attr,
126 		      const char *buf, size_t count)
127 {
128 	struct thermal_zone_device *tz = to_thermal_zone(dev);
129 	int trip, ret;
130 	int temperature;
131 
132 	if (!tz->ops->set_trip_temp)
133 		return -EPERM;
134 
135 	if (sscanf(attr->attr.name, "trip_point_%d_temp", &trip) != 1)
136 		return -EINVAL;
137 
138 	if (kstrtoint(buf, 10, &temperature))
139 		return -EINVAL;
140 
141 	ret = tz->ops->set_trip_temp(tz, trip, temperature);
142 	if (ret)
143 		return ret;
144 
145 	thermal_zone_device_update(tz, THERMAL_EVENT_UNSPECIFIED);
146 
147 	return count;
148 }
149 
150 static ssize_t
151 trip_point_temp_show(struct device *dev, struct device_attribute *attr,
152 		     char *buf)
153 {
154 	struct thermal_zone_device *tz = to_thermal_zone(dev);
155 	int trip, ret;
156 	int temperature;
157 
158 	if (!tz->ops->get_trip_temp)
159 		return -EPERM;
160 
161 	if (sscanf(attr->attr.name, "trip_point_%d_temp", &trip) != 1)
162 		return -EINVAL;
163 
164 	ret = tz->ops->get_trip_temp(tz, trip, &temperature);
165 
166 	if (ret)
167 		return ret;
168 
169 	return sprintf(buf, "%d\n", temperature);
170 }
171 
172 static ssize_t
173 trip_point_hyst_store(struct device *dev, struct device_attribute *attr,
174 		      const char *buf, size_t count)
175 {
176 	struct thermal_zone_device *tz = to_thermal_zone(dev);
177 	int trip, ret;
178 	int temperature;
179 
180 	if (!tz->ops->set_trip_hyst)
181 		return -EPERM;
182 
183 	if (sscanf(attr->attr.name, "trip_point_%d_hyst", &trip) != 1)
184 		return -EINVAL;
185 
186 	if (kstrtoint(buf, 10, &temperature))
187 		return -EINVAL;
188 
189 	/*
190 	 * We are not doing any check on the 'temperature' value
191 	 * here. The driver implementing 'set_trip_hyst' has to
192 	 * take care of this.
193 	 */
194 	ret = tz->ops->set_trip_hyst(tz, trip, temperature);
195 
196 	if (!ret)
197 		thermal_zone_set_trips(tz);
198 
199 	return ret ? ret : count;
200 }
201 
202 static ssize_t
203 trip_point_hyst_show(struct device *dev, struct device_attribute *attr,
204 		     char *buf)
205 {
206 	struct thermal_zone_device *tz = to_thermal_zone(dev);
207 	int trip, ret;
208 	int temperature;
209 
210 	if (!tz->ops->get_trip_hyst)
211 		return -EPERM;
212 
213 	if (sscanf(attr->attr.name, "trip_point_%d_hyst", &trip) != 1)
214 		return -EINVAL;
215 
216 	ret = tz->ops->get_trip_hyst(tz, trip, &temperature);
217 
218 	return ret ? ret : sprintf(buf, "%d\n", temperature);
219 }
220 
221 static ssize_t
222 passive_store(struct device *dev, struct device_attribute *attr,
223 	      const char *buf, size_t count)
224 {
225 	struct thermal_zone_device *tz = to_thermal_zone(dev);
226 	int state;
227 
228 	if (sscanf(buf, "%d\n", &state) != 1)
229 		return -EINVAL;
230 
231 	/* sanity check: values below 1000 millicelcius don't make sense
232 	 * and can cause the system to go into a thermal heart attack
233 	 */
234 	if (state && state < 1000)
235 		return -EINVAL;
236 
237 	if (state && !tz->forced_passive) {
238 		if (!tz->passive_delay)
239 			tz->passive_delay = 1000;
240 		thermal_zone_device_rebind_exception(tz, "Processor",
241 						     sizeof("Processor"));
242 	} else if (!state && tz->forced_passive) {
243 		tz->passive_delay = 0;
244 		thermal_zone_device_unbind_exception(tz, "Processor",
245 						     sizeof("Processor"));
246 	}
247 
248 	tz->forced_passive = state;
249 
250 	thermal_zone_device_update(tz, THERMAL_EVENT_UNSPECIFIED);
251 
252 	return count;
253 }
254 
255 static ssize_t
256 passive_show(struct device *dev, struct device_attribute *attr,
257 	     char *buf)
258 {
259 	struct thermal_zone_device *tz = to_thermal_zone(dev);
260 
261 	return sprintf(buf, "%d\n", tz->forced_passive);
262 }
263 
264 static ssize_t
265 policy_store(struct device *dev, struct device_attribute *attr,
266 	     const char *buf, size_t count)
267 {
268 	struct thermal_zone_device *tz = to_thermal_zone(dev);
269 	char name[THERMAL_NAME_LENGTH];
270 	int ret;
271 
272 	snprintf(name, sizeof(name), "%s", buf);
273 
274 	ret = thermal_zone_device_set_policy(tz, name);
275 	if (!ret)
276 		ret = count;
277 
278 	return ret;
279 }
280 
281 static ssize_t
282 policy_show(struct device *dev, struct device_attribute *devattr, char *buf)
283 {
284 	struct thermal_zone_device *tz = to_thermal_zone(dev);
285 
286 	return sprintf(buf, "%s\n", tz->governor->name);
287 }
288 
289 static ssize_t
290 available_policies_show(struct device *dev, struct device_attribute *devattr,
291 			char *buf)
292 {
293 	return thermal_build_list_of_policies(buf);
294 }
295 
296 #if (IS_ENABLED(CONFIG_THERMAL_EMULATION))
297 static ssize_t
298 emul_temp_store(struct device *dev, struct device_attribute *attr,
299 		const char *buf, size_t count)
300 {
301 	struct thermal_zone_device *tz = to_thermal_zone(dev);
302 	int ret = 0;
303 	int temperature;
304 
305 	if (kstrtoint(buf, 10, &temperature))
306 		return -EINVAL;
307 
308 	if (!tz->ops->set_emul_temp) {
309 		mutex_lock(&tz->lock);
310 		tz->emul_temperature = temperature;
311 		mutex_unlock(&tz->lock);
312 	} else {
313 		ret = tz->ops->set_emul_temp(tz, temperature);
314 	}
315 
316 	if (!ret)
317 		thermal_zone_device_update(tz, THERMAL_EVENT_UNSPECIFIED);
318 
319 	return ret ? ret : count;
320 }
321 static DEVICE_ATTR_WO(emul_temp);
322 #endif
323 
324 static ssize_t
325 sustainable_power_show(struct device *dev, struct device_attribute *devattr,
326 		       char *buf)
327 {
328 	struct thermal_zone_device *tz = to_thermal_zone(dev);
329 
330 	if (tz->tzp)
331 		return sprintf(buf, "%u\n", tz->tzp->sustainable_power);
332 	else
333 		return -EIO;
334 }
335 
336 static ssize_t
337 sustainable_power_store(struct device *dev, struct device_attribute *devattr,
338 			const char *buf, size_t count)
339 {
340 	struct thermal_zone_device *tz = to_thermal_zone(dev);
341 	u32 sustainable_power;
342 
343 	if (!tz->tzp)
344 		return -EIO;
345 
346 	if (kstrtou32(buf, 10, &sustainable_power))
347 		return -EINVAL;
348 
349 	tz->tzp->sustainable_power = sustainable_power;
350 
351 	return count;
352 }
353 
354 #define create_s32_tzp_attr(name)					\
355 	static ssize_t							\
356 	name##_show(struct device *dev, struct device_attribute *devattr, \
357 		char *buf)						\
358 	{								\
359 	struct thermal_zone_device *tz = to_thermal_zone(dev);		\
360 									\
361 	if (tz->tzp)							\
362 		return sprintf(buf, "%d\n", tz->tzp->name);		\
363 	else								\
364 		return -EIO;						\
365 	}								\
366 									\
367 	static ssize_t							\
368 	name##_store(struct device *dev, struct device_attribute *devattr, \
369 		const char *buf, size_t count)				\
370 	{								\
371 		struct thermal_zone_device *tz = to_thermal_zone(dev);	\
372 		s32 value;						\
373 									\
374 		if (!tz->tzp)						\
375 			return -EIO;					\
376 									\
377 		if (kstrtos32(buf, 10, &value))				\
378 			return -EINVAL;					\
379 									\
380 		tz->tzp->name = value;					\
381 									\
382 		return count;						\
383 	}								\
384 	static DEVICE_ATTR(name, S_IWUSR | S_IRUGO, name##_show, name##_store)
385 
386 create_s32_tzp_attr(k_po);
387 create_s32_tzp_attr(k_pu);
388 create_s32_tzp_attr(k_i);
389 create_s32_tzp_attr(k_d);
390 create_s32_tzp_attr(integral_cutoff);
391 create_s32_tzp_attr(slope);
392 create_s32_tzp_attr(offset);
393 #undef create_s32_tzp_attr
394 
395 /*
396  * These are thermal zone device attributes that will always be present.
397  * All the attributes created for tzp (create_s32_tzp_attr) also are always
398  * present on the sysfs interface.
399  */
400 static DEVICE_ATTR_RO(type);
401 static DEVICE_ATTR_RO(temp);
402 static DEVICE_ATTR_RW(policy);
403 static DEVICE_ATTR_RO(available_policies);
404 static DEVICE_ATTR_RW(sustainable_power);
405 
406 /* These thermal zone device attributes are created based on conditions */
407 static DEVICE_ATTR_RW(mode);
408 static DEVICE_ATTR_RW(passive);
409 
410 /* These attributes are unconditionally added to a thermal zone */
411 static struct attribute *thermal_zone_dev_attrs[] = {
412 	&dev_attr_type.attr,
413 	&dev_attr_temp.attr,
414 #if (IS_ENABLED(CONFIG_THERMAL_EMULATION))
415 	&dev_attr_emul_temp.attr,
416 #endif
417 	&dev_attr_policy.attr,
418 	&dev_attr_available_policies.attr,
419 	&dev_attr_sustainable_power.attr,
420 	&dev_attr_k_po.attr,
421 	&dev_attr_k_pu.attr,
422 	&dev_attr_k_i.attr,
423 	&dev_attr_k_d.attr,
424 	&dev_attr_integral_cutoff.attr,
425 	&dev_attr_slope.attr,
426 	&dev_attr_offset.attr,
427 	NULL,
428 };
429 
430 static struct attribute_group thermal_zone_attribute_group = {
431 	.attrs = thermal_zone_dev_attrs,
432 };
433 
434 /* We expose mode only if .get_mode is present */
435 static struct attribute *thermal_zone_mode_attrs[] = {
436 	&dev_attr_mode.attr,
437 	NULL,
438 };
439 
440 static umode_t thermal_zone_mode_is_visible(struct kobject *kobj,
441 					    struct attribute *attr,
442 					    int attrno)
443 {
444 	struct device *dev = container_of(kobj, struct device, kobj);
445 	struct thermal_zone_device *tz;
446 
447 	tz = container_of(dev, struct thermal_zone_device, device);
448 
449 	if (tz->ops->get_mode)
450 		return attr->mode;
451 
452 	return 0;
453 }
454 
455 static struct attribute_group thermal_zone_mode_attribute_group = {
456 	.attrs = thermal_zone_mode_attrs,
457 	.is_visible = thermal_zone_mode_is_visible,
458 };
459 
460 /* We expose passive only if passive trips are present */
461 static struct attribute *thermal_zone_passive_attrs[] = {
462 	&dev_attr_passive.attr,
463 	NULL,
464 };
465 
466 static umode_t thermal_zone_passive_is_visible(struct kobject *kobj,
467 					       struct attribute *attr,
468 					       int attrno)
469 {
470 	struct device *dev = container_of(kobj, struct device, kobj);
471 	struct thermal_zone_device *tz;
472 	enum thermal_trip_type trip_type;
473 	int count, passive = 0;
474 
475 	tz = container_of(dev, struct thermal_zone_device, device);
476 
477 	for (count = 0; count < tz->trips && !passive; count++) {
478 		tz->ops->get_trip_type(tz, count, &trip_type);
479 
480 		if (trip_type == THERMAL_TRIP_PASSIVE)
481 			passive = 1;
482 	}
483 
484 	if (!passive)
485 		return attr->mode;
486 
487 	return 0;
488 }
489 
490 static struct attribute_group thermal_zone_passive_attribute_group = {
491 	.attrs = thermal_zone_passive_attrs,
492 	.is_visible = thermal_zone_passive_is_visible,
493 };
494 
495 static const struct attribute_group *thermal_zone_attribute_groups[] = {
496 	&thermal_zone_attribute_group,
497 	&thermal_zone_mode_attribute_group,
498 	&thermal_zone_passive_attribute_group,
499 	/* This is not NULL terminated as we create the group dynamically */
500 };
501 
502 /**
503  * create_trip_attrs() - create attributes for trip points
504  * @tz:		the thermal zone device
505  * @mask:	Writeable trip point bitmap.
506  *
507  * helper function to instantiate sysfs entries for every trip
508  * point and its properties of a struct thermal_zone_device.
509  *
510  * Return: 0 on success, the proper error value otherwise.
511  */
512 static int create_trip_attrs(struct thermal_zone_device *tz, int mask)
513 {
514 	struct attribute **attrs;
515 	int indx;
516 
517 	/* This function works only for zones with at least one trip */
518 	if (tz->trips <= 0)
519 		return -EINVAL;
520 
521 	tz->trip_type_attrs = kcalloc(tz->trips, sizeof(*tz->trip_type_attrs),
522 				      GFP_KERNEL);
523 	if (!tz->trip_type_attrs)
524 		return -ENOMEM;
525 
526 	tz->trip_temp_attrs = kcalloc(tz->trips, sizeof(*tz->trip_temp_attrs),
527 				      GFP_KERNEL);
528 	if (!tz->trip_temp_attrs) {
529 		kfree(tz->trip_type_attrs);
530 		return -ENOMEM;
531 	}
532 
533 	if (tz->ops->get_trip_hyst) {
534 		tz->trip_hyst_attrs = kcalloc(tz->trips,
535 					      sizeof(*tz->trip_hyst_attrs),
536 					      GFP_KERNEL);
537 		if (!tz->trip_hyst_attrs) {
538 			kfree(tz->trip_type_attrs);
539 			kfree(tz->trip_temp_attrs);
540 			return -ENOMEM;
541 		}
542 	}
543 
544 	attrs = kcalloc(tz->trips * 3 + 1, sizeof(*attrs), GFP_KERNEL);
545 	if (!attrs) {
546 		kfree(tz->trip_type_attrs);
547 		kfree(tz->trip_temp_attrs);
548 		if (tz->ops->get_trip_hyst)
549 			kfree(tz->trip_hyst_attrs);
550 		return -ENOMEM;
551 	}
552 
553 	for (indx = 0; indx < tz->trips; indx++) {
554 		/* create trip type attribute */
555 		snprintf(tz->trip_type_attrs[indx].name, THERMAL_NAME_LENGTH,
556 			 "trip_point_%d_type", indx);
557 
558 		sysfs_attr_init(&tz->trip_type_attrs[indx].attr.attr);
559 		tz->trip_type_attrs[indx].attr.attr.name =
560 						tz->trip_type_attrs[indx].name;
561 		tz->trip_type_attrs[indx].attr.attr.mode = S_IRUGO;
562 		tz->trip_type_attrs[indx].attr.show = trip_point_type_show;
563 		attrs[indx] = &tz->trip_type_attrs[indx].attr.attr;
564 
565 		/* create trip temp attribute */
566 		snprintf(tz->trip_temp_attrs[indx].name, THERMAL_NAME_LENGTH,
567 			 "trip_point_%d_temp", indx);
568 
569 		sysfs_attr_init(&tz->trip_temp_attrs[indx].attr.attr);
570 		tz->trip_temp_attrs[indx].attr.attr.name =
571 						tz->trip_temp_attrs[indx].name;
572 		tz->trip_temp_attrs[indx].attr.attr.mode = S_IRUGO;
573 		tz->trip_temp_attrs[indx].attr.show = trip_point_temp_show;
574 		if (IS_ENABLED(CONFIG_THERMAL_WRITABLE_TRIPS) &&
575 		    mask & (1 << indx)) {
576 			tz->trip_temp_attrs[indx].attr.attr.mode |= S_IWUSR;
577 			tz->trip_temp_attrs[indx].attr.store =
578 							trip_point_temp_store;
579 		}
580 		attrs[indx + tz->trips] = &tz->trip_temp_attrs[indx].attr.attr;
581 
582 		/* create Optional trip hyst attribute */
583 		if (!tz->ops->get_trip_hyst)
584 			continue;
585 		snprintf(tz->trip_hyst_attrs[indx].name, THERMAL_NAME_LENGTH,
586 			 "trip_point_%d_hyst", indx);
587 
588 		sysfs_attr_init(&tz->trip_hyst_attrs[indx].attr.attr);
589 		tz->trip_hyst_attrs[indx].attr.attr.name =
590 					tz->trip_hyst_attrs[indx].name;
591 		tz->trip_hyst_attrs[indx].attr.attr.mode = S_IRUGO;
592 		tz->trip_hyst_attrs[indx].attr.show = trip_point_hyst_show;
593 		if (tz->ops->set_trip_hyst) {
594 			tz->trip_hyst_attrs[indx].attr.attr.mode |= S_IWUSR;
595 			tz->trip_hyst_attrs[indx].attr.store =
596 					trip_point_hyst_store;
597 		}
598 		attrs[indx + tz->trips * 2] =
599 					&tz->trip_hyst_attrs[indx].attr.attr;
600 	}
601 	attrs[tz->trips * 3] = NULL;
602 
603 	tz->trips_attribute_group.attrs = attrs;
604 
605 	return 0;
606 }
607 
608 /**
609  * destroy_trip_attrs() - destroy attributes for trip points
610  * @tz:		the thermal zone device
611  *
612  * helper function to free resources allocated by create_trip_attrs()
613  */
614 static void destroy_trip_attrs(struct thermal_zone_device *tz)
615 {
616 	if (!tz)
617 		return;
618 
619 	kfree(tz->trip_type_attrs);
620 	kfree(tz->trip_temp_attrs);
621 	if (tz->ops->get_trip_hyst)
622 		kfree(tz->trip_hyst_attrs);
623 	kfree(tz->trips_attribute_group.attrs);
624 }
625 
626 int thermal_zone_create_device_groups(struct thermal_zone_device *tz,
627 				      int mask)
628 {
629 	const struct attribute_group **groups;
630 	int i, size, result;
631 
632 	/* we need one extra for trips and the NULL to terminate the array */
633 	size = ARRAY_SIZE(thermal_zone_attribute_groups) + 2;
634 	/* This also takes care of API requirement to be NULL terminated */
635 	groups = kcalloc(size, sizeof(*groups), GFP_KERNEL);
636 	if (!groups)
637 		return -ENOMEM;
638 
639 	for (i = 0; i < size - 2; i++)
640 		groups[i] = thermal_zone_attribute_groups[i];
641 
642 	if (tz->trips) {
643 		result = create_trip_attrs(tz, mask);
644 		if (result) {
645 			kfree(groups);
646 
647 			return result;
648 		}
649 
650 		groups[size - 2] = &tz->trips_attribute_group;
651 	}
652 
653 	tz->device.groups = groups;
654 
655 	return 0;
656 }
657 
658 void thermal_zone_destroy_device_groups(struct thermal_zone_device *tz)
659 {
660 	if (!tz)
661 		return;
662 
663 	if (tz->trips)
664 		destroy_trip_attrs(tz);
665 
666 	kfree(tz->device.groups);
667 }
668 
669 /* sys I/F for cooling device */
670 static ssize_t
671 thermal_cooling_device_type_show(struct device *dev,
672 				 struct device_attribute *attr, char *buf)
673 {
674 	struct thermal_cooling_device *cdev = to_cooling_device(dev);
675 
676 	return sprintf(buf, "%s\n", cdev->type);
677 }
678 
679 static ssize_t
680 thermal_cooling_device_max_state_show(struct device *dev,
681 				      struct device_attribute *attr, char *buf)
682 {
683 	struct thermal_cooling_device *cdev = to_cooling_device(dev);
684 	unsigned long state;
685 	int ret;
686 
687 	ret = cdev->ops->get_max_state(cdev, &state);
688 	if (ret)
689 		return ret;
690 	return sprintf(buf, "%ld\n", state);
691 }
692 
693 static ssize_t
694 thermal_cooling_device_cur_state_show(struct device *dev,
695 				      struct device_attribute *attr, char *buf)
696 {
697 	struct thermal_cooling_device *cdev = to_cooling_device(dev);
698 	unsigned long state;
699 	int ret;
700 
701 	ret = cdev->ops->get_cur_state(cdev, &state);
702 	if (ret)
703 		return ret;
704 	return sprintf(buf, "%ld\n", state);
705 }
706 
707 static ssize_t
708 thermal_cooling_device_cur_state_store(struct device *dev,
709 				       struct device_attribute *attr,
710 				       const char *buf, size_t count)
711 {
712 	struct thermal_cooling_device *cdev = to_cooling_device(dev);
713 	unsigned long state;
714 	int result;
715 
716 	if (sscanf(buf, "%ld\n", &state) != 1)
717 		return -EINVAL;
718 
719 	if ((long)state < 0)
720 		return -EINVAL;
721 
722 	result = cdev->ops->set_cur_state(cdev, state);
723 	if (result)
724 		return result;
725 	thermal_cooling_device_stats_update(cdev, state);
726 	return count;
727 }
728 
729 static struct device_attribute dev_attr_cdev_type =
730 __ATTR(type, 0444, thermal_cooling_device_type_show, NULL);
731 static DEVICE_ATTR(max_state, 0444,
732 		   thermal_cooling_device_max_state_show, NULL);
733 static DEVICE_ATTR(cur_state, 0644,
734 		   thermal_cooling_device_cur_state_show,
735 		   thermal_cooling_device_cur_state_store);
736 
737 static struct attribute *cooling_device_attrs[] = {
738 	&dev_attr_cdev_type.attr,
739 	&dev_attr_max_state.attr,
740 	&dev_attr_cur_state.attr,
741 	NULL,
742 };
743 
744 static const struct attribute_group cooling_device_attr_group = {
745 	.attrs = cooling_device_attrs,
746 };
747 
748 static const struct attribute_group *cooling_device_attr_groups[] = {
749 	&cooling_device_attr_group,
750 	NULL, /* Space allocated for cooling_device_stats_attr_group */
751 	NULL,
752 };
753 
754 #ifdef CONFIG_THERMAL_STATISTICS
755 struct cooling_dev_stats {
756 	spinlock_t lock;
757 	unsigned int total_trans;
758 	unsigned long state;
759 	unsigned long max_states;
760 	ktime_t last_time;
761 	ktime_t *time_in_state;
762 	unsigned int *trans_table;
763 };
764 
765 static void update_time_in_state(struct cooling_dev_stats *stats)
766 {
767 	ktime_t now = ktime_get(), delta;
768 
769 	delta = ktime_sub(now, stats->last_time);
770 	stats->time_in_state[stats->state] =
771 		ktime_add(stats->time_in_state[stats->state], delta);
772 	stats->last_time = now;
773 }
774 
775 void thermal_cooling_device_stats_update(struct thermal_cooling_device *cdev,
776 					 unsigned long new_state)
777 {
778 	struct cooling_dev_stats *stats = cdev->stats;
779 
780 	spin_lock(&stats->lock);
781 
782 	if (stats->state == new_state)
783 		goto unlock;
784 
785 	update_time_in_state(stats);
786 	stats->trans_table[stats->state * stats->max_states + new_state]++;
787 	stats->state = new_state;
788 	stats->total_trans++;
789 
790 unlock:
791 	spin_unlock(&stats->lock);
792 }
793 
794 static ssize_t
795 thermal_cooling_device_total_trans_show(struct device *dev,
796 					struct device_attribute *attr,
797 					char *buf)
798 {
799 	struct thermal_cooling_device *cdev = to_cooling_device(dev);
800 	struct cooling_dev_stats *stats = cdev->stats;
801 	int ret;
802 
803 	spin_lock(&stats->lock);
804 	ret = sprintf(buf, "%u\n", stats->total_trans);
805 	spin_unlock(&stats->lock);
806 
807 	return ret;
808 }
809 
810 static ssize_t
811 thermal_cooling_device_time_in_state_show(struct device *dev,
812 					  struct device_attribute *attr,
813 					  char *buf)
814 {
815 	struct thermal_cooling_device *cdev = to_cooling_device(dev);
816 	struct cooling_dev_stats *stats = cdev->stats;
817 	ssize_t len = 0;
818 	int i;
819 
820 	spin_lock(&stats->lock);
821 	update_time_in_state(stats);
822 
823 	for (i = 0; i < stats->max_states; i++) {
824 		len += sprintf(buf + len, "state%u\t%llu\n", i,
825 			       ktime_to_ms(stats->time_in_state[i]));
826 	}
827 	spin_unlock(&stats->lock);
828 
829 	return len;
830 }
831 
832 static ssize_t
833 thermal_cooling_device_reset_store(struct device *dev,
834 				   struct device_attribute *attr,
835 				   const char *buf, size_t count)
836 {
837 	struct thermal_cooling_device *cdev = to_cooling_device(dev);
838 	struct cooling_dev_stats *stats = cdev->stats;
839 	int i, states = stats->max_states;
840 
841 	spin_lock(&stats->lock);
842 
843 	stats->total_trans = 0;
844 	stats->last_time = ktime_get();
845 	memset(stats->trans_table, 0,
846 	       states * states * sizeof(*stats->trans_table));
847 
848 	for (i = 0; i < stats->max_states; i++)
849 		stats->time_in_state[i] = ktime_set(0, 0);
850 
851 	spin_unlock(&stats->lock);
852 
853 	return count;
854 }
855 
856 static ssize_t
857 thermal_cooling_device_trans_table_show(struct device *dev,
858 					struct device_attribute *attr,
859 					char *buf)
860 {
861 	struct thermal_cooling_device *cdev = to_cooling_device(dev);
862 	struct cooling_dev_stats *stats = cdev->stats;
863 	ssize_t len = 0;
864 	int i, j;
865 
866 	len += snprintf(buf + len, PAGE_SIZE - len, " From  :    To\n");
867 	len += snprintf(buf + len, PAGE_SIZE - len, "       : ");
868 	for (i = 0; i < stats->max_states; i++) {
869 		if (len >= PAGE_SIZE)
870 			break;
871 		len += snprintf(buf + len, PAGE_SIZE - len, "state%2u  ", i);
872 	}
873 	if (len >= PAGE_SIZE)
874 		return PAGE_SIZE;
875 
876 	len += snprintf(buf + len, PAGE_SIZE - len, "\n");
877 
878 	for (i = 0; i < stats->max_states; i++) {
879 		if (len >= PAGE_SIZE)
880 			break;
881 
882 		len += snprintf(buf + len, PAGE_SIZE - len, "state%2u:", i);
883 
884 		for (j = 0; j < stats->max_states; j++) {
885 			if (len >= PAGE_SIZE)
886 				break;
887 			len += snprintf(buf + len, PAGE_SIZE - len, "%8u ",
888 				stats->trans_table[i * stats->max_states + j]);
889 		}
890 		if (len >= PAGE_SIZE)
891 			break;
892 		len += snprintf(buf + len, PAGE_SIZE - len, "\n");
893 	}
894 
895 	if (len >= PAGE_SIZE) {
896 		pr_warn_once("Thermal transition table exceeds PAGE_SIZE. Disabling\n");
897 		return -EFBIG;
898 	}
899 	return len;
900 }
901 
902 static DEVICE_ATTR(total_trans, 0444, thermal_cooling_device_total_trans_show,
903 		   NULL);
904 static DEVICE_ATTR(time_in_state_ms, 0444,
905 		   thermal_cooling_device_time_in_state_show, NULL);
906 static DEVICE_ATTR(reset, 0200, NULL, thermal_cooling_device_reset_store);
907 static DEVICE_ATTR(trans_table, 0444,
908 		   thermal_cooling_device_trans_table_show, NULL);
909 
910 static struct attribute *cooling_device_stats_attrs[] = {
911 	&dev_attr_total_trans.attr,
912 	&dev_attr_time_in_state_ms.attr,
913 	&dev_attr_reset.attr,
914 	&dev_attr_trans_table.attr,
915 	NULL
916 };
917 
918 static const struct attribute_group cooling_device_stats_attr_group = {
919 	.attrs = cooling_device_stats_attrs,
920 	.name = "stats"
921 };
922 
923 static void cooling_device_stats_setup(struct thermal_cooling_device *cdev)
924 {
925 	struct cooling_dev_stats *stats;
926 	unsigned long states;
927 	int var;
928 
929 	if (cdev->ops->get_max_state(cdev, &states))
930 		return;
931 
932 	states++; /* Total number of states is highest state + 1 */
933 
934 	var = sizeof(*stats);
935 	var += sizeof(*stats->time_in_state) * states;
936 	var += sizeof(*stats->trans_table) * states * states;
937 
938 	stats = kzalloc(var, GFP_KERNEL);
939 	if (!stats)
940 		return;
941 
942 	stats->time_in_state = (ktime_t *)(stats + 1);
943 	stats->trans_table = (unsigned int *)(stats->time_in_state + states);
944 	cdev->stats = stats;
945 	stats->last_time = ktime_get();
946 	stats->max_states = states;
947 
948 	spin_lock_init(&stats->lock);
949 
950 	/* Fill the empty slot left in cooling_device_attr_groups */
951 	var = ARRAY_SIZE(cooling_device_attr_groups) - 2;
952 	cooling_device_attr_groups[var] = &cooling_device_stats_attr_group;
953 }
954 
955 static void cooling_device_stats_destroy(struct thermal_cooling_device *cdev)
956 {
957 	kfree(cdev->stats);
958 	cdev->stats = NULL;
959 }
960 
961 #else
962 
963 static inline void
964 cooling_device_stats_setup(struct thermal_cooling_device *cdev) {}
965 static inline void
966 cooling_device_stats_destroy(struct thermal_cooling_device *cdev) {}
967 
968 #endif /* CONFIG_THERMAL_STATISTICS */
969 
970 void thermal_cooling_device_setup_sysfs(struct thermal_cooling_device *cdev)
971 {
972 	cooling_device_stats_setup(cdev);
973 	cdev->device.groups = cooling_device_attr_groups;
974 }
975 
976 void thermal_cooling_device_destroy_sysfs(struct thermal_cooling_device *cdev)
977 {
978 	cooling_device_stats_destroy(cdev);
979 }
980 
981 /* these helper will be used only at the time of bindig */
982 ssize_t
983 thermal_cooling_device_trip_point_show(struct device *dev,
984 				       struct device_attribute *attr, char *buf)
985 {
986 	struct thermal_instance *instance;
987 
988 	instance =
989 	    container_of(attr, struct thermal_instance, attr);
990 
991 	if (instance->trip == THERMAL_TRIPS_NONE)
992 		return sprintf(buf, "-1\n");
993 	else
994 		return sprintf(buf, "%d\n", instance->trip);
995 }
996 
997 ssize_t
998 thermal_cooling_device_weight_show(struct device *dev,
999 				   struct device_attribute *attr, char *buf)
1000 {
1001 	struct thermal_instance *instance;
1002 
1003 	instance = container_of(attr, struct thermal_instance, weight_attr);
1004 
1005 	return sprintf(buf, "%d\n", instance->weight);
1006 }
1007 
1008 ssize_t
1009 thermal_cooling_device_weight_store(struct device *dev,
1010 				    struct device_attribute *attr,
1011 				    const char *buf, size_t count)
1012 {
1013 	struct thermal_instance *instance;
1014 	int ret, weight;
1015 
1016 	ret = kstrtoint(buf, 0, &weight);
1017 	if (ret)
1018 		return ret;
1019 
1020 	instance = container_of(attr, struct thermal_instance, weight_attr);
1021 	instance->weight = weight;
1022 
1023 	return count;
1024 }
1025