diff options
-rw-r--r-- | Documentation/hwmon/it87 | 4 | ||||
-rw-r--r-- | drivers/hwmon/it87.c | 32 |
2 files changed, 36 insertions, 0 deletions
diff --git a/Documentation/hwmon/it87 b/Documentation/hwmon/it87 index 0083bd317351..8d08bf0d38ed 100644 --- a/Documentation/hwmon/it87 +++ b/Documentation/hwmon/it87 | |||
@@ -177,3 +177,7 @@ between trip point N and trip point N+1 then the PWM output value is | |||
177 | the one of trip point N. The automatic control mode is less flexible | 177 | the one of trip point N. The automatic control mode is less flexible |
178 | than the manual control mode, but it reacts faster, is more robust and | 178 | than the manual control mode, but it reacts faster, is more robust and |
179 | doesn't use CPU cycles. | 179 | doesn't use CPU cycles. |
180 | |||
181 | Trip points must be set properly before switching to automatic fan speed | ||
182 | control mode. The driver will perform basic integrity checks before | ||
183 | actually switching to automatic control mode. | ||
diff --git a/drivers/hwmon/it87.c b/drivers/hwmon/it87.c index bbb0c7443b9b..1002befd87d5 100644 --- a/drivers/hwmon/it87.c +++ b/drivers/hwmon/it87.c | |||
@@ -719,6 +719,32 @@ static ssize_t set_fan_div(struct device *dev, struct device_attribute *attr, | |||
719 | mutex_unlock(&data->update_lock); | 719 | mutex_unlock(&data->update_lock); |
720 | return count; | 720 | return count; |
721 | } | 721 | } |
722 | |||
723 | /* Returns 0 if OK, -EINVAL otherwise */ | ||
724 | static int check_trip_points(struct device *dev, int nr) | ||
725 | { | ||
726 | const struct it87_data *data = dev_get_drvdata(dev); | ||
727 | int i, err = 0; | ||
728 | |||
729 | if (has_old_autopwm(data)) { | ||
730 | for (i = 0; i < 3; i++) { | ||
731 | if (data->auto_temp[nr][i] > data->auto_temp[nr][i + 1]) | ||
732 | err = -EINVAL; | ||
733 | } | ||
734 | for (i = 0; i < 2; i++) { | ||
735 | if (data->auto_pwm[nr][i] > data->auto_pwm[nr][i + 1]) | ||
736 | err = -EINVAL; | ||
737 | } | ||
738 | } | ||
739 | |||
740 | if (err) { | ||
741 | dev_err(dev, "Inconsistent trip points, not switching to " | ||
742 | "automatic mode\n"); | ||
743 | dev_err(dev, "Adjust the trip points and try again\n"); | ||
744 | } | ||
745 | return err; | ||
746 | } | ||
747 | |||
722 | static ssize_t set_pwm_enable(struct device *dev, | 748 | static ssize_t set_pwm_enable(struct device *dev, |
723 | struct device_attribute *attr, const char *buf, size_t count) | 749 | struct device_attribute *attr, const char *buf, size_t count) |
724 | { | 750 | { |
@@ -731,6 +757,12 @@ static ssize_t set_pwm_enable(struct device *dev, | |||
731 | if (strict_strtol(buf, 10, &val) < 0 || val < 0 || val > 2) | 757 | if (strict_strtol(buf, 10, &val) < 0 || val < 0 || val > 2) |
732 | return -EINVAL; | 758 | return -EINVAL; |
733 | 759 | ||
760 | /* Check trip points before switching to automatic mode */ | ||
761 | if (val == 2) { | ||
762 | if (check_trip_points(dev, nr) < 0) | ||
763 | return -EINVAL; | ||
764 | } | ||
765 | |||
734 | mutex_lock(&data->update_lock); | 766 | mutex_lock(&data->update_lock); |
735 | 767 | ||
736 | if (val == 0) { | 768 | if (val == 0) { |