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
Unified · Split
| @@ -238,7 +238,7 @@ static int i8k_get_fan_speed(int fan) · 237 unmodified lines | |||
| 238 | /* | 238 | /* |
| 239 | * Read the fan type. | 239 | * Read the fan type. |
| 240 | */ | 240 | */ |
| 241 | static int i8k_get_fan_type(int fan) | 241 | static int _i8k_get_fan_type(int fan) |
| 242 | { | 242 | { |
| 243 | struct smm_regs regs = { .eax = I8K_SMM_GET_FAN_TYPE, }; | 243 | struct smm_regs regs = { .eax = I8K_SMM_GET_FAN_TYPE, }; |
| 244 | 244 | ||
| @@ -249,6 +249,17 @@ static int i8k_get_fan_type(int fan) · 4 unmodified lines | |||
| 249 | return i8k_smm(®s) ? : regs.eax & 0xff; | 249 | return i8k_smm(®s) ? : regs.eax & 0xff; |
| 250 | } | 250 | } |
| 251 | 251 | ||
| 252 | static int i8k_get_fan_type(int fan) | ||
| 253 | { | ||
| 254 | /* I8K_SMM_GET_FAN_TYPE SMM call is expensive, so cache values */ | ||
| 255 | static int types[2] = { INT_MIN, INT_MIN }; | ||
| 256 | |||
| 257 | if (types[fan] == INT_MIN) | ||
| 258 | types[fan] = _i8k_get_fan_type(fan); | ||
| 259 | |||
| 260 | return types[fan]; | ||
| 261 | } | ||
| 262 | |||
| 252 | /* | 263 | /* |
| 253 | * Read the fan nominal rpm for specific fan speed. | 264 | * Read the fan nominal rpm for specific fan speed. |
| 254 | */ | 265 | */ |
| @@ -782,13 +793,17 @@ static int __init i8k_init_hwmon(void) · 527 unmodified lines | |||
| 782 | if (err >= 0) | 793 | if (err >= 0) |
| 783 | i8k_hwmon_flags |= I8K_HWMON_HAVE_TEMP4; | 794 | i8k_hwmon_flags |= I8K_HWMON_HAVE_TEMP4; |
| 784 | 795 | ||
| 785 | /* First fan attributes, if fan type is OK */ | 796 | /* First fan attributes, if fan status or type is OK */ |
| 786 | err = i8k_get_fan_type(0); | 797 | err = i8k_get_fan_status(0); |
| 798 | if (err < 0) | ||
| 799 | err = i8k_get_fan_type(0); | ||
| 787 | if (err >= 0) | 800 | if (err >= 0) |
| 788 | i8k_hwmon_flags |= I8K_HWMON_HAVE_FAN1; | 801 | i8k_hwmon_flags |= I8K_HWMON_HAVE_FAN1; |
| 789 | 802 | ||
| 790 | /* Second fan attributes, if fan type is OK */ | 803 | /* Second fan attributes, if fan status or type is OK */ |
| 791 | err = i8k_get_fan_type(1); | 804 | err = i8k_get_fan_status(1); |
| 805 | if (err < 0) | ||
| 806 | err = i8k_get_fan_type(1); | ||
| 792 | if (err >= 0) | 807 | if (err >= 0) |
| 793 | i8k_hwmon_flags |= I8K_HWMON_HAVE_FAN2; | 808 | i8k_hwmon_flags |= I8K_HWMON_HAVE_FAN2; |
| 794 | 809 | ||