Эх сурвалжийг харах

Merge tag 'hwmon-for-linus-v4.7-rc5' of git://git.kernel.org/pub/scm/linux/kernel/git/groeck/linux-staging

Pull hwmon fix from Guenter Roeck:
 "Improve fan type detection for dell-smm to prevent kernel hang"

* tag 'hwmon-for-linus-v4.7-rc5' of git://git.kernel.org/pub/scm/linux/kernel/git/groeck/linux-staging:
  hwmon: (dell-smm) Cache fan_type() calls and change fan detection
Linus Torvalds 9 жил өмнө
parent
commit
260eaba4ea

+ 20 - 5
drivers/hwmon/dell-smm-hwmon.c

@@ -238,7 +238,7 @@ static int i8k_get_fan_speed(int fan)
 /*
 /*
  * Read the fan type.
  * Read the fan type.
  */
  */
-static int i8k_get_fan_type(int fan)
+static int _i8k_get_fan_type(int fan)
 {
 {
 	struct smm_regs regs = { .eax = I8K_SMM_GET_FAN_TYPE, };
 	struct smm_regs regs = { .eax = I8K_SMM_GET_FAN_TYPE, };
 
 
@@ -249,6 +249,17 @@ static int i8k_get_fan_type(int fan)
 	return i8k_smm(&regs) ? : regs.eax & 0xff;
 	return i8k_smm(&regs) ? : regs.eax & 0xff;
 }
 }
 
 
+static int i8k_get_fan_type(int fan)
+{
+	/* I8K_SMM_GET_FAN_TYPE SMM call is expensive, so cache values */
+	static int types[2] = { INT_MIN, INT_MIN };
+
+	if (types[fan] == INT_MIN)
+		types[fan] = _i8k_get_fan_type(fan);
+
+	return types[fan];
+}
+
 /*
 /*
  * Read the fan nominal rpm for specific fan speed.
  * Read the fan nominal rpm for specific fan speed.
  */
  */
@@ -782,13 +793,17 @@ static int __init i8k_init_hwmon(void)
 	if (err >= 0)
 	if (err >= 0)
 		i8k_hwmon_flags |= I8K_HWMON_HAVE_TEMP4;
 		i8k_hwmon_flags |= I8K_HWMON_HAVE_TEMP4;
 
 
-	/* First fan attributes, if fan type is OK */
-	err = i8k_get_fan_type(0);
+	/* First fan attributes, if fan status or type is OK */
+	err = i8k_get_fan_status(0);
+	if (err < 0)
+		err = i8k_get_fan_type(0);
 	if (err >= 0)
 	if (err >= 0)
 		i8k_hwmon_flags |= I8K_HWMON_HAVE_FAN1;
 		i8k_hwmon_flags |= I8K_HWMON_HAVE_FAN1;
 
 
-	/* Second fan attributes, if fan type is OK */
-	err = i8k_get_fan_type(1);
+	/* Second fan attributes, if fan status or type is OK */
+	err = i8k_get_fan_status(1);
+	if (err < 0)
+		err = i8k_get_fan_type(1);
 	if (err >= 0)
 	if (err >= 0)
 		i8k_hwmon_flags |= I8K_HWMON_HAVE_FAN2;
 		i8k_hwmon_flags |= I8K_HWMON_HAVE_FAN2;