hwmon: (dell-smm) Speed up setting of fan speed
authorArmin Wolf <W_Armin@gmx.de>
Thu, 21 Oct 2021 19:05:31 +0000 (21:05 +0200)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Wed, 16 Feb 2022 11:43:55 +0000 (12:43 +0100)
commit c0d79987a0d82671bff374c07f2201f9bdf4aaa2 upstream.

When setting the fan speed, i8k_set_fan() calls i8k_get_fan_status(),
causing an unnecessary SMM call since from the two users of this
function, only i8k_ioctl_unlocked() needs to know the new fan status
while dell_smm_write() ignores the new fan status.
Since SMM calls can be very slow while also making error reporting
difficult for dell_smm_write(), remove the function call from
i8k_set_fan() and call it separately in i8k_ioctl_unlocked().

Tested on a Dell Inspiron 3505.

Signed-off-by: Armin Wolf <W_Armin@gmx.de>
Reviewed-by: Pali Rohár <pali@kernel.org>
Link: https://lore.kernel.org/r/20211021190531.17379-6-W_Armin@gmx.de
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
drivers/hwmon/dell-smm-hwmon.c

index d19ad92eede9531480cd2ca9abed6686973c54e3..b7d7f40885689470b2e36455a200b08a10e24bb0 100644 (file)
@@ -294,7 +294,7 @@ static int i8k_get_fan_nominal_speed(int fan, int speed)
 }
 
 /*
- * Set the fan speed (off, low, high). Returns the new fan status.
+ * Set the fan speed (off, low, high, ...).
  */
 static int i8k_set_fan(int fan, int speed)
 {
@@ -303,7 +303,7 @@ static int i8k_set_fan(int fan, int speed)
        speed = (speed < 0) ? 0 : ((speed > i8k_fan_max) ? i8k_fan_max : speed);
        regs.ebx = (fan & 0xff) | (speed << 8);
 
-       return i8k_smm(&regs) ? : i8k_get_fan_status(fan);
+       return i8k_smm(&regs);
 }
 
 static int i8k_get_temp_type(int sensor)
@@ -417,7 +417,7 @@ static int
 i8k_ioctl_unlocked(struct file *fp, unsigned int cmd, unsigned long arg)
 {
        int val = 0;
-       int speed;
+       int speed, err;
        unsigned char buff[16];
        int __user *argp = (int __user *)arg;
 
@@ -478,7 +478,11 @@ i8k_ioctl_unlocked(struct file *fp, unsigned int cmd, unsigned long arg)
                if (copy_from_user(&speed, argp + 1, sizeof(int)))
                        return -EFAULT;
 
-               val = i8k_set_fan(val, speed);
+               err = i8k_set_fan(val, speed);
+               if (err < 0)
+                       return err;
+
+               val = i8k_get_fan_status(val);
                break;
 
        default: