diff options
Diffstat (limited to 'drivers/hwmon/pc87360.c')
-rw-r--r-- | drivers/hwmon/pc87360.c | 61 |
1 files changed, 31 insertions, 30 deletions
diff --git a/drivers/hwmon/pc87360.c b/drivers/hwmon/pc87360.c index 2de69322f525..ae05e483a778 100644 --- a/drivers/hwmon/pc87360.c +++ b/drivers/hwmon/pc87360.c | |||
@@ -43,6 +43,7 @@ | |||
43 | #include <linux/hwmon-sysfs.h> | 43 | #include <linux/hwmon-sysfs.h> |
44 | #include <linux/hwmon-vid.h> | 44 | #include <linux/hwmon-vid.h> |
45 | #include <linux/err.h> | 45 | #include <linux/err.h> |
46 | #include <linux/mutex.h> | ||
46 | #include <asm/io.h> | 47 | #include <asm/io.h> |
47 | 48 | ||
48 | static u8 devid; | 49 | static u8 devid; |
@@ -183,8 +184,8 @@ static inline u8 PWM_TO_REG(int val, int inv) | |||
183 | struct pc87360_data { | 184 | struct pc87360_data { |
184 | struct i2c_client client; | 185 | struct i2c_client client; |
185 | struct class_device *class_dev; | 186 | struct class_device *class_dev; |
186 | struct semaphore lock; | 187 | struct mutex lock; |
187 | struct semaphore update_lock; | 188 | struct mutex update_lock; |
188 | char valid; /* !=0 if following fields are valid */ | 189 | char valid; /* !=0 if following fields are valid */ |
189 | unsigned long last_updated; /* In jiffies */ | 190 | unsigned long last_updated; /* In jiffies */ |
190 | 191 | ||
@@ -283,7 +284,7 @@ static ssize_t set_fan_min(struct device *dev, struct device_attribute *devattr, | |||
283 | struct pc87360_data *data = i2c_get_clientdata(client); | 284 | struct pc87360_data *data = i2c_get_clientdata(client); |
284 | long fan_min = simple_strtol(buf, NULL, 10); | 285 | long fan_min = simple_strtol(buf, NULL, 10); |
285 | 286 | ||
286 | down(&data->update_lock); | 287 | mutex_lock(&data->update_lock); |
287 | fan_min = FAN_TO_REG(fan_min, FAN_DIV_FROM_REG(data->fan_status[attr->index])); | 288 | fan_min = FAN_TO_REG(fan_min, FAN_DIV_FROM_REG(data->fan_status[attr->index])); |
288 | 289 | ||
289 | /* If it wouldn't fit, change clock divisor */ | 290 | /* If it wouldn't fit, change clock divisor */ |
@@ -300,7 +301,7 @@ static ssize_t set_fan_min(struct device *dev, struct device_attribute *devattr, | |||
300 | /* Write new divider, preserve alarm bits */ | 301 | /* Write new divider, preserve alarm bits */ |
301 | pc87360_write_value(data, LD_FAN, NO_BANK, PC87360_REG_FAN_STATUS(attr->index), | 302 | pc87360_write_value(data, LD_FAN, NO_BANK, PC87360_REG_FAN_STATUS(attr->index), |
302 | data->fan_status[attr->index] & 0xF9); | 303 | data->fan_status[attr->index] & 0xF9); |
303 | up(&data->update_lock); | 304 | mutex_unlock(&data->update_lock); |
304 | 305 | ||
305 | return count; | 306 | return count; |
306 | } | 307 | } |
@@ -343,12 +344,12 @@ static ssize_t set_pwm(struct device *dev, struct device_attribute *devattr, con | |||
343 | struct pc87360_data *data = i2c_get_clientdata(client); | 344 | struct pc87360_data *data = i2c_get_clientdata(client); |
344 | long val = simple_strtol(buf, NULL, 10); | 345 | long val = simple_strtol(buf, NULL, 10); |
345 | 346 | ||
346 | down(&data->update_lock); | 347 | mutex_lock(&data->update_lock); |
347 | data->pwm[attr->index] = PWM_TO_REG(val, | 348 | data->pwm[attr->index] = PWM_TO_REG(val, |
348 | FAN_CONFIG_INVERT(data->fan_conf, attr->index)); | 349 | FAN_CONFIG_INVERT(data->fan_conf, attr->index)); |
349 | pc87360_write_value(data, LD_FAN, NO_BANK, PC87360_REG_PWM(attr->index), | 350 | pc87360_write_value(data, LD_FAN, NO_BANK, PC87360_REG_PWM(attr->index), |
350 | data->pwm[attr->index]); | 351 | data->pwm[attr->index]); |
351 | up(&data->update_lock); | 352 | mutex_unlock(&data->update_lock); |
352 | return count; | 353 | return count; |
353 | } | 354 | } |
354 | 355 | ||
@@ -393,11 +394,11 @@ static ssize_t set_in_min(struct device *dev, struct device_attribute *devattr, | |||
393 | struct pc87360_data *data = i2c_get_clientdata(client); | 394 | struct pc87360_data *data = i2c_get_clientdata(client); |
394 | long val = simple_strtol(buf, NULL, 10); | 395 | long val = simple_strtol(buf, NULL, 10); |
395 | 396 | ||
396 | down(&data->update_lock); | 397 | mutex_lock(&data->update_lock); |
397 | data->in_min[attr->index] = IN_TO_REG(val, data->in_vref); | 398 | data->in_min[attr->index] = IN_TO_REG(val, data->in_vref); |
398 | pc87360_write_value(data, LD_IN, attr->index, PC87365_REG_IN_MIN, | 399 | pc87360_write_value(data, LD_IN, attr->index, PC87365_REG_IN_MIN, |
399 | data->in_min[attr->index]); | 400 | data->in_min[attr->index]); |
400 | up(&data->update_lock); | 401 | mutex_unlock(&data->update_lock); |
401 | return count; | 402 | return count; |
402 | } | 403 | } |
403 | static ssize_t set_in_max(struct device *dev, struct device_attribute *devattr, const char *buf, | 404 | static ssize_t set_in_max(struct device *dev, struct device_attribute *devattr, const char *buf, |
@@ -408,12 +409,12 @@ static ssize_t set_in_max(struct device *dev, struct device_attribute *devattr, | |||
408 | struct pc87360_data *data = i2c_get_clientdata(client); | 409 | struct pc87360_data *data = i2c_get_clientdata(client); |
409 | long val = simple_strtol(buf, NULL, 10); | 410 | long val = simple_strtol(buf, NULL, 10); |
410 | 411 | ||
411 | down(&data->update_lock); | 412 | mutex_lock(&data->update_lock); |
412 | data->in_max[attr->index] = IN_TO_REG(val, | 413 | data->in_max[attr->index] = IN_TO_REG(val, |
413 | data->in_vref); | 414 | data->in_vref); |
414 | pc87360_write_value(data, LD_IN, attr->index, PC87365_REG_IN_MAX, | 415 | pc87360_write_value(data, LD_IN, attr->index, PC87365_REG_IN_MAX, |
415 | data->in_max[attr->index]); | 416 | data->in_max[attr->index]); |
416 | up(&data->update_lock); | 417 | mutex_unlock(&data->update_lock); |
417 | return count; | 418 | return count; |
418 | } | 419 | } |
419 | 420 | ||
@@ -512,11 +513,11 @@ static ssize_t set_therm_min(struct device *dev, struct device_attribute *devatt | |||
512 | struct pc87360_data *data = i2c_get_clientdata(client); | 513 | struct pc87360_data *data = i2c_get_clientdata(client); |
513 | long val = simple_strtol(buf, NULL, 10); | 514 | long val = simple_strtol(buf, NULL, 10); |
514 | 515 | ||
515 | down(&data->update_lock); | 516 | mutex_lock(&data->update_lock); |
516 | data->in_min[attr->index] = IN_TO_REG(val, data->in_vref); | 517 | data->in_min[attr->index] = IN_TO_REG(val, data->in_vref); |
517 | pc87360_write_value(data, LD_IN, attr->index, PC87365_REG_TEMP_MIN, | 518 | pc87360_write_value(data, LD_IN, attr->index, PC87365_REG_TEMP_MIN, |
518 | data->in_min[attr->index]); | 519 | data->in_min[attr->index]); |
519 | up(&data->update_lock); | 520 | mutex_unlock(&data->update_lock); |
520 | return count; | 521 | return count; |
521 | } | 522 | } |
522 | static ssize_t set_therm_max(struct device *dev, struct device_attribute *devattr, const char *buf, | 523 | static ssize_t set_therm_max(struct device *dev, struct device_attribute *devattr, const char *buf, |
@@ -527,11 +528,11 @@ static ssize_t set_therm_max(struct device *dev, struct device_attribute *devatt | |||
527 | struct pc87360_data *data = i2c_get_clientdata(client); | 528 | struct pc87360_data *data = i2c_get_clientdata(client); |
528 | long val = simple_strtol(buf, NULL, 10); | 529 | long val = simple_strtol(buf, NULL, 10); |
529 | 530 | ||
530 | down(&data->update_lock); | 531 | mutex_lock(&data->update_lock); |
531 | data->in_max[attr->index] = IN_TO_REG(val, data->in_vref); | 532 | data->in_max[attr->index] = IN_TO_REG(val, data->in_vref); |
532 | pc87360_write_value(data, LD_IN, attr->index, PC87365_REG_TEMP_MAX, | 533 | pc87360_write_value(data, LD_IN, attr->index, PC87365_REG_TEMP_MAX, |
533 | data->in_max[attr->index]); | 534 | data->in_max[attr->index]); |
534 | up(&data->update_lock); | 535 | mutex_unlock(&data->update_lock); |
535 | return count; | 536 | return count; |
536 | } | 537 | } |
537 | static ssize_t set_therm_crit(struct device *dev, struct device_attribute *devattr, const char *buf, | 538 | static ssize_t set_therm_crit(struct device *dev, struct device_attribute *devattr, const char *buf, |
@@ -542,11 +543,11 @@ static ssize_t set_therm_crit(struct device *dev, struct device_attribute *devat | |||
542 | struct pc87360_data *data = i2c_get_clientdata(client); | 543 | struct pc87360_data *data = i2c_get_clientdata(client); |
543 | long val = simple_strtol(buf, NULL, 10); | 544 | long val = simple_strtol(buf, NULL, 10); |
544 | 545 | ||
545 | down(&data->update_lock); | 546 | mutex_lock(&data->update_lock); |
546 | data->in_crit[attr->index-11] = IN_TO_REG(val, data->in_vref); | 547 | data->in_crit[attr->index-11] = IN_TO_REG(val, data->in_vref); |
547 | pc87360_write_value(data, LD_IN, attr->index, PC87365_REG_TEMP_CRIT, | 548 | pc87360_write_value(data, LD_IN, attr->index, PC87365_REG_TEMP_CRIT, |
548 | data->in_crit[attr->index-11]); | 549 | data->in_crit[attr->index-11]); |
549 | up(&data->update_lock); | 550 | mutex_unlock(&data->update_lock); |
550 | return count; | 551 | return count; |
551 | } | 552 | } |
552 | 553 | ||
@@ -654,11 +655,11 @@ static ssize_t set_temp_min(struct device *dev, struct device_attribute *devattr | |||
654 | struct pc87360_data *data = i2c_get_clientdata(client); | 655 | struct pc87360_data *data = i2c_get_clientdata(client); |
655 | long val = simple_strtol(buf, NULL, 10); | 656 | long val = simple_strtol(buf, NULL, 10); |
656 | 657 | ||
657 | down(&data->update_lock); | 658 | mutex_lock(&data->update_lock); |
658 | data->temp_min[attr->index] = TEMP_TO_REG(val); | 659 | data->temp_min[attr->index] = TEMP_TO_REG(val); |
659 | pc87360_write_value(data, LD_TEMP, attr->index, PC87365_REG_TEMP_MIN, | 660 | pc87360_write_value(data, LD_TEMP, attr->index, PC87365_REG_TEMP_MIN, |
660 | data->temp_min[attr->index]); | 661 | data->temp_min[attr->index]); |
661 | up(&data->update_lock); | 662 | mutex_unlock(&data->update_lock); |
662 | return count; | 663 | return count; |
663 | } | 664 | } |
664 | static ssize_t set_temp_max(struct device *dev, struct device_attribute *devattr, const char *buf, | 665 | static ssize_t set_temp_max(struct device *dev, struct device_attribute *devattr, const char *buf, |
@@ -669,11 +670,11 @@ static ssize_t set_temp_max(struct device *dev, struct device_attribute *devattr | |||
669 | struct pc87360_data *data = i2c_get_clientdata(client); | 670 | struct pc87360_data *data = i2c_get_clientdata(client); |
670 | long val = simple_strtol(buf, NULL, 10); | 671 | long val = simple_strtol(buf, NULL, 10); |
671 | 672 | ||
672 | down(&data->update_lock); | 673 | mutex_lock(&data->update_lock); |
673 | data->temp_max[attr->index] = TEMP_TO_REG(val); | 674 | data->temp_max[attr->index] = TEMP_TO_REG(val); |
674 | pc87360_write_value(data, LD_TEMP, attr->index, PC87365_REG_TEMP_MAX, | 675 | pc87360_write_value(data, LD_TEMP, attr->index, PC87365_REG_TEMP_MAX, |
675 | data->temp_max[attr->index]); | 676 | data->temp_max[attr->index]); |
676 | up(&data->update_lock); | 677 | mutex_unlock(&data->update_lock); |
677 | return count; | 678 | return count; |
678 | } | 679 | } |
679 | static ssize_t set_temp_crit(struct device *dev, struct device_attribute *devattr, const char *buf, | 680 | static ssize_t set_temp_crit(struct device *dev, struct device_attribute *devattr, const char *buf, |
@@ -684,11 +685,11 @@ static ssize_t set_temp_crit(struct device *dev, struct device_attribute *devatt | |||
684 | struct pc87360_data *data = i2c_get_clientdata(client); | 685 | struct pc87360_data *data = i2c_get_clientdata(client); |
685 | long val = simple_strtol(buf, NULL, 10); | 686 | long val = simple_strtol(buf, NULL, 10); |
686 | 687 | ||
687 | down(&data->update_lock); | 688 | mutex_lock(&data->update_lock); |
688 | data->temp_crit[attr->index] = TEMP_TO_REG(val); | 689 | data->temp_crit[attr->index] = TEMP_TO_REG(val); |
689 | pc87360_write_value(data, LD_TEMP, attr->index, PC87365_REG_TEMP_CRIT, | 690 | pc87360_write_value(data, LD_TEMP, attr->index, PC87365_REG_TEMP_CRIT, |
690 | data->temp_crit[attr->index]); | 691 | data->temp_crit[attr->index]); |
691 | up(&data->update_lock); | 692 | mutex_unlock(&data->update_lock); |
692 | return count; | 693 | return count; |
693 | } | 694 | } |
694 | 695 | ||
@@ -845,7 +846,7 @@ static int pc87360_detect(struct i2c_adapter *adapter) | |||
845 | dev = &client->dev; | 846 | dev = &client->dev; |
846 | i2c_set_clientdata(client, data); | 847 | i2c_set_clientdata(client, data); |
847 | client->addr = address; | 848 | client->addr = address; |
848 | init_MUTEX(&data->lock); | 849 | mutex_init(&data->lock); |
849 | client->adapter = adapter; | 850 | client->adapter = adapter; |
850 | client->driver = &pc87360_driver; | 851 | client->driver = &pc87360_driver; |
851 | client->flags = 0; | 852 | client->flags = 0; |
@@ -878,7 +879,7 @@ static int pc87360_detect(struct i2c_adapter *adapter) | |||
878 | 879 | ||
879 | strlcpy(client->name, name, sizeof(client->name)); | 880 | strlcpy(client->name, name, sizeof(client->name)); |
880 | data->valid = 0; | 881 | data->valid = 0; |
881 | init_MUTEX(&data->update_lock); | 882 | mutex_init(&data->update_lock); |
882 | 883 | ||
883 | for (i = 0; i < 3; i++) { | 884 | for (i = 0; i < 3; i++) { |
884 | if (((data->address[i] = extra_isa[i])) | 885 | if (((data->address[i] = extra_isa[i])) |
@@ -1027,11 +1028,11 @@ static int pc87360_read_value(struct pc87360_data *data, u8 ldi, u8 bank, | |||
1027 | { | 1028 | { |
1028 | int res; | 1029 | int res; |
1029 | 1030 | ||
1030 | down(&(data->lock)); | 1031 | mutex_lock(&(data->lock)); |
1031 | if (bank != NO_BANK) | 1032 | if (bank != NO_BANK) |
1032 | outb_p(bank, data->address[ldi] + PC87365_REG_BANK); | 1033 | outb_p(bank, data->address[ldi] + PC87365_REG_BANK); |
1033 | res = inb_p(data->address[ldi] + reg); | 1034 | res = inb_p(data->address[ldi] + reg); |
1034 | up(&(data->lock)); | 1035 | mutex_unlock(&(data->lock)); |
1035 | 1036 | ||
1036 | return res; | 1037 | return res; |
1037 | } | 1038 | } |
@@ -1039,11 +1040,11 @@ static int pc87360_read_value(struct pc87360_data *data, u8 ldi, u8 bank, | |||
1039 | static void pc87360_write_value(struct pc87360_data *data, u8 ldi, u8 bank, | 1040 | static void pc87360_write_value(struct pc87360_data *data, u8 ldi, u8 bank, |
1040 | u8 reg, u8 value) | 1041 | u8 reg, u8 value) |
1041 | { | 1042 | { |
1042 | down(&(data->lock)); | 1043 | mutex_lock(&(data->lock)); |
1043 | if (bank != NO_BANK) | 1044 | if (bank != NO_BANK) |
1044 | outb_p(bank, data->address[ldi] + PC87365_REG_BANK); | 1045 | outb_p(bank, data->address[ldi] + PC87365_REG_BANK); |
1045 | outb_p(value, data->address[ldi] + reg); | 1046 | outb_p(value, data->address[ldi] + reg); |
1046 | up(&(data->lock)); | 1047 | mutex_unlock(&(data->lock)); |
1047 | } | 1048 | } |
1048 | 1049 | ||
1049 | static void pc87360_init_client(struct i2c_client *client, int use_thermistors) | 1050 | static void pc87360_init_client(struct i2c_client *client, int use_thermistors) |
@@ -1215,7 +1216,7 @@ static struct pc87360_data *pc87360_update_device(struct device *dev) | |||
1215 | struct pc87360_data *data = i2c_get_clientdata(client); | 1216 | struct pc87360_data *data = i2c_get_clientdata(client); |
1216 | u8 i; | 1217 | u8 i; |
1217 | 1218 | ||
1218 | down(&data->update_lock); | 1219 | mutex_lock(&data->update_lock); |
1219 | 1220 | ||
1220 | if (time_after(jiffies, data->last_updated + HZ * 2) || !data->valid) { | 1221 | if (time_after(jiffies, data->last_updated + HZ * 2) || !data->valid) { |
1221 | dev_dbg(&client->dev, "Data update\n"); | 1222 | dev_dbg(&client->dev, "Data update\n"); |
@@ -1315,7 +1316,7 @@ static struct pc87360_data *pc87360_update_device(struct device *dev) | |||
1315 | data->valid = 1; | 1316 | data->valid = 1; |
1316 | } | 1317 | } |
1317 | 1318 | ||
1318 | up(&data->update_lock); | 1319 | mutex_unlock(&data->update_lock); |
1319 | 1320 | ||
1320 | return data; | 1321 | return data; |
1321 | } | 1322 | } |