Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

hwmon: Allow to compile dell-smm-hwmon driver without /proc/i8k

This patch splits CONFIG_I8K compile option to SENSORS_DELL_SMM and CONFIG_I8K.
Option SENSORS_DELL_SMM is now used to enable compilation of dell-smm-hwmon
driver and old CONFIG_I8K option to enable /proc/i8k interface in driver.

So this change allows to compile dell-smm-hwmon driver without legacy /proc/i8k
interface which is needed only for old Dell Inspirion models or for userspace
i8kutils package.

For backward compatibility when CONFIG_I8K is enabled then also SENSORS_DELL_SMM
is enabled and so driver dell-smm-hwmon (with /proc/i8k) is compiled.

Signed-off-by: Pali Rohár <pali.rohar@gmail.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>

authored by

Pali Rohár and committed by
Greg Kroah-Hartman
039ae585 a5afba16

+106 -82
+10 -15
arch/x86/Kconfig
··· 1055 1055 Say N otherwise. 1056 1056 1057 1057 config I8K 1058 - tristate "Dell laptop support" 1058 + tristate "Dell i8k legacy laptop support" 1059 1059 select HWMON 1060 + select SENSORS_DELL_SMM 1060 1061 ---help--- 1061 - This adds a driver to safely access the System Management Mode 1062 - of the CPU on the Dell Inspiron 8000. The System Management Mode 1063 - is used to read cpu temperature and cooling fan status and to 1064 - control the fans on the I8K portables. 1062 + This option enables legacy /proc/i8k userspace interface in hwmon 1063 + dell-smm-hwmon driver. Character file /proc/i8k reports bios version, 1064 + temperature and allows controlling fan speeds of Dell laptops via 1065 + System Management Mode. For old Dell laptops (like Dell Inspiron 8000) 1066 + it reports also power and hotkey status. For fan speed control is 1067 + needed userspace package i8kutils. 1065 1068 1066 - This driver has been tested only on the Inspiron 8000 but it may 1067 - also work with other Dell laptops. You can force loading on other 1068 - models by passing the parameter `force=1' to the module. Use at 1069 - your own risk. 1070 - 1071 - For information on utilities to make use of this driver see the 1072 - I8K Linux utilities web site at: 1073 - <http://people.debian.org/~dz/i8k/> 1074 - 1075 - Say Y if you intend to run this kernel on a Dell Inspiron 8000. 1069 + Say Y if you intend to run this kernel on old Dell laptops or want to 1070 + use userspace package i8kutils. 1076 1071 Say N otherwise. 1077 1072 1078 1073 config X86_REBOOTFIXUPS
+11
drivers/hwmon/Kconfig
··· 371 371 This driver can also be built as a module. If so, the module 372 372 will be called ds1621. 373 373 374 + config SENSORS_DELL_SMM 375 + tristate "Dell laptop SMM BIOS hwmon driver" 376 + depends on X86 377 + help 378 + This hwmon driver adds support for reporting temperature of different 379 + sensors and controls the fans on Dell laptops via System Management 380 + Mode provided by Dell BIOS. 381 + 382 + When option I8K is also enabled this driver provides legacy /proc/i8k 383 + userspace interface for i8kutils package. 384 + 374 385 config SENSORS_DA9052_ADC 375 386 tristate "Dialog DA9052/DA9053 ADC" 376 387 depends on PMIC_DA9052
+1 -1
drivers/hwmon/Makefile
··· 49 49 obj-$(CONFIG_SENSORS_CORETEMP) += coretemp.o 50 50 obj-$(CONFIG_SENSORS_DA9052_ADC)+= da9052-hwmon.o 51 51 obj-$(CONFIG_SENSORS_DA9055)+= da9055-hwmon.o 52 + obj-$(CONFIG_SENSORS_DELL_SMM) += dell-smm-hwmon.o 52 53 obj-$(CONFIG_SENSORS_DME1737) += dme1737.o 53 54 obj-$(CONFIG_SENSORS_DS620) += ds620.o 54 55 obj-$(CONFIG_SENSORS_DS1621) += ds1621.o ··· 157 156 obj-$(CONFIG_SENSORS_W83L786NG) += w83l786ng.o 158 157 obj-$(CONFIG_SENSORS_WM831X) += wm831x-hwmon.o 159 158 obj-$(CONFIG_SENSORS_WM8350) += wm8350-hwmon.o 160 - obj-$(CONFIG_I8K) += dell-smm-hwmon.o 161 159 162 160 obj-$(CONFIG_PMBUS) += pmbus/ 163 161
+84 -66
drivers/hwmon/dell-smm-hwmon.c
··· 81 81 82 82 MODULE_AUTHOR("Massimo Dal Zotto (dz@debian.org)"); 83 83 MODULE_AUTHOR("Pali Rohár <pali.rohar@gmail.com>"); 84 - MODULE_DESCRIPTION("Driver for accessing SMM BIOS on Dell laptops"); 84 + MODULE_DESCRIPTION("Dell laptop SMM BIOS hwmon driver"); 85 85 MODULE_LICENSE("GPL"); 86 86 MODULE_ALIAS("i8k"); 87 87 ··· 93 93 module_param(ignore_dmi, bool, 0); 94 94 MODULE_PARM_DESC(ignore_dmi, "Continue probing hardware even if DMI data does not match"); 95 95 96 + #if IS_ENABLED(CONFIG_I8K) 96 97 static bool restricted; 97 98 module_param(restricted, bool, 0); 98 99 MODULE_PARM_DESC(restricted, "Allow fan control if SYS_ADMIN capability set"); ··· 101 100 static bool power_status; 102 101 module_param(power_status, bool, 0600); 103 102 MODULE_PARM_DESC(power_status, "Report power status in /proc/i8k"); 103 + #endif 104 104 105 105 static uint fan_mult; 106 106 module_param(fan_mult, uint, 0); ··· 110 108 static uint fan_max; 111 109 module_param(fan_max, uint, 0); 112 110 MODULE_PARM_DESC(fan_max, "Maximum configurable fan speed (default: autodetect)"); 113 - 114 - static int i8k_open_fs(struct inode *inode, struct file *file); 115 - static long i8k_ioctl(struct file *, unsigned int, unsigned long); 116 - 117 - static const struct file_operations i8k_fops = { 118 - .owner = THIS_MODULE, 119 - .open = i8k_open_fs, 120 - .read = seq_read, 121 - .llseek = seq_lseek, 122 - .release = single_release, 123 - .unlocked_ioctl = i8k_ioctl, 124 - }; 125 111 126 112 struct smm_regs { 127 113 unsigned int eax; ··· 208 218 set_cpus_allowed_ptr(current, old_mask); 209 219 free_cpumask_var(old_mask); 210 220 return rc; 211 - } 212 - 213 - /* 214 - * Read the Fn key status. 215 - */ 216 - static int i8k_get_fn_status(void) 217 - { 218 - struct smm_regs regs = { .eax = I8K_SMM_FN_STATUS, }; 219 - int rc; 220 - 221 - rc = i8k_smm(&regs); 222 - if (rc < 0) 223 - return rc; 224 - 225 - switch ((regs.eax >> I8K_FN_SHIFT) & I8K_FN_MASK) { 226 - case I8K_FN_UP: 227 - return I8K_VOL_UP; 228 - case I8K_FN_DOWN: 229 - return I8K_VOL_DOWN; 230 - case I8K_FN_MUTE: 231 - return I8K_VOL_MUTE; 232 - default: 233 - return 0; 234 - } 235 - } 236 - 237 - /* 238 - * Read the power status. 239 - */ 240 - static int i8k_get_power_status(void) 241 - { 242 - struct smm_regs regs = { .eax = I8K_SMM_POWER_STATUS, }; 243 - int rc; 244 - 245 - rc = i8k_smm(&regs); 246 - if (rc < 0) 247 - return rc; 248 - 249 - return (regs.eax & 0xff) == I8K_POWER_AC ? I8K_AC : I8K_BATTERY; 250 221 } 251 222 252 223 /* ··· 328 377 329 378 return regs.eax == 1145651527 && regs.edx == 1145392204 ? 0 : -1; 330 379 } 380 + 381 + #if IS_ENABLED(CONFIG_I8K) 382 + 383 + /* 384 + * Read the Fn key status. 385 + */ 386 + static int i8k_get_fn_status(void) 387 + { 388 + struct smm_regs regs = { .eax = I8K_SMM_FN_STATUS, }; 389 + int rc; 390 + 391 + rc = i8k_smm(&regs); 392 + if (rc < 0) 393 + return rc; 394 + 395 + switch ((regs.eax >> I8K_FN_SHIFT) & I8K_FN_MASK) { 396 + case I8K_FN_UP: 397 + return I8K_VOL_UP; 398 + case I8K_FN_DOWN: 399 + return I8K_VOL_DOWN; 400 + case I8K_FN_MUTE: 401 + return I8K_VOL_MUTE; 402 + default: 403 + return 0; 404 + } 405 + } 406 + 407 + /* 408 + * Read the power status. 409 + */ 410 + static int i8k_get_power_status(void) 411 + { 412 + struct smm_regs regs = { .eax = I8K_SMM_POWER_STATUS, }; 413 + int rc; 414 + 415 + rc = i8k_smm(&regs); 416 + if (rc < 0) 417 + return rc; 418 + 419 + return (regs.eax & 0xff) == I8K_POWER_AC ? I8K_AC : I8K_BATTERY; 420 + } 421 + 422 + /* 423 + * Procfs interface 424 + */ 331 425 332 426 static int 333 427 i8k_ioctl_unlocked(struct file *fp, unsigned int cmd, unsigned long arg) ··· 524 528 return single_open(file, i8k_proc_show, NULL); 525 529 } 526 530 531 + static const struct file_operations i8k_fops = { 532 + .owner = THIS_MODULE, 533 + .open = i8k_open_fs, 534 + .read = seq_read, 535 + .llseek = seq_lseek, 536 + .release = single_release, 537 + .unlocked_ioctl = i8k_ioctl, 538 + }; 539 + 540 + static void __init i8k_init_procfs(void) 541 + { 542 + /* Register the proc entry */ 543 + proc_create("i8k", 0, NULL, &i8k_fops); 544 + } 545 + 546 + static void __exit i8k_exit_procfs(void) 547 + { 548 + remove_proc_entry("i8k", NULL); 549 + } 550 + 551 + #else 552 + 553 + static inline void __init i8k_init_procfs(void) 554 + { 555 + } 556 + 557 + static inline void __exit i8k_exit_procfs(void) 558 + { 559 + } 560 + 561 + #endif 527 562 528 563 /* 529 564 * Hwmon interface ··· 777 750 if (err >= 0) 778 751 i8k_hwmon_flags |= I8K_HWMON_HAVE_FAN2; 779 752 780 - i8k_hwmon_dev = hwmon_device_register_with_groups(NULL, "i8k", NULL, 781 - i8k_groups); 753 + i8k_hwmon_dev = hwmon_device_register_with_groups(NULL, "dell-smm", 754 + NULL, i8k_groups); 782 755 if (IS_ERR(i8k_hwmon_dev)) { 783 756 err = PTR_ERR(i8k_hwmon_dev); 784 757 i8k_hwmon_dev = NULL; ··· 1003 976 1004 977 static int __init i8k_init(void) 1005 978 { 1006 - struct proc_dir_entry *proc_i8k; 1007 979 int err; 1008 980 1009 981 /* Are we running on an supported laptop? */ 1010 982 if (i8k_probe()) 1011 983 return -ENODEV; 1012 984 1013 - /* Register the proc entry */ 1014 - proc_i8k = proc_create("i8k", 0, NULL, &i8k_fops); 1015 - if (!proc_i8k) 1016 - return -ENOENT; 1017 - 1018 985 err = i8k_init_hwmon(); 1019 986 if (err) 1020 - goto exit_remove_proc; 987 + return err; 1021 988 989 + i8k_init_procfs(); 1022 990 return 0; 1023 - 1024 - exit_remove_proc: 1025 - remove_proc_entry("i8k", NULL); 1026 - return err; 1027 991 } 1028 992 1029 993 static void __exit i8k_exit(void) 1030 994 { 1031 995 hwmon_device_unregister(i8k_hwmon_dev); 1032 - remove_proc_entry("i8k", NULL); 996 + i8k_exit_procfs(); 1033 997 } 1034 998 1035 999 module_init(i8k_init);