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