aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNikolaus Schulz <mail@microschulz.de>2012-02-28 16:15:54 -0500
committerGuenter Roeck <guenter.roeck@ericsson.com>2012-03-02 15:02:23 -0500
commit15d1ad0cc9d2d3f549afddbcdbc9c3637f0d1331 (patch)
treeba695785e271b487c591b86c518f32449258497a
parentb17d6561acc16265b65b1e0d27b649829b61a7e3 (diff)
hwmon: (f75375s) Catch some attempts to write to r/o registers
It makes no sense to attempt to manually configure the fan in auto mode, or set the duty cycle directly in closed loop mode. The corresponding registers are then read-only. If the user tries it nonetheless, error out with EINVAL instead of silently doing nothing. Signed-off-by: Nikolaus Schulz <mail@microschulz.de> [guenter.roeck@ericsson.com: Minor formatting cleanup] Signed-off-by: Guenter Roeck <guenter.roeck@ericsson.com>
-rw-r--r--drivers/hwmon/f75375s.c27
1 files changed, 27 insertions, 0 deletions
diff --git a/drivers/hwmon/f75375s.c b/drivers/hwmon/f75375s.c
index 9ab034a1b4c1..6aa5a9fad879 100644
--- a/drivers/hwmon/f75375s.c
+++ b/drivers/hwmon/f75375s.c
@@ -279,6 +279,21 @@ static bool duty_mode_enabled(u8 pwm_enable)
279 } 279 }
280} 280}
281 281
282static bool auto_mode_enabled(u8 pwm_enable)
283{
284 switch (pwm_enable) {
285 case 0: /* Manual, duty mode (full speed) */
286 case 1: /* Manual, duty mode */
287 case 3: /* Manual, speed mode */
288 return false;
289 case 2: /* Auto, speed mode */
290 case 4: /* Auto, duty mode */
291 return true;
292 default:
293 BUG();
294 }
295}
296
282static ssize_t set_fan_min(struct device *dev, struct device_attribute *attr, 297static ssize_t set_fan_min(struct device *dev, struct device_attribute *attr,
283 const char *buf, size_t count) 298 const char *buf, size_t count)
284{ 299{
@@ -312,6 +327,11 @@ static ssize_t set_fan_target(struct device *dev, struct device_attribute *attr,
312 if (err < 0) 327 if (err < 0)
313 return err; 328 return err;
314 329
330 if (auto_mode_enabled(data->pwm_enable[nr]))
331 return -EINVAL;
332 if (data->kind == f75387 && duty_mode_enabled(data->pwm_enable[nr]))
333 return -EINVAL;
334
315 mutex_lock(&data->update_lock); 335 mutex_lock(&data->update_lock);
316 data->fan_target[nr] = rpm_to_reg(val); 336 data->fan_target[nr] = rpm_to_reg(val);
317 f75375_write16(client, F75375_REG_FAN_EXP(nr), data->fan_target[nr]); 337 f75375_write16(client, F75375_REG_FAN_EXP(nr), data->fan_target[nr]);
@@ -332,6 +352,10 @@ static ssize_t set_pwm(struct device *dev, struct device_attribute *attr,
332 if (err < 0) 352 if (err < 0)
333 return err; 353 return err;
334 354
355 if (auto_mode_enabled(data->pwm_enable[nr]) ||
356 !duty_mode_enabled(data->pwm_enable[nr]))
357 return -EINVAL;
358
335 mutex_lock(&data->update_lock); 359 mutex_lock(&data->update_lock);
336 data->pwm[nr] = SENSORS_LIMIT(val, 0, 255); 360 data->pwm[nr] = SENSORS_LIMIT(val, 0, 255);
337 f75375_write_pwm(client, nr); 361 f75375_write_pwm(client, nr);
@@ -793,6 +817,9 @@ static void f75375_init(struct i2c_client *client, struct f75375_data *data,
793 set_pwm_enable_direct(client, 0, f75375s_pdata->pwm_enable[0]); 817 set_pwm_enable_direct(client, 0, f75375s_pdata->pwm_enable[0]);
794 set_pwm_enable_direct(client, 1, f75375s_pdata->pwm_enable[1]); 818 set_pwm_enable_direct(client, 1, f75375s_pdata->pwm_enable[1]);
795 for (nr = 0; nr < 2; nr++) { 819 for (nr = 0; nr < 2; nr++) {
820 if (auto_mode_enabled(f75375s_pdata->pwm_enable[nr]) ||
821 !duty_mode_enabled(f75375s_pdata->pwm_enable[nr]))
822 continue;
796 data->pwm[nr] = SENSORS_LIMIT(f75375s_pdata->pwm[nr], 0, 255); 823 data->pwm[nr] = SENSORS_LIMIT(f75375s_pdata->pwm[nr], 0, 255);
797 f75375_write_pwm(client, nr); 824 f75375_write_pwm(client, nr);
798 } 825 }