misc: nct: error handling for no regulator
[linux-2.6.git] / drivers / misc / therm_est.c
1 /*
2  * drivers/misc/therm_est.c
3  *
4  * Copyright (c) 2010-2013, NVIDIA CORPORATION.  All rights reserved.
5  *
6  * This software is licensed under the terms of the GNU General Public
7  * License version 2, as published by the Free Software Foundation, and
8  * may be copied, distributed, and modified under those terms.
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  * GNU General Public License for more details.
14  *
15  */
16
17 #include <linux/platform_device.h>
18 #include <linux/kernel.h>
19 #include <linux/cpufreq.h>
20 #include <linux/delay.h>
21 #include <linux/mutex.h>
22 #include <linux/init.h>
23 #include <linux/err.h>
24 #include <linux/clk.h>
25 #include <linux/debugfs.h>
26 #include <linux/seq_file.h>
27 #include <linux/uaccess.h>
28 #include <linux/slab.h>
29 #include <linux/syscalls.h>
30 #include <linux/therm_est.h>
31 #include <linux/thermal.h>
32 #include <linux/module.h>
33 #include <linux/hwmon-sysfs.h>
34 #include <linux/suspend.h>
35 #include <linux/of.h>
36 #include <linux/of_device.h>
37
38 struct therm_estimator {
39         struct thermal_zone_device *thz;
40         int num_trips;
41         struct thermal_trip_info *trips;
42         struct thermal_zone_params *tzp;
43
44         int num_timer_trips;
45         struct therm_est_timer_trip_info *timer_trips;
46         struct delayed_work timer_trip_work;
47         struct mutex timer_trip_lock;
48
49         struct workqueue_struct *workqueue;
50         struct delayed_work therm_est_work;
51         long cur_temp;
52         long low_limit;
53         long high_limit;
54         int ntemp;
55         long toffset;
56         long polling_period;
57         int tc1;
58         int tc2;
59         int ndevs;
60         struct therm_est_subdevice *devs;
61
62 #ifdef CONFIG_PM
63         struct notifier_block pm_nb;
64 #endif
65 };
66
67 #define TIMER_TRIP_INACTIVE             -2
68
69 #define TIMER_TRIP_STATE_NONE           0
70 #define TIMER_TRIP_STATE_START          BIT(0)
71 #define TIMER_TRIP_STATE_STOP           BIT(1)
72 #define TIMER_TRIP_STATE_UP             BIT(2)
73 #define TIMER_TRIP_STATE_DOWN           BIT(3)
74
75 static int __get_trip_temp(struct thermal_zone_device *thz, int trip,
76                            long *temp);
77
78 static struct therm_est_timer_trip_info *
79 __find_timer_trip(struct therm_estimator *est, int trip)
80 {
81         int i;
82
83         /* Find matched timer trip info with trip. */
84         for (i = 0; i < est->num_timer_trips; i++) {
85                 if (est->timer_trips[i].trip == trip)
86                         return &est->timer_trips[i];
87         }
88         return NULL;
89 }
90
91 static int __get_timer_trip_delay(struct therm_est_timer_trip_info *timer_info,
92                                  s64 now, s64 *delay)
93 {
94         int cur = timer_info->cur;
95         int next = (cur + 1 < timer_info->num_timers) ? cur + 1 : cur;
96
97         if (cur == next) /* No more timer on this trip. */
98                 return -ENOENT;
99
100         *delay = timer_info->timers[next].time_after -
101                  (now - timer_info->last_tripped);
102         return 0;
103 }
104
105 static int therm_est_subdev_match(struct thermal_zone_device *thz, void *data)
106 {
107         return strcmp((char *)data, thz->type) == 0;
108 }
109
110 static int therm_est_subdev_get_temp(void *data, long *temp)
111 {
112         struct thermal_zone_device *thz;
113
114         thz = thermal_zone_device_find(data, therm_est_subdev_match);
115
116         if (!thz || thz->ops->get_temp(thz, temp))
117                 *temp = 25000;
118
119         return 0;
120 }
121
122 static void therm_est_update_limits(struct therm_estimator *est)
123 {
124         const int MAX_HIGH_TEMP = 128000;
125         long low_temp = 0, high_temp = MAX_HIGH_TEMP;
126         long trip_temp, passive_low_temp = MAX_HIGH_TEMP;
127         enum thermal_trip_type trip_type;
128         struct thermal_trip_info *trip_state;
129         int i;
130
131         for (i = 0; i < est->num_trips; i++) {
132                 trip_state = &est->trips[i];
133                 __get_trip_temp(est->thz, i, &trip_temp);
134                 est->thz->ops->get_trip_type(est->thz, i, &trip_type);
135
136                 if (!trip_state->tripped) { /* not tripped? update high */
137                         if (trip_temp < high_temp)
138                                 high_temp = trip_temp;
139                 } else { /* tripped? update low */
140                         if (trip_type != THERMAL_TRIP_PASSIVE) {
141                                 /* get highest ACTIVE */
142                                 if (trip_temp > low_temp)
143                                         low_temp = trip_temp;
144                         } else {
145                                 /* get lowest PASSIVE */
146                                 if (trip_temp < passive_low_temp)
147                                         passive_low_temp = trip_temp;
148                         }
149                 }
150         }
151
152         if (passive_low_temp != MAX_HIGH_TEMP)
153                 low_temp = max(low_temp, passive_low_temp);
154
155         est->low_limit = low_temp;
156         est->high_limit = high_temp;
157 }
158
159 static void therm_est_update_timer_trips(struct therm_estimator *est)
160 {
161         struct thermal_trip_info *trip_state;
162         struct therm_est_timer_trip_info *timer_info;
163         s64 now, delay, min_delay;
164         int i;
165
166         mutex_lock(&est->timer_trip_lock);
167         min_delay = LLONG_MAX;
168         now = ktime_to_ms(ktime_get());
169
170         for (i = 0; i < est->num_timer_trips; i++) {
171                 timer_info = &est->timer_trips[i];
172                 trip_state = &est->trips[timer_info->trip];
173
174                 pr_debug("%s: i %d, trip %d, tripped %d, cur %d\n",
175                         __func__, i, timer_info->trip, trip_state->tripped,
176                         timer_info->cur);
177                 if ((timer_info->cur == TIMER_TRIP_INACTIVE) ||
178                         (__get_timer_trip_delay(timer_info, now, &delay) < 0))
179                         continue;
180
181                 if (delay > 0)
182                         min_delay = min(min_delay, delay);
183                 pr_debug("%s: delay %lld, min_delay %lld\n",
184                         __func__, delay, min_delay);
185         }
186         mutex_unlock(&est->timer_trip_lock);
187
188         cancel_delayed_work(&est->timer_trip_work);
189         if (min_delay != LLONG_MAX)
190                 queue_delayed_work(est->workqueue, &est->timer_trip_work,
191                                    msecs_to_jiffies(min_delay));
192 }
193
194 static void therm_est_timer_trip_work_func(struct work_struct *work)
195 {
196         struct therm_estimator *est = container_of(work, struct therm_estimator,
197                                                    timer_trip_work.work);
198         struct thermal_trip_info *trip_state;
199         struct therm_est_timer_trip_info *timer_info;
200         s64 now, delay;
201         int timer_trip_state, i;
202
203         mutex_lock(&est->timer_trip_lock);
204         timer_trip_state = TIMER_TRIP_STATE_NONE;
205         now = ktime_to_ms(ktime_get());
206
207         for (i = 0; i < est->num_timer_trips; i++) {
208                 timer_info = &est->timer_trips[i];
209                 trip_state = &est->trips[timer_info->trip];
210
211                 pr_debug("%s: i %d, trip %d, tripped %d, cur %d\n",
212                         __func__, i, timer_info->trip, trip_state->tripped,
213                         timer_info->cur);
214                 if ((timer_info->cur == TIMER_TRIP_INACTIVE) ||
215                         (__get_timer_trip_delay(timer_info, now, &delay) < 0))
216                         continue;
217
218                 if (delay <= 0) { /* Timer on this trip has expired. */
219                         if (timer_info->cur + 1 < timer_info->num_timers) {
220                                 timer_info->last_tripped = now;
221                                 timer_info->cur++;
222                                 timer_trip_state |= TIMER_TRIP_STATE_UP;
223                         }
224                 }
225
226                 /* If delay > 0, timer on this trip has not yet expired.
227                  * So need to restart timer with remaining delay. */
228                 timer_trip_state |= TIMER_TRIP_STATE_START;
229                 pr_debug("%s: new_cur %d, delay %lld, timer_trip_state 0x%x\n",
230                         __func__, timer_info->cur, delay, timer_trip_state);
231         }
232         mutex_unlock(&est->timer_trip_lock);
233
234         if (timer_trip_state & (TIMER_TRIP_STATE_START | TIMER_TRIP_STATE_UP)) {
235                 therm_est_update_timer_trips(est);
236                 therm_est_update_limits(est);
237         }
238 }
239
240 static void therm_est_work_func(struct work_struct *work)
241 {
242         int i, j, index, sum = 0;
243         long temp;
244         struct delayed_work *dwork = container_of(work,
245                                         struct delayed_work, work);
246         struct therm_estimator *est = container_of(dwork,
247                                         struct therm_estimator,
248                                         therm_est_work);
249
250         for (i = 0; i < est->ndevs; i++) {
251                 if (therm_est_subdev_get_temp(est->devs[i].dev_data, &temp))
252                         continue;
253                 est->devs[i].hist[(est->ntemp % HIST_LEN)] = temp;
254         }
255
256         for (i = 0; i < est->ndevs; i++) {
257                 for (j = 0; j < HIST_LEN; j++) {
258                         index = (est->ntemp - j + HIST_LEN) % HIST_LEN;
259                         sum += est->devs[i].hist[index] *
260                                 est->devs[i].coeffs[j];
261                 }
262         }
263
264         est->cur_temp = sum / 100 + est->toffset;
265         est->ntemp++;
266
267         if (est->thz && ((est->cur_temp < est->low_limit) ||
268                         (est->cur_temp >= est->high_limit))) {
269                 thermal_zone_device_update(est->thz);
270                 therm_est_update_timer_trips(est);
271                 therm_est_update_limits(est);
272         }
273
274         queue_delayed_work(est->workqueue, &est->therm_est_work,
275                                 msecs_to_jiffies(est->polling_period));
276 }
277
278 static int therm_est_bind(struct thermal_zone_device *thz,
279                                 struct thermal_cooling_device *cdev)
280 {
281         struct therm_estimator *est = thz->devdata;
282         struct thermal_trip_info *trip_state;
283         int i;
284
285         for (i = 0; i < est->num_trips; i++) {
286                 trip_state = &est->trips[i];
287                 if (trip_state->cdev_type &&
288                     !strncmp(trip_state->cdev_type, cdev->type,
289                              THERMAL_NAME_LENGTH))
290                         thermal_zone_bind_cooling_device(thz, i, cdev,
291                                                          trip_state->upper,
292                                                          trip_state->lower);
293         }
294
295         return 0;
296 }
297
298 static int therm_est_unbind(struct thermal_zone_device *thz,
299                                 struct thermal_cooling_device *cdev)
300 {
301         struct therm_estimator *est = thz->devdata;
302         struct thermal_trip_info *trip_state;
303         int i;
304
305         for (i = 0; i < est->num_trips; i++) {
306                 trip_state = &est->trips[i];
307                 if (trip_state->cdev_type &&
308                     !strncmp(trip_state->cdev_type, cdev->type,
309                              THERMAL_NAME_LENGTH))
310                         thermal_zone_unbind_cooling_device(thz, i, cdev);
311         }
312
313         return 0;
314 }
315
316 static int therm_est_get_trip_type(struct thermal_zone_device *thz,
317                                    int trip, enum thermal_trip_type *type)
318 {
319         struct therm_estimator *est = thz->devdata;
320
321         *type = est->trips[trip].trip_type;
322         return 0;
323 }
324
325 static int __get_trip_temp(struct thermal_zone_device *thz, int trip,
326                            long *temp)
327 {
328         struct therm_estimator *est = thz->devdata;
329         struct thermal_trip_info *trip_state = &est->trips[trip];
330         struct therm_est_timer_trip_info *timer_info;
331         long zone_temp, trip_temp, hysteresis;
332         int cur = TIMER_TRIP_INACTIVE;
333         int ret = TIMER_TRIP_STATE_NONE;
334
335         zone_temp = thz->temperature;
336         trip_temp = trip_state->trip_temp;
337         hysteresis = trip_state->hysteresis;
338
339         timer_info = __find_timer_trip(est, trip);
340         if (timer_info) {
341                 cur = timer_info->cur;
342                 /* If timer trip is available, use trip_temp and hysteresis in
343                  * the timer trip to trip_temp for this trip. */
344                 if (timer_info->cur >= 0) {
345                         trip_temp = timer_info->timers[cur].trip_temp;
346                         hysteresis = timer_info->timers[cur].hysteresis;
347                 }
348         }
349
350         if (zone_temp >= trip_temp) {
351                 trip_temp -= hysteresis;
352                 if (timer_info && !trip_state->tripped)
353                         ret = TIMER_TRIP_STATE_START;
354                 trip_state->tripped = true;
355         } else if (trip_state->tripped) {
356                 trip_temp -= hysteresis;
357                 if (zone_temp < trip_temp) {
358                         if (!timer_info) {
359                                 trip_state->tripped = false;
360                         } else {
361                                 if (cur == TIMER_TRIP_INACTIVE)
362                                         trip_state->tripped = false;
363                                 else
364                                         ret = TIMER_TRIP_STATE_DOWN;
365                         }
366                 }
367         }
368
369         *temp = trip_temp;
370         return ret;
371 }
372
373 static int therm_est_get_trip_temp(struct thermal_zone_device *thz,
374                                    int trip, unsigned long *temp)
375 {
376         struct therm_estimator *est = thz->devdata;
377         struct therm_est_timer_trip_info *timer_info;
378         int ret;
379
380         ret = __get_trip_temp(thz, trip, temp);
381         if (ret & (TIMER_TRIP_STATE_START | TIMER_TRIP_STATE_DOWN)) {
382                 timer_info = __find_timer_trip(est, trip);
383
384                 mutex_lock(&est->timer_trip_lock);
385                 timer_info->last_tripped = ktime_to_ms(ktime_get());
386
387                 if (ret & TIMER_TRIP_STATE_START) {
388                         timer_info->cur = TIMER_TRIP_INACTIVE + 1;
389                 } else if (ret & TIMER_TRIP_STATE_DOWN) {
390                         if (--timer_info->cur < TIMER_TRIP_INACTIVE)
391                                 timer_info->cur = TIMER_TRIP_INACTIVE;
392                 }
393                 mutex_unlock(&est->timer_trip_lock);
394
395                 /* Update limits, because trip temp was changed by timer trip
396                  * changing. */
397                 therm_est_update_limits(est);
398         }
399
400         return 0;
401 }
402
403 static int therm_est_set_trip_temp(struct thermal_zone_device *thz,
404                                    int trip, unsigned long temp)
405 {
406         struct therm_estimator *est = thz->devdata;
407
408         est->trips[trip].trip_temp = temp;
409
410         /* Update limits, because trip temp was changed. */
411         therm_est_update_limits(est);
412         return 0;
413 }
414
415 static int therm_est_get_temp(struct thermal_zone_device *thz,
416                                 unsigned long *temp)
417 {
418         struct therm_estimator *est = thz->devdata;
419
420         *temp = est->cur_temp;
421         return 0;
422 }
423
424 static int therm_est_get_trend(struct thermal_zone_device *thz,
425                                int trip, enum thermal_trend *trend)
426 {
427         struct therm_estimator *est = thz->devdata;
428         struct thermal_trip_info *trip_state = &est->trips[trip];
429         long trip_temp;
430         int new_trend;
431         int cur_temp;
432
433         __get_trip_temp(thz, trip, &trip_temp);
434
435         cur_temp = thz->temperature;
436         new_trend = (est->tc1 * (cur_temp - thz->last_temperature)) +
437                     (est->tc2 * (cur_temp - trip_temp));
438
439         switch (trip_state->trip_type) {
440         case THERMAL_TRIP_ACTIVE:
441                 /* aggressive active cooling */
442                 *trend = THERMAL_TREND_RAISING;
443                 break;
444         case THERMAL_TRIP_PASSIVE:
445                 if (new_trend > 0)
446                         *trend = THERMAL_TREND_RAISING;
447                 else if (new_trend < 0)
448                         *trend = THERMAL_TREND_DROPPING;
449                 else
450                         *trend = THERMAL_TREND_STABLE;
451                 break;
452         default:
453                 return -EINVAL;
454         }
455         return 0;
456 }
457
458 static struct thermal_zone_device_ops therm_est_ops = {
459         .bind = therm_est_bind,
460         .unbind = therm_est_unbind,
461         .get_trip_type = therm_est_get_trip_type,
462         .get_trip_temp = therm_est_get_trip_temp,
463         .set_trip_temp = therm_est_set_trip_temp,
464         .get_temp = therm_est_get_temp,
465         .get_trend = therm_est_get_trend,
466 };
467
468 static ssize_t show_coeff(struct device *dev,
469                                 struct device_attribute *da,
470                                 char *buf)
471 {
472         struct therm_estimator *est = dev_get_drvdata(dev);
473         ssize_t len, total_len = 0;
474         int i, j;
475         for (i = 0; i < est->ndevs; i++) {
476                 len = snprintf(buf + total_len,
477                                 PAGE_SIZE - total_len, "[%d]", i);
478                 total_len += len;
479                 for (j = 0; j < HIST_LEN; j++) {
480                         len = snprintf(buf + total_len,
481                                         PAGE_SIZE - total_len, " %ld",
482                                         est->devs[i].coeffs[j]);
483                         total_len += len;
484                 }
485                 len = snprintf(buf + total_len, PAGE_SIZE - total_len, "\n");
486                 total_len += len;
487         }
488         return strlen(buf);
489 }
490
491 static ssize_t set_coeff(struct device *dev,
492                                 struct device_attribute *da,
493                                 const char *buf, size_t count)
494 {
495         struct therm_estimator *est = dev_get_drvdata(dev);
496         int devid, scount;
497         long coeff[20];
498
499         if (HIST_LEN > 20)
500                 return -EINVAL;
501
502         scount = sscanf(buf, "[%d] %ld %ld %ld %ld %ld %ld %ld %ld %ld %ld " \
503                         "%ld %ld %ld %ld %ld %ld %ld %ld %ld %ld",
504                         &devid,
505                         &coeff[0],
506                         &coeff[1],
507                         &coeff[2],
508                         &coeff[3],
509                         &coeff[4],
510                         &coeff[5],
511                         &coeff[6],
512                         &coeff[7],
513                         &coeff[8],
514                         &coeff[9],
515                         &coeff[10],
516                         &coeff[11],
517                         &coeff[12],
518                         &coeff[13],
519                         &coeff[14],
520                         &coeff[15],
521                         &coeff[16],
522                         &coeff[17],
523                         &coeff[18],
524                         &coeff[19]);
525
526         if (scount != HIST_LEN + 1)
527                 return -1;
528
529         if (devid < 0 || devid >= est->ndevs)
530                 return -EINVAL;
531
532         /* This has obvious locking issues but don't worry about it */
533         memcpy(est->devs[devid].coeffs, coeff, sizeof(coeff[0]) * HIST_LEN);
534
535         return count;
536 }
537
538 static ssize_t show_offset(struct device *dev,
539                                 struct device_attribute *da,
540                                 char *buf)
541 {
542         struct therm_estimator *est = dev_get_drvdata(dev);
543         snprintf(buf, PAGE_SIZE, "%ld\n", est->toffset);
544         return strlen(buf);
545 }
546
547 static ssize_t set_offset(struct device *dev,
548                                 struct device_attribute *da,
549                                 const char *buf, size_t count)
550 {
551         struct therm_estimator *est = dev_get_drvdata(dev);
552         int offset;
553
554         if (kstrtoint(buf, 0, &offset))
555                 return -EINVAL;
556
557         est->toffset = offset;
558
559         return count;
560 }
561
562 static ssize_t show_temps(struct device *dev,
563                                 struct device_attribute *da,
564                                 char *buf)
565 {
566         struct therm_estimator *est = dev_get_drvdata(dev);
567         ssize_t total_len = 0;
568         int i, j;
569         int index;
570
571         /* This has obvious locking issues but don't worry about it */
572         for (i = 0; i < est->ndevs; i++) {
573                 total_len += snprintf(buf + total_len,
574                                         PAGE_SIZE - total_len, "[%d]", i);
575                 for (j = 0; j < HIST_LEN; j++) {
576                         index = (est->ntemp - j + HIST_LEN) % HIST_LEN;
577                         total_len += snprintf(buf + total_len,
578                                                 PAGE_SIZE - total_len, " %ld",
579                                                 est->devs[i].hist[index]);
580                 }
581                 total_len += snprintf(buf + total_len,
582                                         PAGE_SIZE - total_len, "\n");
583         }
584         return strlen(buf);
585 }
586
587 static ssize_t show_tc1(struct device *dev,
588                         struct device_attribute *da,
589                         char *buf)
590 {
591         struct therm_estimator *est = dev_get_drvdata(dev);
592         snprintf(buf, PAGE_SIZE, "%d\n", est->tc1);
593         return strlen(buf);
594 }
595
596 static ssize_t set_tc1(struct device *dev,
597                         struct device_attribute *da,
598                         const char *buf, size_t count)
599 {
600         struct therm_estimator *est = dev_get_drvdata(dev);
601         int tc1;
602
603         if (kstrtoint(buf, 0, &tc1))
604                 return -EINVAL;
605
606         est->tc1 = tc1;
607
608         return count;
609 }
610
611 static ssize_t show_tc2(struct device *dev,
612                         struct device_attribute *da,
613                         char *buf)
614 {
615         struct therm_estimator *est = dev_get_drvdata(dev);
616         snprintf(buf, PAGE_SIZE, "%d\n", est->tc2);
617         return strlen(buf);
618 }
619
620 static ssize_t set_tc2(struct device *dev,
621                         struct device_attribute *da,
622                         const char *buf, size_t count)
623 {
624         struct therm_estimator *est = dev_get_drvdata(dev);
625         int tc2;
626
627         if (kstrtoint(buf, 0, &tc2))
628                 return -EINVAL;
629
630         est->tc2 = tc2;
631
632         return count;
633 }
634
635 static struct sensor_device_attribute therm_est_nodes[] = {
636         SENSOR_ATTR(coeff, S_IRUGO | S_IWUSR, show_coeff, set_coeff, 0),
637         SENSOR_ATTR(offset, S_IRUGO | S_IWUSR, show_offset, set_offset, 0),
638         SENSOR_ATTR(tc1, S_IRUGO | S_IWUSR, show_tc1, set_tc1, 0),
639         SENSOR_ATTR(tc2, S_IRUGO | S_IWUSR, show_tc2, set_tc2, 0),
640         SENSOR_ATTR(temps, S_IRUGO, show_temps, 0, 0),
641 };
642
643 static void therm_est_init_timer_trips(struct therm_estimator *est)
644 {
645         int i;
646
647         for (i = 0; i < est->num_timer_trips; i++)
648                 est->timer_trips[i].cur = TIMER_TRIP_INACTIVE;
649 }
650
651 static int therm_est_init_history(struct therm_estimator *est)
652 {
653         int i, j;
654         struct therm_est_subdevice *dev;
655         long temp;
656
657         for (i = 0; i < est->ndevs; i++) {
658                 dev = &est->devs[i];
659
660                 if (therm_est_subdev_get_temp(dev->dev_data, &temp))
661                         return -EINVAL;
662
663                 for (j = 0; j < HIST_LEN; j++)
664                         dev->hist[j] = temp;
665         }
666
667         return 0;
668 }
669
670 #ifdef CONFIG_PM
671 static int therm_est_pm_notify(struct notifier_block *nb,
672                                 unsigned long event, void *data)
673 {
674         struct therm_estimator *est = container_of(
675                                         nb,
676                                         struct therm_estimator,
677                                         pm_nb);
678
679         switch (event) {
680         case PM_SUSPEND_PREPARE:
681                 cancel_delayed_work_sync(&est->therm_est_work);
682                 cancel_delayed_work_sync(&est->timer_trip_work);
683                 break;
684         case PM_POST_SUSPEND:
685                 est->low_limit = 0;
686                 est->high_limit = 0;
687                 therm_est_init_history(est);
688                 therm_est_init_timer_trips(est);
689                 queue_delayed_work(est->workqueue,
690                                 &est->therm_est_work,
691                                 msecs_to_jiffies(est->polling_period));
692                 break;
693         }
694
695         return NOTIFY_OK;
696 }
697 #endif
698
699 #ifdef CONFIG_OF
700 static int __parse_dt_trip(struct device_node *np,
701                            struct thermal_trip_info *trips)
702 {
703         const char *str;
704         u32 val;
705         int ret;
706
707         ret = of_property_read_string(np, "cdev-type", &str);
708         if (ret < 0)
709                 return ret;
710         trips->cdev_type = (char *)str;
711
712         ret = of_property_read_string(np, "trip-type", &str);
713         if (ret < 0)
714                 return ret;
715
716         if (!strcasecmp("active", str))
717                 trips->trip_type = THERMAL_TRIP_ACTIVE;
718         else if (!strcasecmp("passive", str))
719                 trips->trip_type = THERMAL_TRIP_PASSIVE;
720         else if (!strcasecmp("hot", str))
721                 trips->trip_type = THERMAL_TRIP_HOT;
722         else if (!strcasecmp("critical", str))
723                 trips->trip_type = THERMAL_TRIP_CRITICAL;
724         else
725                 return -EINVAL;
726
727         ret = of_property_read_u32(np, "trip-temp", &val);
728         if (ret < 0)
729                 return ret;
730         trips->trip_temp = val;
731
732         trips->hysteresis = 0;
733         if (of_property_read_u32(np, "hysteresis", &val) == 0)
734                 trips->hysteresis = val;
735
736         trips->upper = THERMAL_NO_LIMIT;
737         if (of_property_read_string(np, "upper", &str) == 0) {
738                 if (kstrtou32(str, 10, &val) == 0)
739                         trips->upper = val;
740         }
741
742         trips->lower = THERMAL_NO_LIMIT;
743         if (of_property_read_string(np, "lower", &str) == 0) {
744                 if (kstrtou32(str, 10, &val) == 0)
745                         trips->lower = val;
746         }
747
748         return 0;
749 }
750
751 static int __parse_dt_subdev(struct device_node *np,
752                              struct therm_est_subdevice *subdev)
753 {
754         const char *str;
755         char *sbegin;
756         int i = 0;
757         int ret;
758
759         subdev->dev_data = (void *)of_get_property(np, "dev-data", NULL);
760         if (!subdev->dev_data)
761                 return -ENODATA;
762
763         ret = of_property_read_string(np, "coeffs", &str);
764         if (ret < 0)
765                 return ret;
766
767         while (str && (i < HIST_LEN)) {
768                 str = skip_spaces(str);
769                 sbegin = strsep((char **)&str, " ");
770                 if (!sbegin || (kstrtol((const char *)sbegin, 10,
771                                 &subdev->coeffs[i++]) < 0))
772                         break;
773         }
774
775         if (i != HIST_LEN)
776                 return -EINVAL;
777
778         return 0;
779 }
780
781 static int __parse_dt_tzp(struct device_node *np,
782                           struct thermal_zone_params *tzp)
783 {
784         const char *str;
785
786         if (of_property_read_string(np, "governor", &str) == 0)
787                 strncpy(tzp->governor_name, str, THERMAL_NAME_LENGTH);
788
789         return 0;
790 }
791
792 static int __parse_dt_timer_trip(struct device_node *np,
793                                  struct therm_est_timer_trip_info *timer_info)
794 {
795         struct device_node *ch;
796         u32 val;
797         int n_timers;
798         int ret;
799
800         ret = of_property_read_u32(np, "trip", &val);
801         if (ret < 0)
802                 return ret;
803         timer_info->trip = val;
804
805         n_timers = 0;
806         for_each_child_of_node(np, ch) {
807                 if (!of_device_is_compatible(ch, "nvidia,therm-est-timer"))
808                         continue;
809
810                 ret = of_property_read_u32(ch, "time-after", &val);
811                 if (ret < 0)
812                         return ret;
813                 timer_info->timers[n_timers].time_after = val;
814
815                 ret = of_property_read_u32(ch, "trip-temp", &val);
816                 if (ret < 0)
817                         return ret;
818                 timer_info->timers[n_timers].trip_temp = val;
819
820                 timer_info->timers[n_timers].hysteresis = 0;
821                 if (of_property_read_u32(ch, "hysteresis", &val) == 0)
822                         timer_info->timers[n_timers].hysteresis = val;
823
824                 n_timers++;
825         }
826
827         timer_info->num_timers = n_timers;
828
829         return 0;
830 }
831
832 static struct therm_est_data *therm_est_get_pdata(struct device *dev)
833 {
834         struct therm_est_data *data;
835         struct device_node *np;
836         struct device_node *ch;
837         u32 val;
838         int i, j, k, l;
839         int ret;
840
841         np = of_find_compatible_node(NULL, NULL, "nvidia,therm-est");
842         if (!np)
843                 return dev->platform_data;
844
845         data = devm_kzalloc(dev, sizeof(struct therm_est_data), GFP_KERNEL);
846         if (!data)
847                 return ERR_PTR(-ENOMEM);
848
849         ret = of_property_read_u32(np, "toffset", &val);
850         if (ret < 0)
851                 return ERR_PTR(ret);
852         data->toffset = val;
853
854         ret = of_property_read_u32(np, "polling-period", &val);
855         if (ret < 0)
856                 return ERR_PTR(ret);
857         data->polling_period = val;
858
859         ret = of_property_read_u32(np, "passive-delay", &val);
860         if (ret < 0)
861                 return ERR_PTR(ret);
862         data->passive_delay = val;
863
864         ret = of_property_read_u32(np, "tc1", &val);
865         if (ret < 0)
866                 return ERR_PTR(ret);
867         data->tc1 = val;
868
869         ret = of_property_read_u32(np, "tc2", &val);
870         if (ret < 0)
871                 return ERR_PTR(ret);
872         data->tc2 = val;
873
874         i = j = k = l = 0;
875         for_each_child_of_node(np, ch) {
876                 if (of_device_is_compatible(ch, "nvidia,therm-est-trip"))
877                         i++;
878                 else if (of_device_is_compatible(ch, "nvidia,therm-est-subdev"))
879                         j++;
880                 else if (of_device_is_compatible(ch, "nvidia,therm-est-tzp"))
881                         k++;
882                 else if (of_device_is_compatible(ch,
883                                                  "nvidia,therm-est-timer-trip"))
884                         l++;
885         }
886
887         /* trip point information and subdevices are must required data. */
888         if ((i == 0) || (j == 0))
889                 return ERR_PTR(-ENOENT);
890
891         data->trips = devm_kzalloc(dev, sizeof(struct thermal_trip_info) * i,
892                                    GFP_KERNEL);
893         if (!data->trips)
894                 return ERR_PTR(-ENOMEM);
895
896         data->devs = devm_kzalloc(dev, sizeof(struct therm_est_subdevice) * j,
897                                   GFP_KERNEL);
898         if (!data->devs)
899                 return ERR_PTR(-ENOMEM);
900
901         /* thermal zone params is optional data. */
902         if (k > 0) {
903                 data->tzp = devm_kzalloc(dev,
904                         sizeof(struct thermal_zone_params) * k, GFP_KERNEL);
905                 if (!data->tzp)
906                         return ERR_PTR(-ENOMEM);
907         }
908
909         /* timer trip point information is optional data. */
910         if (l > 0) {
911                 data->timer_trips = devm_kzalloc(dev,
912                                 sizeof(struct therm_est_timer_trip_info) * l,
913                                 GFP_KERNEL);
914                 if (!data->timer_trips)
915                         return ERR_PTR(-ENOMEM);
916         }
917
918         i = j = l = 0;
919         for_each_child_of_node(np, ch) {
920                 if (of_device_is_compatible(ch, "nvidia,therm-est-trip")) {
921                         ret = __parse_dt_trip(ch, &data->trips[i++]);
922                         if (ret < 0)
923                                 return ERR_PTR(ret);
924                 } else if (of_device_is_compatible(ch,
925                                                    "nvidia,therm-est-subdev")) {
926                         ret = __parse_dt_subdev(ch, &data->devs[j++]);
927                         if (ret < 0)
928                                 return ERR_PTR(ret);
929                 } else if (of_device_is_compatible(ch,
930                                                    "nvidia,therm-est-tzp")) {
931                         ret = __parse_dt_tzp(ch, data->tzp);
932                         if (ret < 0)
933                                 return ERR_PTR(ret);
934                 } else if (of_device_is_compatible(ch,
935                                         "nvidia,therm-est-timer-trip")) {
936                         ret = __parse_dt_timer_trip(ch, &data->timer_trips[l]);
937                         if (!ret)
938                                 l++;
939                 }
940         }
941
942         data->num_trips = i;
943         data->ndevs = j;
944         data->num_timer_trips = l;
945
946         return data;
947 }
948 #else
949 static struct therm_est_data *therm_est_get_pdata(struct device *dev)
950 {
951         return dev->platform_data;
952 }
953 #endif /* CONFIG_OF */
954
955 static int __devinit therm_est_probe(struct platform_device *pdev)
956 {
957         int i;
958         struct therm_estimator *est;
959         struct therm_est_data *data;
960
961         est = kzalloc(sizeof(struct therm_estimator), GFP_KERNEL);
962         if (IS_ERR_OR_NULL(est))
963                 return -ENOMEM;
964
965         platform_set_drvdata(pdev, est);
966
967         data = therm_est_get_pdata(&pdev->dev);
968
969         est->devs = data->devs;
970         est->ndevs = data->ndevs;
971         est->toffset = data->toffset;
972         est->polling_period = data->polling_period;
973         est->tc1 = data->tc1;
974         est->tc2 = data->tc2;
975
976         /* initialize history */
977         therm_est_init_history(est);
978
979         /* initialize timer trips */
980         est->num_timer_trips = data->num_timer_trips;
981         est->timer_trips = data->timer_trips;
982         therm_est_init_timer_trips(est);
983         mutex_init(&est->timer_trip_lock);
984         INIT_DELAYED_WORK(&est->timer_trip_work,
985                           therm_est_timer_trip_work_func);
986
987         est->workqueue = alloc_workqueue(dev_name(&pdev->dev),
988                                     WQ_HIGHPRI | WQ_UNBOUND | WQ_RESCUER, 1);
989         if (!est->workqueue)
990                 goto err;
991
992         INIT_DELAYED_WORK(&est->therm_est_work, therm_est_work_func);
993
994         queue_delayed_work(est->workqueue,
995                                 &est->therm_est_work,
996                                 msecs_to_jiffies(est->polling_period));
997
998         est->num_trips = data->num_trips;
999         est->trips = data->trips;
1000         est->tzp = data->tzp;
1001
1002         est->thz = thermal_zone_device_register(dev_name(&pdev->dev),
1003                                                 est->num_trips,
1004                                                 (1 << est->num_trips) - 1,
1005                                                 est,
1006                                                 &therm_est_ops,
1007                                                 est->tzp,
1008                                                 data->passive_delay,
1009                                                 0);
1010         if (IS_ERR_OR_NULL(est->thz))
1011                 goto err;
1012
1013         for (i = 0; i < ARRAY_SIZE(therm_est_nodes); i++)
1014                 device_create_file(&pdev->dev, &therm_est_nodes[i].dev_attr);
1015
1016 #ifdef CONFIG_PM
1017         est->pm_nb.notifier_call = therm_est_pm_notify,
1018         register_pm_notifier(&est->pm_nb);
1019 #endif
1020
1021         return 0;
1022 err:
1023         cancel_delayed_work_sync(&est->therm_est_work);
1024         if (est->workqueue)
1025                 destroy_workqueue(est->workqueue);
1026         kfree(est);
1027         return -EINVAL;
1028 }
1029
1030 static int __devexit therm_est_remove(struct platform_device *pdev)
1031 {
1032         struct therm_estimator *est = platform_get_drvdata(pdev);
1033         int i;
1034
1035         cancel_delayed_work_sync(&est->therm_est_work);
1036         cancel_delayed_work_sync(&est->timer_trip_work);
1037
1038 #ifdef CONFIG_PM
1039         unregister_pm_notifier(&est->pm_nb);
1040 #endif
1041         for (i = 0; i < ARRAY_SIZE(therm_est_nodes); i++)
1042                 device_remove_file(&pdev->dev, &therm_est_nodes[i].dev_attr);
1043         thermal_zone_device_unregister(est->thz);
1044         destroy_workqueue(est->workqueue);
1045         kfree(est);
1046         return 0;
1047 }
1048
1049 static struct platform_driver therm_est_driver = {
1050         .driver = {
1051                 .owner = THIS_MODULE,
1052                 .name  = "therm_est",
1053         },
1054         .probe  = therm_est_probe,
1055         .remove = __devexit_p(therm_est_remove),
1056 };
1057
1058 static int __init therm_est_driver_init(void)
1059 {
1060         return platform_driver_register(&therm_est_driver);
1061 }
1062 module_init(therm_est_driver_init);