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