]> rtime.felk.cvut.cz Git - sojka/nv-tegra/linux-3.10.git/blob - drivers/misc/therm_est.c
misc: therm_est: Unregister tz and cdev in shutdown
[sojka/nv-tegra/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(struct thermal_zone_device *thz,
112                                         long *temp)
113 {
114         if (!thz || thz->ops->get_temp(thz, temp))
115                 *temp = 25000;
116
117         return 0;
118 }
119
120 static void therm_est_update_limits(struct therm_estimator *est)
121 {
122         const int MAX_HIGH_TEMP = 128000;
123         long low_temp = 0, high_temp = MAX_HIGH_TEMP;
124         long trip_temp, passive_low_temp = MAX_HIGH_TEMP;
125         enum thermal_trip_type trip_type;
126         struct thermal_trip_info *trip_state;
127         int i;
128
129         for (i = 0; i < est->num_trips; i++) {
130                 trip_state = &est->trips[i];
131                 __get_trip_temp(est->thz, i, &trip_temp);
132                 est->thz->ops->get_trip_type(est->thz, i, &trip_type);
133
134                 if (!trip_state->tripped) { /* not tripped? update high */
135                         if (trip_temp < high_temp)
136                                 high_temp = trip_temp;
137                 } else { /* tripped? update low */
138                         if (trip_type != THERMAL_TRIP_PASSIVE) {
139                                 /* get highest ACTIVE */
140                                 if (trip_temp > low_temp)
141                                         low_temp = trip_temp;
142                         } else {
143                                 /* get lowest PASSIVE */
144                                 if (trip_temp < passive_low_temp)
145                                         passive_low_temp = trip_temp;
146                         }
147                 }
148         }
149
150         if (passive_low_temp != MAX_HIGH_TEMP)
151                 low_temp = max(low_temp, passive_low_temp);
152
153         est->low_limit = low_temp;
154         est->high_limit = high_temp;
155 }
156
157 static void therm_est_update_timer_trips(struct therm_estimator *est)
158 {
159         struct thermal_trip_info *trip_state;
160         struct therm_est_timer_trip_info *timer_info;
161         s64 now, delay, min_delay;
162         int i;
163
164         mutex_lock(&est->timer_trip_lock);
165         min_delay = LLONG_MAX;
166         now = ktime_to_ms(ktime_get());
167
168         for (i = 0; i < est->num_timer_trips; i++) {
169                 timer_info = &est->timer_trips[i];
170                 trip_state = &est->trips[timer_info->trip];
171
172                 pr_debug("%s: i %d, trip %d, tripped %d, cur %d\n",
173                         __func__, i, timer_info->trip, trip_state->tripped,
174                         timer_info->cur);
175                 if ((timer_info->cur == TIMER_TRIP_INACTIVE) ||
176                         (__get_timer_trip_delay(timer_info, now, &delay) < 0))
177                         continue;
178
179                 if (delay > 0)
180                         min_delay = min(min_delay, delay);
181                 pr_debug("%s: delay %lld, min_delay %lld\n",
182                         __func__, delay, min_delay);
183         }
184         mutex_unlock(&est->timer_trip_lock);
185
186         cancel_delayed_work(&est->timer_trip_work);
187         if (min_delay != LLONG_MAX)
188                 queue_delayed_work(est->workqueue, &est->timer_trip_work,
189                                    msecs_to_jiffies(min_delay));
190 }
191
192 static void therm_est_timer_trip_work_func(struct work_struct *work)
193 {
194         struct therm_estimator *est = container_of(work, struct therm_estimator,
195                                                    timer_trip_work.work);
196         struct thermal_trip_info *trip_state;
197         struct therm_est_timer_trip_info *timer_info;
198         s64 now, delay;
199         int timer_trip_state, i;
200
201         mutex_lock(&est->timer_trip_lock);
202         timer_trip_state = TIMER_TRIP_STATE_NONE;
203         now = ktime_to_ms(ktime_get());
204
205         for (i = 0; i < est->num_timer_trips; i++) {
206                 timer_info = &est->timer_trips[i];
207                 trip_state = &est->trips[timer_info->trip];
208
209                 pr_debug("%s: i %d, trip %d, tripped %d, cur %d\n",
210                         __func__, i, timer_info->trip, trip_state->tripped,
211                         timer_info->cur);
212                 if ((timer_info->cur == TIMER_TRIP_INACTIVE) ||
213                         (__get_timer_trip_delay(timer_info, now, &delay) < 0))
214                         continue;
215
216                 if (delay <= 0) { /* Timer on this trip has expired. */
217                         if (timer_info->cur + 1 < timer_info->num_timers) {
218                                 timer_info->last_tripped = now;
219                                 timer_info->cur++;
220                                 timer_trip_state |= TIMER_TRIP_STATE_UP;
221                         }
222                 }
223
224                 /* If delay > 0, timer on this trip has not yet expired.
225                  * So need to restart timer with remaining delay. */
226                 timer_trip_state |= TIMER_TRIP_STATE_START;
227                 pr_debug("%s: new_cur %d, delay %lld, timer_trip_state 0x%x\n",
228                         __func__, timer_info->cur, delay, timer_trip_state);
229         }
230         mutex_unlock(&est->timer_trip_lock);
231
232         if (timer_trip_state & (TIMER_TRIP_STATE_START | TIMER_TRIP_STATE_UP)) {
233                 therm_est_update_timer_trips(est);
234                 therm_est_update_limits(est);
235         }
236 }
237
238 static void therm_est_work_func(struct work_struct *work)
239 {
240         int i, j, index, sum = 0;
241         long temp;
242         struct delayed_work *dwork = container_of(work,
243                                         struct delayed_work, work);
244         struct therm_estimator *est = container_of(dwork,
245                                         struct therm_estimator,
246                                         therm_est_work);
247
248         for (i = 0; i < est->ndevs; i++) {
249                 if (therm_est_subdev_get_temp(est->devs[i].sub_thz, &temp))
250                         continue;
251                 est->devs[i].hist[(est->ntemp % HIST_LEN)] = temp;
252         }
253
254         for (i = 0; i < est->ndevs; i++) {
255                 for (j = 0; j < HIST_LEN; j++) {
256                         index = (est->ntemp - j + HIST_LEN) % HIST_LEN;
257                         sum += est->devs[i].hist[index] *
258                                 est->devs[i].coeffs[j];
259                 }
260         }
261
262         est->cur_temp = sum / 100 + est->toffset;
263         est->ntemp++;
264
265         if (est->thz && ((est->cur_temp < est->low_limit) ||
266                         (est->cur_temp >= est->high_limit))) {
267                 thermal_zone_device_update(est->thz);
268                 therm_est_update_timer_trips(est);
269                 therm_est_update_limits(est);
270         }
271
272         if (est->polling_enabled > 0 || !est->use_activator) {
273                 queue_delayed_work(est->workqueue, &est->therm_est_work,
274                         msecs_to_jiffies(est->polling_period));
275         }
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 void therm_est_init_timer_trips(struct therm_estimator *est)
459 {
460         int i;
461
462         for (i = 0; i < est->num_timer_trips; i++)
463                 est->timer_trips[i].cur = TIMER_TRIP_INACTIVE;
464 }
465
466 static int therm_est_init_history(struct therm_estimator *est)
467 {
468         int i, j;
469         struct therm_est_subdevice *dev;
470         long temp;
471
472         for (i = 0; i < est->ndevs; i++) {
473                 dev = &est->devs[i];
474
475                 if (therm_est_subdev_get_temp(dev->sub_thz, &temp))
476                         return -EINVAL;
477
478                 for (j = 0; j < HIST_LEN; j++)
479                         dev->hist[j] = temp;
480         }
481
482         return 0;
483 }
484
485 static int therm_est_polling(struct therm_estimator *est,
486                                 int polling)
487 {
488         est->polling_enabled = polling > 0;
489
490         if (est->polling_enabled > 0) {
491                 est->low_limit = 0;
492                 est->high_limit = 0;
493                 therm_est_init_history(est);
494                 therm_est_init_timer_trips(est);
495                 queue_delayed_work(est->workqueue,
496                         &est->therm_est_work,
497                         msecs_to_jiffies(est->polling_period));
498         } else {
499                 est->cur_temp = 25000;
500                 cancel_delayed_work_sync(&est->therm_est_work);
501         }
502         return 0;
503 }
504
505 static struct thermal_zone_device_ops therm_est_ops = {
506         .bind = therm_est_bind,
507         .unbind = therm_est_unbind,
508         .get_trip_type = therm_est_get_trip_type,
509         .get_trip_temp = therm_est_get_trip_temp,
510         .set_trip_temp = therm_est_set_trip_temp,
511         .get_temp = therm_est_get_temp,
512         .get_trend = therm_est_get_trend,
513 };
514
515 static ssize_t show_coeff(struct device *dev,
516                                 struct device_attribute *da,
517                                 char *buf)
518 {
519         struct therm_estimator *est = dev_get_drvdata(dev);
520         ssize_t len, total_len = 0;
521         int i, j;
522         for (i = 0; i < est->ndevs; i++) {
523                 len = snprintf(buf + total_len,
524                                 PAGE_SIZE - total_len, "[%d]", i);
525                 total_len += len;
526                 for (j = 0; j < HIST_LEN; j++) {
527                         len = snprintf(buf + total_len,
528                                         PAGE_SIZE - total_len, " %ld",
529                                         est->devs[i].coeffs[j]);
530                         total_len += len;
531                 }
532                 len = snprintf(buf + total_len, PAGE_SIZE - total_len, "\n");
533                 total_len += len;
534         }
535         return strlen(buf);
536 }
537
538 static ssize_t set_coeff(struct device *dev,
539                                 struct device_attribute *da,
540                                 const char *buf, size_t count)
541 {
542         struct therm_estimator *est = dev_get_drvdata(dev);
543         int devid, scount;
544         long coeff[20];
545
546         if (HIST_LEN > 20)
547                 return -EINVAL;
548
549         scount = sscanf(buf, "[%d] %ld %ld %ld %ld %ld %ld %ld %ld %ld %ld " \
550                         "%ld %ld %ld %ld %ld %ld %ld %ld %ld %ld",
551                         &devid,
552                         &coeff[0],
553                         &coeff[1],
554                         &coeff[2],
555                         &coeff[3],
556                         &coeff[4],
557                         &coeff[5],
558                         &coeff[6],
559                         &coeff[7],
560                         &coeff[8],
561                         &coeff[9],
562                         &coeff[10],
563                         &coeff[11],
564                         &coeff[12],
565                         &coeff[13],
566                         &coeff[14],
567                         &coeff[15],
568                         &coeff[16],
569                         &coeff[17],
570                         &coeff[18],
571                         &coeff[19]);
572
573         if (scount != HIST_LEN + 1)
574                 return -1;
575
576         if (devid < 0 || devid >= est->ndevs)
577                 return -EINVAL;
578
579         /* This has obvious locking issues but don't worry about it */
580         memcpy(est->devs[devid].coeffs, coeff, sizeof(coeff[0]) * HIST_LEN);
581
582         return count;
583 }
584
585 static ssize_t show_offset(struct device *dev,
586                                 struct device_attribute *da,
587                                 char *buf)
588 {
589         struct therm_estimator *est = dev_get_drvdata(dev);
590         snprintf(buf, PAGE_SIZE, "%ld\n", est->toffset);
591         return strlen(buf);
592 }
593
594 static ssize_t set_offset(struct device *dev,
595                                 struct device_attribute *da,
596                                 const char *buf, size_t count)
597 {
598         struct therm_estimator *est = dev_get_drvdata(dev);
599         int offset;
600
601         if (kstrtoint(buf, 0, &offset))
602                 return -EINVAL;
603
604         est->toffset = offset;
605
606         return count;
607 }
608
609 static ssize_t show_temps(struct device *dev,
610                                 struct device_attribute *da,
611                                 char *buf)
612 {
613         struct therm_estimator *est = dev_get_drvdata(dev);
614         ssize_t total_len = 0;
615         int i, j;
616         int index;
617
618         /* This has obvious locking issues but don't worry about it */
619         for (i = 0; i < est->ndevs; i++) {
620                 total_len += snprintf(buf + total_len,
621                                         PAGE_SIZE - total_len, "[%d]", i);
622                 for (j = 0; j < HIST_LEN; j++) {
623                         index = (est->ntemp - j + HIST_LEN) % HIST_LEN;
624                         total_len += snprintf(buf + total_len,
625                                                 PAGE_SIZE - total_len, " %ld",
626                                                 est->devs[i].hist[index]);
627                 }
628                 total_len += snprintf(buf + total_len,
629                                         PAGE_SIZE - total_len, "\n");
630         }
631         return strlen(buf);
632 }
633
634 static ssize_t show_tc1(struct device *dev,
635                         struct device_attribute *da,
636                         char *buf)
637 {
638         struct therm_estimator *est = dev_get_drvdata(dev);
639         snprintf(buf, PAGE_SIZE, "%d\n", est->tc1);
640         return strlen(buf);
641 }
642
643 static ssize_t set_tc1(struct device *dev,
644                         struct device_attribute *da,
645                         const char *buf, size_t count)
646 {
647         struct therm_estimator *est = dev_get_drvdata(dev);
648         int tc1;
649
650         if (kstrtoint(buf, 0, &tc1))
651                 return -EINVAL;
652
653         est->tc1 = tc1;
654
655         return count;
656 }
657
658 static ssize_t show_tc2(struct device *dev,
659                         struct device_attribute *da,
660                         char *buf)
661 {
662         struct therm_estimator *est = dev_get_drvdata(dev);
663         snprintf(buf, PAGE_SIZE, "%d\n", est->tc2);
664         return strlen(buf);
665 }
666
667 static ssize_t set_tc2(struct device *dev,
668                         struct device_attribute *da,
669                         const char *buf, size_t count)
670 {
671         struct therm_estimator *est = dev_get_drvdata(dev);
672         int tc2;
673
674         if (kstrtoint(buf, 0, &tc2))
675                 return -EINVAL;
676
677         est->tc2 = tc2;
678
679         return count;
680 }
681
682 static struct sensor_device_attribute therm_est_nodes[] = {
683         SENSOR_ATTR(coeff, S_IRUGO | S_IWUSR, show_coeff, set_coeff, 0),
684         SENSOR_ATTR(offset, S_IRUGO | S_IWUSR, show_offset, set_offset, 0),
685         SENSOR_ATTR(tc1, S_IRUGO | S_IWUSR, show_tc1, set_tc1, 0),
686         SENSOR_ATTR(tc2, S_IRUGO | S_IWUSR, show_tc2, set_tc2, 0),
687         SENSOR_ATTR(temps, S_IRUGO, show_temps, 0, 0),
688 };
689
690 #ifdef CONFIG_PM
691 static int therm_est_pm_notify(struct notifier_block *nb,
692                                 unsigned long event, void *data)
693 {
694         struct therm_estimator *est = container_of(
695                                         nb,
696                                         struct therm_estimator,
697                                         pm_nb);
698
699         switch (event) {
700         case PM_SUSPEND_PREPARE:
701                 cancel_delayed_work_sync(&est->therm_est_work);
702                 cancel_delayed_work_sync(&est->timer_trip_work);
703                 break;
704         case PM_POST_SUSPEND:
705                 est->low_limit = 0;
706                 est->high_limit = 0;
707                 therm_est_init_history(est);
708                 therm_est_init_timer_trips(est);
709                 queue_delayed_work(est->workqueue,
710                                 &est->therm_est_work,
711                                 msecs_to_jiffies(est->polling_period));
712                 break;
713         }
714
715         return NOTIFY_OK;
716 }
717 #endif
718
719 static int
720 thermal_est_activation_get_max_state(struct thermal_cooling_device *cdev,
721                                         unsigned long *max_state)
722 {
723         *max_state = 1;
724         return 0;
725 }
726
727 static int
728 thermal_est_activation_get_cur_state(struct thermal_cooling_device *cdev,
729                                         unsigned long *cur_state)
730 {
731         struct therm_estimator *est = cdev->devdata;
732         *cur_state = est->polling_enabled;
733         return 0;
734 }
735
736 static int
737 thermal_est_activation_set_cur_state(struct thermal_cooling_device *cdev,
738                                         unsigned long cur_state)
739 {
740         struct therm_estimator *est = cdev->devdata;
741         if (est->use_activator)
742                 therm_est_polling(est, cur_state > 0);
743
744         return 0;
745 }
746
747 static struct thermal_cooling_device_ops thermal_est_activation_device_ops = {
748         .get_max_state = thermal_est_activation_get_max_state,
749         .get_cur_state = thermal_est_activation_get_cur_state,
750         .set_cur_state = thermal_est_activation_set_cur_state,
751 };
752
753 struct thermal_cooling_device *thermal_est_activation_device_register(
754                                                 struct therm_estimator *est,
755                                                 char *type)
756 {
757         struct thermal_cooling_device *cdev;
758
759         cdev = thermal_cooling_device_register(
760                 type,
761                 est,
762                 &thermal_est_activation_device_ops);
763
764         if (IS_ERR(cdev))
765                 return NULL;
766
767         pr_debug("Therm_est: Cooling-device REGISTERED\n");
768
769         return cdev;
770 }
771
772 static int therm_est_probe(struct platform_device *pdev)
773 {
774         int i;
775         struct therm_estimator *est;
776         struct therm_est_data *data;
777         struct thermal_zone_device *thz;
778
779         est = kzalloc(sizeof(struct therm_estimator), GFP_KERNEL);
780         if (IS_ERR_OR_NULL(est))
781                 return -ENOMEM;
782
783         platform_set_drvdata(pdev, est);
784
785         data = pdev->dev.platform_data;
786
787         for (i = 0; i < data->ndevs; i++) {
788                 thz = thermal_zone_device_find(data->devs[i].dev_data,
789                                                         therm_est_subdev_match);
790                 if (!thz)
791                         goto err;
792                 data->devs[i].sub_thz = thz;
793         }
794
795         est->devs = data->devs;
796         est->ndevs = data->ndevs;
797         est->toffset = data->toffset;
798         est->polling_period = data->polling_period;
799         est->polling_enabled = 0; /* By default polling is switched off */
800         est->tc1 = data->tc1;
801         est->tc2 = data->tc2;
802         est->use_activator = data->use_activator;
803
804         /* initialize history */
805         therm_est_init_history(est);
806
807         /* initialize timer trips */
808         est->num_timer_trips = data->num_timer_trips;
809         est->timer_trips = data->timer_trips;
810         therm_est_init_timer_trips(est);
811         mutex_init(&est->timer_trip_lock);
812         INIT_DELAYED_WORK(&est->timer_trip_work,
813                           therm_est_timer_trip_work_func);
814
815         est->workqueue = alloc_workqueue(dev_name(&pdev->dev),
816                                     WQ_HIGHPRI | WQ_UNBOUND, 1);
817         if (!est->workqueue)
818                 goto err;
819
820         INIT_DELAYED_WORK(&est->therm_est_work, therm_est_work_func);
821
822         est->cdev = thermal_est_activation_device_register(est,
823                                                         "therm_est_activ");
824
825         est->num_trips = data->num_trips;
826         est->trips = data->trips;
827         est->tzp = data->tzp;
828
829         est->thz = thermal_zone_device_register(dev_name(&pdev->dev),
830                                                 est->num_trips,
831                                                 (1ULL << est->num_trips) - 1,
832                                                 est,
833                                                 &therm_est_ops,
834                                                 est->tzp,
835                                                 data->passive_delay,
836                                                 0);
837         if (IS_ERR_OR_NULL(est->thz))
838                 goto err;
839
840         for (i = 0; i < ARRAY_SIZE(therm_est_nodes); i++)
841                 device_create_file(&pdev->dev, &therm_est_nodes[i].dev_attr);
842
843 #ifdef CONFIG_PM
844         est->pm_nb.notifier_call = therm_est_pm_notify,
845         register_pm_notifier(&est->pm_nb);
846 #endif
847
848         if (!est->use_activator)
849                 queue_delayed_work(est->workqueue, &est->therm_est_work,
850                         msecs_to_jiffies(est->polling_period));
851
852         return 0;
853
854 err:
855         if (est->workqueue)
856                 destroy_workqueue(est->workqueue);
857         kfree(est);
858         return -EINVAL;
859 }
860
861 static int therm_est_remove(struct platform_device *pdev)
862 {
863         struct therm_estimator *est = platform_get_drvdata(pdev);
864         int i;
865
866         cancel_delayed_work_sync(&est->therm_est_work);
867         cancel_delayed_work_sync(&est->timer_trip_work);
868
869 #ifdef CONFIG_PM
870         unregister_pm_notifier(&est->pm_nb);
871 #endif
872         for (i = 0; i < ARRAY_SIZE(therm_est_nodes); i++)
873                 device_remove_file(&pdev->dev, &therm_est_nodes[i].dev_attr);
874         thermal_zone_device_unregister(est->thz);
875         thermal_cooling_device_unregister(est->cdev);
876         kfree(est->thz);
877         destroy_workqueue(est->workqueue);
878         kfree(est);
879         return 0;
880 }
881
882 static void therm_est_shutdown(struct platform_device *pdev)
883 {
884         struct therm_estimator *est = platform_get_drvdata(pdev);
885
886         cancel_delayed_work_sync(&est->therm_est_work);
887         cancel_delayed_work_sync(&est->timer_trip_work);
888         thermal_zone_device_unregister(est->thz);
889         thermal_cooling_device_unregister(est->cdev);
890 }
891
892 static struct platform_driver therm_est_driver = {
893         .driver = {
894                 .owner = THIS_MODULE,
895                 .name  = "therm_est",
896         },
897         .probe  = therm_est_probe,
898         .remove = therm_est_remove,
899         .shutdown = therm_est_shutdown,
900 };
901
902 static int __init therm_est_driver_init(void)
903 {
904         return platform_driver_register(&therm_est_driver);
905 }
906 module_init(therm_est_driver_init);