drivers: misc: enable therm_est based on temp.
[linux-3.10.git] / drivers / misc / therm_est.c
1 /*
2  * drivers/misc/therm_est.c
3  *
4  * Copyright (c) 2010-2014, 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
36 struct therm_estimator {
37         struct thermal_zone_device *thz;
38         int num_trips;
39         struct thermal_trip_info *trips;
40         struct thermal_zone_params *tzp;
41
42         int num_timer_trips;
43         struct therm_est_timer_trip_info *timer_trips;
44         struct delayed_work timer_trip_work;
45         struct mutex timer_trip_lock;
46
47         struct thermal_cooling_device *cdev; /* activation device */
48         struct workqueue_struct *workqueue;
49         struct delayed_work therm_est_work;
50         long cur_temp;
51         long low_limit;
52         long high_limit;
53         int ntemp;
54         long toffset;
55         long polling_period;
56         int polling_enabled;
57         int tc1;
58         int tc2;
59         int ndevs;
60         struct therm_est_subdevice *devs;
61
62         int use_activator;
63 #ifdef CONFIG_PM
64         struct notifier_block pm_nb;
65 #endif
66 };
67
68 #define TIMER_TRIP_INACTIVE             -2
69
70 #define TIMER_TRIP_STATE_NONE           0
71 #define TIMER_TRIP_STATE_START          BIT(0)
72 #define TIMER_TRIP_STATE_STOP           BIT(1)
73 #define TIMER_TRIP_STATE_UP             BIT(2)
74 #define TIMER_TRIP_STATE_DOWN           BIT(3)
75
76 static int __get_trip_temp(struct thermal_zone_device *thz, int trip,
77                            long *temp);
78
79 static struct therm_est_timer_trip_info *
80 __find_timer_trip(struct therm_estimator *est, int trip)
81 {
82         int i;
83
84         /* Find matched timer trip info with trip. */
85         for (i = 0; i < est->num_timer_trips; i++) {
86                 if (est->timer_trips[i].trip == trip)
87                         return &est->timer_trips[i];
88         }
89         return NULL;
90 }
91
92 static int __get_timer_trip_delay(struct therm_est_timer_trip_info *timer_info,
93                                  s64 now, s64 *delay)
94 {
95         int cur = timer_info->cur;
96         int next = (cur + 1 < timer_info->num_timers) ? cur + 1 : cur;
97
98         if (cur == next) /* No more timer on this trip. */
99                 return -ENOENT;
100
101         *delay = timer_info->timers[next].time_after -
102                  (now - timer_info->last_tripped);
103         return 0;
104 }
105
106 static int therm_est_subdev_match(struct thermal_zone_device *thz, void *data)
107 {
108         return strcmp((char *)data, thz->type) == 0;
109 }
110
111 static int therm_est_subdev_get_temp(void *data, long *temp)
112 {
113         struct thermal_zone_device *thz;
114
115         thz = thermal_zone_device_find(data, therm_est_subdev_match);
116
117         if (!thz || thz->ops->get_temp(thz, temp))
118                 *temp = 25000;
119
120         return 0;
121 }
122
123 static void therm_est_update_limits(struct therm_estimator *est)
124 {
125         const int MAX_HIGH_TEMP = 128000;
126         long low_temp = 0, high_temp = MAX_HIGH_TEMP;
127         long trip_temp, passive_low_temp = MAX_HIGH_TEMP;
128         enum thermal_trip_type trip_type;
129         struct thermal_trip_info *trip_state;
130         int i;
131
132         for (i = 0; i < est->num_trips; i++) {
133                 trip_state = &est->trips[i];
134                 __get_trip_temp(est->thz, i, &trip_temp);
135                 est->thz->ops->get_trip_type(est->thz, i, &trip_type);
136
137                 if (!trip_state->tripped) { /* not tripped? update high */
138                         if (trip_temp < high_temp)
139                                 high_temp = trip_temp;
140                 } else { /* tripped? update low */
141                         if (trip_type != THERMAL_TRIP_PASSIVE) {
142                                 /* get highest ACTIVE */
143                                 if (trip_temp > low_temp)
144                                         low_temp = trip_temp;
145                         } else {
146                                 /* get lowest PASSIVE */
147                                 if (trip_temp < passive_low_temp)
148                                         passive_low_temp = trip_temp;
149                         }
150                 }
151         }
152
153         if (passive_low_temp != MAX_HIGH_TEMP)
154                 low_temp = max(low_temp, passive_low_temp);
155
156         est->low_limit = low_temp;
157         est->high_limit = high_temp;
158 }
159
160 static void therm_est_update_timer_trips(struct therm_estimator *est)
161 {
162         struct thermal_trip_info *trip_state;
163         struct therm_est_timer_trip_info *timer_info;
164         s64 now, delay, min_delay;
165         int i;
166
167         mutex_lock(&est->timer_trip_lock);
168         min_delay = LLONG_MAX;
169         now = ktime_to_ms(ktime_get());
170
171         for (i = 0; i < est->num_timer_trips; i++) {
172                 timer_info = &est->timer_trips[i];
173                 trip_state = &est->trips[timer_info->trip];
174
175                 pr_debug("%s: i %d, trip %d, tripped %d, cur %d\n",
176                         __func__, i, timer_info->trip, trip_state->tripped,
177                         timer_info->cur);
178                 if ((timer_info->cur == TIMER_TRIP_INACTIVE) ||
179                         (__get_timer_trip_delay(timer_info, now, &delay) < 0))
180                         continue;
181
182                 if (delay > 0)
183                         min_delay = min(min_delay, delay);
184                 pr_debug("%s: delay %lld, min_delay %lld\n",
185                         __func__, delay, min_delay);
186         }
187         mutex_unlock(&est->timer_trip_lock);
188
189         cancel_delayed_work(&est->timer_trip_work);
190         if (min_delay != LLONG_MAX)
191                 queue_delayed_work(est->workqueue, &est->timer_trip_work,
192                                    msecs_to_jiffies(min_delay));
193 }
194
195 static void therm_est_timer_trip_work_func(struct work_struct *work)
196 {
197         struct therm_estimator *est = container_of(work, struct therm_estimator,
198                                                    timer_trip_work.work);
199         struct thermal_trip_info *trip_state;
200         struct therm_est_timer_trip_info *timer_info;
201         s64 now, delay;
202         int timer_trip_state, i;
203
204         mutex_lock(&est->timer_trip_lock);
205         timer_trip_state = TIMER_TRIP_STATE_NONE;
206         now = ktime_to_ms(ktime_get());
207
208         for (i = 0; i < est->num_timer_trips; i++) {
209                 timer_info = &est->timer_trips[i];
210                 trip_state = &est->trips[timer_info->trip];
211
212                 pr_debug("%s: i %d, trip %d, tripped %d, cur %d\n",
213                         __func__, i, timer_info->trip, trip_state->tripped,
214                         timer_info->cur);
215                 if ((timer_info->cur == TIMER_TRIP_INACTIVE) ||
216                         (__get_timer_trip_delay(timer_info, now, &delay) < 0))
217                         continue;
218
219                 if (delay <= 0) { /* Timer on this trip has expired. */
220                         if (timer_info->cur + 1 < timer_info->num_timers) {
221                                 timer_info->last_tripped = now;
222                                 timer_info->cur++;
223                                 timer_trip_state |= TIMER_TRIP_STATE_UP;
224                         }
225                 }
226
227                 /* If delay > 0, timer on this trip has not yet expired.
228                  * So need to restart timer with remaining delay. */
229                 timer_trip_state |= TIMER_TRIP_STATE_START;
230                 pr_debug("%s: new_cur %d, delay %lld, timer_trip_state 0x%x\n",
231                         __func__, timer_info->cur, delay, timer_trip_state);
232         }
233         mutex_unlock(&est->timer_trip_lock);
234
235         if (timer_trip_state & (TIMER_TRIP_STATE_START | TIMER_TRIP_STATE_UP)) {
236                 therm_est_update_timer_trips(est);
237                 therm_est_update_limits(est);
238         }
239 }
240
241 static void therm_est_work_func(struct work_struct *work)
242 {
243         int i, j, index, sum = 0;
244         long temp;
245         struct delayed_work *dwork = container_of(work,
246                                         struct delayed_work, work);
247         struct therm_estimator *est = container_of(dwork,
248                                         struct therm_estimator,
249                                         therm_est_work);
250
251         for (i = 0; i < est->ndevs; i++) {
252                 if (therm_est_subdev_get_temp(est->devs[i].dev_data, &temp))
253                         continue;
254                 est->devs[i].hist[(est->ntemp % HIST_LEN)] = temp;
255         }
256
257         for (i = 0; i < est->ndevs; i++) {
258                 for (j = 0; j < HIST_LEN; j++) {
259                         index = (est->ntemp - j + HIST_LEN) % HIST_LEN;
260                         sum += est->devs[i].hist[index] *
261                                 est->devs[i].coeffs[j];
262                 }
263         }
264
265         est->cur_temp = sum / 100 + est->toffset;
266         est->ntemp++;
267
268         if (est->thz && ((est->cur_temp < est->low_limit) ||
269                         (est->cur_temp >= est->high_limit))) {
270                 thermal_zone_device_update(est->thz);
271                 therm_est_update_timer_trips(est);
272                 therm_est_update_limits(est);
273         }
274
275         if (est->polling_enabled > 0 || !est->use_activator) {
276                 queue_delayed_work(est->workqueue, &est->therm_est_work,
277                         msecs_to_jiffies(est->polling_period));
278         }
279 }
280
281 static int therm_est_bind(struct thermal_zone_device *thz,
282                                 struct thermal_cooling_device *cdev)
283 {
284         struct therm_estimator *est = thz->devdata;
285         struct thermal_trip_info *trip_state;
286         int i;
287
288         for (i = 0; i < est->num_trips; i++) {
289                 trip_state = &est->trips[i];
290                 if (trip_state->cdev_type &&
291                     !strncmp(trip_state->cdev_type, cdev->type,
292                              THERMAL_NAME_LENGTH))
293                         thermal_zone_bind_cooling_device(thz, i, cdev,
294                                                          trip_state->upper,
295                                                          trip_state->lower);
296         }
297
298         return 0;
299 }
300
301 static int therm_est_unbind(struct thermal_zone_device *thz,
302                                 struct thermal_cooling_device *cdev)
303 {
304         struct therm_estimator *est = thz->devdata;
305         struct thermal_trip_info *trip_state;
306         int i;
307
308         for (i = 0; i < est->num_trips; i++) {
309                 trip_state = &est->trips[i];
310                 if (trip_state->cdev_type &&
311                     !strncmp(trip_state->cdev_type, cdev->type,
312                              THERMAL_NAME_LENGTH))
313                         thermal_zone_unbind_cooling_device(thz, i, cdev);
314         }
315
316         return 0;
317 }
318
319 static int therm_est_get_trip_type(struct thermal_zone_device *thz,
320                                    int trip, enum thermal_trip_type *type)
321 {
322         struct therm_estimator *est = thz->devdata;
323
324         *type = est->trips[trip].trip_type;
325         return 0;
326 }
327
328 static int __get_trip_temp(struct thermal_zone_device *thz, int trip,
329                            long *temp)
330 {
331         struct therm_estimator *est = thz->devdata;
332         struct thermal_trip_info *trip_state = &est->trips[trip];
333         struct therm_est_timer_trip_info *timer_info;
334         long zone_temp, trip_temp, hysteresis;
335         int cur = TIMER_TRIP_INACTIVE;
336         int ret = TIMER_TRIP_STATE_NONE;
337
338         zone_temp = thz->temperature;
339         trip_temp = trip_state->trip_temp;
340         hysteresis = trip_state->hysteresis;
341
342         timer_info = __find_timer_trip(est, trip);
343         if (timer_info) {
344                 cur = timer_info->cur;
345                 /* If timer trip is available, use trip_temp and hysteresis in
346                  * the timer trip to trip_temp for this trip. */
347                 if (timer_info->cur >= 0) {
348                         trip_temp = timer_info->timers[cur].trip_temp;
349                         hysteresis = timer_info->timers[cur].hysteresis;
350                 }
351         }
352
353         if (zone_temp >= trip_temp) {
354                 trip_temp -= hysteresis;
355                 if (timer_info && !trip_state->tripped)
356                         ret = TIMER_TRIP_STATE_START;
357                 trip_state->tripped = true;
358         } else if (trip_state->tripped) {
359                 trip_temp -= hysteresis;
360                 if (zone_temp < trip_temp) {
361                         if (!timer_info) {
362                                 trip_state->tripped = false;
363                         } else {
364                                 if (cur == TIMER_TRIP_INACTIVE)
365                                         trip_state->tripped = false;
366                                 else
367                                         ret = TIMER_TRIP_STATE_DOWN;
368                         }
369                 }
370         }
371
372         *temp = trip_temp;
373         return ret;
374 }
375
376 static int therm_est_get_trip_temp(struct thermal_zone_device *thz,
377                                    int trip, unsigned long *temp)
378 {
379         struct therm_estimator *est = thz->devdata;
380         struct therm_est_timer_trip_info *timer_info;
381         int ret;
382
383         ret = __get_trip_temp(thz, trip, temp);
384         if (ret & (TIMER_TRIP_STATE_START | TIMER_TRIP_STATE_DOWN)) {
385                 timer_info = __find_timer_trip(est, trip);
386
387                 mutex_lock(&est->timer_trip_lock);
388                 timer_info->last_tripped = ktime_to_ms(ktime_get());
389
390                 if (ret & TIMER_TRIP_STATE_START) {
391                         timer_info->cur = TIMER_TRIP_INACTIVE + 1;
392                 } else if (ret & TIMER_TRIP_STATE_DOWN) {
393                         if (--timer_info->cur < TIMER_TRIP_INACTIVE)
394                                 timer_info->cur = TIMER_TRIP_INACTIVE;
395                 }
396                 mutex_unlock(&est->timer_trip_lock);
397
398                 /* Update limits, because trip temp was changed by timer trip
399                  * changing. */
400                 therm_est_update_limits(est);
401         }
402
403         return 0;
404 }
405
406 static int therm_est_set_trip_temp(struct thermal_zone_device *thz,
407                                    int trip, unsigned long temp)
408 {
409         struct therm_estimator *est = thz->devdata;
410
411         est->trips[trip].trip_temp = temp;
412
413         /* Update limits, because trip temp was changed. */
414         therm_est_update_limits(est);
415         return 0;
416 }
417
418 static int therm_est_get_temp(struct thermal_zone_device *thz,
419                                 unsigned long *temp)
420 {
421         struct therm_estimator *est = thz->devdata;
422
423         *temp = est->cur_temp;
424         return 0;
425 }
426
427 static int therm_est_get_trend(struct thermal_zone_device *thz,
428                                int trip, enum thermal_trend *trend)
429 {
430         struct therm_estimator *est = thz->devdata;
431         struct thermal_trip_info *trip_state = &est->trips[trip];
432         long trip_temp;
433         int new_trend;
434         int cur_temp;
435
436         __get_trip_temp(thz, trip, &trip_temp);
437
438         cur_temp = thz->temperature;
439         new_trend = (est->tc1 * (cur_temp - thz->last_temperature)) +
440                     (est->tc2 * (cur_temp - trip_temp));
441
442         switch (trip_state->trip_type) {
443         case THERMAL_TRIP_ACTIVE:
444                 /* aggressive active cooling */
445                 *trend = THERMAL_TREND_RAISING;
446                 break;
447         case THERMAL_TRIP_PASSIVE:
448                 if (new_trend > 0)
449                         *trend = THERMAL_TREND_RAISING;
450                 else if (new_trend < 0)
451                         *trend = THERMAL_TREND_DROPPING;
452                 else
453                         *trend = THERMAL_TREND_STABLE;
454                 break;
455         default:
456                 return -EINVAL;
457         }
458         return 0;
459 }
460
461 static void therm_est_init_timer_trips(struct therm_estimator *est)
462 {
463         int i;
464
465         for (i = 0; i < est->num_timer_trips; i++)
466                 est->timer_trips[i].cur = TIMER_TRIP_INACTIVE;
467 }
468
469 static int therm_est_init_history(struct therm_estimator *est)
470 {
471         int i, j;
472         struct therm_est_subdevice *dev;
473         long temp;
474
475         for (i = 0; i < est->ndevs; i++) {
476                 dev = &est->devs[i];
477
478                 if (therm_est_subdev_get_temp(dev->dev_data, &temp))
479                         return -EINVAL;
480
481                 for (j = 0; j < HIST_LEN; j++)
482                         dev->hist[j] = temp;
483         }
484
485         return 0;
486 }
487
488 static int therm_est_polling(struct therm_estimator *est,
489                                 int polling)
490 {
491         est->polling_enabled = polling > 0;
492
493         if (est->polling_enabled > 0) {
494                 est->low_limit = 0;
495                 est->high_limit = 0;
496                 therm_est_init_history(est);
497                 therm_est_init_timer_trips(est);
498                 queue_delayed_work(est->workqueue,
499                         &est->therm_est_work,
500                         msecs_to_jiffies(est->polling_period));
501         } else {
502                 est->cur_temp = 25000;
503                 cancel_delayed_work_sync(&est->therm_est_work);
504         }
505         return 0;
506 }
507
508 static struct thermal_zone_device_ops therm_est_ops = {
509         .bind = therm_est_bind,
510         .unbind = therm_est_unbind,
511         .get_trip_type = therm_est_get_trip_type,
512         .get_trip_temp = therm_est_get_trip_temp,
513         .set_trip_temp = therm_est_set_trip_temp,
514         .get_temp = therm_est_get_temp,
515         .get_trend = therm_est_get_trend,
516 };
517
518 static ssize_t show_coeff(struct device *dev,
519                                 struct device_attribute *da,
520                                 char *buf)
521 {
522         struct therm_estimator *est = dev_get_drvdata(dev);
523         ssize_t len, total_len = 0;
524         int i, j;
525         for (i = 0; i < est->ndevs; i++) {
526                 len = snprintf(buf + total_len,
527                                 PAGE_SIZE - total_len, "[%d]", i);
528                 total_len += len;
529                 for (j = 0; j < HIST_LEN; j++) {
530                         len = snprintf(buf + total_len,
531                                         PAGE_SIZE - total_len, " %ld",
532                                         est->devs[i].coeffs[j]);
533                         total_len += len;
534                 }
535                 len = snprintf(buf + total_len, PAGE_SIZE - total_len, "\n");
536                 total_len += len;
537         }
538         return strlen(buf);
539 }
540
541 static ssize_t set_coeff(struct device *dev,
542                                 struct device_attribute *da,
543                                 const char *buf, size_t count)
544 {
545         struct therm_estimator *est = dev_get_drvdata(dev);
546         int devid, scount;
547         long coeff[20];
548
549         if (HIST_LEN > 20)
550                 return -EINVAL;
551
552         scount = sscanf(buf, "[%d] %ld %ld %ld %ld %ld %ld %ld %ld %ld %ld " \
553                         "%ld %ld %ld %ld %ld %ld %ld %ld %ld %ld",
554                         &devid,
555                         &coeff[0],
556                         &coeff[1],
557                         &coeff[2],
558                         &coeff[3],
559                         &coeff[4],
560                         &coeff[5],
561                         &coeff[6],
562                         &coeff[7],
563                         &coeff[8],
564                         &coeff[9],
565                         &coeff[10],
566                         &coeff[11],
567                         &coeff[12],
568                         &coeff[13],
569                         &coeff[14],
570                         &coeff[15],
571                         &coeff[16],
572                         &coeff[17],
573                         &coeff[18],
574                         &coeff[19]);
575
576         if (scount != HIST_LEN + 1)
577                 return -1;
578
579         if (devid < 0 || devid >= est->ndevs)
580                 return -EINVAL;
581
582         /* This has obvious locking issues but don't worry about it */
583         memcpy(est->devs[devid].coeffs, coeff, sizeof(coeff[0]) * HIST_LEN);
584
585         return count;
586 }
587
588 static ssize_t show_offset(struct device *dev,
589                                 struct device_attribute *da,
590                                 char *buf)
591 {
592         struct therm_estimator *est = dev_get_drvdata(dev);
593         snprintf(buf, PAGE_SIZE, "%ld\n", est->toffset);
594         return strlen(buf);
595 }
596
597 static ssize_t set_offset(struct device *dev,
598                                 struct device_attribute *da,
599                                 const char *buf, size_t count)
600 {
601         struct therm_estimator *est = dev_get_drvdata(dev);
602         int offset;
603
604         if (kstrtoint(buf, 0, &offset))
605                 return -EINVAL;
606
607         est->toffset = offset;
608
609         return count;
610 }
611
612 static ssize_t show_temps(struct device *dev,
613                                 struct device_attribute *da,
614                                 char *buf)
615 {
616         struct therm_estimator *est = dev_get_drvdata(dev);
617         ssize_t total_len = 0;
618         int i, j;
619         int index;
620
621         /* This has obvious locking issues but don't worry about it */
622         for (i = 0; i < est->ndevs; i++) {
623                 total_len += snprintf(buf + total_len,
624                                         PAGE_SIZE - total_len, "[%d]", i);
625                 for (j = 0; j < HIST_LEN; j++) {
626                         index = (est->ntemp - j + HIST_LEN) % HIST_LEN;
627                         total_len += snprintf(buf + total_len,
628                                                 PAGE_SIZE - total_len, " %ld",
629                                                 est->devs[i].hist[index]);
630                 }
631                 total_len += snprintf(buf + total_len,
632                                         PAGE_SIZE - total_len, "\n");
633         }
634         return strlen(buf);
635 }
636
637 static ssize_t show_tc1(struct device *dev,
638                         struct device_attribute *da,
639                         char *buf)
640 {
641         struct therm_estimator *est = dev_get_drvdata(dev);
642         snprintf(buf, PAGE_SIZE, "%d\n", est->tc1);
643         return strlen(buf);
644 }
645
646 static ssize_t set_tc1(struct device *dev,
647                         struct device_attribute *da,
648                         const char *buf, size_t count)
649 {
650         struct therm_estimator *est = dev_get_drvdata(dev);
651         int tc1;
652
653         if (kstrtoint(buf, 0, &tc1))
654                 return -EINVAL;
655
656         est->tc1 = tc1;
657
658         return count;
659 }
660
661 static ssize_t show_tc2(struct device *dev,
662                         struct device_attribute *da,
663                         char *buf)
664 {
665         struct therm_estimator *est = dev_get_drvdata(dev);
666         snprintf(buf, PAGE_SIZE, "%d\n", est->tc2);
667         return strlen(buf);
668 }
669
670 static ssize_t set_tc2(struct device *dev,
671                         struct device_attribute *da,
672                         const char *buf, size_t count)
673 {
674         struct therm_estimator *est = dev_get_drvdata(dev);
675         int tc2;
676
677         if (kstrtoint(buf, 0, &tc2))
678                 return -EINVAL;
679
680         est->tc2 = tc2;
681
682         return count;
683 }
684
685 static struct sensor_device_attribute therm_est_nodes[] = {
686         SENSOR_ATTR(coeff, S_IRUGO | S_IWUSR, show_coeff, set_coeff, 0),
687         SENSOR_ATTR(offset, S_IRUGO | S_IWUSR, show_offset, set_offset, 0),
688         SENSOR_ATTR(tc1, S_IRUGO | S_IWUSR, show_tc1, set_tc1, 0),
689         SENSOR_ATTR(tc2, S_IRUGO | S_IWUSR, show_tc2, set_tc2, 0),
690         SENSOR_ATTR(temps, S_IRUGO, show_temps, 0, 0),
691 };
692
693 #ifdef CONFIG_PM
694 static int therm_est_pm_notify(struct notifier_block *nb,
695                                 unsigned long event, void *data)
696 {
697         struct therm_estimator *est = container_of(
698                                         nb,
699                                         struct therm_estimator,
700                                         pm_nb);
701
702         switch (event) {
703         case PM_SUSPEND_PREPARE:
704                 cancel_delayed_work_sync(&est->therm_est_work);
705                 cancel_delayed_work_sync(&est->timer_trip_work);
706                 break;
707         case PM_POST_SUSPEND:
708                 est->low_limit = 0;
709                 est->high_limit = 0;
710                 therm_est_init_history(est);
711                 therm_est_init_timer_trips(est);
712                 queue_delayed_work(est->workqueue,
713                                 &est->therm_est_work,
714                                 msecs_to_jiffies(est->polling_period));
715                 break;
716         }
717
718         return NOTIFY_OK;
719 }
720 #endif
721
722 static int
723 thermal_est_activation_get_max_state(struct thermal_cooling_device *cdev,
724                                         unsigned long *max_state)
725 {
726         *max_state = 1;
727         return 0;
728 }
729
730 static int
731 thermal_est_activation_get_cur_state(struct thermal_cooling_device *cdev,
732                                         unsigned long *cur_state)
733 {
734         struct therm_estimator *est = cdev->devdata;
735         *cur_state = est->polling_enabled;
736         return 0;
737 }
738
739 static int
740 thermal_est_activation_set_cur_state(struct thermal_cooling_device *cdev,
741                                         unsigned long cur_state)
742 {
743         struct therm_estimator *est = cdev->devdata;
744         if (est->use_activator)
745                 therm_est_polling(est, cur_state > 0);
746
747         return 0;
748 }
749
750 static struct thermal_cooling_device_ops thermal_est_activation_device_ops = {
751         .get_max_state = thermal_est_activation_get_max_state,
752         .get_cur_state = thermal_est_activation_get_cur_state,
753         .set_cur_state = thermal_est_activation_set_cur_state,
754 };
755
756 struct thermal_cooling_device *thermal_est_activation_device_register(
757                                                 struct therm_estimator *est,
758                                                 char *type)
759 {
760         struct thermal_cooling_device *cdev;
761
762         cdev = thermal_cooling_device_register(
763                 type,
764                 est,
765                 &thermal_est_activation_device_ops);
766
767         if (IS_ERR(cdev))
768                 return NULL;
769
770         pr_debug("Therm_est: Cooling-device REGISTERED\n");
771
772         return cdev;
773 }
774
775 static int therm_est_probe(struct platform_device *pdev)
776 {
777         int i;
778         struct therm_estimator *est;
779         struct therm_est_data *data;
780
781         est = kzalloc(sizeof(struct therm_estimator), GFP_KERNEL);
782         if (IS_ERR_OR_NULL(est))
783                 return -ENOMEM;
784
785         platform_set_drvdata(pdev, est);
786
787         data = pdev->dev.platform_data;
788
789         est->devs = data->devs;
790         est->ndevs = data->ndevs;
791         est->toffset = data->toffset;
792         est->polling_period = data->polling_period;
793         est->polling_enabled = 0; /* By default polling is switched off */
794         est->tc1 = data->tc1;
795         est->tc2 = data->tc2;
796         est->use_activator = data->use_activator;
797
798         /* initialize history */
799         therm_est_init_history(est);
800
801         /* initialize timer trips */
802         est->num_timer_trips = data->num_timer_trips;
803         est->timer_trips = data->timer_trips;
804         therm_est_init_timer_trips(est);
805         mutex_init(&est->timer_trip_lock);
806         INIT_DELAYED_WORK(&est->timer_trip_work,
807                           therm_est_timer_trip_work_func);
808
809         est->workqueue = alloc_workqueue(dev_name(&pdev->dev),
810                                     WQ_HIGHPRI | WQ_UNBOUND, 1);
811         if (!est->workqueue)
812                 goto err;
813
814         INIT_DELAYED_WORK(&est->therm_est_work, therm_est_work_func);
815
816         est->cdev = thermal_est_activation_device_register(est,
817                                                         "therm_est_activ");
818
819         est->num_trips = data->num_trips;
820         est->trips = data->trips;
821         est->tzp = data->tzp;
822
823         est->thz = thermal_zone_device_register(dev_name(&pdev->dev),
824                                                 est->num_trips,
825                                                 (1ULL << est->num_trips) - 1,
826                                                 est,
827                                                 &therm_est_ops,
828                                                 est->tzp,
829                                                 data->passive_delay,
830                                                 0);
831         if (IS_ERR_OR_NULL(est->thz))
832                 goto err;
833
834         for (i = 0; i < ARRAY_SIZE(therm_est_nodes); i++)
835                 device_create_file(&pdev->dev, &therm_est_nodes[i].dev_attr);
836
837 #ifdef CONFIG_PM
838         est->pm_nb.notifier_call = therm_est_pm_notify,
839         register_pm_notifier(&est->pm_nb);
840 #endif
841
842         if (!est->use_activator)
843                 queue_delayed_work(est->workqueue, &est->therm_est_work,
844                         msecs_to_jiffies(est->polling_period));
845
846         return 0;
847
848 err:
849         if (est->workqueue)
850                 destroy_workqueue(est->workqueue);
851         kfree(est);
852         return -EINVAL;
853 }
854
855 static int therm_est_remove(struct platform_device *pdev)
856 {
857         struct therm_estimator *est = platform_get_drvdata(pdev);
858         int i;
859
860         cancel_delayed_work_sync(&est->therm_est_work);
861         cancel_delayed_work_sync(&est->timer_trip_work);
862
863 #ifdef CONFIG_PM
864         unregister_pm_notifier(&est->pm_nb);
865 #endif
866         for (i = 0; i < ARRAY_SIZE(therm_est_nodes); i++)
867                 device_remove_file(&pdev->dev, &therm_est_nodes[i].dev_attr);
868         thermal_zone_device_unregister(est->thz);
869         thermal_cooling_device_unregister(est->cdev);
870         kfree(est->thz);
871         destroy_workqueue(est->workqueue);
872         kfree(est);
873         return 0;
874 }
875
876 static struct platform_driver therm_est_driver = {
877         .driver = {
878                 .owner = THIS_MODULE,
879                 .name  = "therm_est",
880         },
881         .probe  = therm_est_probe,
882         .remove = therm_est_remove,
883 };
884
885 static int __init therm_est_driver_init(void)
886 {
887         return platform_driver_register(&therm_est_driver);
888 }
889 module_init(therm_est_driver_init);