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