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