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