thermal: Fix for setting the thermal zone mode to enable/disable
[linux-2.6.git] / drivers / thermal / thermal_sys.c
1 /*
2  *  thermal.c - Generic Thermal Management Sysfs support.
3  *
4  *  Copyright (C) 2008 Intel Corp
5  *  Copyright (C) 2008 Zhang Rui <rui.zhang@intel.com>
6  *  Copyright (C) 2008 Sujith Thomas <sujith.thomas@intel.com>
7  *
8  *  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
9  *
10  *  This program is free software; you can redistribute it and/or modify
11  *  it under the terms of the GNU General Public License as published by
12  *  the Free Software Foundation; version 2 of the License.
13  *
14  *  This program is distributed in the hope that it will be useful, but
15  *  WITHOUT ANY WARRANTY; without even the implied warranty of
16  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
17  *  General Public License for more details.
18  *
19  *  You should have received a copy of the GNU General Public License along
20  *  with this program; if not, write to the Free Software Foundation, Inc.,
21  *  59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
22  *
23  * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
24  */
25
26 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
27
28 #include <linux/module.h>
29 #include <linux/device.h>
30 #include <linux/err.h>
31 #include <linux/slab.h>
32 #include <linux/kdev_t.h>
33 #include <linux/idr.h>
34 #include <linux/thermal.h>
35 #include <linux/spinlock.h>
36 #include <linux/reboot.h>
37 #include <net/netlink.h>
38 #include <net/genetlink.h>
39
40 MODULE_AUTHOR("Zhang Rui");
41 MODULE_DESCRIPTION("Generic thermal management sysfs support");
42 MODULE_LICENSE("GPL");
43
44 struct thermal_cooling_device_instance {
45         int id;
46         char name[THERMAL_NAME_LENGTH];
47         struct thermal_zone_device *tz;
48         struct thermal_cooling_device *cdev;
49         int trip;
50         char attr_name[THERMAL_NAME_LENGTH];
51         struct device_attribute attr;
52         struct list_head node;
53 };
54
55 static DEFINE_IDR(thermal_tz_idr);
56 static DEFINE_IDR(thermal_cdev_idr);
57 static DEFINE_MUTEX(thermal_idr_lock);
58
59 static LIST_HEAD(thermal_tz_list);
60 static LIST_HEAD(thermal_cdev_list);
61 static DEFINE_MUTEX(thermal_list_lock);
62
63 static int get_idr(struct idr *idr, struct mutex *lock, int *id)
64 {
65         int err;
66
67 again:
68         if (unlikely(idr_pre_get(idr, GFP_KERNEL) == 0))
69                 return -ENOMEM;
70
71         if (lock)
72                 mutex_lock(lock);
73         err = idr_get_new(idr, NULL, id);
74         if (lock)
75                 mutex_unlock(lock);
76         if (unlikely(err == -EAGAIN))
77                 goto again;
78         else if (unlikely(err))
79                 return err;
80
81         *id = *id & MAX_ID_MASK;
82         return 0;
83 }
84
85 static void release_idr(struct idr *idr, struct mutex *lock, int id)
86 {
87         if (lock)
88                 mutex_lock(lock);
89         idr_remove(idr, id);
90         if (lock)
91                 mutex_unlock(lock);
92 }
93
94 /* sys I/F for thermal zone */
95
96 #define to_thermal_zone(_dev) \
97         container_of(_dev, struct thermal_zone_device, device)
98
99 static ssize_t
100 type_show(struct device *dev, struct device_attribute *attr, char *buf)
101 {
102         struct thermal_zone_device *tz = to_thermal_zone(dev);
103
104         return sprintf(buf, "%s\n", tz->type);
105 }
106
107 static ssize_t
108 temp_show(struct device *dev, struct device_attribute *attr, char *buf)
109 {
110         struct thermal_zone_device *tz = to_thermal_zone(dev);
111         long temperature;
112         int ret;
113
114         if (!tz->ops->get_temp)
115                 return -EPERM;
116
117         ret = tz->ops->get_temp(tz, &temperature);
118
119         if (ret)
120                 return ret;
121
122         return sprintf(buf, "%ld\n", temperature);
123 }
124
125 static ssize_t
126 mode_show(struct device *dev, struct device_attribute *attr, char *buf)
127 {
128         struct thermal_zone_device *tz = to_thermal_zone(dev);
129         enum thermal_device_mode mode;
130         int result;
131
132         if (!tz->ops->get_mode)
133                 return -EPERM;
134
135         result = tz->ops->get_mode(tz, &mode);
136         if (result)
137                 return result;
138
139         return sprintf(buf, "%s\n", mode == THERMAL_DEVICE_ENABLED ? "enabled"
140                        : "disabled");
141 }
142
143 static ssize_t
144 mode_store(struct device *dev, struct device_attribute *attr,
145            const char *buf, size_t count)
146 {
147         struct thermal_zone_device *tz = to_thermal_zone(dev);
148         int result;
149
150         if (!tz->ops->set_mode)
151                 return -EPERM;
152
153         if (!strncmp(buf, "enabled", sizeof("enabled") - 1))
154                 result = tz->ops->set_mode(tz, THERMAL_DEVICE_ENABLED);
155         else if (!strncmp(buf, "disabled", sizeof("disabled") - 1))
156                 result = tz->ops->set_mode(tz, THERMAL_DEVICE_DISABLED);
157         else
158                 result = -EINVAL;
159
160         if (result)
161                 return result;
162
163         return count;
164 }
165
166 static ssize_t
167 trip_point_type_show(struct device *dev, struct device_attribute *attr,
168                      char *buf)
169 {
170         struct thermal_zone_device *tz = to_thermal_zone(dev);
171         enum thermal_trip_type type;
172         int trip, result;
173
174         if (!tz->ops->get_trip_type)
175                 return -EPERM;
176
177         if (!sscanf(attr->attr.name, "trip_point_%d_type", &trip))
178                 return -EINVAL;
179
180         result = tz->ops->get_trip_type(tz, trip, &type);
181         if (result)
182                 return result;
183
184         switch (type) {
185         case THERMAL_TRIP_CRITICAL:
186                 return sprintf(buf, "critical\n");
187         case THERMAL_TRIP_HOT:
188                 return sprintf(buf, "hot\n");
189         case THERMAL_TRIP_PASSIVE:
190                 return sprintf(buf, "passive\n");
191         case THERMAL_TRIP_ACTIVE:
192                 return sprintf(buf, "active\n");
193         default:
194                 return sprintf(buf, "unknown\n");
195         }
196 }
197
198 static ssize_t
199 trip_point_temp_show(struct device *dev, struct device_attribute *attr,
200                      char *buf)
201 {
202         struct thermal_zone_device *tz = to_thermal_zone(dev);
203         int trip, ret;
204         long temperature;
205
206         if (!tz->ops->get_trip_temp)
207                 return -EPERM;
208
209         if (!sscanf(attr->attr.name, "trip_point_%d_temp", &trip))
210                 return -EINVAL;
211
212         ret = tz->ops->get_trip_temp(tz, trip, &temperature);
213
214         if (ret)
215                 return ret;
216
217         return sprintf(buf, "%ld\n", temperature);
218 }
219
220 static ssize_t
221 passive_store(struct device *dev, struct device_attribute *attr,
222                     const char *buf, size_t count)
223 {
224         struct thermal_zone_device *tz = to_thermal_zone(dev);
225         struct thermal_cooling_device *cdev = NULL;
226         int state;
227
228         if (!sscanf(buf, "%d\n", &state))
229                 return -EINVAL;
230
231         /* sanity check: values below 1000 millicelcius don't make sense
232          * and can cause the system to go into a thermal heart attack
233          */
234         if (state && state < 1000)
235                 return -EINVAL;
236
237         if (state && !tz->forced_passive) {
238                 mutex_lock(&thermal_list_lock);
239                 list_for_each_entry(cdev, &thermal_cdev_list, node) {
240                         if (!strncmp("Processor", cdev->type,
241                                      sizeof("Processor")))
242                                 thermal_zone_bind_cooling_device(tz,
243                                                                  THERMAL_TRIPS_NONE,
244                                                                  cdev);
245                 }
246                 mutex_unlock(&thermal_list_lock);
247                 if (!tz->passive_delay)
248                         tz->passive_delay = 1000;
249         } else if (!state && tz->forced_passive) {
250                 mutex_lock(&thermal_list_lock);
251                 list_for_each_entry(cdev, &thermal_cdev_list, node) {
252                         if (!strncmp("Processor", cdev->type,
253                                      sizeof("Processor")))
254                                 thermal_zone_unbind_cooling_device(tz,
255                                                                    THERMAL_TRIPS_NONE,
256                                                                    cdev);
257                 }
258                 mutex_unlock(&thermal_list_lock);
259                 tz->passive_delay = 0;
260         }
261
262         tz->tc1 = 1;
263         tz->tc2 = 1;
264
265         tz->forced_passive = state;
266
267         thermal_zone_device_update(tz);
268
269         return count;
270 }
271
272 static ssize_t
273 passive_show(struct device *dev, struct device_attribute *attr,
274                    char *buf)
275 {
276         struct thermal_zone_device *tz = to_thermal_zone(dev);
277
278         return sprintf(buf, "%d\n", tz->forced_passive);
279 }
280
281 static DEVICE_ATTR(type, 0444, type_show, NULL);
282 static DEVICE_ATTR(temp, 0444, temp_show, NULL);
283 static DEVICE_ATTR(mode, 0644, mode_show, mode_store);
284 static DEVICE_ATTR(passive, S_IRUGO | S_IWUSR, passive_show, passive_store);
285
286 static struct device_attribute trip_point_attrs[] = {
287         __ATTR(trip_point_0_type, 0444, trip_point_type_show, NULL),
288         __ATTR(trip_point_0_temp, 0444, trip_point_temp_show, NULL),
289         __ATTR(trip_point_1_type, 0444, trip_point_type_show, NULL),
290         __ATTR(trip_point_1_temp, 0444, trip_point_temp_show, NULL),
291         __ATTR(trip_point_2_type, 0444, trip_point_type_show, NULL),
292         __ATTR(trip_point_2_temp, 0444, trip_point_temp_show, NULL),
293         __ATTR(trip_point_3_type, 0444, trip_point_type_show, NULL),
294         __ATTR(trip_point_3_temp, 0444, trip_point_temp_show, NULL),
295         __ATTR(trip_point_4_type, 0444, trip_point_type_show, NULL),
296         __ATTR(trip_point_4_temp, 0444, trip_point_temp_show, NULL),
297         __ATTR(trip_point_5_type, 0444, trip_point_type_show, NULL),
298         __ATTR(trip_point_5_temp, 0444, trip_point_temp_show, NULL),
299         __ATTR(trip_point_6_type, 0444, trip_point_type_show, NULL),
300         __ATTR(trip_point_6_temp, 0444, trip_point_temp_show, NULL),
301         __ATTR(trip_point_7_type, 0444, trip_point_type_show, NULL),
302         __ATTR(trip_point_7_temp, 0444, trip_point_temp_show, NULL),
303         __ATTR(trip_point_8_type, 0444, trip_point_type_show, NULL),
304         __ATTR(trip_point_8_temp, 0444, trip_point_temp_show, NULL),
305         __ATTR(trip_point_9_type, 0444, trip_point_type_show, NULL),
306         __ATTR(trip_point_9_temp, 0444, trip_point_temp_show, NULL),
307         __ATTR(trip_point_10_type, 0444, trip_point_type_show, NULL),
308         __ATTR(trip_point_10_temp, 0444, trip_point_temp_show, NULL),
309         __ATTR(trip_point_11_type, 0444, trip_point_type_show, NULL),
310         __ATTR(trip_point_11_temp, 0444, trip_point_temp_show, NULL),
311 };
312
313 /* sys I/F for cooling device */
314 #define to_cooling_device(_dev) \
315         container_of(_dev, struct thermal_cooling_device, device)
316
317 static ssize_t
318 thermal_cooling_device_type_show(struct device *dev,
319                                  struct device_attribute *attr, char *buf)
320 {
321         struct thermal_cooling_device *cdev = to_cooling_device(dev);
322
323         return sprintf(buf, "%s\n", cdev->type);
324 }
325
326 static ssize_t
327 thermal_cooling_device_max_state_show(struct device *dev,
328                                       struct device_attribute *attr, char *buf)
329 {
330         struct thermal_cooling_device *cdev = to_cooling_device(dev);
331         unsigned long state;
332         int ret;
333
334         ret = cdev->ops->get_max_state(cdev, &state);
335         if (ret)
336                 return ret;
337         return sprintf(buf, "%ld\n", state);
338 }
339
340 static ssize_t
341 thermal_cooling_device_cur_state_show(struct device *dev,
342                                       struct device_attribute *attr, char *buf)
343 {
344         struct thermal_cooling_device *cdev = to_cooling_device(dev);
345         unsigned long state;
346         int ret;
347
348         ret = cdev->ops->get_cur_state(cdev, &state);
349         if (ret)
350                 return ret;
351         return sprintf(buf, "%ld\n", state);
352 }
353
354 static ssize_t
355 thermal_cooling_device_cur_state_store(struct device *dev,
356                                        struct device_attribute *attr,
357                                        const char *buf, size_t count)
358 {
359         struct thermal_cooling_device *cdev = to_cooling_device(dev);
360         unsigned long state;
361         int result;
362
363         if (!sscanf(buf, "%ld\n", &state))
364                 return -EINVAL;
365
366         if ((long)state < 0)
367                 return -EINVAL;
368
369         result = cdev->ops->set_cur_state(cdev, state);
370         if (result)
371                 return result;
372         return count;
373 }
374
375 static struct device_attribute dev_attr_cdev_type =
376 __ATTR(type, 0444, thermal_cooling_device_type_show, NULL);
377 static DEVICE_ATTR(max_state, 0444,
378                    thermal_cooling_device_max_state_show, NULL);
379 static DEVICE_ATTR(cur_state, 0644,
380                    thermal_cooling_device_cur_state_show,
381                    thermal_cooling_device_cur_state_store);
382
383 static ssize_t
384 thermal_cooling_device_trip_point_show(struct device *dev,
385                                        struct device_attribute *attr, char *buf)
386 {
387         struct thermal_cooling_device_instance *instance;
388
389         instance =
390             container_of(attr, struct thermal_cooling_device_instance, attr);
391
392         if (instance->trip == THERMAL_TRIPS_NONE)
393                 return sprintf(buf, "-1\n");
394         else
395                 return sprintf(buf, "%d\n", instance->trip);
396 }
397
398 /* Device management */
399
400 #if defined(CONFIG_THERMAL_HWMON)
401
402 /* hwmon sys I/F */
403 #include <linux/hwmon.h>
404
405 /* thermal zone devices with the same type share one hwmon device */
406 struct thermal_hwmon_device {
407         char type[THERMAL_NAME_LENGTH];
408         struct device *device;
409         int count;
410         struct list_head tz_list;
411         struct list_head node;
412 };
413
414 struct thermal_hwmon_attr {
415         struct device_attribute attr;
416         char name[16];
417 };
418
419 /* one temperature input for each thermal zone */
420 struct thermal_hwmon_temp {
421         struct list_head hwmon_node;
422         struct thermal_zone_device *tz;
423         struct thermal_hwmon_attr temp_input;   /* hwmon sys attr */
424         struct thermal_hwmon_attr temp_crit;    /* hwmon sys attr */
425 };
426
427 static LIST_HEAD(thermal_hwmon_list);
428
429 static ssize_t
430 name_show(struct device *dev, struct device_attribute *attr, char *buf)
431 {
432         struct thermal_hwmon_device *hwmon = dev_get_drvdata(dev);
433         return sprintf(buf, "%s\n", hwmon->type);
434 }
435 static DEVICE_ATTR(name, 0444, name_show, NULL);
436
437 static ssize_t
438 temp_input_show(struct device *dev, struct device_attribute *attr, char *buf)
439 {
440         long temperature;
441         int ret;
442         struct thermal_hwmon_attr *hwmon_attr
443                         = container_of(attr, struct thermal_hwmon_attr, attr);
444         struct thermal_hwmon_temp *temp
445                         = container_of(hwmon_attr, struct thermal_hwmon_temp,
446                                        temp_input);
447         struct thermal_zone_device *tz = temp->tz;
448
449         ret = tz->ops->get_temp(tz, &temperature);
450
451         if (ret)
452                 return ret;
453
454         return sprintf(buf, "%ld\n", temperature);
455 }
456
457 static ssize_t
458 temp_crit_show(struct device *dev, struct device_attribute *attr,
459                 char *buf)
460 {
461         struct thermal_hwmon_attr *hwmon_attr
462                         = container_of(attr, struct thermal_hwmon_attr, attr);
463         struct thermal_hwmon_temp *temp
464                         = container_of(hwmon_attr, struct thermal_hwmon_temp,
465                                        temp_crit);
466         struct thermal_zone_device *tz = temp->tz;
467         long temperature;
468         int ret;
469
470         ret = tz->ops->get_trip_temp(tz, 0, &temperature);
471         if (ret)
472                 return ret;
473
474         return sprintf(buf, "%ld\n", temperature);
475 }
476
477
478 static struct thermal_hwmon_device *
479 thermal_hwmon_lookup_by_type(const struct thermal_zone_device *tz)
480 {
481         struct thermal_hwmon_device *hwmon;
482
483         mutex_lock(&thermal_list_lock);
484         list_for_each_entry(hwmon, &thermal_hwmon_list, node)
485                 if (!strcmp(hwmon->type, tz->type)) {
486                         mutex_unlock(&thermal_list_lock);
487                         return hwmon;
488                 }
489         mutex_unlock(&thermal_list_lock);
490
491         return NULL;
492 }
493
494 /* Find the temperature input matching a given thermal zone */
495 static struct thermal_hwmon_temp *
496 thermal_hwmon_lookup_temp(const struct thermal_hwmon_device *hwmon,
497                           const struct thermal_zone_device *tz)
498 {
499         struct thermal_hwmon_temp *temp;
500
501         mutex_lock(&thermal_list_lock);
502         list_for_each_entry(temp, &hwmon->tz_list, hwmon_node)
503                 if (temp->tz == tz) {
504                         mutex_unlock(&thermal_list_lock);
505                         return temp;
506                 }
507         mutex_unlock(&thermal_list_lock);
508
509         return NULL;
510 }
511
512 static int
513 thermal_add_hwmon_sysfs(struct thermal_zone_device *tz)
514 {
515         struct thermal_hwmon_device *hwmon;
516         struct thermal_hwmon_temp *temp;
517         int new_hwmon_device = 1;
518         int result;
519
520         hwmon = thermal_hwmon_lookup_by_type(tz);
521         if (hwmon) {
522                 new_hwmon_device = 0;
523                 goto register_sys_interface;
524         }
525
526         hwmon = kzalloc(sizeof(struct thermal_hwmon_device), GFP_KERNEL);
527         if (!hwmon)
528                 return -ENOMEM;
529
530         INIT_LIST_HEAD(&hwmon->tz_list);
531         strlcpy(hwmon->type, tz->type, THERMAL_NAME_LENGTH);
532         hwmon->device = hwmon_device_register(NULL);
533         if (IS_ERR(hwmon->device)) {
534                 result = PTR_ERR(hwmon->device);
535                 goto free_mem;
536         }
537         dev_set_drvdata(hwmon->device, hwmon);
538         result = device_create_file(hwmon->device, &dev_attr_name);
539         if (result)
540                 goto free_mem;
541
542  register_sys_interface:
543         temp = kzalloc(sizeof(struct thermal_hwmon_temp), GFP_KERNEL);
544         if (!temp) {
545                 result = -ENOMEM;
546                 goto unregister_name;
547         }
548
549         temp->tz = tz;
550         hwmon->count++;
551
552         snprintf(temp->temp_input.name, THERMAL_NAME_LENGTH,
553                  "temp%d_input", hwmon->count);
554         temp->temp_input.attr.attr.name = temp->temp_input.name;
555         temp->temp_input.attr.attr.mode = 0444;
556         temp->temp_input.attr.show = temp_input_show;
557         sysfs_attr_init(&temp->temp_input.attr.attr);
558         result = device_create_file(hwmon->device, &temp->temp_input.attr);
559         if (result)
560                 goto free_temp_mem;
561
562         if (tz->ops->get_crit_temp) {
563                 unsigned long temperature;
564                 if (!tz->ops->get_crit_temp(tz, &temperature)) {
565                         snprintf(temp->temp_crit.name, THERMAL_NAME_LENGTH,
566                                 "temp%d_crit", hwmon->count);
567                         temp->temp_crit.attr.attr.name = temp->temp_crit.name;
568                         temp->temp_crit.attr.attr.mode = 0444;
569                         temp->temp_crit.attr.show = temp_crit_show;
570                         sysfs_attr_init(&temp->temp_crit.attr.attr);
571                         result = device_create_file(hwmon->device,
572                                                     &temp->temp_crit.attr);
573                         if (result)
574                                 goto unregister_input;
575                 }
576         }
577
578         mutex_lock(&thermal_list_lock);
579         if (new_hwmon_device)
580                 list_add_tail(&hwmon->node, &thermal_hwmon_list);
581         list_add_tail(&temp->hwmon_node, &hwmon->tz_list);
582         mutex_unlock(&thermal_list_lock);
583
584         return 0;
585
586  unregister_input:
587         device_remove_file(hwmon->device, &temp->temp_input.attr);
588  free_temp_mem:
589         kfree(temp);
590  unregister_name:
591         if (new_hwmon_device) {
592                 device_remove_file(hwmon->device, &dev_attr_name);
593                 hwmon_device_unregister(hwmon->device);
594         }
595  free_mem:
596         if (new_hwmon_device)
597                 kfree(hwmon);
598
599         return result;
600 }
601
602 static void
603 thermal_remove_hwmon_sysfs(struct thermal_zone_device *tz)
604 {
605         struct thermal_hwmon_device *hwmon;
606         struct thermal_hwmon_temp *temp;
607
608         hwmon = thermal_hwmon_lookup_by_type(tz);
609         if (unlikely(!hwmon)) {
610                 /* Should never happen... */
611                 dev_dbg(&tz->device, "hwmon device lookup failed!\n");
612                 return;
613         }
614
615         temp = thermal_hwmon_lookup_temp(hwmon, tz);
616         if (unlikely(!temp)) {
617                 /* Should never happen... */
618                 dev_dbg(&tz->device, "temperature input lookup failed!\n");
619                 return;
620         }
621
622         device_remove_file(hwmon->device, &temp->temp_input.attr);
623         if (tz->ops->get_crit_temp)
624                 device_remove_file(hwmon->device, &temp->temp_crit.attr);
625
626         mutex_lock(&thermal_list_lock);
627         list_del(&temp->hwmon_node);
628         kfree(temp);
629         if (!list_empty(&hwmon->tz_list)) {
630                 mutex_unlock(&thermal_list_lock);
631                 return;
632         }
633         list_del(&hwmon->node);
634         mutex_unlock(&thermal_list_lock);
635
636         device_remove_file(hwmon->device, &dev_attr_name);
637         hwmon_device_unregister(hwmon->device);
638         kfree(hwmon);
639 }
640 #else
641 static int
642 thermal_add_hwmon_sysfs(struct thermal_zone_device *tz)
643 {
644         return 0;
645 }
646
647 static void
648 thermal_remove_hwmon_sysfs(struct thermal_zone_device *tz)
649 {
650 }
651 #endif
652
653 static void thermal_zone_device_set_polling(struct thermal_zone_device *tz,
654                                             int delay)
655 {
656         cancel_delayed_work(&(tz->poll_queue));
657
658         if (!delay)
659                 return;
660
661         if (delay > 1000)
662                 queue_delayed_work(system_freezable_wq, &(tz->poll_queue),
663                                       round_jiffies(msecs_to_jiffies(delay)));
664         else
665                 queue_delayed_work(system_freezable_wq, &(tz->poll_queue),
666                                       msecs_to_jiffies(delay));
667 }
668
669 static void thermal_zone_device_passive(struct thermal_zone_device *tz,
670                                         int temp, int trip_temp, int trip)
671 {
672         int trend = 0;
673         struct thermal_cooling_device_instance *instance;
674         struct thermal_cooling_device *cdev;
675         long state, max_state;
676
677         /*
678          * Above Trip?
679          * -----------
680          * Calculate the thermal trend (using the passive cooling equation)
681          * and modify the performance limit for all passive cooling devices
682          * accordingly.  Note that we assume symmetry.
683          */
684         if (temp >= trip_temp) {
685                 tz->passive = true;
686
687                 trend = (tz->tc1 * (temp - tz->last_temperature)) +
688                         (tz->tc2 * (temp - trip_temp));
689
690                 /* Heating up? */
691                 if (trend > 0) {
692                         list_for_each_entry(instance, &tz->cooling_devices,
693                                             node) {
694                                 if (instance->trip != trip)
695                                         continue;
696                                 cdev = instance->cdev;
697                                 cdev->ops->get_cur_state(cdev, &state);
698                                 cdev->ops->get_max_state(cdev, &max_state);
699                                 if (state++ < max_state)
700                                         cdev->ops->set_cur_state(cdev, state);
701                         }
702                 } else if (trend < 0) { /* Cooling off? */
703                         list_for_each_entry(instance, &tz->cooling_devices,
704                                             node) {
705                                 if (instance->trip != trip)
706                                         continue;
707                                 cdev = instance->cdev;
708                                 cdev->ops->get_cur_state(cdev, &state);
709                                 cdev->ops->get_max_state(cdev, &max_state);
710                                 if (state > 0)
711                                         cdev->ops->set_cur_state(cdev, --state);
712                         }
713                 }
714                 return;
715         }
716
717         /*
718          * Below Trip?
719          * -----------
720          * Implement passive cooling hysteresis to slowly increase performance
721          * and avoid thrashing around the passive trip point.  Note that we
722          * assume symmetry.
723          */
724         list_for_each_entry(instance, &tz->cooling_devices, node) {
725                 if (instance->trip != trip)
726                         continue;
727                 cdev = instance->cdev;
728                 cdev->ops->get_cur_state(cdev, &state);
729                 cdev->ops->get_max_state(cdev, &max_state);
730                 if (state > 0)
731                         cdev->ops->set_cur_state(cdev, --state);
732                 if (state == 0)
733                         tz->passive = false;
734         }
735 }
736
737 static void thermal_zone_device_check(struct work_struct *work)
738 {
739         struct thermal_zone_device *tz = container_of(work, struct
740                                                       thermal_zone_device,
741                                                       poll_queue.work);
742         thermal_zone_device_update(tz);
743 }
744
745 /**
746  * thermal_zone_bind_cooling_device - bind a cooling device to a thermal zone
747  * @tz:         thermal zone device
748  * @trip:       indicates which trip point the cooling devices is
749  *              associated with in this thermal zone.
750  * @cdev:       thermal cooling device
751  *
752  * This function is usually called in the thermal zone device .bind callback.
753  */
754 int thermal_zone_bind_cooling_device(struct thermal_zone_device *tz,
755                                      int trip,
756                                      struct thermal_cooling_device *cdev)
757 {
758         struct thermal_cooling_device_instance *dev;
759         struct thermal_cooling_device_instance *pos;
760         struct thermal_zone_device *pos1;
761         struct thermal_cooling_device *pos2;
762         int result;
763
764         if (trip >= tz->trips || (trip < 0 && trip != THERMAL_TRIPS_NONE))
765                 return -EINVAL;
766
767         list_for_each_entry(pos1, &thermal_tz_list, node) {
768                 if (pos1 == tz)
769                         break;
770         }
771         list_for_each_entry(pos2, &thermal_cdev_list, node) {
772                 if (pos2 == cdev)
773                         break;
774         }
775
776         if (tz != pos1 || cdev != pos2)
777                 return -EINVAL;
778
779         dev =
780             kzalloc(sizeof(struct thermal_cooling_device_instance), GFP_KERNEL);
781         if (!dev)
782                 return -ENOMEM;
783         dev->tz = tz;
784         dev->cdev = cdev;
785         dev->trip = trip;
786         result = get_idr(&tz->idr, &tz->lock, &dev->id);
787         if (result)
788                 goto free_mem;
789
790         sprintf(dev->name, "cdev%d", dev->id);
791         result =
792             sysfs_create_link(&tz->device.kobj, &cdev->device.kobj, dev->name);
793         if (result)
794                 goto release_idr;
795
796         sprintf(dev->attr_name, "cdev%d_trip_point", dev->id);
797         sysfs_attr_init(&dev->attr.attr);
798         dev->attr.attr.name = dev->attr_name;
799         dev->attr.attr.mode = 0444;
800         dev->attr.show = thermal_cooling_device_trip_point_show;
801         result = device_create_file(&tz->device, &dev->attr);
802         if (result)
803                 goto remove_symbol_link;
804
805         mutex_lock(&tz->lock);
806         list_for_each_entry(pos, &tz->cooling_devices, node)
807             if (pos->tz == tz && pos->trip == trip && pos->cdev == cdev) {
808                 result = -EEXIST;
809                 break;
810         }
811         if (!result)
812                 list_add_tail(&dev->node, &tz->cooling_devices);
813         mutex_unlock(&tz->lock);
814
815         if (!result)
816                 return 0;
817
818         device_remove_file(&tz->device, &dev->attr);
819 remove_symbol_link:
820         sysfs_remove_link(&tz->device.kobj, dev->name);
821 release_idr:
822         release_idr(&tz->idr, &tz->lock, dev->id);
823 free_mem:
824         kfree(dev);
825         return result;
826 }
827 EXPORT_SYMBOL(thermal_zone_bind_cooling_device);
828
829 /**
830  * thermal_zone_unbind_cooling_device - unbind a cooling device from a thermal zone
831  * @tz:         thermal zone device
832  * @trip:       indicates which trip point the cooling devices is
833  *              associated with in this thermal zone.
834  * @cdev:       thermal cooling device
835  *
836  * This function is usually called in the thermal zone device .unbind callback.
837  */
838 int thermal_zone_unbind_cooling_device(struct thermal_zone_device *tz,
839                                        int trip,
840                                        struct thermal_cooling_device *cdev)
841 {
842         struct thermal_cooling_device_instance *pos, *next;
843
844         mutex_lock(&tz->lock);
845         list_for_each_entry_safe(pos, next, &tz->cooling_devices, node) {
846                 if (pos->tz == tz && pos->trip == trip && pos->cdev == cdev) {
847                         list_del(&pos->node);
848                         mutex_unlock(&tz->lock);
849                         goto unbind;
850                 }
851         }
852         mutex_unlock(&tz->lock);
853
854         return -ENODEV;
855
856 unbind:
857         device_remove_file(&tz->device, &pos->attr);
858         sysfs_remove_link(&tz->device.kobj, pos->name);
859         release_idr(&tz->idr, &tz->lock, pos->id);
860         kfree(pos);
861         return 0;
862 }
863 EXPORT_SYMBOL(thermal_zone_unbind_cooling_device);
864
865 static void thermal_release(struct device *dev)
866 {
867         struct thermal_zone_device *tz;
868         struct thermal_cooling_device *cdev;
869
870         if (!strncmp(dev_name(dev), "thermal_zone",
871                      sizeof("thermal_zone") - 1)) {
872                 tz = to_thermal_zone(dev);
873                 kfree(tz);
874         } else {
875                 cdev = to_cooling_device(dev);
876                 kfree(cdev);
877         }
878 }
879
880 static struct class thermal_class = {
881         .name = "thermal",
882         .dev_release = thermal_release,
883 };
884
885 /**
886  * thermal_cooling_device_register - register a new thermal cooling device
887  * @type:       the thermal cooling device type.
888  * @devdata:    device private data.
889  * @ops:                standard thermal cooling devices callbacks.
890  */
891 struct thermal_cooling_device *
892 thermal_cooling_device_register(char *type, void *devdata,
893                                 const struct thermal_cooling_device_ops *ops)
894 {
895         struct thermal_cooling_device *cdev;
896         struct thermal_zone_device *pos;
897         int result;
898
899         if (strlen(type) >= THERMAL_NAME_LENGTH)
900                 return ERR_PTR(-EINVAL);
901
902         if (!ops || !ops->get_max_state || !ops->get_cur_state ||
903             !ops->set_cur_state)
904                 return ERR_PTR(-EINVAL);
905
906         cdev = kzalloc(sizeof(struct thermal_cooling_device), GFP_KERNEL);
907         if (!cdev)
908                 return ERR_PTR(-ENOMEM);
909
910         result = get_idr(&thermal_cdev_idr, &thermal_idr_lock, &cdev->id);
911         if (result) {
912                 kfree(cdev);
913                 return ERR_PTR(result);
914         }
915
916         strcpy(cdev->type, type);
917         cdev->ops = ops;
918         cdev->device.class = &thermal_class;
919         cdev->devdata = devdata;
920         dev_set_name(&cdev->device, "cooling_device%d", cdev->id);
921         result = device_register(&cdev->device);
922         if (result) {
923                 release_idr(&thermal_cdev_idr, &thermal_idr_lock, cdev->id);
924                 kfree(cdev);
925                 return ERR_PTR(result);
926         }
927
928         /* sys I/F */
929         if (type) {
930                 result = device_create_file(&cdev->device, &dev_attr_cdev_type);
931                 if (result)
932                         goto unregister;
933         }
934
935         result = device_create_file(&cdev->device, &dev_attr_max_state);
936         if (result)
937                 goto unregister;
938
939         result = device_create_file(&cdev->device, &dev_attr_cur_state);
940         if (result)
941                 goto unregister;
942
943         mutex_lock(&thermal_list_lock);
944         list_add(&cdev->node, &thermal_cdev_list);
945         list_for_each_entry(pos, &thermal_tz_list, node) {
946                 if (!pos->ops->bind)
947                         continue;
948                 result = pos->ops->bind(pos, cdev);
949                 if (result)
950                         break;
951
952         }
953         mutex_unlock(&thermal_list_lock);
954
955         if (!result)
956                 return cdev;
957
958 unregister:
959         release_idr(&thermal_cdev_idr, &thermal_idr_lock, cdev->id);
960         device_unregister(&cdev->device);
961         return ERR_PTR(result);
962 }
963 EXPORT_SYMBOL(thermal_cooling_device_register);
964
965 /**
966  * thermal_cooling_device_unregister - removes the registered thermal cooling device
967  * @cdev:       the thermal cooling device to remove.
968  *
969  * thermal_cooling_device_unregister() must be called when the device is no
970  * longer needed.
971  */
972 void thermal_cooling_device_unregister(struct
973                                        thermal_cooling_device
974                                        *cdev)
975 {
976         struct thermal_zone_device *tz;
977         struct thermal_cooling_device *pos = NULL;
978
979         if (!cdev)
980                 return;
981
982         mutex_lock(&thermal_list_lock);
983         list_for_each_entry(pos, &thermal_cdev_list, node)
984             if (pos == cdev)
985                 break;
986         if (pos != cdev) {
987                 /* thermal cooling device not found */
988                 mutex_unlock(&thermal_list_lock);
989                 return;
990         }
991         list_del(&cdev->node);
992         list_for_each_entry(tz, &thermal_tz_list, node) {
993                 if (!tz->ops->unbind)
994                         continue;
995                 tz->ops->unbind(tz, cdev);
996         }
997         mutex_unlock(&thermal_list_lock);
998         if (cdev->type[0])
999                 device_remove_file(&cdev->device, &dev_attr_cdev_type);
1000         device_remove_file(&cdev->device, &dev_attr_max_state);
1001         device_remove_file(&cdev->device, &dev_attr_cur_state);
1002
1003         release_idr(&thermal_cdev_idr, &thermal_idr_lock, cdev->id);
1004         device_unregister(&cdev->device);
1005         return;
1006 }
1007 EXPORT_SYMBOL(thermal_cooling_device_unregister);
1008
1009 /**
1010  * thermal_zone_device_update - force an update of a thermal zone's state
1011  * @ttz:        the thermal zone to update
1012  */
1013
1014 void thermal_zone_device_update(struct thermal_zone_device *tz)
1015 {
1016         int count, ret = 0;
1017         long temp, trip_temp;
1018         enum thermal_trip_type trip_type;
1019         struct thermal_cooling_device_instance *instance;
1020         struct thermal_cooling_device *cdev;
1021
1022         mutex_lock(&tz->lock);
1023
1024         if (tz->ops->get_temp(tz, &temp)) {
1025                 /* get_temp failed - retry it later */
1026                 pr_warn("failed to read out thermal zone %d\n", tz->id);
1027                 goto leave;
1028         }
1029
1030         for (count = 0; count < tz->trips; count++) {
1031                 tz->ops->get_trip_type(tz, count, &trip_type);
1032                 tz->ops->get_trip_temp(tz, count, &trip_temp);
1033
1034                 switch (trip_type) {
1035                 case THERMAL_TRIP_CRITICAL:
1036                         if (temp >= trip_temp) {
1037                                 if (tz->ops->notify)
1038                                         ret = tz->ops->notify(tz, count,
1039                                                               trip_type);
1040                                 if (!ret) {
1041                                         pr_emerg("Critical temperature reached (%ld C), shutting down\n",
1042                                                  temp/1000);
1043                                         orderly_poweroff(true);
1044                                 }
1045                         }
1046                         break;
1047                 case THERMAL_TRIP_HOT:
1048                         if (temp >= trip_temp)
1049                                 if (tz->ops->notify)
1050                                         tz->ops->notify(tz, count, trip_type);
1051                         break;
1052                 case THERMAL_TRIP_ACTIVE:
1053                         list_for_each_entry(instance, &tz->cooling_devices,
1054                                             node) {
1055                                 if (instance->trip != count)
1056                                         continue;
1057
1058                                 cdev = instance->cdev;
1059
1060                                 if (temp >= trip_temp)
1061                                         cdev->ops->set_cur_state(cdev, 1);
1062                                 else
1063                                         cdev->ops->set_cur_state(cdev, 0);
1064                         }
1065                         break;
1066                 case THERMAL_TRIP_PASSIVE:
1067                         if (temp >= trip_temp || tz->passive)
1068                                 thermal_zone_device_passive(tz, temp,
1069                                                             trip_temp, count);
1070                         break;
1071                 }
1072         }
1073
1074         if (tz->forced_passive)
1075                 thermal_zone_device_passive(tz, temp, tz->forced_passive,
1076                                             THERMAL_TRIPS_NONE);
1077
1078         tz->last_temperature = temp;
1079
1080 leave:
1081         if (tz->passive)
1082                 thermal_zone_device_set_polling(tz, tz->passive_delay);
1083         else if (tz->polling_delay)
1084                 thermal_zone_device_set_polling(tz, tz->polling_delay);
1085         else
1086                 thermal_zone_device_set_polling(tz, 0);
1087         mutex_unlock(&tz->lock);
1088 }
1089 EXPORT_SYMBOL(thermal_zone_device_update);
1090
1091 /**
1092  * thermal_zone_device_register - register a new thermal zone device
1093  * @type:       the thermal zone device type
1094  * @trips:      the number of trip points the thermal zone support
1095  * @devdata:    private device data
1096  * @ops:        standard thermal zone device callbacks
1097  * @tc1:        thermal coefficient 1 for passive calculations
1098  * @tc2:        thermal coefficient 2 for passive calculations
1099  * @passive_delay: number of milliseconds to wait between polls when
1100  *                 performing passive cooling
1101  * @polling_delay: number of milliseconds to wait between polls when checking
1102  *                 whether trip points have been crossed (0 for interrupt
1103  *                 driven systems)
1104  *
1105  * thermal_zone_device_unregister() must be called when the device is no
1106  * longer needed. The passive cooling formula uses tc1 and tc2 as described in
1107  * section 11.1.5.1 of the ACPI specification 3.0.
1108  */
1109 struct thermal_zone_device *thermal_zone_device_register(char *type,
1110         int trips, void *devdata,
1111         const struct thermal_zone_device_ops *ops,
1112         int tc1, int tc2, int passive_delay, int polling_delay)
1113 {
1114         struct thermal_zone_device *tz;
1115         struct thermal_cooling_device *pos;
1116         enum thermal_trip_type trip_type;
1117         int result;
1118         int count;
1119         int passive = 0;
1120
1121         if (strlen(type) >= THERMAL_NAME_LENGTH)
1122                 return ERR_PTR(-EINVAL);
1123
1124         if (trips > THERMAL_MAX_TRIPS || trips < 0)
1125                 return ERR_PTR(-EINVAL);
1126
1127         if (!ops || !ops->get_temp)
1128                 return ERR_PTR(-EINVAL);
1129
1130         tz = kzalloc(sizeof(struct thermal_zone_device), GFP_KERNEL);
1131         if (!tz)
1132                 return ERR_PTR(-ENOMEM);
1133
1134         INIT_LIST_HEAD(&tz->cooling_devices);
1135         idr_init(&tz->idr);
1136         mutex_init(&tz->lock);
1137         result = get_idr(&thermal_tz_idr, &thermal_idr_lock, &tz->id);
1138         if (result) {
1139                 kfree(tz);
1140                 return ERR_PTR(result);
1141         }
1142
1143         strcpy(tz->type, type);
1144         tz->ops = ops;
1145         tz->device.class = &thermal_class;
1146         tz->devdata = devdata;
1147         tz->trips = trips;
1148         tz->tc1 = tc1;
1149         tz->tc2 = tc2;
1150         tz->passive_delay = passive_delay;
1151         tz->polling_delay = polling_delay;
1152
1153         dev_set_name(&tz->device, "thermal_zone%d", tz->id);
1154         result = device_register(&tz->device);
1155         if (result) {
1156                 release_idr(&thermal_tz_idr, &thermal_idr_lock, tz->id);
1157                 kfree(tz);
1158                 return ERR_PTR(result);
1159         }
1160
1161         /* sys I/F */
1162         if (type) {
1163                 result = device_create_file(&tz->device, &dev_attr_type);
1164                 if (result)
1165                         goto unregister;
1166         }
1167
1168         result = device_create_file(&tz->device, &dev_attr_temp);
1169         if (result)
1170                 goto unregister;
1171
1172         if (ops->get_mode) {
1173                 result = device_create_file(&tz->device, &dev_attr_mode);
1174                 if (result)
1175                         goto unregister;
1176         }
1177
1178         for (count = 0; count < trips; count++) {
1179                 result = device_create_file(&tz->device,
1180                                             &trip_point_attrs[count * 2]);
1181                 if (result)
1182                         break;
1183                 result = device_create_file(&tz->device,
1184                                             &trip_point_attrs[count * 2 + 1]);
1185                 if (result)
1186                         goto unregister;
1187                 tz->ops->get_trip_type(tz, count, &trip_type);
1188                 if (trip_type == THERMAL_TRIP_PASSIVE)
1189                         passive = 1;
1190         }
1191
1192         if (!passive)
1193                 result = device_create_file(&tz->device,
1194                                             &dev_attr_passive);
1195
1196         if (result)
1197                 goto unregister;
1198
1199         result = thermal_add_hwmon_sysfs(tz);
1200         if (result)
1201                 goto unregister;
1202
1203         mutex_lock(&thermal_list_lock);
1204         list_add_tail(&tz->node, &thermal_tz_list);
1205         if (ops->bind)
1206                 list_for_each_entry(pos, &thermal_cdev_list, node) {
1207                 result = ops->bind(tz, pos);
1208                 if (result)
1209                         break;
1210                 }
1211         mutex_unlock(&thermal_list_lock);
1212
1213         INIT_DELAYED_WORK(&(tz->poll_queue), thermal_zone_device_check);
1214
1215         thermal_zone_device_update(tz);
1216
1217         if (!result)
1218                 return tz;
1219
1220 unregister:
1221         release_idr(&thermal_tz_idr, &thermal_idr_lock, tz->id);
1222         device_unregister(&tz->device);
1223         return ERR_PTR(result);
1224 }
1225 EXPORT_SYMBOL(thermal_zone_device_register);
1226
1227 /**
1228  * thermal_device_unregister - removes the registered thermal zone device
1229  * @tz: the thermal zone device to remove
1230  */
1231 void thermal_zone_device_unregister(struct thermal_zone_device *tz)
1232 {
1233         struct thermal_cooling_device *cdev;
1234         struct thermal_zone_device *pos = NULL;
1235         int count;
1236
1237         if (!tz)
1238                 return;
1239
1240         mutex_lock(&thermal_list_lock);
1241         list_for_each_entry(pos, &thermal_tz_list, node)
1242             if (pos == tz)
1243                 break;
1244         if (pos != tz) {
1245                 /* thermal zone device not found */
1246                 mutex_unlock(&thermal_list_lock);
1247                 return;
1248         }
1249         list_del(&tz->node);
1250         if (tz->ops->unbind)
1251                 list_for_each_entry(cdev, &thermal_cdev_list, node)
1252                     tz->ops->unbind(tz, cdev);
1253         mutex_unlock(&thermal_list_lock);
1254
1255         thermal_zone_device_set_polling(tz, 0);
1256
1257         if (tz->type[0])
1258                 device_remove_file(&tz->device, &dev_attr_type);
1259         device_remove_file(&tz->device, &dev_attr_temp);
1260         if (tz->ops->get_mode)
1261                 device_remove_file(&tz->device, &dev_attr_mode);
1262
1263         for (count = 0; count < tz->trips; count++) {
1264                 device_remove_file(&tz->device,
1265                                    &trip_point_attrs[count * 2]);
1266                 device_remove_file(&tz->device,
1267                                    &trip_point_attrs[count * 2 + 1]);
1268         }
1269         thermal_remove_hwmon_sysfs(tz);
1270         release_idr(&thermal_tz_idr, &thermal_idr_lock, tz->id);
1271         idr_destroy(&tz->idr);
1272         mutex_destroy(&tz->lock);
1273         device_unregister(&tz->device);
1274         return;
1275 }
1276 EXPORT_SYMBOL(thermal_zone_device_unregister);
1277
1278 #ifdef CONFIG_NET
1279 static struct genl_family thermal_event_genl_family = {
1280         .id = GENL_ID_GENERATE,
1281         .name = THERMAL_GENL_FAMILY_NAME,
1282         .version = THERMAL_GENL_VERSION,
1283         .maxattr = THERMAL_GENL_ATTR_MAX,
1284 };
1285
1286 static struct genl_multicast_group thermal_event_mcgrp = {
1287         .name = THERMAL_GENL_MCAST_GROUP_NAME,
1288 };
1289
1290 int thermal_generate_netlink_event(u32 orig, enum events event)
1291 {
1292         struct sk_buff *skb;
1293         struct nlattr *attr;
1294         struct thermal_genl_event *thermal_event;
1295         void *msg_header;
1296         int size;
1297         int result;
1298         static unsigned int thermal_event_seqnum;
1299
1300         /* allocate memory */
1301         size = nla_total_size(sizeof(struct thermal_genl_event)) +
1302                nla_total_size(0);
1303
1304         skb = genlmsg_new(size, GFP_ATOMIC);
1305         if (!skb)
1306                 return -ENOMEM;
1307
1308         /* add the genetlink message header */
1309         msg_header = genlmsg_put(skb, 0, thermal_event_seqnum++,
1310                                  &thermal_event_genl_family, 0,
1311                                  THERMAL_GENL_CMD_EVENT);
1312         if (!msg_header) {
1313                 nlmsg_free(skb);
1314                 return -ENOMEM;
1315         }
1316
1317         /* fill the data */
1318         attr = nla_reserve(skb, THERMAL_GENL_ATTR_EVENT,
1319                            sizeof(struct thermal_genl_event));
1320
1321         if (!attr) {
1322                 nlmsg_free(skb);
1323                 return -EINVAL;
1324         }
1325
1326         thermal_event = nla_data(attr);
1327         if (!thermal_event) {
1328                 nlmsg_free(skb);
1329                 return -EINVAL;
1330         }
1331
1332         memset(thermal_event, 0, sizeof(struct thermal_genl_event));
1333
1334         thermal_event->orig = orig;
1335         thermal_event->event = event;
1336
1337         /* send multicast genetlink message */
1338         result = genlmsg_end(skb, msg_header);
1339         if (result < 0) {
1340                 nlmsg_free(skb);
1341                 return result;
1342         }
1343
1344         result = genlmsg_multicast(skb, 0, thermal_event_mcgrp.id, GFP_ATOMIC);
1345         if (result)
1346                 pr_info("failed to send netlink event:%d\n", result);
1347
1348         return result;
1349 }
1350 EXPORT_SYMBOL(thermal_generate_netlink_event);
1351
1352 static int genetlink_init(void)
1353 {
1354         int result;
1355
1356         result = genl_register_family(&thermal_event_genl_family);
1357         if (result)
1358                 return result;
1359
1360         result = genl_register_mc_group(&thermal_event_genl_family,
1361                                         &thermal_event_mcgrp);
1362         if (result)
1363                 genl_unregister_family(&thermal_event_genl_family);
1364         return result;
1365 }
1366
1367 static void genetlink_exit(void)
1368 {
1369         genl_unregister_family(&thermal_event_genl_family);
1370 }
1371 #else /* !CONFIG_NET */
1372 static inline int genetlink_init(void) { return 0; }
1373 static inline void genetlink_exit(void) {}
1374 #endif /* !CONFIG_NET */
1375
1376 static int __init thermal_init(void)
1377 {
1378         int result = 0;
1379
1380         result = class_register(&thermal_class);
1381         if (result) {
1382                 idr_destroy(&thermal_tz_idr);
1383                 idr_destroy(&thermal_cdev_idr);
1384                 mutex_destroy(&thermal_idr_lock);
1385                 mutex_destroy(&thermal_list_lock);
1386         }
1387         result = genetlink_init();
1388         return result;
1389 }
1390
1391 static void __exit thermal_exit(void)
1392 {
1393         class_unregister(&thermal_class);
1394         idr_destroy(&thermal_tz_idr);
1395         idr_destroy(&thermal_cdev_idr);
1396         mutex_destroy(&thermal_idr_lock);
1397         mutex_destroy(&thermal_list_lock);
1398         genetlink_exit();
1399 }
1400
1401 fs_initcall(thermal_init);
1402 module_exit(thermal_exit);