diff options
author | Pali Rohár <pali.rohar@gmail.com> | 2016-06-17 18:54:48 -0400 |
---|---|---|
committer | Guenter Roeck <linux@roeck-us.net> | 2016-06-27 21:58:03 -0400 |
commit | 747bc8b063ae6b66447918280922253721cb1d9b (patch) | |
tree | 072e24eb7dae1f66fb4debc22433b0bdfe7dcb8a | |
parent | 68f86c75ca1eaf790907eb43c68f9f2996474116 (diff) |
hwmon: (dell-smm) Detect fan with index=2
Some Dell machines (e.g. Dell Precision M3800) have two fans, first with
index=0 and second with index=2. So export also attributes for third fan
device with index=2.
Reported-by: Tolga Cakir <cevelnet@gmail.com>
Signed-off-by: Pali Rohár <pali.rohar@gmail.com>
Tested-by: Tolga Cakir <cevelnet@gmail.com>
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
-rw-r--r-- | drivers/hwmon/dell-smm-hwmon.c | 24 |
1 files changed, 22 insertions, 2 deletions
diff --git a/drivers/hwmon/dell-smm-hwmon.c b/drivers/hwmon/dell-smm-hwmon.c index 2ac87d553e22..571d4984d39c 100644 --- a/drivers/hwmon/dell-smm-hwmon.c +++ b/drivers/hwmon/dell-smm-hwmon.c | |||
@@ -81,6 +81,7 @@ static bool disallow_fan_type_call; | |||
81 | #define I8K_HWMON_HAVE_TEMP4 (1 << 3) | 81 | #define I8K_HWMON_HAVE_TEMP4 (1 << 3) |
82 | #define I8K_HWMON_HAVE_FAN1 (1 << 4) | 82 | #define I8K_HWMON_HAVE_FAN1 (1 << 4) |
83 | #define I8K_HWMON_HAVE_FAN2 (1 << 5) | 83 | #define I8K_HWMON_HAVE_FAN2 (1 << 5) |
84 | #define I8K_HWMON_HAVE_FAN3 (1 << 6) | ||
84 | 85 | ||
85 | MODULE_AUTHOR("Massimo Dal Zotto (dz@debian.org)"); | 86 | MODULE_AUTHOR("Massimo Dal Zotto (dz@debian.org)"); |
86 | MODULE_AUTHOR("Pali Rohár <pali.rohar@gmail.com>"); | 87 | MODULE_AUTHOR("Pali Rohár <pali.rohar@gmail.com>"); |
@@ -252,7 +253,7 @@ static int _i8k_get_fan_type(int fan) | |||
252 | static int i8k_get_fan_type(int fan) | 253 | static int i8k_get_fan_type(int fan) |
253 | { | 254 | { |
254 | /* I8K_SMM_GET_FAN_TYPE SMM call is expensive, so cache values */ | 255 | /* I8K_SMM_GET_FAN_TYPE SMM call is expensive, so cache values */ |
255 | static int types[2] = { INT_MIN, INT_MIN }; | 256 | static int types[3] = { INT_MIN, INT_MIN, INT_MIN }; |
256 | 257 | ||
257 | if (types[fan] == INT_MIN) | 258 | if (types[fan] == INT_MIN) |
258 | types[fan] = _i8k_get_fan_type(fan); | 259 | types[fan] = _i8k_get_fan_type(fan); |
@@ -719,6 +720,12 @@ static SENSOR_DEVICE_ATTR(fan2_label, S_IRUGO, i8k_hwmon_show_fan_label, NULL, | |||
719 | 1); | 720 | 1); |
720 | static SENSOR_DEVICE_ATTR(pwm2, S_IRUGO | S_IWUSR, i8k_hwmon_show_pwm, | 721 | static SENSOR_DEVICE_ATTR(pwm2, S_IRUGO | S_IWUSR, i8k_hwmon_show_pwm, |
721 | i8k_hwmon_set_pwm, 1); | 722 | i8k_hwmon_set_pwm, 1); |
723 | static SENSOR_DEVICE_ATTR(fan3_input, S_IRUGO, i8k_hwmon_show_fan, NULL, | ||
724 | 2); | ||
725 | static SENSOR_DEVICE_ATTR(fan3_label, S_IRUGO, i8k_hwmon_show_fan_label, NULL, | ||
726 | 2); | ||
727 | static SENSOR_DEVICE_ATTR(pwm3, S_IRUGO | S_IWUSR, i8k_hwmon_show_pwm, | ||
728 | i8k_hwmon_set_pwm, 2); | ||
722 | 729 | ||
723 | static struct attribute *i8k_attrs[] = { | 730 | static struct attribute *i8k_attrs[] = { |
724 | &sensor_dev_attr_temp1_input.dev_attr.attr, /* 0 */ | 731 | &sensor_dev_attr_temp1_input.dev_attr.attr, /* 0 */ |
@@ -735,6 +742,9 @@ static struct attribute *i8k_attrs[] = { | |||
735 | &sensor_dev_attr_fan2_input.dev_attr.attr, /* 11 */ | 742 | &sensor_dev_attr_fan2_input.dev_attr.attr, /* 11 */ |
736 | &sensor_dev_attr_fan2_label.dev_attr.attr, /* 12 */ | 743 | &sensor_dev_attr_fan2_label.dev_attr.attr, /* 12 */ |
737 | &sensor_dev_attr_pwm2.dev_attr.attr, /* 13 */ | 744 | &sensor_dev_attr_pwm2.dev_attr.attr, /* 13 */ |
745 | &sensor_dev_attr_fan3_input.dev_attr.attr, /* 14 */ | ||
746 | &sensor_dev_attr_fan3_label.dev_attr.attr, /* 15 */ | ||
747 | &sensor_dev_attr_pwm3.dev_attr.attr, /* 16 */ | ||
738 | NULL | 748 | NULL |
739 | }; | 749 | }; |
740 | 750 | ||
@@ -742,7 +752,7 @@ static umode_t i8k_is_visible(struct kobject *kobj, struct attribute *attr, | |||
742 | int index) | 752 | int index) |
743 | { | 753 | { |
744 | if (disallow_fan_type_call && | 754 | if (disallow_fan_type_call && |
745 | (index == 9 || index == 12)) | 755 | (index == 9 || index == 12 || index == 15)) |
746 | return 0; | 756 | return 0; |
747 | if (index >= 0 && index <= 1 && | 757 | if (index >= 0 && index <= 1 && |
748 | !(i8k_hwmon_flags & I8K_HWMON_HAVE_TEMP1)) | 758 | !(i8k_hwmon_flags & I8K_HWMON_HAVE_TEMP1)) |
@@ -762,6 +772,9 @@ static umode_t i8k_is_visible(struct kobject *kobj, struct attribute *attr, | |||
762 | if (index >= 11 && index <= 13 && | 772 | if (index >= 11 && index <= 13 && |
763 | !(i8k_hwmon_flags & I8K_HWMON_HAVE_FAN2)) | 773 | !(i8k_hwmon_flags & I8K_HWMON_HAVE_FAN2)) |
764 | return 0; | 774 | return 0; |
775 | if (index >= 14 && index <= 16 && | ||
776 | !(i8k_hwmon_flags & I8K_HWMON_HAVE_FAN3)) | ||
777 | return 0; | ||
765 | 778 | ||
766 | return attr->mode; | 779 | return attr->mode; |
767 | } | 780 | } |
@@ -807,6 +820,13 @@ static int __init i8k_init_hwmon(void) | |||
807 | if (err >= 0) | 820 | if (err >= 0) |
808 | i8k_hwmon_flags |= I8K_HWMON_HAVE_FAN2; | 821 | i8k_hwmon_flags |= I8K_HWMON_HAVE_FAN2; |
809 | 822 | ||
823 | /* Third fan attributes, if fan status or type is OK */ | ||
824 | err = i8k_get_fan_status(2); | ||
825 | if (err < 0) | ||
826 | err = i8k_get_fan_type(2); | ||
827 | if (err >= 0) | ||
828 | i8k_hwmon_flags |= I8K_HWMON_HAVE_FAN3; | ||
829 | |||
810 | i8k_hwmon_dev = hwmon_device_register_with_groups(NULL, "dell_smm", | 830 | i8k_hwmon_dev = hwmon_device_register_with_groups(NULL, "dell_smm", |
811 | NULL, i8k_groups); | 831 | NULL, i8k_groups); |
812 | if (IS_ERR(i8k_hwmon_dev)) { | 832 | if (IS_ERR(i8k_hwmon_dev)) { |