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

adt7470: make automatic fan control really work

It turns out that the adt7470's automatic fan control algorithm only works
when the temperature sensors get updated. This in turn happens only when
someone tells the chip to read its temperature sensors. Regrettably, this
means that we have to drive the chip periodically.

Signed-off-by: Darrick J. Wong <djwong@us.ibm.com>
Cc: Jean Delvare <khali@linux-fr.org>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>

authored by

Darrick J. Wong and committed by
Linus Torvalds
89fac11c 2f22d5df

+142 -33
+8 -11
Documentation/hwmon/adt7470
··· 31 31 limit values. The ADT7470 will signal an ALARM if any measured value exceeds 32 32 either limit. 33 33 34 - The ADT7470 DOES NOT sample all inputs continuously. A single pin on the 35 - ADT7470 is connected to a multitude of thermal diodes, but the chip must be 36 - instructed explicitly to read the multitude of diodes. If you want to use 37 - automatic fan control mode, you must manually read any of the temperature 38 - sensors or the fan control algorithm will not run. The chip WILL NOT DO THIS 39 - AUTOMATICALLY; this must be done from userspace. This may be a bug in the chip 40 - design, given that many other AD chips take care of this. The driver will not 41 - read the registers more often than once every 5 seconds. Further, 42 - configuration data is only read once per minute. 34 + The ADT7470 samples all inputs continuously. A kernel thread is started up for 35 + the purpose of periodically querying the temperature sensors, thus allowing the 36 + automatic fan pwm control to set the fan speed. The driver will not read the 37 + registers more often than once every 5 seconds. Further, configuration data is 38 + only read once per minute. 43 39 44 40 Special Features 45 41 ---------------- ··· 68 72 Notes 69 73 ----- 70 74 71 - As stated above, the temperature inputs must be read periodically from 72 - userspace in order for the automatic pwm algorithm to run. 75 + The temperature inputs no longer need to be read periodically from userspace in 76 + order for the automatic pwm algorithm to run. This was the case for earlier 77 + versions of the driver.
+134 -22
drivers/hwmon/adt7470.c
··· 28 28 #include <linux/mutex.h> 29 29 #include <linux/delay.h> 30 30 #include <linux/log2.h> 31 + #include <linux/kthread.h> 31 32 32 33 /* Addresses to scan */ 33 34 static const unsigned short normal_i2c[] = { 0x2C, 0x2E, 0x2F, I2C_CLIENT_END }; ··· 133 132 /* Wait at least 200ms per sensor for 10 sensors */ 134 133 #define TEMP_COLLECTION_TIME 2000 135 134 135 + /* auto update thing won't fire more than every 2s */ 136 + #define AUTO_UPDATE_INTERVAL 2000 137 + 136 138 /* datasheet says to divide this number by the fan reading to get fan rpm */ 137 139 #define FAN_PERIOD_TO_RPM(x) ((90000 * 60) / (x)) 138 140 #define FAN_RPM_TO_PERIOD FAN_PERIOD_TO_RPM ··· 152 148 unsigned long limits_last_updated; /* In jiffies */ 153 149 154 150 int num_temp_sensors; /* -1 = probe */ 151 + int temperatures_probed; 155 152 156 153 s8 temp[ADT7470_TEMP_COUNT]; 157 154 s8 temp_min[ADT7470_TEMP_COUNT]; ··· 169 164 u8 pwm_min[ADT7470_PWM_COUNT]; 170 165 s8 pwm_tmin[ADT7470_PWM_COUNT]; 171 166 u8 pwm_auto_temp[ADT7470_PWM_COUNT]; 167 + 168 + struct task_struct *auto_update; 169 + struct completion auto_update_stop; 170 + unsigned int auto_update_interval; 172 171 }; 173 172 174 173 static int adt7470_probe(struct i2c_client *client, ··· 230 221 } 231 222 } 232 223 233 - static struct adt7470_data *adt7470_update_device(struct device *dev) 224 + /* Probe for temperature sensors. Assumes lock is held */ 225 + static int adt7470_read_temperatures(struct i2c_client *client, 226 + struct adt7470_data *data) 234 227 { 235 - struct i2c_client *client = to_i2c_client(dev); 236 - struct adt7470_data *data = i2c_get_clientdata(client); 237 - unsigned long local_jiffies = jiffies; 238 - u8 cfg, pwm[4], pwm_cfg[2]; 228 + unsigned long res; 239 229 int i; 240 - 241 - mutex_lock(&data->lock); 242 - if (time_before(local_jiffies, data->sensors_last_updated + 243 - SENSOR_REFRESH_INTERVAL) 244 - && data->sensors_valid) 245 - goto no_sensor_update; 230 + u8 cfg, pwm[4], pwm_cfg[2]; 246 231 247 232 /* save pwm[1-4] config register */ 248 233 pwm_cfg[0] = i2c_smbus_read_byte_data(client, ADT7470_REG_PWM_CFG(0)); ··· 262 259 i2c_smbus_write_byte_data(client, ADT7470_REG_CFG, cfg); 263 260 264 261 /* Delay is 200ms * number of temp sensors. */ 265 - msleep((data->num_temp_sensors >= 0 ? 266 - data->num_temp_sensors * 200 : 267 - TEMP_COLLECTION_TIME)); 262 + res = msleep_interruptible((data->num_temp_sensors >= 0 ? 263 + data->num_temp_sensors * 200 : 264 + TEMP_COLLECTION_TIME)); 268 265 269 266 /* done reading temperature sensors */ 270 267 cfg = i2c_smbus_read_byte_data(client, ADT7470_REG_CFG); ··· 275 272 i2c_smbus_write_byte_data(client, ADT7470_REG_PWM_CFG(0), pwm_cfg[0]); 276 273 i2c_smbus_write_byte_data(client, ADT7470_REG_PWM_CFG(2), pwm_cfg[1]); 277 274 278 - for (i = 0; i < ADT7470_TEMP_COUNT; i++) 275 + if (res) { 276 + printk(KERN_ERR "ha ha, interrupted"); 277 + return -EAGAIN; 278 + } 279 + 280 + /* Only count fans if we have to */ 281 + if (data->num_temp_sensors >= 0) 282 + return 0; 283 + 284 + for (i = 0; i < ADT7470_TEMP_COUNT; i++) { 279 285 data->temp[i] = i2c_smbus_read_byte_data(client, 280 286 ADT7470_TEMP_REG(i)); 287 + if (data->temp[i]) 288 + data->num_temp_sensors = i + 1; 289 + } 290 + data->temperatures_probed = 1; 291 + return 0; 292 + } 281 293 282 - /* Figure out the number of temp sensors */ 283 - if (data->num_temp_sensors < 0) 294 + static int adt7470_update_thread(void *p) 295 + { 296 + struct i2c_client *client = p; 297 + struct adt7470_data *data = i2c_get_clientdata(client); 298 + 299 + while (!kthread_should_stop()) { 300 + mutex_lock(&data->lock); 301 + adt7470_read_temperatures(client, data); 302 + mutex_unlock(&data->lock); 303 + if (kthread_should_stop()) 304 + break; 305 + msleep_interruptible(data->auto_update_interval); 306 + } 307 + 308 + complete_all(&data->auto_update_stop); 309 + return 0; 310 + } 311 + 312 + static struct adt7470_data *adt7470_update_device(struct device *dev) 313 + { 314 + struct i2c_client *client = to_i2c_client(dev); 315 + struct adt7470_data *data = i2c_get_clientdata(client); 316 + unsigned long local_jiffies = jiffies; 317 + u8 cfg; 318 + int i; 319 + int need_sensors = 1; 320 + int need_limits = 1; 321 + 322 + /* 323 + * Figure out if we need to update the shadow registers. 324 + * Lockless means that we may occasionally report out of 325 + * date data. 326 + */ 327 + if (time_before(local_jiffies, data->sensors_last_updated + 328 + SENSOR_REFRESH_INTERVAL) && 329 + data->sensors_valid) 330 + need_sensors = 0; 331 + 332 + if (time_before(local_jiffies, data->limits_last_updated + 333 + LIMIT_REFRESH_INTERVAL) && 334 + data->limits_valid) 335 + need_limits = 0; 336 + 337 + if (!need_sensors && !need_limits) 338 + return data; 339 + 340 + mutex_lock(&data->lock); 341 + if (!need_sensors) 342 + goto no_sensor_update; 343 + 344 + if (!data->temperatures_probed) 345 + adt7470_read_temperatures(client, data); 346 + else 284 347 for (i = 0; i < ADT7470_TEMP_COUNT; i++) 285 - if (data->temp[i]) 286 - data->num_temp_sensors = i + 1; 348 + data->temp[i] = i2c_smbus_read_byte_data(client, 349 + ADT7470_TEMP_REG(i)); 287 350 288 351 for (i = 0; i < ADT7470_FAN_COUNT; i++) 289 352 data->fan[i] = adt7470_read_word_data(client, ··· 398 329 data->sensors_valid = 1; 399 330 400 331 no_sensor_update: 401 - if (time_before(local_jiffies, data->limits_last_updated + 402 - LIMIT_REFRESH_INTERVAL) 403 - && data->limits_valid) 332 + if (!need_limits) 404 333 goto out; 405 334 406 335 for (i = 0; i < ADT7470_TEMP_COUNT; i++) { ··· 432 365 return data; 433 366 } 434 367 368 + static ssize_t show_auto_update_interval(struct device *dev, 369 + struct device_attribute *devattr, 370 + char *buf) 371 + { 372 + struct adt7470_data *data = adt7470_update_device(dev); 373 + return sprintf(buf, "%d\n", data->auto_update_interval); 374 + } 375 + 376 + static ssize_t set_auto_update_interval(struct device *dev, 377 + struct device_attribute *devattr, 378 + const char *buf, 379 + size_t count) 380 + { 381 + struct i2c_client *client = to_i2c_client(dev); 382 + struct adt7470_data *data = i2c_get_clientdata(client); 383 + long temp; 384 + 385 + if (strict_strtol(buf, 10, &temp)) 386 + return -EINVAL; 387 + 388 + temp = SENSORS_LIMIT(temp, 0, 60000); 389 + 390 + mutex_lock(&data->lock); 391 + data->auto_update_interval = temp; 392 + mutex_unlock(&data->lock); 393 + 394 + return count; 395 + } 396 + 435 397 static ssize_t show_num_temp_sensors(struct device *dev, 436 398 struct device_attribute *devattr, 437 399 char *buf) ··· 485 389 486 390 mutex_lock(&data->lock); 487 391 data->num_temp_sensors = temp; 392 + if (temp < 0) 393 + data->temperatures_probed = 0; 488 394 mutex_unlock(&data->lock); 489 395 490 396 return count; ··· 960 862 static DEVICE_ATTR(alarm_mask, S_IRUGO, show_alarm_mask, NULL); 961 863 static DEVICE_ATTR(num_temp_sensors, S_IWUSR | S_IRUGO, show_num_temp_sensors, 962 864 set_num_temp_sensors); 865 + static DEVICE_ATTR(auto_update_interval, S_IWUSR | S_IRUGO, 866 + show_auto_update_interval, set_auto_update_interval); 963 867 964 868 static SENSOR_DEVICE_ATTR(temp1_max, S_IWUSR | S_IRUGO, show_temp_max, 965 869 set_temp_max, 0); ··· 1135 1035 { 1136 1036 &dev_attr_alarm_mask.attr, 1137 1037 &dev_attr_num_temp_sensors.attr, 1038 + &dev_attr_auto_update_interval.attr, 1138 1039 &sensor_dev_attr_temp1_max.dev_attr.attr, 1139 1040 &sensor_dev_attr_temp2_max.dev_attr.attr, 1140 1041 &sensor_dev_attr_temp3_max.dev_attr.attr, ··· 1269 1168 } 1270 1169 1271 1170 data->num_temp_sensors = -1; 1171 + data->auto_update_interval = AUTO_UPDATE_INTERVAL; 1272 1172 1273 1173 i2c_set_clientdata(client, data); 1274 1174 mutex_init(&data->lock); ··· 1290 1188 goto exit_remove; 1291 1189 } 1292 1190 1191 + init_completion(&data->auto_update_stop); 1192 + data->auto_update = kthread_run(adt7470_update_thread, client, 1193 + dev_name(data->hwmon_dev)); 1194 + if (IS_ERR(data->auto_update)) 1195 + goto exit_unregister; 1196 + 1293 1197 return 0; 1294 1198 1199 + exit_unregister: 1200 + hwmon_device_unregister(data->hwmon_dev); 1295 1201 exit_remove: 1296 1202 sysfs_remove_group(&client->dev.kobj, &data->attrs); 1297 1203 exit_free: ··· 1312 1202 { 1313 1203 struct adt7470_data *data = i2c_get_clientdata(client); 1314 1204 1205 + kthread_stop(data->auto_update); 1206 + wait_for_completion(&data->auto_update_stop); 1315 1207 hwmon_device_unregister(data->hwmon_dev); 1316 1208 sysfs_remove_group(&client->dev.kobj, &data->attrs); 1317 1209 kfree(data);