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