linux/drivers/hwmon/dell-smm-hwmon.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0-or-later
   2/*
   3 * dell-smm-hwmon.c -- Linux driver for accessing the SMM BIOS on Dell laptops.
   4 *
   5 * Copyright (C) 2001  Massimo Dal Zotto <dz@debian.org>
   6 *
   7 * Hwmon integration:
   8 * Copyright (C) 2011  Jean Delvare <jdelvare@suse.de>
   9 * Copyright (C) 2013, 2014  Guenter Roeck <linux@roeck-us.net>
  10 * Copyright (C) 2014, 2015  Pali Rohár <pali@kernel.org>
  11 */
  12
  13#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
  14
  15#include <linux/capability.h>
  16#include <linux/cpu.h>
  17#include <linux/ctype.h>
  18#include <linux/delay.h>
  19#include <linux/dmi.h>
  20#include <linux/err.h>
  21#include <linux/errno.h>
  22#include <linux/hwmon.h>
  23#include <linux/init.h>
  24#include <linux/module.h>
  25#include <linux/mutex.h>
  26#include <linux/platform_device.h>
  27#include <linux/proc_fs.h>
  28#include <linux/seq_file.h>
  29#include <linux/string.h>
  30#include <linux/smp.h>
  31#include <linux/types.h>
  32#include <linux/uaccess.h>
  33
  34#include <linux/i8k.h>
  35
  36#define I8K_SMM_FN_STATUS       0x0025
  37#define I8K_SMM_POWER_STATUS    0x0069
  38#define I8K_SMM_SET_FAN         0x01a3
  39#define I8K_SMM_GET_FAN         0x00a3
  40#define I8K_SMM_GET_SPEED       0x02a3
  41#define I8K_SMM_GET_FAN_TYPE    0x03a3
  42#define I8K_SMM_GET_NOM_SPEED   0x04a3
  43#define I8K_SMM_GET_TEMP        0x10a3
  44#define I8K_SMM_GET_TEMP_TYPE   0x11a3
  45#define I8K_SMM_GET_DELL_SIG1   0xfea3
  46#define I8K_SMM_GET_DELL_SIG2   0xffa3
  47
  48#define I8K_FAN_MULT            30
  49#define I8K_FAN_MAX_RPM         30000
  50#define I8K_MAX_TEMP            127
  51
  52#define I8K_FN_NONE             0x00
  53#define I8K_FN_UP               0x01
  54#define I8K_FN_DOWN             0x02
  55#define I8K_FN_MUTE             0x04
  56#define I8K_FN_MASK             0x07
  57#define I8K_FN_SHIFT            8
  58
  59#define I8K_POWER_AC            0x05
  60#define I8K_POWER_BATTERY       0x01
  61
  62#define DELL_SMM_NO_TEMP        10
  63#define DELL_SMM_NO_FANS        3
  64
  65struct dell_smm_data {
  66        struct mutex i8k_mutex; /* lock for sensors writes */
  67        char bios_version[4];
  68        char bios_machineid[16];
  69        uint i8k_fan_mult;
  70        uint i8k_pwm_mult;
  71        uint i8k_fan_max;
  72        bool disallow_fan_type_call;
  73        bool disallow_fan_support;
  74        unsigned int manual_fan;
  75        unsigned int auto_fan;
  76        int temp_type[DELL_SMM_NO_TEMP];
  77        bool fan[DELL_SMM_NO_FANS];
  78        int fan_type[DELL_SMM_NO_FANS];
  79        int *fan_nominal_speed[DELL_SMM_NO_FANS];
  80};
  81
  82MODULE_AUTHOR("Massimo Dal Zotto (dz@debian.org)");
  83MODULE_AUTHOR("Pali Rohár <pali@kernel.org>");
  84MODULE_DESCRIPTION("Dell laptop SMM BIOS hwmon driver");
  85MODULE_LICENSE("GPL");
  86MODULE_ALIAS("i8k");
  87
  88static bool force;
  89module_param(force, bool, 0);
  90MODULE_PARM_DESC(force, "Force loading without checking for supported models");
  91
  92static bool ignore_dmi;
  93module_param(ignore_dmi, bool, 0);
  94MODULE_PARM_DESC(ignore_dmi, "Continue probing hardware even if DMI data does not match");
  95
  96#if IS_ENABLED(CONFIG_I8K)
  97static bool restricted = true;
  98module_param(restricted, bool, 0);
  99MODULE_PARM_DESC(restricted, "Restrict fan control and serial number to CAP_SYS_ADMIN (default: 1)");
 100
 101static bool power_status;
 102module_param(power_status, bool, 0600);
 103MODULE_PARM_DESC(power_status, "Report power status in /proc/i8k (default: 0)");
 104#endif
 105
 106static uint fan_mult;
 107module_param(fan_mult, uint, 0);
 108MODULE_PARM_DESC(fan_mult, "Factor to multiply fan speed with (default: autodetect)");
 109
 110static uint fan_max;
 111module_param(fan_max, uint, 0);
 112MODULE_PARM_DESC(fan_max, "Maximum configurable fan speed (default: autodetect)");
 113
 114struct smm_regs {
 115        unsigned int eax;
 116        unsigned int ebx __packed;
 117        unsigned int ecx __packed;
 118        unsigned int edx __packed;
 119        unsigned int esi __packed;
 120        unsigned int edi __packed;
 121};
 122
 123static const char * const temp_labels[] = {
 124        "CPU",
 125        "GPU",
 126        "SODIMM",
 127        "Other",
 128        "Ambient",
 129        "Other",
 130};
 131
 132static const char * const fan_labels[] = {
 133        "Processor Fan",
 134        "Motherboard Fan",
 135        "Video Fan",
 136        "Power Supply Fan",
 137        "Chipset Fan",
 138        "Other Fan",
 139};
 140
 141static const char * const docking_labels[] = {
 142        "Docking Processor Fan",
 143        "Docking Motherboard Fan",
 144        "Docking Video Fan",
 145        "Docking Power Supply Fan",
 146        "Docking Chipset Fan",
 147        "Docking Other Fan",
 148};
 149
 150static inline const char __init *i8k_get_dmi_data(int field)
 151{
 152        const char *dmi_data = dmi_get_system_info(field);
 153
 154        return dmi_data && *dmi_data ? dmi_data : "?";
 155}
 156
 157/*
 158 * Call the System Management Mode BIOS. Code provided by Jonathan Buzzard.
 159 */
 160static int i8k_smm_func(void *par)
 161{
 162        ktime_t calltime = ktime_get();
 163        struct smm_regs *regs = par;
 164        int eax = regs->eax;
 165        int ebx = regs->ebx;
 166        long long duration;
 167        int rc;
 168
 169        /* SMM requires CPU 0 */
 170        if (smp_processor_id() != 0)
 171                return -EBUSY;
 172
 173#if defined(CONFIG_X86_64)
 174        asm volatile("pushq %%rax\n\t"
 175                "movl 0(%%rax),%%edx\n\t"
 176                "pushq %%rdx\n\t"
 177                "movl 4(%%rax),%%ebx\n\t"
 178                "movl 8(%%rax),%%ecx\n\t"
 179                "movl 12(%%rax),%%edx\n\t"
 180                "movl 16(%%rax),%%esi\n\t"
 181                "movl 20(%%rax),%%edi\n\t"
 182                "popq %%rax\n\t"
 183                "out %%al,$0xb2\n\t"
 184                "out %%al,$0x84\n\t"
 185                "xchgq %%rax,(%%rsp)\n\t"
 186                "movl %%ebx,4(%%rax)\n\t"
 187                "movl %%ecx,8(%%rax)\n\t"
 188                "movl %%edx,12(%%rax)\n\t"
 189                "movl %%esi,16(%%rax)\n\t"
 190                "movl %%edi,20(%%rax)\n\t"
 191                "popq %%rdx\n\t"
 192                "movl %%edx,0(%%rax)\n\t"
 193                "pushfq\n\t"
 194                "popq %%rax\n\t"
 195                "andl $1,%%eax\n"
 196                : "=a"(rc)
 197                :    "a"(regs)
 198                :    "%ebx", "%ecx", "%edx", "%esi", "%edi", "memory");
 199#else
 200        asm volatile("pushl %%eax\n\t"
 201            "movl 0(%%eax),%%edx\n\t"
 202            "push %%edx\n\t"
 203            "movl 4(%%eax),%%ebx\n\t"
 204            "movl 8(%%eax),%%ecx\n\t"
 205            "movl 12(%%eax),%%edx\n\t"
 206            "movl 16(%%eax),%%esi\n\t"
 207            "movl 20(%%eax),%%edi\n\t"
 208            "popl %%eax\n\t"
 209            "out %%al,$0xb2\n\t"
 210            "out %%al,$0x84\n\t"
 211            "xchgl %%eax,(%%esp)\n\t"
 212            "movl %%ebx,4(%%eax)\n\t"
 213            "movl %%ecx,8(%%eax)\n\t"
 214            "movl %%edx,12(%%eax)\n\t"
 215            "movl %%esi,16(%%eax)\n\t"
 216            "movl %%edi,20(%%eax)\n\t"
 217            "popl %%edx\n\t"
 218            "movl %%edx,0(%%eax)\n\t"
 219            "lahf\n\t"
 220            "shrl $8,%%eax\n\t"
 221            "andl $1,%%eax\n"
 222            : "=a"(rc)
 223            :    "a"(regs)
 224            :    "%ebx", "%ecx", "%edx", "%esi", "%edi", "memory");
 225#endif
 226        if (rc != 0 || (regs->eax & 0xffff) == 0xffff || regs->eax == eax)
 227                rc = -EINVAL;
 228
 229        duration = ktime_us_delta(ktime_get(), calltime);
 230        pr_debug("smm(0x%.4x 0x%.4x) = 0x%.4x  (took %7lld usecs)\n", eax, ebx,
 231                 (rc ? 0xffff : regs->eax & 0xffff), duration);
 232
 233        return rc;
 234}
 235
 236/*
 237 * Call the System Management Mode BIOS.
 238 */
 239static int i8k_smm(struct smm_regs *regs)
 240{
 241        int ret;
 242
 243        cpus_read_lock();
 244        ret = smp_call_on_cpu(0, i8k_smm_func, regs, true);
 245        cpus_read_unlock();
 246
 247        return ret;
 248}
 249
 250/*
 251 * Read the fan status.
 252 */
 253static int i8k_get_fan_status(const struct dell_smm_data *data, int fan)
 254{
 255        struct smm_regs regs = { .eax = I8K_SMM_GET_FAN, };
 256
 257        if (data->disallow_fan_support)
 258                return -EINVAL;
 259
 260        regs.ebx = fan & 0xff;
 261        return i8k_smm(&regs) ? : regs.eax & 0xff;
 262}
 263
 264/*
 265 * Read the fan speed in RPM.
 266 */
 267static int i8k_get_fan_speed(const struct dell_smm_data *data, int fan)
 268{
 269        struct smm_regs regs = { .eax = I8K_SMM_GET_SPEED, };
 270
 271        if (data->disallow_fan_support)
 272                return -EINVAL;
 273
 274        regs.ebx = fan & 0xff;
 275        return i8k_smm(&regs) ? : (regs.eax & 0xffff) * data->i8k_fan_mult;
 276}
 277
 278/*
 279 * Read the fan type.
 280 */
 281static int _i8k_get_fan_type(const struct dell_smm_data *data, int fan)
 282{
 283        struct smm_regs regs = { .eax = I8K_SMM_GET_FAN_TYPE, };
 284
 285        if (data->disallow_fan_support || data->disallow_fan_type_call)
 286                return -EINVAL;
 287
 288        regs.ebx = fan & 0xff;
 289        return i8k_smm(&regs) ? : regs.eax & 0xff;
 290}
 291
 292static int i8k_get_fan_type(struct dell_smm_data *data, int fan)
 293{
 294        /* I8K_SMM_GET_FAN_TYPE SMM call is expensive, so cache values */
 295        if (data->fan_type[fan] == INT_MIN)
 296                data->fan_type[fan] = _i8k_get_fan_type(data, fan);
 297
 298        return data->fan_type[fan];
 299}
 300
 301/*
 302 * Read the fan nominal rpm for specific fan speed.
 303 */
 304static int __init i8k_get_fan_nominal_speed(const struct dell_smm_data *data, int fan, int speed)
 305{
 306        struct smm_regs regs = { .eax = I8K_SMM_GET_NOM_SPEED, };
 307
 308        if (data->disallow_fan_support)
 309                return -EINVAL;
 310
 311        regs.ebx = (fan & 0xff) | (speed << 8);
 312        return i8k_smm(&regs) ? : (regs.eax & 0xffff) * data->i8k_fan_mult;
 313}
 314
 315/*
 316 * Enable or disable automatic BIOS fan control support
 317 */
 318static int i8k_enable_fan_auto_mode(const struct dell_smm_data *data, bool enable)
 319{
 320        struct smm_regs regs = { };
 321
 322        if (data->disallow_fan_support)
 323                return -EINVAL;
 324
 325        regs.eax = enable ? data->auto_fan : data->manual_fan;
 326        return i8k_smm(&regs);
 327}
 328
 329/*
 330 * Set the fan speed (off, low, high, ...).
 331 */
 332static int i8k_set_fan(const struct dell_smm_data *data, int fan, int speed)
 333{
 334        struct smm_regs regs = { .eax = I8K_SMM_SET_FAN, };
 335
 336        if (data->disallow_fan_support)
 337                return -EINVAL;
 338
 339        speed = (speed < 0) ? 0 : ((speed > data->i8k_fan_max) ? data->i8k_fan_max : speed);
 340        regs.ebx = (fan & 0xff) | (speed << 8);
 341
 342        return i8k_smm(&regs);
 343}
 344
 345static int __init i8k_get_temp_type(int sensor)
 346{
 347        struct smm_regs regs = { .eax = I8K_SMM_GET_TEMP_TYPE, };
 348
 349        regs.ebx = sensor & 0xff;
 350        return i8k_smm(&regs) ? : regs.eax & 0xff;
 351}
 352
 353/*
 354 * Read the cpu temperature.
 355 */
 356static int _i8k_get_temp(int sensor)
 357{
 358        struct smm_regs regs = {
 359                .eax = I8K_SMM_GET_TEMP,
 360                .ebx = sensor & 0xff,
 361        };
 362
 363        return i8k_smm(&regs) ? : regs.eax & 0xff;
 364}
 365
 366static int i8k_get_temp(int sensor)
 367{
 368        int temp = _i8k_get_temp(sensor);
 369
 370        /*
 371         * Sometimes the temperature sensor returns 0x99, which is out of range.
 372         * In this case we retry (once) before returning an error.
 373         # 1003655137 00000058 00005a4b
 374         # 1003655138 00000099 00003a80 <--- 0x99 = 153 degrees
 375         # 1003655139 00000054 00005c52
 376         */
 377        if (temp == 0x99) {
 378                msleep(100);
 379                temp = _i8k_get_temp(sensor);
 380        }
 381        /*
 382         * Return -ENODATA for all invalid temperatures.
 383         *
 384         * Known instances are the 0x99 value as seen above as well as
 385         * 0xc1 (193), which may be returned when trying to read the GPU
 386         * temperature if the system supports a GPU and it is currently
 387         * turned off.
 388         */
 389        if (temp > I8K_MAX_TEMP)
 390                return -ENODATA;
 391
 392        return temp;
 393}
 394
 395static int __init i8k_get_dell_signature(int req_fn)
 396{
 397        struct smm_regs regs = { .eax = req_fn, };
 398        int rc;
 399
 400        rc = i8k_smm(&regs);
 401        if (rc < 0)
 402                return rc;
 403
 404        return regs.eax == 1145651527 && regs.edx == 1145392204 ? 0 : -1;
 405}
 406
 407#if IS_ENABLED(CONFIG_I8K)
 408
 409/*
 410 * Read the Fn key status.
 411 */
 412static int i8k_get_fn_status(void)
 413{
 414        struct smm_regs regs = { .eax = I8K_SMM_FN_STATUS, };
 415        int rc;
 416
 417        rc = i8k_smm(&regs);
 418        if (rc < 0)
 419                return rc;
 420
 421        switch ((regs.eax >> I8K_FN_SHIFT) & I8K_FN_MASK) {
 422        case I8K_FN_UP:
 423                return I8K_VOL_UP;
 424        case I8K_FN_DOWN:
 425                return I8K_VOL_DOWN;
 426        case I8K_FN_MUTE:
 427                return I8K_VOL_MUTE;
 428        default:
 429                return 0;
 430        }
 431}
 432
 433/*
 434 * Read the power status.
 435 */
 436static int i8k_get_power_status(void)
 437{
 438        struct smm_regs regs = { .eax = I8K_SMM_POWER_STATUS, };
 439        int rc;
 440
 441        rc = i8k_smm(&regs);
 442        if (rc < 0)
 443                return rc;
 444
 445        return (regs.eax & 0xff) == I8K_POWER_AC ? I8K_AC : I8K_BATTERY;
 446}
 447
 448/*
 449 * Procfs interface
 450 */
 451
 452static int
 453i8k_ioctl_unlocked(struct file *fp, struct dell_smm_data *data, unsigned int cmd, unsigned long arg)
 454{
 455        int val = 0;
 456        int speed, err;
 457        unsigned char buff[16];
 458        int __user *argp = (int __user *)arg;
 459
 460        if (!argp)
 461                return -EINVAL;
 462
 463        switch (cmd) {
 464        case I8K_BIOS_VERSION:
 465                if (!isdigit(data->bios_version[0]) || !isdigit(data->bios_version[1]) ||
 466                    !isdigit(data->bios_version[2]))
 467                        return -EINVAL;
 468
 469                val = (data->bios_version[0] << 16) |
 470                                (data->bios_version[1] << 8) | data->bios_version[2];
 471                break;
 472
 473        case I8K_MACHINE_ID:
 474                if (restricted && !capable(CAP_SYS_ADMIN))
 475                        return -EPERM;
 476
 477                strscpy_pad(buff, data->bios_machineid, sizeof(buff));
 478                break;
 479
 480        case I8K_FN_STATUS:
 481                val = i8k_get_fn_status();
 482                break;
 483
 484        case I8K_POWER_STATUS:
 485                val = i8k_get_power_status();
 486                break;
 487
 488        case I8K_GET_TEMP:
 489                val = i8k_get_temp(0);
 490                break;
 491
 492        case I8K_GET_SPEED:
 493                if (copy_from_user(&val, argp, sizeof(int)))
 494                        return -EFAULT;
 495
 496                val = i8k_get_fan_speed(data, val);
 497                break;
 498
 499        case I8K_GET_FAN:
 500                if (copy_from_user(&val, argp, sizeof(int)))
 501                        return -EFAULT;
 502
 503                val = i8k_get_fan_status(data, val);
 504                break;
 505
 506        case I8K_SET_FAN:
 507                if (restricted && !capable(CAP_SYS_ADMIN))
 508                        return -EPERM;
 509
 510                if (copy_from_user(&val, argp, sizeof(int)))
 511                        return -EFAULT;
 512
 513                if (copy_from_user(&speed, argp + 1, sizeof(int)))
 514                        return -EFAULT;
 515
 516                err = i8k_set_fan(data, val, speed);
 517                if (err < 0)
 518                        return err;
 519
 520                val = i8k_get_fan_status(data, val);
 521                break;
 522
 523        default:
 524                return -ENOIOCTLCMD;
 525        }
 526
 527        if (val < 0)
 528                return val;
 529
 530        switch (cmd) {
 531        case I8K_BIOS_VERSION:
 532                if (copy_to_user(argp, &val, 4))
 533                        return -EFAULT;
 534
 535                break;
 536        case I8K_MACHINE_ID:
 537                if (copy_to_user(argp, buff, 16))
 538                        return -EFAULT;
 539
 540                break;
 541        default:
 542                if (copy_to_user(argp, &val, sizeof(int)))
 543                        return -EFAULT;
 544
 545                break;
 546        }
 547
 548        return 0;
 549}
 550
 551static long i8k_ioctl(struct file *fp, unsigned int cmd, unsigned long arg)
 552{
 553        struct dell_smm_data *data = PDE_DATA(file_inode(fp));
 554        long ret;
 555
 556        mutex_lock(&data->i8k_mutex);
 557        ret = i8k_ioctl_unlocked(fp, data, cmd, arg);
 558        mutex_unlock(&data->i8k_mutex);
 559
 560        return ret;
 561}
 562
 563/*
 564 * Print the information for /proc/i8k.
 565 */
 566static int i8k_proc_show(struct seq_file *seq, void *offset)
 567{
 568        struct dell_smm_data *data = seq->private;
 569        int fn_key, cpu_temp, ac_power;
 570        int left_fan, right_fan, left_speed, right_speed;
 571
 572        cpu_temp        = i8k_get_temp(0);                              /* 11100 µs */
 573        left_fan        = i8k_get_fan_status(data, I8K_FAN_LEFT);       /*   580 µs */
 574        right_fan       = i8k_get_fan_status(data, I8K_FAN_RIGHT);      /*   580 µs */
 575        left_speed      = i8k_get_fan_speed(data, I8K_FAN_LEFT);        /*   580 µs */
 576        right_speed     = i8k_get_fan_speed(data, I8K_FAN_RIGHT);       /*   580 µs */
 577        fn_key          = i8k_get_fn_status();                          /*   750 µs */
 578        if (power_status)
 579                ac_power = i8k_get_power_status();                      /* 14700 µs */
 580        else
 581                ac_power = -1;
 582
 583        /*
 584         * Info:
 585         *
 586         * 1)  Format version (this will change if format changes)
 587         * 2)  BIOS version
 588         * 3)  BIOS machine ID
 589         * 4)  Cpu temperature
 590         * 5)  Left fan status
 591         * 6)  Right fan status
 592         * 7)  Left fan speed
 593         * 8)  Right fan speed
 594         * 9)  AC power
 595         * 10) Fn Key status
 596         */
 597        seq_printf(seq, "%s %s %s %d %d %d %d %d %d %d\n",
 598                   I8K_PROC_FMT,
 599                   data->bios_version,
 600                   (restricted && !capable(CAP_SYS_ADMIN)) ? "-1" : data->bios_machineid,
 601                   cpu_temp,
 602                   left_fan, right_fan, left_speed, right_speed,
 603                   ac_power, fn_key);
 604
 605        return 0;
 606}
 607
 608static int i8k_open_fs(struct inode *inode, struct file *file)
 609{
 610        return single_open(file, i8k_proc_show, PDE_DATA(inode));
 611}
 612
 613static const struct proc_ops i8k_proc_ops = {
 614        .proc_open      = i8k_open_fs,
 615        .proc_read      = seq_read,
 616        .proc_lseek     = seq_lseek,
 617        .proc_release   = single_release,
 618        .proc_ioctl     = i8k_ioctl,
 619};
 620
 621static void i8k_exit_procfs(void *param)
 622{
 623        remove_proc_entry("i8k", NULL);
 624}
 625
 626static void __init i8k_init_procfs(struct device *dev)
 627{
 628        struct dell_smm_data *data = dev_get_drvdata(dev);
 629
 630        /* Only register exit function if creation was successful */
 631        if (proc_create_data("i8k", 0, NULL, &i8k_proc_ops, data))
 632                devm_add_action_or_reset(dev, i8k_exit_procfs, NULL);
 633}
 634
 635#else
 636
 637static void __init i8k_init_procfs(struct device *dev)
 638{
 639}
 640
 641#endif
 642
 643/*
 644 * Hwmon interface
 645 */
 646
 647static umode_t dell_smm_is_visible(const void *drvdata, enum hwmon_sensor_types type, u32 attr,
 648                                   int channel)
 649{
 650        const struct dell_smm_data *data = drvdata;
 651
 652        switch (type) {
 653        case hwmon_temp:
 654                switch (attr) {
 655                case hwmon_temp_input:
 656                case hwmon_temp_label:
 657                        if (data->temp_type[channel] >= 0)
 658                                return 0444;
 659
 660                        break;
 661                default:
 662                        break;
 663                }
 664                break;
 665        case hwmon_fan:
 666                if (data->disallow_fan_support)
 667                        break;
 668
 669                switch (attr) {
 670                case hwmon_fan_input:
 671                        if (data->fan[channel])
 672                                return 0444;
 673
 674                        break;
 675                case hwmon_fan_label:
 676                        if (data->fan[channel] && !data->disallow_fan_type_call)
 677                                return 0444;
 678
 679                        break;
 680                case hwmon_fan_min:
 681                case hwmon_fan_max:
 682                case hwmon_fan_target:
 683                        if (data->fan_nominal_speed[channel])
 684                                return 0444;
 685
 686                        break;
 687                default:
 688                        break;
 689                }
 690                break;
 691        case hwmon_pwm:
 692                if (data->disallow_fan_support)
 693                        break;
 694
 695                switch (attr) {
 696                case hwmon_pwm_input:
 697                        if (data->fan[channel])
 698                                return 0644;
 699
 700                        break;
 701                case hwmon_pwm_enable:
 702                        if (data->auto_fan)
 703                                /*
 704                                 * There is no command for retrieve the current status
 705                                 * from BIOS, and userspace/firmware itself can change
 706                                 * it.
 707                                 * Thus we can only provide write-only access for now.
 708                                 */
 709                                return 0200;
 710
 711                        break;
 712                default:
 713                        break;
 714                }
 715                break;
 716        default:
 717                break;
 718        }
 719
 720        return 0;
 721}
 722
 723static int dell_smm_read(struct device *dev, enum hwmon_sensor_types type, u32 attr, int channel,
 724                         long *val)
 725{
 726        struct dell_smm_data *data = dev_get_drvdata(dev);
 727        int ret;
 728
 729        switch (type) {
 730        case hwmon_temp:
 731                switch (attr) {
 732                case hwmon_temp_input:
 733                        ret = i8k_get_temp(channel);
 734                        if (ret < 0)
 735                                return ret;
 736
 737                        *val = ret * 1000;
 738
 739                        return 0;
 740                default:
 741                        break;
 742                }
 743                break;
 744        case hwmon_fan:
 745                switch (attr) {
 746                case hwmon_fan_input:
 747                        ret = i8k_get_fan_speed(data, channel);
 748                        if (ret < 0)
 749                                return ret;
 750
 751                        *val = ret;
 752
 753                        return 0;
 754                case hwmon_fan_min:
 755                        *val = data->fan_nominal_speed[channel][0];
 756
 757                        return 0;
 758                case hwmon_fan_max:
 759                        *val = data->fan_nominal_speed[channel][data->i8k_fan_max];
 760
 761                        return 0;
 762                case hwmon_fan_target:
 763                        ret = i8k_get_fan_status(data, channel);
 764                        if (ret < 0)
 765                                return ret;
 766
 767                        if (ret > data->i8k_fan_max)
 768                                ret = data->i8k_fan_max;
 769
 770                        *val = data->fan_nominal_speed[channel][ret];
 771
 772                        return 0;
 773                default:
 774                        break;
 775                }
 776                break;
 777        case hwmon_pwm:
 778                switch (attr) {
 779                case hwmon_pwm_input:
 780                        ret = i8k_get_fan_status(data, channel);
 781                        if (ret < 0)
 782                                return ret;
 783
 784                        *val = clamp_val(ret * data->i8k_pwm_mult, 0, 255);
 785
 786                        return 0;
 787                default:
 788                        break;
 789                }
 790                break;
 791        default:
 792                break;
 793        }
 794
 795        return -EOPNOTSUPP;
 796}
 797
 798static const char *dell_smm_fan_label(struct dell_smm_data *data, int channel)
 799{
 800        bool dock = false;
 801        int type = i8k_get_fan_type(data, channel);
 802
 803        if (type < 0)
 804                return ERR_PTR(type);
 805
 806        if (type & 0x10) {
 807                dock = true;
 808                type &= 0x0F;
 809        }
 810
 811        if (type >= ARRAY_SIZE(fan_labels))
 812                type = ARRAY_SIZE(fan_labels) - 1;
 813
 814        return dock ? docking_labels[type] : fan_labels[type];
 815}
 816
 817static int dell_smm_read_string(struct device *dev, enum hwmon_sensor_types type, u32 attr,
 818                                int channel, const char **str)
 819{
 820        struct dell_smm_data *data = dev_get_drvdata(dev);
 821
 822        switch (type) {
 823        case hwmon_temp:
 824                switch (attr) {
 825                case hwmon_temp_label:
 826                        *str = temp_labels[data->temp_type[channel]];
 827                        return 0;
 828                default:
 829                        break;
 830                }
 831                break;
 832        case hwmon_fan:
 833                switch (attr) {
 834                case hwmon_fan_label:
 835                        *str = dell_smm_fan_label(data, channel);
 836                        return PTR_ERR_OR_ZERO(*str);
 837                default:
 838                        break;
 839                }
 840                break;
 841        default:
 842                break;
 843        }
 844
 845        return -EOPNOTSUPP;
 846}
 847
 848static int dell_smm_write(struct device *dev, enum hwmon_sensor_types type, u32 attr, int channel,
 849                          long val)
 850{
 851        struct dell_smm_data *data = dev_get_drvdata(dev);
 852        unsigned long pwm;
 853        bool enable;
 854        int err;
 855
 856        switch (type) {
 857        case hwmon_pwm:
 858                switch (attr) {
 859                case hwmon_pwm_input:
 860                        pwm = clamp_val(DIV_ROUND_CLOSEST(val, data->i8k_pwm_mult), 0,
 861                                        data->i8k_fan_max);
 862
 863                        mutex_lock(&data->i8k_mutex);
 864                        err = i8k_set_fan(data, channel, pwm);
 865                        mutex_unlock(&data->i8k_mutex);
 866
 867                        if (err < 0)
 868                                return err;
 869
 870                        return 0;
 871                case hwmon_pwm_enable:
 872                        if (!val)
 873                                return -EINVAL;
 874
 875                        if (val == 1)
 876                                enable = false;
 877                        else
 878                                enable = true;
 879
 880                        mutex_lock(&data->i8k_mutex);
 881                        err = i8k_enable_fan_auto_mode(data, enable);
 882                        mutex_unlock(&data->i8k_mutex);
 883
 884                        if (err < 0)
 885                                return err;
 886
 887                        return 0;
 888                default:
 889                        break;
 890                }
 891                break;
 892        default:
 893                break;
 894        }
 895
 896        return -EOPNOTSUPP;
 897}
 898
 899static const struct hwmon_ops dell_smm_ops = {
 900        .is_visible = dell_smm_is_visible,
 901        .read = dell_smm_read,
 902        .read_string = dell_smm_read_string,
 903        .write = dell_smm_write,
 904};
 905
 906static const struct hwmon_channel_info *dell_smm_info[] = {
 907        HWMON_CHANNEL_INFO(chip, HWMON_C_REGISTER_TZ),
 908        HWMON_CHANNEL_INFO(temp,
 909                           HWMON_T_INPUT | HWMON_T_LABEL,
 910                           HWMON_T_INPUT | HWMON_T_LABEL,
 911                           HWMON_T_INPUT | HWMON_T_LABEL,
 912                           HWMON_T_INPUT | HWMON_T_LABEL,
 913                           HWMON_T_INPUT | HWMON_T_LABEL,
 914                           HWMON_T_INPUT | HWMON_T_LABEL,
 915                           HWMON_T_INPUT | HWMON_T_LABEL,
 916                           HWMON_T_INPUT | HWMON_T_LABEL,
 917                           HWMON_T_INPUT | HWMON_T_LABEL,
 918                           HWMON_T_INPUT | HWMON_T_LABEL
 919                           ),
 920        HWMON_CHANNEL_INFO(fan,
 921                           HWMON_F_INPUT | HWMON_F_LABEL | HWMON_F_MIN | HWMON_F_MAX |
 922                           HWMON_F_TARGET,
 923                           HWMON_F_INPUT | HWMON_F_LABEL | HWMON_F_MIN | HWMON_F_MAX |
 924                           HWMON_F_TARGET,
 925                           HWMON_F_INPUT | HWMON_F_LABEL | HWMON_F_MIN | HWMON_F_MAX |
 926                           HWMON_F_TARGET
 927                           ),
 928        HWMON_CHANNEL_INFO(pwm,
 929                           HWMON_PWM_INPUT | HWMON_PWM_ENABLE,
 930                           HWMON_PWM_INPUT,
 931                           HWMON_PWM_INPUT
 932                           ),
 933        NULL
 934};
 935
 936static const struct hwmon_chip_info dell_smm_chip_info = {
 937        .ops = &dell_smm_ops,
 938        .info = dell_smm_info,
 939};
 940
 941static int __init dell_smm_init_hwmon(struct device *dev)
 942{
 943        struct dell_smm_data *data = dev_get_drvdata(dev);
 944        struct device *dell_smm_hwmon_dev;
 945        int i, state, err;
 946
 947        for (i = 0; i < DELL_SMM_NO_TEMP; i++) {
 948                data->temp_type[i] = i8k_get_temp_type(i);
 949                if (data->temp_type[i] < 0)
 950                        continue;
 951
 952                if (data->temp_type[i] >= ARRAY_SIZE(temp_labels))
 953                        data->temp_type[i] = ARRAY_SIZE(temp_labels) - 1;
 954        }
 955
 956        for (i = 0; i < DELL_SMM_NO_FANS; i++) {
 957                data->fan_type[i] = INT_MIN;
 958                err = i8k_get_fan_status(data, i);
 959                if (err < 0)
 960                        err = i8k_get_fan_type(data, i);
 961
 962                if (err < 0)
 963                        continue;
 964
 965                data->fan[i] = true;
 966                data->fan_nominal_speed[i] = devm_kmalloc_array(dev, data->i8k_fan_max + 1,
 967                                                                sizeof(*data->fan_nominal_speed[i]),
 968                                                                GFP_KERNEL);
 969                if (!data->fan_nominal_speed[i])
 970                        continue;
 971
 972                for (state = 0; state <= data->i8k_fan_max; state++) {
 973                        err = i8k_get_fan_nominal_speed(data, i, state);
 974                        if (err < 0) {
 975                                /* Mark nominal speed table as invalid in case of error */
 976                                devm_kfree(dev, data->fan_nominal_speed[i]);
 977                                data->fan_nominal_speed[i] = NULL;
 978                                break;
 979                        }
 980                        data->fan_nominal_speed[i][state] = err;
 981                }
 982        }
 983
 984        dell_smm_hwmon_dev = devm_hwmon_device_register_with_info(dev, "dell_smm", data,
 985                                                                  &dell_smm_chip_info, NULL);
 986
 987        return PTR_ERR_OR_ZERO(dell_smm_hwmon_dev);
 988}
 989
 990struct i8k_config_data {
 991        uint fan_mult;
 992        uint fan_max;
 993};
 994
 995enum i8k_configs {
 996        DELL_LATITUDE_D520,
 997        DELL_PRECISION_490,
 998        DELL_STUDIO,
 999        DELL_XPS,
1000};
1001
1002/*
1003 * Only use for machines which need some special configuration
1004 * in order to work correctly (e.g. if autoconfig fails on this machines).
1005 */
1006
1007static const struct i8k_config_data i8k_config_data[] __initconst = {
1008        [DELL_LATITUDE_D520] = {
1009                .fan_mult = 1,
1010                .fan_max = I8K_FAN_TURBO,
1011        },
1012        [DELL_PRECISION_490] = {
1013                .fan_mult = 1,
1014                .fan_max = I8K_FAN_TURBO,
1015        },
1016        [DELL_STUDIO] = {
1017                .fan_mult = 1,
1018                .fan_max = I8K_FAN_HIGH,
1019        },
1020        [DELL_XPS] = {
1021                .fan_mult = 1,
1022                .fan_max = I8K_FAN_HIGH,
1023        },
1024};
1025
1026static const struct dmi_system_id i8k_dmi_table[] __initconst = {
1027        {
1028                .ident = "Dell Inspiron",
1029                .matches = {
1030                        DMI_MATCH(DMI_SYS_VENDOR, "Dell Computer"),
1031                        DMI_MATCH(DMI_PRODUCT_NAME, "Inspiron"),
1032                },
1033        },
1034        {
1035                .ident = "Dell Latitude",
1036                .matches = {
1037                        DMI_MATCH(DMI_SYS_VENDOR, "Dell Computer"),
1038                        DMI_MATCH(DMI_PRODUCT_NAME, "Latitude"),
1039                },
1040        },
1041        {
1042                .ident = "Dell Inspiron 2",
1043                .matches = {
1044                        DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
1045                        DMI_MATCH(DMI_PRODUCT_NAME, "Inspiron"),
1046                },
1047        },
1048        {
1049                .ident = "Dell Latitude D520",
1050                .matches = {
1051                        DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
1052                        DMI_MATCH(DMI_PRODUCT_NAME, "Latitude D520"),
1053                },
1054                .driver_data = (void *)&i8k_config_data[DELL_LATITUDE_D520],
1055        },
1056        {
1057                .ident = "Dell Latitude 2",
1058                .matches = {
1059                        DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
1060                        DMI_MATCH(DMI_PRODUCT_NAME, "Latitude"),
1061                },
1062        },
1063        {       /* UK Inspiron 6400  */
1064                .ident = "Dell Inspiron 3",
1065                .matches = {
1066                        DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
1067                        DMI_MATCH(DMI_PRODUCT_NAME, "MM061"),
1068                },
1069        },
1070        {
1071                .ident = "Dell Inspiron 3",
1072                .matches = {
1073                        DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
1074                        DMI_MATCH(DMI_PRODUCT_NAME, "MP061"),
1075                },
1076        },
1077        {
1078                .ident = "Dell Precision 490",
1079                .matches = {
1080                        DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
1081                        DMI_MATCH(DMI_PRODUCT_NAME,
1082                                  "Precision WorkStation 490"),
1083                },
1084                .driver_data = (void *)&i8k_config_data[DELL_PRECISION_490],
1085        },
1086        {
1087                .ident = "Dell Precision",
1088                .matches = {
1089                        DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
1090                        DMI_MATCH(DMI_PRODUCT_NAME, "Precision"),
1091                },
1092        },
1093        {
1094                .ident = "Dell Vostro",
1095                .matches = {
1096                        DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
1097                        DMI_MATCH(DMI_PRODUCT_NAME, "Vostro"),
1098                },
1099        },
1100        {
1101                .ident = "Dell Studio",
1102                .matches = {
1103                        DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
1104                        DMI_MATCH(DMI_PRODUCT_NAME, "Studio"),
1105                },
1106                .driver_data = (void *)&i8k_config_data[DELL_STUDIO],
1107        },
1108        {
1109                .ident = "Dell XPS M140",
1110                .matches = {
1111                        DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
1112                        DMI_MATCH(DMI_PRODUCT_NAME, "MXC051"),
1113                },
1114                .driver_data = (void *)&i8k_config_data[DELL_XPS],
1115        },
1116        {
1117                .ident = "Dell XPS",
1118                .matches = {
1119                        DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
1120                        DMI_MATCH(DMI_PRODUCT_NAME, "XPS"),
1121                },
1122        },
1123        { }
1124};
1125
1126MODULE_DEVICE_TABLE(dmi, i8k_dmi_table);
1127
1128/*
1129 * On some machines once I8K_SMM_GET_FAN_TYPE is issued then CPU fan speed
1130 * randomly going up and down due to bug in Dell SMM or BIOS. Here is blacklist
1131 * of affected Dell machines for which we disallow I8K_SMM_GET_FAN_TYPE call.
1132 * See bug: https://bugzilla.kernel.org/show_bug.cgi?id=100121
1133 */
1134static const struct dmi_system_id i8k_blacklist_fan_type_dmi_table[] __initconst = {
1135        {
1136                .ident = "Dell Studio XPS 8000",
1137                .matches = {
1138                        DMI_EXACT_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
1139                        DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "Studio XPS 8000"),
1140                },
1141        },
1142        {
1143                .ident = "Dell Studio XPS 8100",
1144                .matches = {
1145                        DMI_EXACT_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
1146                        DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "Studio XPS 8100"),
1147                },
1148        },
1149        {
1150                .ident = "Dell Inspiron 580",
1151                .matches = {
1152                        DMI_EXACT_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
1153                        DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "Inspiron 580 "),
1154                },
1155        },
1156        { }
1157};
1158
1159/*
1160 * On some machines all fan related SMM functions implemented by Dell BIOS
1161 * firmware freeze kernel for about 500ms. Until Dell fixes these problems fan
1162 * support for affected blacklisted Dell machines stay disabled.
1163 * See bug: https://bugzilla.kernel.org/show_bug.cgi?id=195751
1164 */
1165static const struct dmi_system_id i8k_blacklist_fan_support_dmi_table[] __initconst = {
1166        {
1167                .ident = "Dell Inspiron 7720",
1168                .matches = {
1169                        DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
1170                        DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "Inspiron 7720"),
1171                },
1172        },
1173        {
1174                .ident = "Dell Vostro 3360",
1175                .matches = {
1176                        DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
1177                        DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "Vostro 3360"),
1178                },
1179        },
1180        {
1181                .ident = "Dell XPS13 9333",
1182                .matches = {
1183                        DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
1184                        DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "XPS13 9333"),
1185                },
1186        },
1187        {
1188                .ident = "Dell XPS 15 L502X",
1189                .matches = {
1190                        DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
1191                        DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "Dell System XPS L502X"),
1192                },
1193        },
1194        { }
1195};
1196
1197struct i8k_fan_control_data {
1198        unsigned int manual_fan;
1199        unsigned int auto_fan;
1200};
1201
1202enum i8k_fan_controls {
1203        I8K_FAN_34A3_35A3,
1204};
1205
1206static const struct i8k_fan_control_data i8k_fan_control_data[] __initconst = {
1207        [I8K_FAN_34A3_35A3] = {
1208                .manual_fan = 0x34a3,
1209                .auto_fan = 0x35a3,
1210        },
1211};
1212
1213static const struct dmi_system_id i8k_whitelist_fan_control[] __initconst = {
1214        {
1215                .ident = "Dell Latitude 5480",
1216                .matches = {
1217                        DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
1218                        DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "Latitude 5480"),
1219                },
1220                .driver_data = (void *)&i8k_fan_control_data[I8K_FAN_34A3_35A3],
1221        },
1222        {
1223                .ident = "Dell Latitude E6440",
1224                .matches = {
1225                        DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
1226                        DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "Latitude E6440"),
1227                },
1228                .driver_data = (void *)&i8k_fan_control_data[I8K_FAN_34A3_35A3],
1229        },
1230        {
1231                .ident = "Dell Latitude E7440",
1232                .matches = {
1233                        DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
1234                        DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "Latitude E7440"),
1235                },
1236                .driver_data = (void *)&i8k_fan_control_data[I8K_FAN_34A3_35A3],
1237        },
1238        {
1239                .ident = "Dell Precision 5530",
1240                .matches = {
1241                        DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
1242                        DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "Precision 5530"),
1243                },
1244                .driver_data = (void *)&i8k_fan_control_data[I8K_FAN_34A3_35A3],
1245        },
1246        {
1247                .ident = "Dell Precision 7510",
1248                .matches = {
1249                        DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
1250                        DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "Precision 7510"),
1251                },
1252                .driver_data = (void *)&i8k_fan_control_data[I8K_FAN_34A3_35A3],
1253        },
1254        { }
1255};
1256
1257static int __init dell_smm_probe(struct platform_device *pdev)
1258{
1259        struct dell_smm_data *data;
1260        const struct dmi_system_id *id, *fan_control;
1261        int fan, ret;
1262
1263        data = devm_kzalloc(&pdev->dev, sizeof(struct dell_smm_data), GFP_KERNEL);
1264        if (!data)
1265                return -ENOMEM;
1266
1267        mutex_init(&data->i8k_mutex);
1268        data->i8k_fan_mult = I8K_FAN_MULT;
1269        data->i8k_fan_max = I8K_FAN_HIGH;
1270        platform_set_drvdata(pdev, data);
1271
1272        if (dmi_check_system(i8k_blacklist_fan_support_dmi_table)) {
1273                dev_warn(&pdev->dev, "broken Dell BIOS detected, disallow fan support\n");
1274                if (!force)
1275                        data->disallow_fan_support = true;
1276        }
1277
1278        if (dmi_check_system(i8k_blacklist_fan_type_dmi_table)) {
1279                dev_warn(&pdev->dev, "broken Dell BIOS detected, disallow fan type call\n");
1280                if (!force)
1281                        data->disallow_fan_type_call = true;
1282        }
1283
1284        strscpy(data->bios_version, i8k_get_dmi_data(DMI_BIOS_VERSION),
1285                sizeof(data->bios_version));
1286        strscpy(data->bios_machineid, i8k_get_dmi_data(DMI_PRODUCT_SERIAL),
1287                sizeof(data->bios_machineid));
1288
1289        /*
1290         * Set fan multiplier and maximal fan speed from dmi config
1291         * Values specified in module parameters override values from dmi
1292         */
1293        id = dmi_first_match(i8k_dmi_table);
1294        if (id && id->driver_data) {
1295                const struct i8k_config_data *conf = id->driver_data;
1296
1297                if (!fan_mult && conf->fan_mult)
1298                        fan_mult = conf->fan_mult;
1299
1300                if (!fan_max && conf->fan_max)
1301                        fan_max = conf->fan_max;
1302        }
1303
1304        data->i8k_fan_max = fan_max ? : I8K_FAN_HIGH;   /* Must not be 0 */
1305        data->i8k_pwm_mult = DIV_ROUND_UP(255, data->i8k_fan_max);
1306
1307        fan_control = dmi_first_match(i8k_whitelist_fan_control);
1308        if (fan_control && fan_control->driver_data) {
1309                const struct i8k_fan_control_data *control = fan_control->driver_data;
1310
1311                data->manual_fan = control->manual_fan;
1312                data->auto_fan = control->auto_fan;
1313                dev_info(&pdev->dev, "enabling support for setting automatic/manual fan control\n");
1314        }
1315
1316        if (!fan_mult) {
1317                /*
1318                 * Autodetect fan multiplier based on nominal rpm
1319                 * If fan reports rpm value too high then set multiplier to 1
1320                 */
1321                for (fan = 0; fan < DELL_SMM_NO_FANS; ++fan) {
1322                        ret = i8k_get_fan_nominal_speed(data, fan, data->i8k_fan_max);
1323                        if (ret < 0)
1324                                continue;
1325
1326                        if (ret > I8K_FAN_MAX_RPM)
1327                                data->i8k_fan_mult = 1;
1328                        break;
1329                }
1330        } else {
1331                /* Fan multiplier was specified in module param or in dmi */
1332                data->i8k_fan_mult = fan_mult;
1333        }
1334
1335        ret = dell_smm_init_hwmon(&pdev->dev);
1336        if (ret)
1337                return ret;
1338
1339        i8k_init_procfs(&pdev->dev);
1340
1341        return 0;
1342}
1343
1344static struct platform_driver dell_smm_driver = {
1345        .driver         = {
1346                .name   = KBUILD_MODNAME,
1347        },
1348};
1349
1350static struct platform_device *dell_smm_device;
1351
1352/*
1353 * Probe for the presence of a supported laptop.
1354 */
1355static int __init i8k_init(void)
1356{
1357        /*
1358         * Get DMI information
1359         */
1360        if (!dmi_check_system(i8k_dmi_table)) {
1361                if (!ignore_dmi && !force)
1362                        return -ENODEV;
1363
1364                pr_info("not running on a supported Dell system.\n");
1365                pr_info("vendor=%s, model=%s, version=%s\n",
1366                        i8k_get_dmi_data(DMI_SYS_VENDOR),
1367                        i8k_get_dmi_data(DMI_PRODUCT_NAME),
1368                        i8k_get_dmi_data(DMI_BIOS_VERSION));
1369        }
1370
1371        /*
1372         * Get SMM Dell signature
1373         */
1374        if (i8k_get_dell_signature(I8K_SMM_GET_DELL_SIG1) &&
1375            i8k_get_dell_signature(I8K_SMM_GET_DELL_SIG2)) {
1376                pr_err("unable to get SMM Dell signature\n");
1377                if (!force)
1378                        return -ENODEV;
1379        }
1380
1381        dell_smm_device = platform_create_bundle(&dell_smm_driver, dell_smm_probe, NULL, 0, NULL,
1382                                                 0);
1383
1384        return PTR_ERR_OR_ZERO(dell_smm_device);
1385}
1386
1387static void __exit i8k_exit(void)
1388{
1389        platform_device_unregister(dell_smm_device);
1390        platform_driver_unregister(&dell_smm_driver);
1391}
1392
1393module_init(i8k_init);
1394module_exit(i8k_exit);
1395