summaryrefslogtreecommitdiffstats
path: root/drivers/hwmon
diff options
context:
space:
mode:
authorArmin Wolf <W_Armin@gmx.de>2021-10-21 21:05:31 +0200
committerGuenter Roeck <linux@roeck-us.net>2021-10-21 22:14:27 +0200
commitc0d79987a0d82671bff374c07f2201f9bdf4aaa2 (patch)
tree0d8dc6f7d726d96fe901c12f040d6b9f7f1504cc /drivers/hwmon
parenthwmon: (dell-smm) Add comment explaining usage of i8k_config_data[] (diff)
downloadlinux-c0d79987a0d82671bff374c07f2201f9bdf4aaa2.tar.xz
linux-c0d79987a0d82671bff374c07f2201f9bdf4aaa2.zip
hwmon: (dell-smm) Speed up setting of fan speed
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>
Diffstat (limited to 'drivers/hwmon')
-rw-r--r--drivers/hwmon/dell-smm-hwmon.c12
1 files changed, 8 insertions, 4 deletions
diff --git a/drivers/hwmon/dell-smm-hwmon.c b/drivers/hwmon/dell-smm-hwmon.c
index 0e1bc3a2dd12..eaace478f508 100644
--- a/drivers/hwmon/dell-smm-hwmon.c
+++ b/drivers/hwmon/dell-smm-hwmon.c
@@ -327,7 +327,7 @@ static int i8k_enable_fan_auto_mode(const struct dell_smm_data *data, bool enabl
}
/*
- * Set the fan speed (off, low, high). Returns the new fan status.
+ * Set the fan speed (off, low, high, ...).
*/
static int i8k_set_fan(const struct dell_smm_data *data, int fan, int speed)
{
@@ -339,7 +339,7 @@ static int i8k_set_fan(const struct dell_smm_data *data, int fan, int speed)
speed = (speed < 0) ? 0 : ((speed > data->i8k_fan_max) ? data->i8k_fan_max : speed);
regs.ebx = (fan & 0xff) | (speed << 8);
- return i8k_smm(&regs) ? : i8k_get_fan_status(data, fan);
+ return i8k_smm(&regs);
}
static int __init i8k_get_temp_type(int sensor)
@@ -453,7 +453,7 @@ static int
i8k_ioctl_unlocked(struct file *fp, struct dell_smm_data *data, unsigned int cmd, unsigned long arg)
{
int val = 0;
- int speed;
+ int speed, err;
unsigned char buff[16];
int __user *argp = (int __user *)arg;
@@ -513,7 +513,11 @@ i8k_ioctl_unlocked(struct file *fp, struct dell_smm_data *data, unsigned int cmd
if (copy_from_user(&speed, argp + 1, sizeof(int)))
return -EFAULT;
- val = i8k_set_fan(data, val, speed);
+ err = i8k_set_fan(data, val, speed);
+ if (err < 0)
+ return err;
+
+ val = i8k_get_fan_status(data, val);
break;
default: