aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorYuan Mu <ymu@winbond.com.tw>2006-06-04 14:18:45 -0400
committerGreg Kroah-Hartman <gregkh@suse.de>2006-06-22 14:10:34 -0400
commitbed730821b74be4c7d135098842219473f7c8f2c (patch)
tree8cc046bc9b7415c5036322de29d754dd5bc97be5
parent53e2761bb2e4ed58913c266ad13e8c10692aec1e (diff)
[PATCH] w83792d: Add missing data access locks
Add missing data lock in w83792d driver to avoid unexpected data change. Signed-off-by: Yuan Mu <ymu@winbond.com.tw> Signed-off-by: Jean Delvare <khali@linux-fr.org> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
-rw-r--r--drivers/hwmon/w83792d.c30
1 files changed, 25 insertions, 5 deletions
diff --git a/drivers/hwmon/w83792d.c b/drivers/hwmon/w83792d.c
index 6cdef18b1b27..4ef884c216e2 100644
--- a/drivers/hwmon/w83792d.c
+++ b/drivers/hwmon/w83792d.c
@@ -372,8 +372,10 @@ static ssize_t store_in_##reg (struct device *dev, \
372 u32 val; \ 372 u32 val; \
373 \ 373 \
374 val = simple_strtoul(buf, NULL, 10); \ 374 val = simple_strtoul(buf, NULL, 10); \
375 mutex_lock(&data->update_lock); \
375 data->in_##reg[nr] = SENSORS_LIMIT(IN_TO_REG(nr, val)/4, 0, 255); \ 376 data->in_##reg[nr] = SENSORS_LIMIT(IN_TO_REG(nr, val)/4, 0, 255); \
376 w83792d_write_value(client, W83792D_REG_IN_##REG[nr], data->in_##reg[nr]); \ 377 w83792d_write_value(client, W83792D_REG_IN_##REG[nr], data->in_##reg[nr]); \
378 mutex_unlock(&data->update_lock); \
377 \ 379 \
378 return count; \ 380 return count; \
379} 381}
@@ -440,9 +442,11 @@ store_fan_min(struct device *dev, struct device_attribute *attr,
440 u32 val; 442 u32 val;
441 443
442 val = simple_strtoul(buf, NULL, 10); 444 val = simple_strtoul(buf, NULL, 10);
445 mutex_lock(&data->update_lock);
443 data->fan_min[nr] = FAN_TO_REG(val, DIV_FROM_REG(data->fan_div[nr])); 446 data->fan_min[nr] = FAN_TO_REG(val, DIV_FROM_REG(data->fan_div[nr]));
444 w83792d_write_value(client, W83792D_REG_FAN_MIN[nr], 447 w83792d_write_value(client, W83792D_REG_FAN_MIN[nr],
445 data->fan_min[nr]); 448 data->fan_min[nr]);
449 mutex_unlock(&data->update_lock);
446 450
447 return count; 451 return count;
448} 452}
@@ -475,6 +479,7 @@ store_fan_div(struct device *dev, struct device_attribute *attr,
475 u8 tmp_fan_div; 479 u8 tmp_fan_div;
476 480
477 /* Save fan_min */ 481 /* Save fan_min */
482 mutex_lock(&data->update_lock);
478 min = FAN_FROM_REG(data->fan_min[nr], 483 min = FAN_FROM_REG(data->fan_min[nr],
479 DIV_FROM_REG(data->fan_div[nr])); 484 DIV_FROM_REG(data->fan_div[nr]));
480 485
@@ -490,6 +495,7 @@ store_fan_div(struct device *dev, struct device_attribute *attr,
490 /* Restore fan_min */ 495 /* Restore fan_min */
491 data->fan_min[nr] = FAN_TO_REG(min, DIV_FROM_REG(data->fan_div[nr])); 496 data->fan_min[nr] = FAN_TO_REG(min, DIV_FROM_REG(data->fan_div[nr]));
492 w83792d_write_value(client, W83792D_REG_FAN_MIN[nr], data->fan_min[nr]); 497 w83792d_write_value(client, W83792D_REG_FAN_MIN[nr], data->fan_min[nr]);
498 mutex_unlock(&data->update_lock);
493 499
494 return count; 500 return count;
495} 501}
@@ -544,10 +550,11 @@ static ssize_t store_temp1(struct device *dev, struct device_attribute *attr,
544 s32 val; 550 s32 val;
545 551
546 val = simple_strtol(buf, NULL, 10); 552 val = simple_strtol(buf, NULL, 10);
547 553 mutex_lock(&data->update_lock);
548 data->temp1[nr] = TEMP1_TO_REG(val); 554 data->temp1[nr] = TEMP1_TO_REG(val);
549 w83792d_write_value(client, W83792D_REG_TEMP1[nr], 555 w83792d_write_value(client, W83792D_REG_TEMP1[nr],
550 data->temp1[nr]); 556 data->temp1[nr]);
557 mutex_unlock(&data->update_lock);
551 558
552 return count; 559 return count;
553} 560}
@@ -577,13 +584,14 @@ static ssize_t store_temp23(struct device *dev, struct device_attribute *attr,
577 s32 val; 584 s32 val;
578 585
579 val = simple_strtol(buf, NULL, 10); 586 val = simple_strtol(buf, NULL, 10);
580 587 mutex_lock(&data->update_lock);
581 data->temp_add[nr][index] = TEMP_ADD_TO_REG_HIGH(val); 588 data->temp_add[nr][index] = TEMP_ADD_TO_REG_HIGH(val);
582 data->temp_add[nr][index+1] = TEMP_ADD_TO_REG_LOW(val); 589 data->temp_add[nr][index+1] = TEMP_ADD_TO_REG_LOW(val);
583 w83792d_write_value(client, W83792D_REG_TEMP_ADD[nr][index], 590 w83792d_write_value(client, W83792D_REG_TEMP_ADD[nr][index],
584 data->temp_add[nr][index]); 591 data->temp_add[nr][index]);
585 w83792d_write_value(client, W83792D_REG_TEMP_ADD[nr][index+1], 592 w83792d_write_value(client, W83792D_REG_TEMP_ADD[nr][index+1],
586 data->temp_add[nr][index+1]); 593 data->temp_add[nr][index+1]);
594 mutex_unlock(&data->update_lock);
587 595
588 return count; 596 return count;
589} 597}
@@ -682,6 +690,10 @@ store_pwmenable(struct device *dev, struct device_attribute *attr,
682 u8 fan_cfg_tmp, cfg1_tmp, cfg2_tmp, cfg3_tmp, cfg4_tmp; 690 u8 fan_cfg_tmp, cfg1_tmp, cfg2_tmp, cfg3_tmp, cfg4_tmp;
683 691
684 val = simple_strtoul(buf, NULL, 10); 692 val = simple_strtoul(buf, NULL, 10);
693 if (val < 1 || val > 3)
694 return -EINVAL;
695
696 mutex_lock(&data->update_lock);
685 switch (val) { 697 switch (val) {
686 case 1: 698 case 1:
687 data->pwmenable[nr] = 0; /* manual mode */ 699 data->pwmenable[nr] = 0; /* manual mode */
@@ -692,8 +704,6 @@ store_pwmenable(struct device *dev, struct device_attribute *attr,
692 case 3: 704 case 3:
693 data->pwmenable[nr] = 1; /* thermal cruise/Smart Fan I */ 705 data->pwmenable[nr] = 1; /* thermal cruise/Smart Fan I */
694 break; 706 break;
695 default:
696 return -EINVAL;
697 } 707 }
698 cfg1_tmp = data->pwmenable[0]; 708 cfg1_tmp = data->pwmenable[0];
699 cfg2_tmp = (data->pwmenable[1]) << 2; 709 cfg2_tmp = (data->pwmenable[1]) << 2;
@@ -701,6 +711,7 @@ store_pwmenable(struct device *dev, struct device_attribute *attr,
701 cfg4_tmp = w83792d_read_value(client,W83792D_REG_FAN_CFG) & 0xc0; 711 cfg4_tmp = w83792d_read_value(client,W83792D_REG_FAN_CFG) & 0xc0;
702 fan_cfg_tmp = ((cfg4_tmp | cfg3_tmp) | cfg2_tmp) | cfg1_tmp; 712 fan_cfg_tmp = ((cfg4_tmp | cfg3_tmp) | cfg2_tmp) | cfg1_tmp;
703 w83792d_write_value(client, W83792D_REG_FAN_CFG, fan_cfg_tmp); 713 w83792d_write_value(client, W83792D_REG_FAN_CFG, fan_cfg_tmp);
714 mutex_unlock(&data->update_lock);
704 715
705 return count; 716 return count;
706} 717}
@@ -794,12 +805,13 @@ store_chassis_clear(struct device *dev, struct device_attribute *attr,
794 u8 temp1 = 0, temp2 = 0; 805 u8 temp1 = 0, temp2 = 0;
795 806
796 val = simple_strtoul(buf, NULL, 10); 807 val = simple_strtoul(buf, NULL, 10);
797 808 mutex_lock(&data->update_lock);
798 data->chassis_clear = SENSORS_LIMIT(val, 0 ,1); 809 data->chassis_clear = SENSORS_LIMIT(val, 0 ,1);
799 temp1 = ((data->chassis_clear) << 7) & 0x80; 810 temp1 = ((data->chassis_clear) << 7) & 0x80;
800 temp2 = w83792d_read_value(client, 811 temp2 = w83792d_read_value(client,
801 W83792D_REG_CHASSIS_CLR) & 0x7f; 812 W83792D_REG_CHASSIS_CLR) & 0x7f;
802 w83792d_write_value(client, W83792D_REG_CHASSIS_CLR, temp1 | temp2); 813 w83792d_write_value(client, W83792D_REG_CHASSIS_CLR, temp1 | temp2);
814 mutex_unlock(&data->update_lock);
803 815
804 return count; 816 return count;
805} 817}
@@ -832,10 +844,12 @@ store_thermal_cruise(struct device *dev, struct device_attribute *attr,
832 val = simple_strtoul(buf, NULL, 10); 844 val = simple_strtoul(buf, NULL, 10);
833 target_tmp = val; 845 target_tmp = val;
834 target_tmp = target_tmp & 0x7f; 846 target_tmp = target_tmp & 0x7f;
847 mutex_lock(&data->update_lock);
835 target_mask = w83792d_read_value(client, W83792D_REG_THERMAL[nr]) & 0x80; 848 target_mask = w83792d_read_value(client, W83792D_REG_THERMAL[nr]) & 0x80;
836 data->thermal_cruise[nr] = SENSORS_LIMIT(target_tmp, 0, 255); 849 data->thermal_cruise[nr] = SENSORS_LIMIT(target_tmp, 0, 255);
837 w83792d_write_value(client, W83792D_REG_THERMAL[nr], 850 w83792d_write_value(client, W83792D_REG_THERMAL[nr],
838 (data->thermal_cruise[nr]) | target_mask); 851 (data->thermal_cruise[nr]) | target_mask);
852 mutex_unlock(&data->update_lock);
839 853
840 return count; 854 return count;
841} 855}
@@ -872,6 +886,7 @@ store_tolerance(struct device *dev, struct device_attribute *attr,
872 u8 tol_tmp, tol_mask; 886 u8 tol_tmp, tol_mask;
873 887
874 val = simple_strtoul(buf, NULL, 10); 888 val = simple_strtoul(buf, NULL, 10);
889 mutex_lock(&data->update_lock);
875 tol_mask = w83792d_read_value(client, 890 tol_mask = w83792d_read_value(client,
876 W83792D_REG_TOLERANCE[nr]) & ((nr == 1) ? 0x0f : 0xf0); 891 W83792D_REG_TOLERANCE[nr]) & ((nr == 1) ? 0x0f : 0xf0);
877 tol_tmp = SENSORS_LIMIT(val, 0, 15); 892 tol_tmp = SENSORS_LIMIT(val, 0, 15);
@@ -882,6 +897,7 @@ store_tolerance(struct device *dev, struct device_attribute *attr,
882 } 897 }
883 w83792d_write_value(client, W83792D_REG_TOLERANCE[nr], 898 w83792d_write_value(client, W83792D_REG_TOLERANCE[nr],
884 tol_mask | tol_tmp); 899 tol_mask | tol_tmp);
900 mutex_unlock(&data->update_lock);
885 901
886 return count; 902 return count;
887} 903}
@@ -920,11 +936,13 @@ store_sf2_point(struct device *dev, struct device_attribute *attr,
920 u8 mask_tmp = 0; 936 u8 mask_tmp = 0;
921 937
922 val = simple_strtoul(buf, NULL, 10); 938 val = simple_strtoul(buf, NULL, 10);
939 mutex_lock(&data->update_lock);
923 data->sf2_points[index][nr] = SENSORS_LIMIT(val, 0, 127); 940 data->sf2_points[index][nr] = SENSORS_LIMIT(val, 0, 127);
924 mask_tmp = w83792d_read_value(client, 941 mask_tmp = w83792d_read_value(client,
925 W83792D_REG_POINTS[index][nr]) & 0x80; 942 W83792D_REG_POINTS[index][nr]) & 0x80;
926 w83792d_write_value(client, W83792D_REG_POINTS[index][nr], 943 w83792d_write_value(client, W83792D_REG_POINTS[index][nr],
927 mask_tmp|data->sf2_points[index][nr]); 944 mask_tmp|data->sf2_points[index][nr]);
945 mutex_unlock(&data->update_lock);
928 946
929 return count; 947 return count;
930} 948}
@@ -984,6 +1002,7 @@ store_sf2_level(struct device *dev, struct device_attribute *attr,
984 u8 mask_tmp=0, level_tmp=0; 1002 u8 mask_tmp=0, level_tmp=0;
985 1003
986 val = simple_strtoul(buf, NULL, 10); 1004 val = simple_strtoul(buf, NULL, 10);
1005 mutex_lock(&data->update_lock);
987 data->sf2_levels[index][nr] = SENSORS_LIMIT((val * 15) / 100, 0, 15); 1006 data->sf2_levels[index][nr] = SENSORS_LIMIT((val * 15) / 100, 0, 15);
988 mask_tmp = w83792d_read_value(client, W83792D_REG_LEVELS[index][nr]) 1007 mask_tmp = w83792d_read_value(client, W83792D_REG_LEVELS[index][nr])
989 & ((nr==3) ? 0xf0 : 0x0f); 1008 & ((nr==3) ? 0xf0 : 0x0f);
@@ -993,6 +1012,7 @@ store_sf2_level(struct device *dev, struct device_attribute *attr,
993 level_tmp = data->sf2_levels[index][nr] << 4; 1012 level_tmp = data->sf2_levels[index][nr] << 4;
994 } 1013 }
995 w83792d_write_value(client, W83792D_REG_LEVELS[index][nr], level_tmp | mask_tmp); 1014 w83792d_write_value(client, W83792D_REG_LEVELS[index][nr], level_tmp | mask_tmp);
1015 mutex_unlock(&data->update_lock);
996 1016
997 return count; 1017 return count;
998} 1018}