Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

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

hhwmon fixes for 3.3-rc6 from Guenter Roeck:

These patches are necessary for correct operation and management of
F75387.

* tag 'hwmon-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/groeck/linux-staging:
hwmon: (f75375s) Catch some attempts to write to r/o registers
hwmon: (f75375s) Properly map the F75387 automatic modes to pwm_enable
hwmon: (f75375s) Make pwm*_mode writable for the F75387
hwmon: (f75375s) Fix writes to the pwm* attribute for the F75387

+75 -14
+75 -14
drivers/hwmon/f75375s.c
··· 178 178 i2c_smbus_write_byte_data(client, reg + 1, (value & 0xFF)); 179 179 } 180 180 181 + static void f75375_write_pwm(struct i2c_client *client, int nr) 182 + { 183 + struct f75375_data *data = i2c_get_clientdata(client); 184 + if (data->kind == f75387) 185 + f75375_write16(client, F75375_REG_FAN_EXP(nr), data->pwm[nr]); 186 + else 187 + f75375_write8(client, F75375_REG_FAN_PWM_DUTY(nr), 188 + data->pwm[nr]); 189 + } 190 + 181 191 static struct f75375_data *f75375_update_device(struct device *dev) 182 192 { 183 193 struct i2c_client *client = to_i2c_client(dev); ··· 264 254 return 1500000 / rpm; 265 255 } 266 256 257 + static bool duty_mode_enabled(u8 pwm_enable) 258 + { 259 + switch (pwm_enable) { 260 + case 0: /* Manual, duty mode (full speed) */ 261 + case 1: /* Manual, duty mode */ 262 + case 4: /* Auto, duty mode */ 263 + return true; 264 + case 2: /* Auto, speed mode */ 265 + case 3: /* Manual, speed mode */ 266 + return false; 267 + default: 268 + BUG(); 269 + } 270 + } 271 + 272 + static bool auto_mode_enabled(u8 pwm_enable) 273 + { 274 + switch (pwm_enable) { 275 + case 0: /* Manual, duty mode (full speed) */ 276 + case 1: /* Manual, duty mode */ 277 + case 3: /* Manual, speed mode */ 278 + return false; 279 + case 2: /* Auto, speed mode */ 280 + case 4: /* Auto, duty mode */ 281 + return true; 282 + default: 283 + BUG(); 284 + } 285 + } 286 + 267 287 static ssize_t set_fan_min(struct device *dev, struct device_attribute *attr, 268 288 const char *buf, size_t count) 269 289 { ··· 327 287 if (err < 0) 328 288 return err; 329 289 290 + if (auto_mode_enabled(data->pwm_enable[nr])) 291 + return -EINVAL; 292 + if (data->kind == f75387 && duty_mode_enabled(data->pwm_enable[nr])) 293 + return -EINVAL; 294 + 330 295 mutex_lock(&data->update_lock); 331 296 data->fan_target[nr] = rpm_to_reg(val); 332 297 f75375_write16(client, F75375_REG_FAN_EXP(nr), data->fan_target[nr]); ··· 352 307 if (err < 0) 353 308 return err; 354 309 310 + if (auto_mode_enabled(data->pwm_enable[nr]) || 311 + !duty_mode_enabled(data->pwm_enable[nr])) 312 + return -EINVAL; 313 + 355 314 mutex_lock(&data->update_lock); 356 315 data->pwm[nr] = SENSORS_LIMIT(val, 0, 255); 357 - f75375_write8(client, F75375_REG_FAN_PWM_DUTY(nr), data->pwm[nr]); 316 + f75375_write_pwm(client, nr); 358 317 mutex_unlock(&data->update_lock); 359 318 return count; 360 319 } ··· 376 327 struct f75375_data *data = i2c_get_clientdata(client); 377 328 u8 fanmode; 378 329 379 - if (val < 0 || val > 3) 330 + if (val < 0 || val > 4) 380 331 return -EINVAL; 381 332 382 333 fanmode = f75375_read8(client, F75375_REG_FAN_TIMER); 383 334 if (data->kind == f75387) { 335 + /* For now, deny dangerous toggling of duty mode */ 336 + if (duty_mode_enabled(data->pwm_enable[nr]) != 337 + duty_mode_enabled(val)) 338 + return -EOPNOTSUPP; 384 339 /* clear each fanX_mode bit before setting them properly */ 385 340 fanmode &= ~(1 << F75387_FAN_DUTY_MODE(nr)); 386 341 fanmode &= ~(1 << F75387_FAN_MANU_MODE(nr)); ··· 398 345 fanmode |= (1 << F75387_FAN_MANU_MODE(nr)); 399 346 fanmode |= (1 << F75387_FAN_DUTY_MODE(nr)); 400 347 break; 401 - case 2: /* AUTOMATIC*/ 402 - fanmode |= (1 << F75387_FAN_DUTY_MODE(nr)); 348 + case 2: /* Automatic, speed mode */ 403 349 break; 404 350 case 3: /* fan speed */ 405 351 fanmode |= (1 << F75387_FAN_MANU_MODE(nr)); 352 + break; 353 + case 4: /* Automatic, pwm */ 354 + fanmode |= (1 << F75387_FAN_DUTY_MODE(nr)); 406 355 break; 407 356 } 408 357 } else { ··· 423 368 break; 424 369 case 3: /* fan speed */ 425 370 break; 371 + case 4: /* Automatic pwm */ 372 + return -EINVAL; 426 373 } 427 374 } 428 375 429 376 f75375_write8(client, F75375_REG_FAN_TIMER, fanmode); 430 377 data->pwm_enable[nr] = val; 431 378 if (val == 0) 432 - f75375_write8(client, F75375_REG_FAN_PWM_DUTY(nr), 433 - data->pwm[nr]); 379 + f75375_write_pwm(client, nr); 434 380 return 0; 435 381 } 436 382 ··· 782 726 783 727 manu = ((mode >> F75387_FAN_MANU_MODE(nr)) & 1); 784 728 duty = ((mode >> F75387_FAN_DUTY_MODE(nr)) & 1); 785 - if (manu && duty) 786 - /* speed */ 729 + if (!manu && duty) 730 + /* auto, pwm */ 731 + data->pwm_enable[nr] = 4; 732 + else if (manu && !duty) 733 + /* manual, speed */ 787 734 data->pwm_enable[nr] = 3; 788 - else if (!manu && duty) 789 - /* automatic */ 735 + else if (!manu && !duty) 736 + /* automatic, speed */ 790 737 data->pwm_enable[nr] = 2; 791 738 else 792 - /* manual */ 739 + /* manual, pwm */ 793 740 data->pwm_enable[nr] = 1; 794 741 } else { 795 742 if (!(conf & (1 << F75375_FAN_CTRL_LINEAR(nr)))) ··· 817 758 set_pwm_enable_direct(client, 0, f75375s_pdata->pwm_enable[0]); 818 759 set_pwm_enable_direct(client, 1, f75375s_pdata->pwm_enable[1]); 819 760 for (nr = 0; nr < 2; nr++) { 761 + if (auto_mode_enabled(f75375s_pdata->pwm_enable[nr]) || 762 + !duty_mode_enabled(f75375s_pdata->pwm_enable[nr])) 763 + continue; 820 764 data->pwm[nr] = SENSORS_LIMIT(f75375s_pdata->pwm[nr], 0, 255); 821 - f75375_write8(client, F75375_REG_FAN_PWM_DUTY(nr), 822 - data->pwm[nr]); 765 + f75375_write_pwm(client, nr); 823 766 } 824 767 825 768 } ··· 848 787 if (err) 849 788 goto exit_free; 850 789 851 - if (data->kind == f75375) { 790 + if (data->kind != f75373) { 852 791 err = sysfs_chmod_file(&client->dev.kobj, 853 792 &sensor_dev_attr_pwm1_mode.dev_attr.attr, 854 793 S_IRUGO | S_IWUSR);