fixup: remove __dev*
[linux-3.10.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
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 workqueue_struct *workqueue;
48         struct delayed_work therm_est_work;
49         long cur_temp;
50         long low_limit;
51         long high_limit;
52         int ntemp;
53         long toffset;
54         long polling_period;
55         int tc1;
56         int tc2;
57         int ndevs;
58         struct therm_est_subdevice *devs;
59
60 #ifdef CONFIG_PM
61         struct notifier_block pm_nb;
62 #endif
63 };
64
65 #define TIMER_TRIP_INACTIVE             -2
66
67 #define TIMER_TRIP_STATE_NONE           0
68 #define TIMER_TRIP_STATE_START          BIT(0)
69 #define TIMER_TRIP_STATE_STOP           BIT(1)
70 #define TIMER_TRIP_STATE_UP             BIT(2)
71 #define TIMER_TRIP_STATE_DOWN           BIT(3)
72
73 static int __get_trip_temp(struct thermal_zone_device *thz, int trip,
74                            long *temp);
75
76 static struct therm_est_timer_trip_info *
77 __find_timer_trip(struct therm_estimator *est, int trip)
78 {
79         int i;
80
81         /* Find matched timer trip info with trip. */
82         for (i = 0; i < est->num_timer_trips; i++) {
83                 if (est->timer_trips[i].trip == trip)
84                         return &est->timer_trips[i];
85         }
86         return NULL;
87 }
88
89 static int __get_timer_trip_delay(struct therm_est_timer_trip_info *timer_info,
90                                  s64 now, s64 *delay)
91 {
92         int cur = timer_info->cur;
93         int next = (cur + 1 < timer_info->num_timers) ? cur + 1 : cur;
94
95         if (cur == next) /* No more timer on this trip. */
96                 return -ENOENT;
97
98         *delay = timer_info->timers[next].time_after -
99                  (now - timer_info->last_tripped);
100         return 0;
101 }
102
103 static int therm_est_subdev_match(struct thermal_zone_device *thz, void *data)
104 {
105         return strcmp((char *)data, thz->type) == 0;
106 }
107
108 static int therm_est_subdev_get_temp(void *data, long *temp)
109 {
110         struct thermal_zone_device *thz;
111
112         thz = thermal_zone_device_find(data, therm_est_subdev_match);
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].dev_data, &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         queue_delayed_work(est->workqueue, &est->therm_est_work,
273                                 msecs_to_jiffies(est->polling_period));
274 }
275
276 static int therm_est_bind(struct thermal_zone_device *thz,
277                                 struct thermal_cooling_device *cdev)
278 {
279         struct therm_estimator *est = thz->devdata;
280         struct thermal_trip_info *trip_state;
281         int i;
282
283         for (i = 0; i < est->num_trips; i++) {
284                 trip_state = &est->trips[i];
285                 if (trip_state->cdev_type &&
286                     !strncmp(trip_state->cdev_type, cdev->type,
287                              THERMAL_NAME_LENGTH))
288                         thermal_zone_bind_cooling_device(thz, i, cdev,
289                                                          trip_state->upper,
290                                                          trip_state->lower);
291         }
292
293         return 0;
294 }
295
296 static int therm_est_unbind(struct thermal_zone_device *thz,
297                                 struct thermal_cooling_device *cdev)
298 {
299         struct therm_estimator *est = thz->devdata;
300         struct thermal_trip_info *trip_state;
301         int i;
302
303         for (i = 0; i < est->num_trips; i++) {
304                 trip_state = &est->trips[i];
305                 if (trip_state->cdev_type &&
306                     !strncmp(trip_state->cdev_type, cdev->type,
307                              THERMAL_NAME_LENGTH))
308                         thermal_zone_unbind_cooling_device(thz, i, cdev);
309         }
310
311         return 0;
312 }
313
314 static int therm_est_get_trip_type(struct thermal_zone_device *thz,
315                                    int trip, enum thermal_trip_type *type)
316 {
317         struct therm_estimator *est = thz->devdata;
318
319         *type = est->trips[trip].trip_type;
320         return 0;
321 }
322
323 static int __get_trip_temp(struct thermal_zone_device *thz, int trip,
324                            long *temp)
325 {
326         struct therm_estimator *est = thz->devdata;
327         struct thermal_trip_info *trip_state = &est->trips[trip];
328         struct therm_est_timer_trip_info *timer_info;
329         long zone_temp, trip_temp, hysteresis;
330         int cur = TIMER_TRIP_INACTIVE;
331         int ret = TIMER_TRIP_STATE_NONE;
332
333         zone_temp = thz->temperature;
334         trip_temp = trip_state->trip_temp;
335         hysteresis = trip_state->hysteresis;
336
337         timer_info = __find_timer_trip(est, trip);
338         if (timer_info) {
339                 cur = timer_info->cur;
340                 /* If timer trip is available, use trip_temp and hysteresis in
341                  * the timer trip to trip_temp for this trip. */
342                 if (timer_info->cur >= 0) {
343                         trip_temp = timer_info->timers[cur].trip_temp;
344                         hysteresis = timer_info->timers[cur].hysteresis;
345                 }
346         }
347
348         if (zone_temp >= trip_temp) {
349                 trip_temp -= hysteresis;
350                 if (timer_info && !trip_state->tripped)
351                         ret = TIMER_TRIP_STATE_START;
352                 trip_state->tripped = true;
353         } else if (trip_state->tripped) {
354                 trip_temp -= hysteresis;
355                 if (zone_temp < trip_temp) {
356                         if (!timer_info) {
357                                 trip_state->tripped = false;
358                         } else {
359                                 if (cur == TIMER_TRIP_INACTIVE)
360                                         trip_state->tripped = false;
361                                 else
362                                         ret = TIMER_TRIP_STATE_DOWN;
363                         }
364                 }
365         }
366
367         *temp = trip_temp;
368         return ret;
369 }
370
371 static int therm_est_get_trip_temp(struct thermal_zone_device *thz,
372                                    int trip, unsigned long *temp)
373 {
374         struct therm_estimator *est = thz->devdata;
375         struct therm_est_timer_trip_info *timer_info;
376         int ret;
377
378         ret = __get_trip_temp(thz, trip, temp);
379         if (ret & (TIMER_TRIP_STATE_START | TIMER_TRIP_STATE_DOWN)) {
380                 timer_info = __find_timer_trip(est, trip);
381
382                 mutex_lock(&est->timer_trip_lock);
383                 timer_info->last_tripped = ktime_to_ms(ktime_get());
384
385                 if (ret & TIMER_TRIP_STATE_START) {
386                         timer_info->cur = TIMER_TRIP_INACTIVE + 1;
387                 } else if (ret & TIMER_TRIP_STATE_DOWN) {
388                         if (--timer_info->cur < TIMER_TRIP_INACTIVE)
389                                 timer_info->cur = TIMER_TRIP_INACTIVE;
390                 }
391                 mutex_unlock(&est->timer_trip_lock);
392
393                 /* Update limits, because trip temp was changed by timer trip
394                  * changing. */
395                 therm_est_update_limits(est);
396         }
397
398         return 0;
399 }
400
401 static int therm_est_set_trip_temp(struct thermal_zone_device *thz,
402                                    int trip, unsigned long temp)
403 {
404         struct therm_estimator *est = thz->devdata;
405
406         est->trips[trip].trip_temp = temp;
407
408         /* Update limits, because trip temp was changed. */
409         therm_est_update_limits(est);
410         return 0;
411 }
412
413 static int therm_est_get_temp(struct thermal_zone_device *thz,
414                                 unsigned long *temp)
415 {
416         struct therm_estimator *est = thz->devdata;
417
418         *temp = est->cur_temp;
419         return 0;
420 }
421
422 static int therm_est_get_trend(struct thermal_zone_device *thz,
423                                int trip, enum thermal_trend *trend)
424 {
425         struct therm_estimator *est = thz->devdata;
426         struct thermal_trip_info *trip_state = &est->trips[trip];
427         long trip_temp;
428         int new_trend;
429         int cur_temp;
430
431         __get_trip_temp(thz, trip, &trip_temp);
432
433         cur_temp = thz->temperature;
434         new_trend = (est->tc1 * (cur_temp - thz->last_temperature)) +
435                     (est->tc2 * (cur_temp - trip_temp));
436
437         switch (trip_state->trip_type) {
438         case THERMAL_TRIP_ACTIVE:
439                 /* aggressive active cooling */
440                 *trend = THERMAL_TREND_RAISING;
441                 break;
442         case THERMAL_TRIP_PASSIVE:
443                 if (new_trend > 0)
444                         *trend = THERMAL_TREND_RAISING;
445                 else if (new_trend < 0)
446                         *trend = THERMAL_TREND_DROPPING;
447                 else
448                         *trend = THERMAL_TREND_STABLE;
449                 break;
450         default:
451                 return -EINVAL;
452         }
453         return 0;
454 }
455
456 static struct thermal_zone_device_ops therm_est_ops = {
457         .bind = therm_est_bind,
458         .unbind = therm_est_unbind,
459         .get_trip_type = therm_est_get_trip_type,
460         .get_trip_temp = therm_est_get_trip_temp,
461         .set_trip_temp = therm_est_set_trip_temp,
462         .get_temp = therm_est_get_temp,
463         .get_trend = therm_est_get_trend,
464 };
465
466 static ssize_t show_coeff(struct device *dev,
467                                 struct device_attribute *da,
468                                 char *buf)
469 {
470         struct therm_estimator *est = dev_get_drvdata(dev);
471         ssize_t len, total_len = 0;
472         int i, j;
473         for (i = 0; i < est->ndevs; i++) {
474                 len = snprintf(buf + total_len,
475                                 PAGE_SIZE - total_len, "[%d]", i);
476                 total_len += len;
477                 for (j = 0; j < HIST_LEN; j++) {
478                         len = snprintf(buf + total_len,
479                                         PAGE_SIZE - total_len, " %ld",
480                                         est->devs[i].coeffs[j]);
481                         total_len += len;
482                 }
483                 len = snprintf(buf + total_len, PAGE_SIZE - total_len, "\n");
484                 total_len += len;
485         }
486         return strlen(buf);
487 }
488
489 static ssize_t set_coeff(struct device *dev,
490                                 struct device_attribute *da,
491                                 const char *buf, size_t count)
492 {
493         struct therm_estimator *est = dev_get_drvdata(dev);
494         int devid, scount;
495         long coeff[20];
496
497         if (HIST_LEN > 20)
498                 return -EINVAL;
499
500         scount = sscanf(buf, "[%d] %ld %ld %ld %ld %ld %ld %ld %ld %ld %ld " \
501                         "%ld %ld %ld %ld %ld %ld %ld %ld %ld %ld",
502                         &devid,
503                         &coeff[0],
504                         &coeff[1],
505                         &coeff[2],
506                         &coeff[3],
507                         &coeff[4],
508                         &coeff[5],
509                         &coeff[6],
510                         &coeff[7],
511                         &coeff[8],
512                         &coeff[9],
513                         &coeff[10],
514                         &coeff[11],
515                         &coeff[12],
516                         &coeff[13],
517                         &coeff[14],
518                         &coeff[15],
519                         &coeff[16],
520                         &coeff[17],
521                         &coeff[18],
522                         &coeff[19]);
523
524         if (scount != HIST_LEN + 1)
525                 return -1;
526
527         if (devid < 0 || devid >= est->ndevs)
528                 return -EINVAL;
529
530         /* This has obvious locking issues but don't worry about it */
531         memcpy(est->devs[devid].coeffs, coeff, sizeof(coeff[0]) * HIST_LEN);
532
533         return count;
534 }
535
536 static ssize_t show_offset(struct device *dev,
537                                 struct device_attribute *da,
538                                 char *buf)
539 {
540         struct therm_estimator *est = dev_get_drvdata(dev);
541         snprintf(buf, PAGE_SIZE, "%ld\n", est->toffset);
542         return strlen(buf);
543 }
544
545 static ssize_t set_offset(struct device *dev,
546                                 struct device_attribute *da,
547                                 const char *buf, size_t count)
548 {
549         struct therm_estimator *est = dev_get_drvdata(dev);
550         int offset;
551
552         if (kstrtoint(buf, 0, &offset))
553                 return -EINVAL;
554
555         est->toffset = offset;
556
557         return count;
558 }
559
560 static ssize_t show_temps(struct device *dev,
561                                 struct device_attribute *da,
562                                 char *buf)
563 {
564         struct therm_estimator *est = dev_get_drvdata(dev);
565         ssize_t total_len = 0;
566         int i, j;
567         int index;
568
569         /* This has obvious locking issues but don't worry about it */
570         for (i = 0; i < est->ndevs; i++) {
571                 total_len += snprintf(buf + total_len,
572                                         PAGE_SIZE - total_len, "[%d]", i);
573                 for (j = 0; j < HIST_LEN; j++) {
574                         index = (est->ntemp - j + HIST_LEN) % HIST_LEN;
575                         total_len += snprintf(buf + total_len,
576                                                 PAGE_SIZE - total_len, " %ld",
577                                                 est->devs[i].hist[index]);
578                 }
579                 total_len += snprintf(buf + total_len,
580                                         PAGE_SIZE - total_len, "\n");
581         }
582         return strlen(buf);
583 }
584
585 static ssize_t show_tc1(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, "%d\n", est->tc1);
591         return strlen(buf);
592 }
593
594 static ssize_t set_tc1(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 tc1;
600
601         if (kstrtoint(buf, 0, &tc1))
602                 return -EINVAL;
603
604         est->tc1 = tc1;
605
606         return count;
607 }
608
609 static ssize_t show_tc2(struct device *dev,
610                         struct device_attribute *da,
611                         char *buf)
612 {
613         struct therm_estimator *est = dev_get_drvdata(dev);
614         snprintf(buf, PAGE_SIZE, "%d\n", est->tc2);
615         return strlen(buf);
616 }
617
618 static ssize_t set_tc2(struct device *dev,
619                         struct device_attribute *da,
620                         const char *buf, size_t count)
621 {
622         struct therm_estimator *est = dev_get_drvdata(dev);
623         int tc2;
624
625         if (kstrtoint(buf, 0, &tc2))
626                 return -EINVAL;
627
628         est->tc2 = tc2;
629
630         return count;
631 }
632
633 static struct sensor_device_attribute therm_est_nodes[] = {
634         SENSOR_ATTR(coeff, S_IRUGO | S_IWUSR, show_coeff, set_coeff, 0),
635         SENSOR_ATTR(offset, S_IRUGO | S_IWUSR, show_offset, set_offset, 0),
636         SENSOR_ATTR(tc1, S_IRUGO | S_IWUSR, show_tc1, set_tc1, 0),
637         SENSOR_ATTR(tc2, S_IRUGO | S_IWUSR, show_tc2, set_tc2, 0),
638         SENSOR_ATTR(temps, S_IRUGO, show_temps, 0, 0),
639 };
640
641 static void therm_est_init_timer_trips(struct therm_estimator *est)
642 {
643         int i;
644
645         for (i = 0; i < est->num_timer_trips; i++)
646                 est->timer_trips[i].cur = TIMER_TRIP_INACTIVE;
647 }
648
649 static int therm_est_init_history(struct therm_estimator *est)
650 {
651         int i, j;
652         struct therm_est_subdevice *dev;
653         long temp;
654
655         for (i = 0; i < est->ndevs; i++) {
656                 dev = &est->devs[i];
657
658                 if (therm_est_subdev_get_temp(dev->dev_data, &temp))
659                         return -EINVAL;
660
661                 for (j = 0; j < HIST_LEN; j++)
662                         dev->hist[j] = temp;
663         }
664
665         return 0;
666 }
667
668 #ifdef CONFIG_PM
669 static int therm_est_pm_notify(struct notifier_block *nb,
670                                 unsigned long event, void *data)
671 {
672         struct therm_estimator *est = container_of(
673                                         nb,
674                                         struct therm_estimator,
675                                         pm_nb);
676
677         switch (event) {
678         case PM_SUSPEND_PREPARE:
679                 cancel_delayed_work_sync(&est->therm_est_work);
680                 cancel_delayed_work_sync(&est->timer_trip_work);
681                 break;
682         case PM_POST_SUSPEND:
683                 est->low_limit = 0;
684                 est->high_limit = 0;
685                 therm_est_init_history(est);
686                 therm_est_init_timer_trips(est);
687                 queue_delayed_work(est->workqueue,
688                                 &est->therm_est_work,
689                                 msecs_to_jiffies(est->polling_period));
690                 break;
691         }
692
693         return NOTIFY_OK;
694 }
695 #endif
696
697 static int therm_est_probe(struct platform_device *pdev)
698 {
699         int i;
700         struct therm_estimator *est;
701         struct therm_est_data *data;
702
703         est = kzalloc(sizeof(struct therm_estimator), GFP_KERNEL);
704         if (IS_ERR_OR_NULL(est))
705                 return -ENOMEM;
706
707         platform_set_drvdata(pdev, est);
708
709         data = pdev->dev.platform_data;
710
711         est->devs = data->devs;
712         est->ndevs = data->ndevs;
713         est->toffset = data->toffset;
714         est->polling_period = data->polling_period;
715         est->tc1 = data->tc1;
716         est->tc2 = data->tc2;
717
718         /* initialize history */
719         therm_est_init_history(est);
720
721         /* initialize timer trips */
722         est->num_timer_trips = data->num_timer_trips;
723         est->timer_trips = data->timer_trips;
724         therm_est_init_timer_trips(est);
725         mutex_init(&est->timer_trip_lock);
726         INIT_DELAYED_WORK(&est->timer_trip_work,
727                           therm_est_timer_trip_work_func);
728
729         est->workqueue = alloc_workqueue(dev_name(&pdev->dev),
730                                     WQ_HIGHPRI | WQ_UNBOUND | WQ_RESCUER, 1);
731         if (!est->workqueue)
732                 goto err;
733
734         INIT_DELAYED_WORK(&est->therm_est_work, therm_est_work_func);
735
736         queue_delayed_work(est->workqueue,
737                                 &est->therm_est_work,
738                                 msecs_to_jiffies(est->polling_period));
739
740         est->num_trips = data->num_trips;
741         est->trips = data->trips;
742         est->tzp = data->tzp;
743
744         est->thz = thermal_zone_device_register(dev_name(&pdev->dev),
745                                                 est->num_trips,
746                                                 (1 << est->num_trips) - 1,
747                                                 est,
748                                                 &therm_est_ops,
749                                                 est->tzp,
750                                                 data->passive_delay,
751                                                 0);
752         if (IS_ERR_OR_NULL(est->thz))
753                 goto err;
754
755         for (i = 0; i < ARRAY_SIZE(therm_est_nodes); i++)
756                 device_create_file(&pdev->dev, &therm_est_nodes[i].dev_attr);
757
758 #ifdef CONFIG_PM
759         est->pm_nb.notifier_call = therm_est_pm_notify,
760         register_pm_notifier(&est->pm_nb);
761 #endif
762
763         return 0;
764 err:
765         cancel_delayed_work_sync(&est->therm_est_work);
766         if (est->workqueue)
767                 destroy_workqueue(est->workqueue);
768         kfree(est);
769         return -EINVAL;
770 }
771
772 static int therm_est_remove(struct platform_device *pdev)
773 {
774         struct therm_estimator *est = platform_get_drvdata(pdev);
775         int i;
776
777         cancel_delayed_work_sync(&est->therm_est_work);
778         cancel_delayed_work_sync(&est->timer_trip_work);
779
780 #ifdef CONFIG_PM
781         unregister_pm_notifier(&est->pm_nb);
782 #endif
783         for (i = 0; i < ARRAY_SIZE(therm_est_nodes); i++)
784                 device_remove_file(&pdev->dev, &therm_est_nodes[i].dev_attr);
785         thermal_zone_device_unregister(est->thz);
786         destroy_workqueue(est->workqueue);
787         kfree(est);
788         return 0;
789 }
790
791 static struct platform_driver therm_est_driver = {
792         .driver = {
793                 .owner = THIS_MODULE,
794                 .name  = "therm_est",
795         },
796         .probe  = therm_est_probe,
797         .remove = therm_est_remove,
798 };
799
800 static int __init therm_est_driver_init(void)
801 {
802         return platform_driver_register(&therm_est_driver);
803 }
804 module_init(therm_est_driver_init);