hwmon: Allow to compile dell-smm-hwmon driver without /proc/i8k
authorPali Rohár <pali.rohar@gmail.com>
Thu, 14 May 2015 11:16:37 +0000 (13:16 +0200)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Sun, 24 May 2015 19:48:12 +0000 (12:48 -0700)
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>
arch/x86/Kconfig
drivers/hwmon/Kconfig
drivers/hwmon/Makefile
drivers/hwmon/dell-smm-hwmon.c

index 226d5696e1d1dd5fe715124710b0f2cd04f8c495..7b756b337926b73a2bfe492cce64665439639db2 100644 (file)
@@ -1055,24 +1055,19 @@ config TOSHIBA
          Say N otherwise.
 
 config I8K
-       tristate "Dell laptop support"
+       tristate "Dell i8k legacy laptop support"
        select HWMON
+       select SENSORS_DELL_SMM
        ---help---
-         This adds a driver to safely access the System Management Mode
-         of the CPU on the Dell Inspiron 8000. The System Management Mode
-         is used to read cpu temperature and cooling fan status and to
-         control the fans on the I8K portables.
+         This option enables legacy /proc/i8k userspace interface in hwmon
+         dell-smm-hwmon driver. Character file /proc/i8k reports bios version,
+         temperature and allows controlling fan speeds of Dell laptops via
+         System Management Mode. For old Dell laptops (like Dell Inspiron 8000)
+         it reports also power and hotkey status. For fan speed control is
+         needed userspace package i8kutils.
 
-         This driver has been tested only on the Inspiron 8000 but it may
-         also work with other Dell laptops. You can force loading on other
-         models by passing the parameter `force=1' to the module. Use at
-         your own risk.
-
-         For information on utilities to make use of this driver see the
-         I8K Linux utilities web site at:
-         <http://people.debian.org/~dz/i8k/>
-
-         Say Y if you intend to run this kernel on a Dell Inspiron 8000.
+         Say Y if you intend to run this kernel on old Dell laptops or want to
+         use userspace package i8kutils.
          Say N otherwise.
 
 config X86_REBOOTFIXUPS
index 25d9e72627e9df97cb607de8038d2310d28c214b..bc9d90b108d2d1063a5e366c21638c536d750451 100644 (file)
@@ -371,6 +371,17 @@ config SENSORS_DS1621
          This driver can also be built as a module.  If so, the module
          will be called ds1621.
 
+config SENSORS_DELL_SMM
+       tristate "Dell laptop SMM BIOS hwmon driver"
+       depends on X86
+       help
+         This hwmon driver adds support for reporting temperature of different
+         sensors and controls the fans on Dell laptops via System Management
+         Mode provided by Dell BIOS.
+
+         When option I8K is also enabled this driver provides legacy /proc/i8k
+         userspace interface for i8kutils package.
+
 config SENSORS_DA9052_ADC
        tristate "Dialog DA9052/DA9053 ADC"
        depends on PMIC_DA9052
index 51533acfa01e9722cfe3948b427e94edf0d9c513..6cacd0ff06c3e6425c422e4fabaf56b4eba238ea 100644 (file)
@@ -49,6 +49,7 @@ obj-$(CONFIG_SENSORS_ATXP1)   += atxp1.o
 obj-$(CONFIG_SENSORS_CORETEMP) += coretemp.o
 obj-$(CONFIG_SENSORS_DA9052_ADC)+= da9052-hwmon.o
 obj-$(CONFIG_SENSORS_DA9055)+= da9055-hwmon.o
+obj-$(CONFIG_SENSORS_DELL_SMM) += dell-smm-hwmon.o
 obj-$(CONFIG_SENSORS_DME1737)  += dme1737.o
 obj-$(CONFIG_SENSORS_DS620)    += ds620.o
 obj-$(CONFIG_SENSORS_DS1621)   += ds1621.o
@@ -156,7 +157,6 @@ obj-$(CONFIG_SENSORS_W83L785TS)     += w83l785ts.o
 obj-$(CONFIG_SENSORS_W83L786NG)        += w83l786ng.o
 obj-$(CONFIG_SENSORS_WM831X)   += wm831x-hwmon.o
 obj-$(CONFIG_SENSORS_WM8350)   += wm8350-hwmon.o
-obj-$(CONFIG_I8K)              += dell-smm-hwmon.o
 
 obj-$(CONFIG_PMBUS)            += pmbus/
 
index 65d314b0f197add98cdf212e73be7ff190c33d56..2a808822af2163d89d83fb02ce1e67eb5f1474d7 100644 (file)
@@ -81,7 +81,7 @@ static uint i8k_fan_max = I8K_FAN_HIGH;
 
 MODULE_AUTHOR("Massimo Dal Zotto (dz@debian.org)");
 MODULE_AUTHOR("Pali Rohár <pali.rohar@gmail.com>");
-MODULE_DESCRIPTION("Driver for accessing SMM BIOS on Dell laptops");
+MODULE_DESCRIPTION("Dell laptop SMM BIOS hwmon driver");
 MODULE_LICENSE("GPL");
 MODULE_ALIAS("i8k");
 
@@ -93,6 +93,7 @@ static bool ignore_dmi;
 module_param(ignore_dmi, bool, 0);
 MODULE_PARM_DESC(ignore_dmi, "Continue probing hardware even if DMI data does not match");
 
+#if IS_ENABLED(CONFIG_I8K)
 static bool restricted;
 module_param(restricted, bool, 0);
 MODULE_PARM_DESC(restricted, "Allow fan control if SYS_ADMIN capability set");
@@ -100,6 +101,7 @@ MODULE_PARM_DESC(restricted, "Allow fan control if SYS_ADMIN capability set");
 static bool power_status;
 module_param(power_status, bool, 0600);
 MODULE_PARM_DESC(power_status, "Report power status in /proc/i8k");
+#endif
 
 static uint fan_mult;
 module_param(fan_mult, uint, 0);
@@ -109,18 +111,6 @@ static uint fan_max;
 module_param(fan_max, uint, 0);
 MODULE_PARM_DESC(fan_max, "Maximum configurable fan speed (default: autodetect)");
 
-static int i8k_open_fs(struct inode *inode, struct file *file);
-static long i8k_ioctl(struct file *, unsigned int, unsigned long);
-
-static const struct file_operations i8k_fops = {
-       .owner          = THIS_MODULE,
-       .open           = i8k_open_fs,
-       .read           = seq_read,
-       .llseek         = seq_lseek,
-       .release        = single_release,
-       .unlocked_ioctl = i8k_ioctl,
-};
-
 struct smm_regs {
        unsigned int eax;
        unsigned int ebx __packed;
@@ -220,45 +210,6 @@ out:
        return rc;
 }
 
-/*
- * Read the Fn key status.
- */
-static int i8k_get_fn_status(void)
-{
-       struct smm_regs regs = { .eax = I8K_SMM_FN_STATUS, };
-       int rc;
-
-       rc = i8k_smm(&regs);
-       if (rc < 0)
-               return rc;
-
-       switch ((regs.eax >> I8K_FN_SHIFT) & I8K_FN_MASK) {
-       case I8K_FN_UP:
-               return I8K_VOL_UP;
-       case I8K_FN_DOWN:
-               return I8K_VOL_DOWN;
-       case I8K_FN_MUTE:
-               return I8K_VOL_MUTE;
-       default:
-               return 0;
-       }
-}
-
-/*
- * Read the power status.
- */
-static int i8k_get_power_status(void)
-{
-       struct smm_regs regs = { .eax = I8K_SMM_POWER_STATUS, };
-       int rc;
-
-       rc = i8k_smm(&regs);
-       if (rc < 0)
-               return rc;
-
-       return (regs.eax & 0xff) == I8K_POWER_AC ? I8K_AC : I8K_BATTERY;
-}
-
 /*
  * Read the fan status.
  */
@@ -378,6 +329,51 @@ static int i8k_get_dell_signature(int req_fn)
        return regs.eax == 1145651527 && regs.edx == 1145392204 ? 0 : -1;
 }
 
+#if IS_ENABLED(CONFIG_I8K)
+
+/*
+ * Read the Fn key status.
+ */
+static int i8k_get_fn_status(void)
+{
+       struct smm_regs regs = { .eax = I8K_SMM_FN_STATUS, };
+       int rc;
+
+       rc = i8k_smm(&regs);
+       if (rc < 0)
+               return rc;
+
+       switch ((regs.eax >> I8K_FN_SHIFT) & I8K_FN_MASK) {
+       case I8K_FN_UP:
+               return I8K_VOL_UP;
+       case I8K_FN_DOWN:
+               return I8K_VOL_DOWN;
+       case I8K_FN_MUTE:
+               return I8K_VOL_MUTE;
+       default:
+               return 0;
+       }
+}
+
+/*
+ * Read the power status.
+ */
+static int i8k_get_power_status(void)
+{
+       struct smm_regs regs = { .eax = I8K_SMM_POWER_STATUS, };
+       int rc;
+
+       rc = i8k_smm(&regs);
+       if (rc < 0)
+               return rc;
+
+       return (regs.eax & 0xff) == I8K_POWER_AC ? I8K_AC : I8K_BATTERY;
+}
+
+/*
+ * Procfs interface
+ */
+
 static int
 i8k_ioctl_unlocked(struct file *fp, unsigned int cmd, unsigned long arg)
 {
@@ -528,6 +524,37 @@ static int i8k_open_fs(struct inode *inode, struct file *file)
        return single_open(file, i8k_proc_show, NULL);
 }
 
+static const struct file_operations i8k_fops = {
+       .owner          = THIS_MODULE,
+       .open           = i8k_open_fs,
+       .read           = seq_read,
+       .llseek         = seq_lseek,
+       .release        = single_release,
+       .unlocked_ioctl = i8k_ioctl,
+};
+
+static void __init i8k_init_procfs(void)
+{
+       /* Register the proc entry */
+       proc_create("i8k", 0, NULL, &i8k_fops);
+}
+
+static void __exit i8k_exit_procfs(void)
+{
+       remove_proc_entry("i8k", NULL);
+}
+
+#else
+
+static inline void __init i8k_init_procfs(void)
+{
+}
+
+static inline void __exit i8k_exit_procfs(void)
+{
+}
+
+#endif
 
 /*
  * Hwmon interface
@@ -750,8 +777,8 @@ static int __init i8k_init_hwmon(void)
        if (err >= 0)
                i8k_hwmon_flags |= I8K_HWMON_HAVE_FAN2;
 
-       i8k_hwmon_dev = hwmon_device_register_with_groups(NULL, "i8k", NULL,
-                                                         i8k_groups);
+       i8k_hwmon_dev = hwmon_device_register_with_groups(NULL, "dell-smm",
+                                                         NULL, i8k_groups);
        if (IS_ERR(i8k_hwmon_dev)) {
                err = PTR_ERR(i8k_hwmon_dev);
                i8k_hwmon_dev = NULL;
@@ -976,33 +1003,24 @@ static int __init i8k_probe(void)
 
 static int __init i8k_init(void)
 {
-       struct proc_dir_entry *proc_i8k;
        int err;
 
        /* Are we running on an supported laptop? */
        if (i8k_probe())
                return -ENODEV;
 
-       /* Register the proc entry */
-       proc_i8k = proc_create("i8k", 0, NULL, &i8k_fops);
-       if (!proc_i8k)
-               return -ENOENT;
-
        err = i8k_init_hwmon();
        if (err)
-               goto exit_remove_proc;
+               return err;
 
+       i8k_init_procfs();
        return 0;
-
- exit_remove_proc:
-       remove_proc_entry("i8k", NULL);
-       return err;
 }
 
 static void __exit i8k_exit(void)
 {
        hwmon_device_unregister(i8k_hwmon_dev);
-       remove_proc_entry("i8k", NULL);
+       i8k_exit_procfs();
 }
 
 module_init(i8k_init);