brintos

brintos / linux-shallow public Read only

0
0
Text · 38.6 KiB · f5bdf84 Raw
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		&regs->eax,256		&regs->ebx,257		&regs->ecx,258		&regs->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, &regs) ? : 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, &regs) ? : (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, &regs) ? : 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, &regs) ? : (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, &regs);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, &regs);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, &regs) ? : 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, &regs) ? : 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, &regs);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, &regs);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, &regs);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