1752 lines · c
1// SPDX-License-Identifier: GPL-2.0-or-later2/*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 ": " fmt14 15#include <linux/acpi.h>16#include <linux/capability.h>17#include <linux/cpu.h>18#include <linux/ctype.h>19#include <linux/delay.h>20#include <linux/dmi.h>21#include <linux/err.h>22#include <linux/errno.h>23#include <linux/hwmon.h>24#include <linux/init.h>25#include <linux/kconfig.h>26#include <linux/kernel.h>27#include <linux/module.h>28#include <linux/mutex.h>29#include <linux/platform_device.h>30#include <linux/proc_fs.h>31#include <linux/seq_file.h>32#include <linux/slab.h>33#include <linux/smp.h>34#include <linux/string.h>35#include <linux/thermal.h>36#include <linux/types.h>37#include <linux/uaccess.h>38#include <linux/wmi.h>39 40#include <linux/i8k.h>41#include <linux/unaligned.h>42 43#define I8K_SMM_FN_STATUS 0x002544#define I8K_SMM_POWER_STATUS 0x006945#define I8K_SMM_SET_FAN 0x01a346#define I8K_SMM_GET_FAN 0x00a347#define I8K_SMM_GET_SPEED 0x02a348#define I8K_SMM_GET_FAN_TYPE 0x03a349#define I8K_SMM_GET_NOM_SPEED 0x04a350#define I8K_SMM_GET_TEMP 0x10a351#define I8K_SMM_GET_TEMP_TYPE 0x11a352#define I8K_SMM_GET_DELL_SIG1 0xfea353#define I8K_SMM_GET_DELL_SIG2 0xffa354 55/* in usecs */56#define DELL_SMM_MAX_DURATION 25000057 58#define I8K_FAN_MULT 3059#define I8K_FAN_RPM_THRESHOLD 100060#define I8K_MAX_TEMP 12761 62#define I8K_FN_NONE 0x0063#define I8K_FN_UP 0x0164#define I8K_FN_DOWN 0x0265#define I8K_FN_MUTE 0x0466#define I8K_FN_MASK 0x0767#define I8K_FN_SHIFT 868 69#define I8K_POWER_AC 0x0570#define I8K_POWER_BATTERY 0x0171 72#define DELL_SMM_WMI_GUID "F1DDEE52-063C-4784-A11E-8A06684B9B01"73#define DELL_SMM_LEGACY_EXECUTE 0x174 75#define DELL_SMM_NO_TEMP 1076#define DELL_SMM_NO_FANS 377 78struct smm_regs {79 unsigned int eax;80 unsigned int ebx;81 unsigned int ecx;82 unsigned int edx;83 unsigned int esi;84 unsigned int edi;85};86 87struct dell_smm_ops {88 struct device *smm_dev;89 int (*smm_call)(struct device *smm_dev, struct smm_regs *regs);90};91 92struct dell_smm_data {93 struct mutex i8k_mutex; /* lock for sensors writes */94 char bios_version[4];95 char bios_machineid[16];96 uint i8k_fan_mult;97 uint i8k_pwm_mult;98 uint i8k_fan_max;99 int temp_type[DELL_SMM_NO_TEMP];100 bool fan[DELL_SMM_NO_FANS];101 int fan_type[DELL_SMM_NO_FANS];102 int *fan_nominal_speed[DELL_SMM_NO_FANS];103 const struct dell_smm_ops *ops;104};105 106struct dell_smm_cooling_data {107 u8 fan_num;108 struct dell_smm_data *data;109};110 111MODULE_AUTHOR("Massimo Dal Zotto <dz@debian.org>");112MODULE_AUTHOR("Pali Rohár <pali@kernel.org>");113MODULE_DESCRIPTION("Dell laptop SMM BIOS hwmon driver");114MODULE_LICENSE("GPL");115MODULE_ALIAS("i8k");116 117static bool force;118module_param_unsafe(force, bool, 0);119MODULE_PARM_DESC(force, "Force loading without checking for supported models and features");120 121static bool ignore_dmi;122module_param(ignore_dmi, bool, 0);123MODULE_PARM_DESC(ignore_dmi, "Continue probing hardware even if DMI data does not match");124 125#if IS_ENABLED(CONFIG_I8K)126static bool restricted = true;127module_param(restricted, bool, 0);128MODULE_PARM_DESC(restricted, "Restrict fan control and serial number to CAP_SYS_ADMIN (default: 1)");129 130static bool power_status;131module_param(power_status, bool, 0600);132MODULE_PARM_DESC(power_status, "Report power status in /proc/i8k (default: 0)");133#endif134 135static uint fan_mult;136module_param(fan_mult, uint, 0);137MODULE_PARM_DESC(fan_mult, "Factor to multiply fan speed with (default: autodetect)");138 139static uint fan_max;140module_param(fan_max, uint, 0);141MODULE_PARM_DESC(fan_max, "Maximum configurable fan speed (default: autodetect)");142 143static bool disallow_fan_type_call, disallow_fan_support;144 145static unsigned int manual_fan, auto_fan;146 147static const char * const temp_labels[] = {148 "CPU",149 "GPU",150 "SODIMM",151 "Other",152 "Ambient",153 "Other",154};155 156static const char * const fan_labels[] = {157 "Processor Fan",158 "Motherboard Fan",159 "Video Fan",160 "Power Supply Fan",161 "Chipset Fan",162 "Other Fan",163};164 165static const char * const docking_labels[] = {166 "Docking Processor Fan",167 "Docking Motherboard Fan",168 "Docking Video Fan",169 "Docking Power Supply Fan",170 "Docking Chipset Fan",171 "Docking Other Fan",172};173 174static inline const char __init *i8k_get_dmi_data(int field)175{176 const char *dmi_data = dmi_get_system_info(field);177 178 return dmi_data && *dmi_data ? dmi_data : "?";179}180 181/*182 * Call the System Management Mode BIOS. Code provided by Jonathan Buzzard.183 */184static int i8k_smm_func(void *par)185{186 struct smm_regs *regs = par;187 unsigned char carry;188 189 /* SMM requires CPU 0 */190 if (smp_processor_id() != 0)191 return -EBUSY;192 193 asm volatile("out %%al,$0xb2\n\t"194 "out %%al,$0x84\n\t"195 "setc %0\n"196 : "=mr" (carry),197 "+a" (regs->eax),198 "+b" (regs->ebx),199 "+c" (regs->ecx),200 "+d" (regs->edx),201 "+S" (regs->esi),202 "+D" (regs->edi));203 204 if (carry)205 return -EINVAL;206 207 return 0;208}209 210/*211 * Call the System Management Mode BIOS.212 */213static int i8k_smm_call(struct device *dummy, struct smm_regs *regs)214{215 int ret;216 217 cpus_read_lock();218 ret = smp_call_on_cpu(0, i8k_smm_func, regs, true);219 cpus_read_unlock();220 221 return ret;222}223 224static const struct dell_smm_ops i8k_smm_ops = {225 .smm_call = i8k_smm_call,226};227 228/*229 * Call the System Management Mode BIOS over WMI.230 */231static ssize_t wmi_parse_register(u8 *buffer, u32 length, unsigned int *reg)232{233 __le32 value;234 u32 reg_size;235 236 if (length <= sizeof(reg_size))237 return -ENODATA;238 239 reg_size = get_unaligned_le32(buffer);240 if (!reg_size || reg_size > sizeof(value))241 return -ENOMSG;242 243 if (length < sizeof(reg_size) + reg_size)244 return -ENODATA;245 246 memcpy_and_pad(&value, sizeof(value), buffer + sizeof(reg_size), reg_size, 0);247 *reg = le32_to_cpu(value);248 249 return reg_size + sizeof(reg_size);250}251 252static int wmi_parse_response(u8 *buffer, u32 length, struct smm_regs *regs)253{254 unsigned int *registers[] = {255 ®s->eax,256 ®s->ebx,257 ®s->ecx,258 ®s->edx259 };260 u32 offset = 0;261 ssize_t ret;262 int i;263 264 for (i = 0; i < ARRAY_SIZE(registers); i++) {265 if (offset >= length)266 return -ENODATA;267 268 ret = wmi_parse_register(buffer + offset, length - offset, registers[i]);269 if (ret < 0)270 return ret;271 272 offset += ret;273 }274 275 if (offset != length)276 return -ENOMSG;277 278 return 0;279}280 281static int wmi_smm_call(struct device *dev, struct smm_regs *regs)282{283 struct wmi_device *wdev = container_of(dev, struct wmi_device, dev);284 struct acpi_buffer out = { ACPI_ALLOCATE_BUFFER, NULL };285 u32 wmi_payload[] = {286 sizeof(regs->eax),287 regs->eax,288 sizeof(regs->ebx),289 regs->ebx,290 sizeof(regs->ecx),291 regs->ecx,292 sizeof(regs->edx),293 regs->edx294 };295 const struct acpi_buffer in = {296 .length = sizeof(wmi_payload),297 .pointer = &wmi_payload,298 };299 union acpi_object *obj;300 acpi_status status;301 int ret;302 303 status = wmidev_evaluate_method(wdev, 0x0, DELL_SMM_LEGACY_EXECUTE, &in, &out);304 if (ACPI_FAILURE(status))305 return -EIO;306 307 obj = out.pointer;308 if (!obj)309 return -ENODATA;310 311 if (obj->type != ACPI_TYPE_BUFFER) {312 ret = -ENOMSG;313 314 goto err_free;315 }316 317 ret = wmi_parse_response(obj->buffer.pointer, obj->buffer.length, regs);318 319err_free:320 kfree(obj);321 322 return ret;323}324 325static int dell_smm_call(const struct dell_smm_ops *ops, struct smm_regs *regs)326{327 unsigned int eax = regs->eax;328 unsigned int ebx = regs->ebx;329 long long duration;330 ktime_t calltime;331 int ret;332 333 calltime = ktime_get();334 ret = ops->smm_call(ops->smm_dev, regs);335 duration = ktime_us_delta(ktime_get(), calltime);336 337 pr_debug("SMM(0x%.4x 0x%.4x) = 0x%.4x status: %d (took %7lld usecs)\n",338 eax, ebx, regs->eax & 0xffff, ret, duration);339 340 if (duration > DELL_SMM_MAX_DURATION)341 pr_warn_once("SMM call took %lld usecs!\n", duration);342 343 if (ret < 0)344 return ret;345 346 if ((regs->eax & 0xffff) == 0xffff || regs->eax == eax)347 return -EINVAL;348 349 return 0;350}351 352/*353 * Read the fan status.354 */355static int i8k_get_fan_status(const struct dell_smm_data *data, u8 fan)356{357 struct smm_regs regs = {358 .eax = I8K_SMM_GET_FAN,359 .ebx = fan,360 };361 362 if (disallow_fan_support)363 return -EINVAL;364 365 return dell_smm_call(data->ops, ®s) ? : regs.eax & 0xff;366}367 368/*369 * Read the fan speed in RPM.370 */371static int i8k_get_fan_speed(const struct dell_smm_data *data, u8 fan)372{373 struct smm_regs regs = {374 .eax = I8K_SMM_GET_SPEED,375 .ebx = fan,376 };377 378 if (disallow_fan_support)379 return -EINVAL;380 381 return dell_smm_call(data->ops, ®s) ? : (regs.eax & 0xffff) * data->i8k_fan_mult;382}383 384/*385 * Read the fan type.386 */387static int _i8k_get_fan_type(const struct dell_smm_data *data, u8 fan)388{389 struct smm_regs regs = {390 .eax = I8K_SMM_GET_FAN_TYPE,391 .ebx = fan,392 };393 394 if (disallow_fan_support || disallow_fan_type_call)395 return -EINVAL;396 397 return dell_smm_call(data->ops, ®s) ? : regs.eax & 0xff;398}399 400static int i8k_get_fan_type(struct dell_smm_data *data, u8 fan)401{402 /* I8K_SMM_GET_FAN_TYPE SMM call is expensive, so cache values */403 if (data->fan_type[fan] == INT_MIN)404 data->fan_type[fan] = _i8k_get_fan_type(data, fan);405 406 return data->fan_type[fan];407}408 409/*410 * Read the fan nominal rpm for specific fan speed.411 */412static int i8k_get_fan_nominal_speed(const struct dell_smm_data *data, u8 fan, int speed)413{414 struct smm_regs regs = {415 .eax = I8K_SMM_GET_NOM_SPEED,416 .ebx = fan | (speed << 8),417 };418 419 if (disallow_fan_support)420 return -EINVAL;421 422 return dell_smm_call(data->ops, ®s) ? : (regs.eax & 0xffff);423}424 425/*426 * Enable or disable automatic BIOS fan control support427 */428static int i8k_enable_fan_auto_mode(const struct dell_smm_data *data, bool enable)429{430 struct smm_regs regs = { };431 432 if (disallow_fan_support)433 return -EINVAL;434 435 regs.eax = enable ? auto_fan : manual_fan;436 return dell_smm_call(data->ops, ®s);437}438 439/*440 * Set the fan speed (off, low, high, ...).441 */442static int i8k_set_fan(const struct dell_smm_data *data, u8 fan, int speed)443{444 struct smm_regs regs = { .eax = I8K_SMM_SET_FAN, };445 446 if (disallow_fan_support)447 return -EINVAL;448 449 speed = (speed < 0) ? 0 : ((speed > data->i8k_fan_max) ? data->i8k_fan_max : speed);450 regs.ebx = fan | (speed << 8);451 452 return dell_smm_call(data->ops, ®s);453}454 455static int i8k_get_temp_type(const struct dell_smm_data *data, u8 sensor)456{457 struct smm_regs regs = {458 .eax = I8K_SMM_GET_TEMP_TYPE,459 .ebx = sensor,460 };461 462 return dell_smm_call(data->ops, ®s) ? : regs.eax & 0xff;463}464 465/*466 * Read the cpu temperature.467 */468static int _i8k_get_temp(const struct dell_smm_data *data, u8 sensor)469{470 struct smm_regs regs = {471 .eax = I8K_SMM_GET_TEMP,472 .ebx = sensor,473 };474 475 return dell_smm_call(data->ops, ®s) ? : regs.eax & 0xff;476}477 478static int i8k_get_temp(const struct dell_smm_data *data, u8 sensor)479{480 int temp = _i8k_get_temp(data, sensor);481 482 /*483 * Sometimes the temperature sensor returns 0x99, which is out of range.484 * In this case we retry (once) before returning an error.485 # 1003655137 00000058 00005a4b486 # 1003655138 00000099 00003a80 <--- 0x99 = 153 degrees487 # 1003655139 00000054 00005c52488 */489 if (temp == 0x99) {490 msleep(100);491 temp = _i8k_get_temp(data, sensor);492 }493 /*494 * Return -ENODATA for all invalid temperatures.495 *496 * Known instances are the 0x99 value as seen above as well as497 * 0xc1 (193), which may be returned when trying to read the GPU498 * temperature if the system supports a GPU and it is currently499 * turned off.500 */501 if (temp > I8K_MAX_TEMP)502 return -ENODATA;503 504 return temp;505}506 507static int dell_smm_get_signature(const struct dell_smm_ops *ops, int req_fn)508{509 struct smm_regs regs = { .eax = req_fn, };510 int rc;511 512 rc = dell_smm_call(ops, ®s);513 if (rc < 0)514 return rc;515 516 return regs.eax == 1145651527 && regs.edx == 1145392204 ? 0 : -1;517}518 519#if IS_ENABLED(CONFIG_I8K)520 521/*522 * Read the Fn key status.523 */524static int i8k_get_fn_status(const struct dell_smm_data *data)525{526 struct smm_regs regs = { .eax = I8K_SMM_FN_STATUS, };527 int rc;528 529 rc = dell_smm_call(data->ops, ®s);530 if (rc < 0)531 return rc;532 533 switch ((regs.eax >> I8K_FN_SHIFT) & I8K_FN_MASK) {534 case I8K_FN_UP:535 return I8K_VOL_UP;536 case I8K_FN_DOWN:537 return I8K_VOL_DOWN;538 case I8K_FN_MUTE:539 return I8K_VOL_MUTE;540 default:541 return 0;542 }543}544 545/*546 * Read the power status.547 */548static int i8k_get_power_status(const struct dell_smm_data *data)549{550 struct smm_regs regs = { .eax = I8K_SMM_POWER_STATUS, };551 int rc;552 553 rc = dell_smm_call(data->ops, ®s);554 if (rc < 0)555 return rc;556 557 return (regs.eax & 0xff) == I8K_POWER_AC ? I8K_AC : I8K_BATTERY;558}559 560/*561 * Procfs interface562 */563 564static long i8k_ioctl(struct file *fp, unsigned int cmd, unsigned long arg)565{566 struct dell_smm_data *data = pde_data(file_inode(fp));567 int __user *argp = (int __user *)arg;568 int speed, err;569 int val = 0;570 571 if (!argp)572 return -EINVAL;573 574 switch (cmd) {575 case I8K_BIOS_VERSION:576 if (!isdigit(data->bios_version[0]) || !isdigit(data->bios_version[1]) ||577 !isdigit(data->bios_version[2]))578 return -EINVAL;579 580 val = (data->bios_version[0] << 16) |581 (data->bios_version[1] << 8) | data->bios_version[2];582 583 if (copy_to_user(argp, &val, sizeof(val)))584 return -EFAULT;585 586 return 0;587 case I8K_MACHINE_ID:588 if (restricted && !capable(CAP_SYS_ADMIN))589 return -EPERM;590 591 if (copy_to_user(argp, data->bios_machineid, sizeof(data->bios_machineid)))592 return -EFAULT;593 594 return 0;595 case I8K_FN_STATUS:596 val = i8k_get_fn_status(data);597 break;598 599 case I8K_POWER_STATUS:600 val = i8k_get_power_status(data);601 break;602 603 case I8K_GET_TEMP:604 val = i8k_get_temp(data, 0);605 break;606 607 case I8K_GET_SPEED:608 if (copy_from_user(&val, argp, sizeof(int)))609 return -EFAULT;610 611 if (val > U8_MAX || val < 0)612 return -EINVAL;613 614 val = i8k_get_fan_speed(data, val);615 break;616 617 case I8K_GET_FAN:618 if (copy_from_user(&val, argp, sizeof(int)))619 return -EFAULT;620 621 if (val > U8_MAX || val < 0)622 return -EINVAL;623 624 val = i8k_get_fan_status(data, val);625 break;626 627 case I8K_SET_FAN:628 if (restricted && !capable(CAP_SYS_ADMIN))629 return -EPERM;630 631 if (copy_from_user(&val, argp, sizeof(int)))632 return -EFAULT;633 634 if (val > U8_MAX || val < 0)635 return -EINVAL;636 637 if (copy_from_user(&speed, argp + 1, sizeof(int)))638 return -EFAULT;639 640 mutex_lock(&data->i8k_mutex);641 err = i8k_set_fan(data, val, speed);642 if (err < 0)643 val = err;644 else645 val = i8k_get_fan_status(data, val);646 mutex_unlock(&data->i8k_mutex);647 break;648 649 default:650 return -ENOIOCTLCMD;651 }652 653 if (val < 0)654 return val;655 656 if (copy_to_user(argp, &val, sizeof(int)))657 return -EFAULT;658 659 return 0;660}661 662/*663 * Print the information for /proc/i8k.664 */665static int i8k_proc_show(struct seq_file *seq, void *offset)666{667 struct dell_smm_data *data = seq->private;668 int fn_key, cpu_temp, ac_power;669 int left_fan, right_fan, left_speed, right_speed;670 671 cpu_temp = i8k_get_temp(data, 0); /* 11100 µs */672 left_fan = i8k_get_fan_status(data, I8K_FAN_LEFT); /* 580 µs */673 right_fan = i8k_get_fan_status(data, I8K_FAN_RIGHT); /* 580 µs */674 left_speed = i8k_get_fan_speed(data, I8K_FAN_LEFT); /* 580 µs */675 right_speed = i8k_get_fan_speed(data, I8K_FAN_RIGHT); /* 580 µs */676 fn_key = i8k_get_fn_status(data); /* 750 µs */677 if (power_status)678 ac_power = i8k_get_power_status(data); /* 14700 µs */679 else680 ac_power = -1;681 682 /*683 * Info:684 *685 * 1) Format version (this will change if format changes)686 * 2) BIOS version687 * 3) BIOS machine ID688 * 4) Cpu temperature689 * 5) Left fan status690 * 6) Right fan status691 * 7) Left fan speed692 * 8) Right fan speed693 * 9) AC power694 * 10) Fn Key status695 */696 seq_printf(seq, "%s %s %s %d %d %d %d %d %d %d\n",697 I8K_PROC_FMT,698 data->bios_version,699 (restricted && !capable(CAP_SYS_ADMIN)) ? "-1" : data->bios_machineid,700 cpu_temp,701 left_fan, right_fan, left_speed, right_speed,702 ac_power, fn_key);703 704 return 0;705}706 707static int i8k_open_fs(struct inode *inode, struct file *file)708{709 return single_open(file, i8k_proc_show, pde_data(inode));710}711 712static const struct proc_ops i8k_proc_ops = {713 .proc_open = i8k_open_fs,714 .proc_read = seq_read,715 .proc_lseek = seq_lseek,716 .proc_release = single_release,717 .proc_ioctl = i8k_ioctl,718};719 720static void i8k_exit_procfs(void *param)721{722 remove_proc_entry("i8k", NULL);723}724 725static void __init i8k_init_procfs(struct device *dev)726{727 struct dell_smm_data *data = dev_get_drvdata(dev);728 729 strscpy(data->bios_version, i8k_get_dmi_data(DMI_BIOS_VERSION),730 sizeof(data->bios_version));731 strscpy(data->bios_machineid, i8k_get_dmi_data(DMI_PRODUCT_SERIAL),732 sizeof(data->bios_machineid));733 734 /* Only register exit function if creation was successful */735 if (proc_create_data("i8k", 0, NULL, &i8k_proc_ops, data))736 devm_add_action_or_reset(dev, i8k_exit_procfs, NULL);737}738 739#else740 741static void __init i8k_init_procfs(struct device *dev)742{743}744 745#endif746 747static int dell_smm_get_max_state(struct thermal_cooling_device *dev, unsigned long *state)748{749 struct dell_smm_cooling_data *cdata = dev->devdata;750 751 *state = cdata->data->i8k_fan_max;752 753 return 0;754}755 756static int dell_smm_get_cur_state(struct thermal_cooling_device *dev, unsigned long *state)757{758 struct dell_smm_cooling_data *cdata = dev->devdata;759 int ret;760 761 ret = i8k_get_fan_status(cdata->data, cdata->fan_num);762 if (ret < 0)763 return ret;764 765 *state = ret;766 767 return 0;768}769 770static int dell_smm_set_cur_state(struct thermal_cooling_device *dev, unsigned long state)771{772 struct dell_smm_cooling_data *cdata = dev->devdata;773 struct dell_smm_data *data = cdata->data;774 int ret;775 776 if (state > data->i8k_fan_max)777 return -EINVAL;778 779 mutex_lock(&data->i8k_mutex);780 ret = i8k_set_fan(data, cdata->fan_num, (int)state);781 mutex_unlock(&data->i8k_mutex);782 783 return ret;784}785 786static const struct thermal_cooling_device_ops dell_smm_cooling_ops = {787 .get_max_state = dell_smm_get_max_state,788 .get_cur_state = dell_smm_get_cur_state,789 .set_cur_state = dell_smm_set_cur_state,790};791 792static umode_t dell_smm_is_visible(const void *drvdata, enum hwmon_sensor_types type, u32 attr,793 int channel)794{795 const struct dell_smm_data *data = drvdata;796 797 switch (type) {798 case hwmon_temp:799 switch (attr) {800 case hwmon_temp_input:801 /* _i8k_get_temp() is fine since we do not care about the actual value */802 if (data->temp_type[channel] >= 0 || _i8k_get_temp(data, channel) >= 0)803 return 0444;804 805 break;806 case hwmon_temp_label:807 if (data->temp_type[channel] >= 0)808 return 0444;809 810 break;811 default:812 break;813 }814 break;815 case hwmon_fan:816 if (disallow_fan_support)817 break;818 819 switch (attr) {820 case hwmon_fan_input:821 if (data->fan[channel])822 return 0444;823 824 break;825 case hwmon_fan_label:826 if (data->fan[channel] && !disallow_fan_type_call)827 return 0444;828 829 break;830 case hwmon_fan_min:831 case hwmon_fan_max:832 case hwmon_fan_target:833 if (data->fan_nominal_speed[channel])834 return 0444;835 836 break;837 default:838 break;839 }840 break;841 case hwmon_pwm:842 if (disallow_fan_support)843 break;844 845 switch (attr) {846 case hwmon_pwm_input:847 if (data->fan[channel])848 return 0644;849 850 break;851 case hwmon_pwm_enable:852 if (auto_fan)853 /*854 * There is no command for retrieve the current status855 * from BIOS, and userspace/firmware itself can change856 * it.857 * Thus we can only provide write-only access for now.858 */859 return 0200;860 861 break;862 default:863 break;864 }865 break;866 default:867 break;868 }869 870 return 0;871}872 873static int dell_smm_read(struct device *dev, enum hwmon_sensor_types type, u32 attr, int channel,874 long *val)875{876 struct dell_smm_data *data = dev_get_drvdata(dev);877 int mult = data->i8k_fan_mult;878 int ret;879 880 switch (type) {881 case hwmon_temp:882 switch (attr) {883 case hwmon_temp_input:884 ret = i8k_get_temp(data, channel);885 if (ret < 0)886 return ret;887 888 *val = ret * 1000;889 890 return 0;891 default:892 break;893 }894 break;895 case hwmon_fan:896 switch (attr) {897 case hwmon_fan_input:898 ret = i8k_get_fan_speed(data, channel);899 if (ret < 0)900 return ret;901 902 *val = ret;903 904 return 0;905 case hwmon_fan_min:906 *val = data->fan_nominal_speed[channel][0] * mult;907 908 return 0;909 case hwmon_fan_max:910 *val = data->fan_nominal_speed[channel][data->i8k_fan_max] * mult;911 912 return 0;913 case hwmon_fan_target:914 ret = i8k_get_fan_status(data, channel);915 if (ret < 0)916 return ret;917 918 if (ret > data->i8k_fan_max)919 ret = data->i8k_fan_max;920 921 *val = data->fan_nominal_speed[channel][ret] * mult;922 923 return 0;924 default:925 break;926 }927 break;928 case hwmon_pwm:929 switch (attr) {930 case hwmon_pwm_input:931 ret = i8k_get_fan_status(data, channel);932 if (ret < 0)933 return ret;934 935 *val = clamp_val(ret * data->i8k_pwm_mult, 0, 255);936 937 return 0;938 default:939 break;940 }941 break;942 default:943 break;944 }945 946 return -EOPNOTSUPP;947}948 949static const char *dell_smm_fan_label(struct dell_smm_data *data, int channel)950{951 bool dock = false;952 int type = i8k_get_fan_type(data, channel);953 954 if (type < 0)955 return ERR_PTR(type);956 957 if (type & 0x10) {958 dock = true;959 type &= 0x0F;960 }961 962 if (type >= ARRAY_SIZE(fan_labels))963 type = ARRAY_SIZE(fan_labels) - 1;964 965 return dock ? docking_labels[type] : fan_labels[type];966}967 968static int dell_smm_read_string(struct device *dev, enum hwmon_sensor_types type, u32 attr,969 int channel, const char **str)970{971 struct dell_smm_data *data = dev_get_drvdata(dev);972 973 switch (type) {974 case hwmon_temp:975 switch (attr) {976 case hwmon_temp_label:977 *str = temp_labels[data->temp_type[channel]];978 return 0;979 default:980 break;981 }982 break;983 case hwmon_fan:984 switch (attr) {985 case hwmon_fan_label:986 *str = dell_smm_fan_label(data, channel);987 return PTR_ERR_OR_ZERO(*str);988 default:989 break;990 }991 break;992 default:993 break;994 }995 996 return -EOPNOTSUPP;997}998 999static int dell_smm_write(struct device *dev, enum hwmon_sensor_types type, u32 attr, int channel,1000 long val)1001{1002 struct dell_smm_data *data = dev_get_drvdata(dev);1003 unsigned long pwm;1004 bool enable;1005 int err;1006 1007 switch (type) {1008 case hwmon_pwm:1009 switch (attr) {1010 case hwmon_pwm_input:1011 pwm = clamp_val(DIV_ROUND_CLOSEST(val, data->i8k_pwm_mult), 0,1012 data->i8k_fan_max);1013 1014 mutex_lock(&data->i8k_mutex);1015 err = i8k_set_fan(data, channel, pwm);1016 mutex_unlock(&data->i8k_mutex);1017 1018 if (err < 0)1019 return err;1020 1021 return 0;1022 case hwmon_pwm_enable:1023 if (!val)1024 return -EINVAL;1025 1026 if (val == 1)1027 enable = false;1028 else1029 enable = true;1030 1031 mutex_lock(&data->i8k_mutex);1032 err = i8k_enable_fan_auto_mode(data, enable);1033 mutex_unlock(&data->i8k_mutex);1034 1035 if (err < 0)1036 return err;1037 1038 return 0;1039 default:1040 break;1041 }1042 break;1043 default:1044 break;1045 }1046 1047 return -EOPNOTSUPP;1048}1049 1050static const struct hwmon_ops dell_smm_ops = {1051 .is_visible = dell_smm_is_visible,1052 .read = dell_smm_read,1053 .read_string = dell_smm_read_string,1054 .write = dell_smm_write,1055};1056 1057static const struct hwmon_channel_info * const dell_smm_info[] = {1058 HWMON_CHANNEL_INFO(chip, HWMON_C_REGISTER_TZ),1059 HWMON_CHANNEL_INFO(temp,1060 HWMON_T_INPUT | HWMON_T_LABEL,1061 HWMON_T_INPUT | HWMON_T_LABEL,1062 HWMON_T_INPUT | HWMON_T_LABEL,1063 HWMON_T_INPUT | HWMON_T_LABEL,1064 HWMON_T_INPUT | HWMON_T_LABEL,1065 HWMON_T_INPUT | HWMON_T_LABEL,1066 HWMON_T_INPUT | HWMON_T_LABEL,1067 HWMON_T_INPUT | HWMON_T_LABEL,1068 HWMON_T_INPUT | HWMON_T_LABEL,1069 HWMON_T_INPUT | HWMON_T_LABEL1070 ),1071 HWMON_CHANNEL_INFO(fan,1072 HWMON_F_INPUT | HWMON_F_LABEL | HWMON_F_MIN | HWMON_F_MAX |1073 HWMON_F_TARGET,1074 HWMON_F_INPUT | HWMON_F_LABEL | HWMON_F_MIN | HWMON_F_MAX |1075 HWMON_F_TARGET,1076 HWMON_F_INPUT | HWMON_F_LABEL | HWMON_F_MIN | HWMON_F_MAX |1077 HWMON_F_TARGET1078 ),1079 HWMON_CHANNEL_INFO(pwm,1080 HWMON_PWM_INPUT | HWMON_PWM_ENABLE,1081 HWMON_PWM_INPUT,1082 HWMON_PWM_INPUT1083 ),1084 NULL1085};1086 1087static const struct hwmon_chip_info dell_smm_chip_info = {1088 .ops = &dell_smm_ops,1089 .info = dell_smm_info,1090};1091 1092static int dell_smm_init_cdev(struct device *dev, u8 fan_num)1093{1094 struct dell_smm_data *data = dev_get_drvdata(dev);1095 struct thermal_cooling_device *cdev;1096 struct dell_smm_cooling_data *cdata;1097 int ret = 0;1098 char *name;1099 1100 name = kasprintf(GFP_KERNEL, "dell-smm-fan%u", fan_num + 1);1101 if (!name)1102 return -ENOMEM;1103 1104 cdata = devm_kmalloc(dev, sizeof(*cdata), GFP_KERNEL);1105 if (cdata) {1106 cdata->fan_num = fan_num;1107 cdata->data = data;1108 cdev = devm_thermal_of_cooling_device_register(dev, NULL, name, cdata,1109 &dell_smm_cooling_ops);1110 if (IS_ERR(cdev)) {1111 devm_kfree(dev, cdata);1112 ret = PTR_ERR(cdev);1113 }1114 } else {1115 ret = -ENOMEM;1116 }1117 1118 kfree(name);1119 1120 return ret;1121}1122 1123static int dell_smm_init_hwmon(struct device *dev)1124{1125 struct dell_smm_data *data = dev_get_drvdata(dev);1126 struct device *dell_smm_hwmon_dev;1127 int state, err;1128 u8 i;1129 1130 for (i = 0; i < DELL_SMM_NO_TEMP; i++) {1131 data->temp_type[i] = i8k_get_temp_type(data, i);1132 if (data->temp_type[i] < 0)1133 continue;1134 1135 if (data->temp_type[i] >= ARRAY_SIZE(temp_labels))1136 data->temp_type[i] = ARRAY_SIZE(temp_labels) - 1;1137 }1138 1139 for (i = 0; i < DELL_SMM_NO_FANS; i++) {1140 data->fan_type[i] = INT_MIN;1141 err = i8k_get_fan_status(data, i);1142 if (err < 0)1143 err = i8k_get_fan_type(data, i);1144 1145 if (err < 0)1146 continue;1147 1148 data->fan[i] = true;1149 1150 /* the cooling device is not critical, ignore failures */1151 if (IS_REACHABLE(CONFIG_THERMAL)) {1152 err = dell_smm_init_cdev(dev, i);1153 if (err < 0)1154 dev_warn(dev, "Failed to register cooling device for fan %u\n",1155 i + 1);1156 }1157 1158 data->fan_nominal_speed[i] = devm_kmalloc_array(dev, data->i8k_fan_max + 1,1159 sizeof(*data->fan_nominal_speed[i]),1160 GFP_KERNEL);1161 if (!data->fan_nominal_speed[i])1162 continue;1163 1164 for (state = 0; state <= data->i8k_fan_max; state++) {1165 err = i8k_get_fan_nominal_speed(data, i, state);1166 if (err < 0) {1167 /* Mark nominal speed table as invalid in case of error */1168 devm_kfree(dev, data->fan_nominal_speed[i]);1169 data->fan_nominal_speed[i] = NULL;1170 break;1171 }1172 data->fan_nominal_speed[i][state] = err;1173 /*1174 * Autodetect fan multiplier based on nominal rpm if multiplier1175 * was not specified as module param or in DMI. If fan reports1176 * rpm value too high then set multiplier to 1.1177 */1178 if (!fan_mult && err > I8K_FAN_RPM_THRESHOLD)1179 data->i8k_fan_mult = 1;1180 }1181 }1182 1183 dell_smm_hwmon_dev = devm_hwmon_device_register_with_info(dev, "dell_smm", data,1184 &dell_smm_chip_info, NULL);1185 1186 return PTR_ERR_OR_ZERO(dell_smm_hwmon_dev);1187}1188 1189static int dell_smm_init_data(struct device *dev, const struct dell_smm_ops *ops)1190{1191 struct dell_smm_data *data;1192 1193 data = devm_kzalloc(dev, sizeof(*data), GFP_KERNEL);1194 if (!data)1195 return -ENOMEM;1196 1197 mutex_init(&data->i8k_mutex);1198 dev_set_drvdata(dev, data);1199 1200 data->ops = ops;1201 /* All options must not be 0 */1202 data->i8k_fan_mult = fan_mult ? : I8K_FAN_MULT;1203 data->i8k_fan_max = fan_max ? : I8K_FAN_HIGH;1204 data->i8k_pwm_mult = DIV_ROUND_UP(255, data->i8k_fan_max);1205 1206 return 0;1207}1208 1209static const struct dmi_system_id i8k_dmi_table[] __initconst = {1210 {1211 .ident = "Dell G5 5590",1212 .matches = {1213 DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),1214 DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "G5 5590"),1215 },1216 },1217 {1218 .ident = "Dell G5 5505",1219 .matches = {1220 DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),1221 DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "G5 5505"),1222 },1223 },1224 {1225 .ident = "Dell Inspiron",1226 .matches = {1227 DMI_MATCH(DMI_SYS_VENDOR, "Dell Computer"),1228 DMI_MATCH(DMI_PRODUCT_NAME, "Inspiron"),1229 },1230 },1231 {1232 .ident = "Dell Latitude",1233 .matches = {1234 DMI_MATCH(DMI_SYS_VENDOR, "Dell Computer"),1235 DMI_MATCH(DMI_PRODUCT_NAME, "Latitude"),1236 },1237 },1238 {1239 .ident = "Dell Inspiron 2",1240 .matches = {1241 DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),1242 DMI_MATCH(DMI_PRODUCT_NAME, "Inspiron"),1243 },1244 },1245 {1246 .ident = "Dell Latitude 2",1247 .matches = {1248 DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),1249 DMI_MATCH(DMI_PRODUCT_NAME, "Latitude"),1250 },1251 },1252 { /* UK Inspiron 6400 */1253 .ident = "Dell Inspiron 3",1254 .matches = {1255 DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),1256 DMI_MATCH(DMI_PRODUCT_NAME, "MM061"),1257 },1258 },1259 {1260 .ident = "Dell Inspiron 3",1261 .matches = {1262 DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),1263 DMI_MATCH(DMI_PRODUCT_NAME, "MP061"),1264 },1265 },1266 {1267 .ident = "Dell OptiPlex 7060",1268 .matches = {1269 DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),1270 DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "OptiPlex 7060"),1271 },1272 },1273 {1274 .ident = "Dell Precision",1275 .matches = {1276 DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),1277 DMI_MATCH(DMI_PRODUCT_NAME, "Precision"),1278 },1279 },1280 {1281 .ident = "Dell Vostro",1282 .matches = {1283 DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),1284 DMI_MATCH(DMI_PRODUCT_NAME, "Vostro"),1285 },1286 },1287 {1288 .ident = "Dell Studio",1289 .matches = {1290 DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),1291 DMI_MATCH(DMI_PRODUCT_NAME, "Studio"),1292 },1293 },1294 {1295 .ident = "Dell XPS M140",1296 .matches = {1297 DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),1298 DMI_MATCH(DMI_PRODUCT_NAME, "MXC051"),1299 },1300 },1301 {1302 .ident = "Dell XPS",1303 .matches = {1304 DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),1305 DMI_MATCH(DMI_PRODUCT_NAME, "XPS"),1306 },1307 },1308 { }1309};1310 1311MODULE_DEVICE_TABLE(dmi, i8k_dmi_table);1312 1313/*1314 * Only use for machines which need some special configuration1315 * in order to work correctly (e.g. if autoconfig fails on this machines).1316 */1317struct i8k_config_data {1318 uint fan_mult;1319 uint fan_max;1320};1321 1322enum i8k_configs {1323 DELL_LATITUDE_D520,1324 DELL_PRECISION_490,1325 DELL_STUDIO,1326 DELL_XPS,1327};1328 1329static const struct i8k_config_data i8k_config_data[] __initconst = {1330 [DELL_LATITUDE_D520] = {1331 .fan_mult = 1,1332 .fan_max = I8K_FAN_TURBO,1333 },1334 [DELL_PRECISION_490] = {1335 .fan_mult = 1,1336 .fan_max = I8K_FAN_TURBO,1337 },1338 [DELL_STUDIO] = {1339 .fan_mult = 1,1340 .fan_max = I8K_FAN_HIGH,1341 },1342 [DELL_XPS] = {1343 .fan_mult = 1,1344 .fan_max = I8K_FAN_HIGH,1345 },1346};1347 1348static const struct dmi_system_id i8k_config_dmi_table[] __initconst = {1349 {1350 .ident = "Dell Latitude D520",1351 .matches = {1352 DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),1353 DMI_MATCH(DMI_PRODUCT_NAME, "Latitude D520"),1354 },1355 .driver_data = (void *)&i8k_config_data[DELL_LATITUDE_D520],1356 },1357 {1358 .ident = "Dell Precision 490",1359 .matches = {1360 DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),1361 DMI_MATCH(DMI_PRODUCT_NAME,1362 "Precision WorkStation 490"),1363 },1364 .driver_data = (void *)&i8k_config_data[DELL_PRECISION_490],1365 },1366 {1367 .ident = "Dell Studio",1368 .matches = {1369 DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),1370 DMI_MATCH(DMI_PRODUCT_NAME, "Studio"),1371 },1372 .driver_data = (void *)&i8k_config_data[DELL_STUDIO],1373 },1374 {1375 .ident = "Dell XPS M140",1376 .matches = {1377 DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),1378 DMI_MATCH(DMI_PRODUCT_NAME, "MXC051"),1379 },1380 .driver_data = (void *)&i8k_config_data[DELL_XPS],1381 },1382 { }1383};1384 1385/*1386 * On some machines once I8K_SMM_GET_FAN_TYPE is issued then CPU fan speed1387 * randomly going up and down due to bug in Dell SMM or BIOS. Here is blacklist1388 * of affected Dell machines for which we disallow I8K_SMM_GET_FAN_TYPE call.1389 * See bug: https://bugzilla.kernel.org/show_bug.cgi?id=1001211390 */1391static const struct dmi_system_id i8k_blacklist_fan_type_dmi_table[] __initconst = {1392 {1393 .ident = "Dell Studio XPS 8000",1394 .matches = {1395 DMI_EXACT_MATCH(DMI_SYS_VENDOR, "Dell Inc."),1396 DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "Studio XPS 8000"),1397 },1398 },1399 {1400 .ident = "Dell Studio XPS 8100",1401 .matches = {1402 DMI_EXACT_MATCH(DMI_SYS_VENDOR, "Dell Inc."),1403 DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "Studio XPS 8100"),1404 },1405 },1406 {1407 .ident = "Dell Inspiron 580",1408 .matches = {1409 DMI_EXACT_MATCH(DMI_SYS_VENDOR, "Dell Inc."),1410 DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "Inspiron 580 "),1411 },1412 },1413 {1414 .ident = "Dell Inspiron 3505",1415 .matches = {1416 DMI_EXACT_MATCH(DMI_SYS_VENDOR, "Dell Inc."),1417 DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "Inspiron 3505"),1418 },1419 },1420 { }1421};1422 1423/*1424 * On some machines all fan related SMM functions implemented by Dell BIOS1425 * firmware freeze kernel for about 500ms. Until Dell fixes these problems fan1426 * support for affected blacklisted Dell machines stay disabled.1427 * See bug: https://bugzilla.kernel.org/show_bug.cgi?id=1957511428 */1429static const struct dmi_system_id i8k_blacklist_fan_support_dmi_table[] __initconst = {1430 {1431 .ident = "Dell Inspiron 7720",1432 .matches = {1433 DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),1434 DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "Inspiron 7720"),1435 },1436 },1437 {1438 .ident = "Dell Vostro 3360",1439 .matches = {1440 DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),1441 DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "Vostro 3360"),1442 },1443 },1444 {1445 .ident = "Dell XPS13 9333",1446 .matches = {1447 DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),1448 DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "XPS13 9333"),1449 },1450 },1451 {1452 .ident = "Dell XPS 15 L502X",1453 .matches = {1454 DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),1455 DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "Dell System XPS L502X"),1456 },1457 },1458 { }1459};1460 1461struct i8k_fan_control_data {1462 unsigned int manual_fan;1463 unsigned int auto_fan;1464};1465 1466enum i8k_fan_controls {1467 I8K_FAN_30A3_31A3,1468 I8K_FAN_34A3_35A3,1469};1470 1471static const struct i8k_fan_control_data i8k_fan_control_data[] __initconst = {1472 [I8K_FAN_30A3_31A3] = {1473 .manual_fan = 0x30a3,1474 .auto_fan = 0x31a3,1475 },1476 [I8K_FAN_34A3_35A3] = {1477 .manual_fan = 0x34a3,1478 .auto_fan = 0x35a3,1479 },1480};1481 1482static const struct dmi_system_id i8k_whitelist_fan_control[] __initconst = {1483 {1484 .ident = "Dell Latitude 5480",1485 .matches = {1486 DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),1487 DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "Latitude 5480"),1488 },1489 .driver_data = (void *)&i8k_fan_control_data[I8K_FAN_34A3_35A3],1490 },1491 {1492 .ident = "Dell Latitude 7320",1493 .matches = {1494 DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),1495 DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "Latitude 7320"),1496 },1497 .driver_data = (void *)&i8k_fan_control_data[I8K_FAN_30A3_31A3],1498 },1499 {1500 .ident = "Dell Latitude E6440",1501 .matches = {1502 DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),1503 DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "Latitude E6440"),1504 },1505 .driver_data = (void *)&i8k_fan_control_data[I8K_FAN_34A3_35A3],1506 },1507 {1508 .ident = "Dell Latitude E7440",1509 .matches = {1510 DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),1511 DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "Latitude E7440"),1512 },1513 .driver_data = (void *)&i8k_fan_control_data[I8K_FAN_34A3_35A3],1514 },1515 {1516 .ident = "Dell Precision 5530",1517 .matches = {1518 DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),1519 DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "Precision 5530"),1520 },1521 .driver_data = (void *)&i8k_fan_control_data[I8K_FAN_34A3_35A3],1522 },1523 {1524 .ident = "Dell Precision 7510",1525 .matches = {1526 DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),1527 DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "Precision 7510"),1528 },1529 .driver_data = (void *)&i8k_fan_control_data[I8K_FAN_34A3_35A3],1530 },1531 {1532 .ident = "Dell Precision 7540",1533 .matches = {1534 DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),1535 DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "Precision 7540"),1536 },1537 .driver_data = (void *)&i8k_fan_control_data[I8K_FAN_34A3_35A3],1538 },1539 {1540 .ident = "Dell XPS 13 7390",1541 .matches = {1542 DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),1543 DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "XPS 13 7390"),1544 },1545 .driver_data = (void *)&i8k_fan_control_data[I8K_FAN_34A3_35A3],1546 },1547 {1548 .ident = "Dell Optiplex 7000",1549 .matches = {1550 DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),1551 DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "OptiPlex 7000"),1552 },1553 .driver_data = (void *)&i8k_fan_control_data[I8K_FAN_34A3_35A3],1554 },1555 {1556 .ident = "Dell XPS 9315",1557 .matches = {1558 DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),1559 DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "XPS 9315"),1560 },1561 .driver_data = (void *)&i8k_fan_control_data[I8K_FAN_30A3_31A3],1562 },1563 {1564 .ident = "Dell G15 5511",1565 .matches = {1566 DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),1567 DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "Dell G15 5511"),1568 },1569 .driver_data = (void *)&i8k_fan_control_data[I8K_FAN_30A3_31A3],1570 },1571 { }1572};1573 1574/*1575 * Legacy SMM backend driver.1576 */1577static int __init dell_smm_probe(struct platform_device *pdev)1578{1579 int ret;1580 1581 ret = dell_smm_init_data(&pdev->dev, &i8k_smm_ops);1582 if (ret < 0)1583 return ret;1584 1585 ret = dell_smm_init_hwmon(&pdev->dev);1586 if (ret)1587 return ret;1588 1589 i8k_init_procfs(&pdev->dev);1590 1591 return 0;1592}1593 1594static struct platform_driver dell_smm_driver = {1595 .driver = {1596 .name = KBUILD_MODNAME,1597 },1598};1599 1600static struct platform_device *dell_smm_device;1601 1602/*1603 * WMI SMM backend driver.1604 */1605static int dell_smm_wmi_probe(struct wmi_device *wdev, const void *context)1606{1607 struct dell_smm_ops *ops;1608 int ret;1609 1610 ops = devm_kzalloc(&wdev->dev, sizeof(*ops), GFP_KERNEL);1611 if (!ops)1612 return -ENOMEM;1613 1614 ops->smm_call = wmi_smm_call;1615 ops->smm_dev = &wdev->dev;1616 1617 if (dell_smm_get_signature(ops, I8K_SMM_GET_DELL_SIG1) &&1618 dell_smm_get_signature(ops, I8K_SMM_GET_DELL_SIG2))1619 return -ENODEV;1620 1621 ret = dell_smm_init_data(&wdev->dev, ops);1622 if (ret < 0)1623 return ret;1624 1625 return dell_smm_init_hwmon(&wdev->dev);1626}1627 1628static const struct wmi_device_id dell_smm_wmi_id_table[] = {1629 { DELL_SMM_WMI_GUID, NULL },1630 { }1631};1632MODULE_DEVICE_TABLE(wmi, dell_smm_wmi_id_table);1633 1634static struct wmi_driver dell_smm_wmi_driver = {1635 .driver = {1636 .name = KBUILD_MODNAME,1637 .probe_type = PROBE_PREFER_ASYNCHRONOUS,1638 },1639 .id_table = dell_smm_wmi_id_table,1640 .probe = dell_smm_wmi_probe,1641 .no_singleton = true,1642};1643 1644/*1645 * Probe for the presence of a supported laptop.1646 */1647static void __init dell_smm_init_dmi(void)1648{1649 struct i8k_fan_control_data *control;1650 struct i8k_config_data *config;1651 const struct dmi_system_id *id;1652 1653 if (dmi_check_system(i8k_blacklist_fan_support_dmi_table)) {1654 if (!force) {1655 pr_notice("Disabling fan support due to BIOS bugs\n");1656 disallow_fan_support = true;1657 } else {1658 pr_warn("Enabling fan support despite BIOS bugs\n");1659 }1660 }1661 1662 if (dmi_check_system(i8k_blacklist_fan_type_dmi_table)) {1663 if (!force) {1664 pr_notice("Disabling fan type call due to BIOS bugs\n");1665 disallow_fan_type_call = true;1666 } else {1667 pr_warn("Enabling fan type call despite BIOS bugs\n");1668 }1669 }1670 1671 /*1672 * Set fan multiplier and maximal fan speed from DMI config.1673 * Values specified in module parameters override values from DMI.1674 */1675 id = dmi_first_match(i8k_config_dmi_table);1676 if (id && id->driver_data) {1677 config = id->driver_data;1678 if (!fan_mult && config->fan_mult)1679 fan_mult = config->fan_mult;1680 1681 if (!fan_max && config->fan_max)1682 fan_max = config->fan_max;1683 }1684 1685 id = dmi_first_match(i8k_whitelist_fan_control);1686 if (id && id->driver_data) {1687 control = id->driver_data;1688 manual_fan = control->manual_fan;1689 auto_fan = control->auto_fan;1690 1691 pr_info("Enabling support for setting automatic/manual fan control\n");1692 }1693}1694 1695static int __init dell_smm_legacy_check(void)1696{1697 if (!dmi_check_system(i8k_dmi_table)) {1698 if (!ignore_dmi && !force)1699 return -ENODEV;1700 1701 pr_info("Probing for legacy SMM handler on unsupported machine\n");1702 pr_info("vendor=%s, model=%s, version=%s\n",1703 i8k_get_dmi_data(DMI_SYS_VENDOR),1704 i8k_get_dmi_data(DMI_PRODUCT_NAME),1705 i8k_get_dmi_data(DMI_BIOS_VERSION));1706 }1707 1708 if (dell_smm_get_signature(&i8k_smm_ops, I8K_SMM_GET_DELL_SIG1) &&1709 dell_smm_get_signature(&i8k_smm_ops, I8K_SMM_GET_DELL_SIG2)) {1710 if (!force)1711 return -ENODEV;1712 1713 pr_warn("Forcing legacy SMM calls on a possibly incompatible machine\n");1714 }1715 1716 return 0;1717}1718 1719static int __init i8k_init(void)1720{1721 int ret;1722 1723 dell_smm_init_dmi();1724 1725 ret = dell_smm_legacy_check();1726 if (ret < 0) {1727 /*1728 * On modern machines, SMM communication happens over WMI, meaning1729 * the SMM handler might not react to legacy SMM calls.1730 */1731 return wmi_driver_register(&dell_smm_wmi_driver);1732 }1733 1734 dell_smm_device = platform_create_bundle(&dell_smm_driver, dell_smm_probe, NULL, 0, NULL,1735 0);1736 1737 return PTR_ERR_OR_ZERO(dell_smm_device);1738}1739 1740static void __exit i8k_exit(void)1741{1742 if (dell_smm_device) {1743 platform_device_unregister(dell_smm_device);1744 platform_driver_unregister(&dell_smm_driver);1745 } else {1746 wmi_driver_unregister(&dell_smm_wmi_driver);1747 }1748}1749 1750module_init(i8k_init);1751module_exit(i8k_exit);1752