aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@ppc970.osdl.org>2005-04-01 06:02:46 -0800
committerLinus Torvalds <torvalds@ppc970.osdl.org>2005-04-01 06:02:46 -0800
commitaf3c4ba378116570005cc4563ea09e5f8a2f422d (patch)
tree169bce22b378a1957aa0776cba9be1146412a689
parent916e34199eb6a66e08030e0f8495704f2e2d1829 (diff)
parent2b55b78c26ba106c5caabd6a2529b8af749e4151 (diff)
downloadhistory-af3c4ba378116570005cc4563ea09e5f8a2f422d.tar.gz
Merge bk://kernel.bkbits.net/davem/sparc-2.6
into ppc970.osdl.org:/home/torvalds/v2.6/linux
-rw-r--r--drivers/i2c/chips/adm1021.c2
-rw-r--r--drivers/i2c/chips/adm1025.c12
-rw-r--r--drivers/i2c/chips/adm1026.c55
-rw-r--r--drivers/i2c/chips/adm1031.c23
-rw-r--r--drivers/i2c/chips/asb100.c25
-rw-r--r--drivers/i2c/chips/ds1621.c6
-rw-r--r--drivers/i2c/chips/fscher.c34
-rw-r--r--drivers/i2c/chips/fscpos.c18
-rw-r--r--drivers/i2c/chips/gl518sm.c25
-rw-r--r--drivers/i2c/chips/gl520sm.c43
-rw-r--r--drivers/i2c/chips/it87.c44
-rw-r--r--drivers/i2c/chips/lm63.c19
-rw-r--r--drivers/i2c/chips/lm75.c3
-rw-r--r--drivers/i2c/chips/lm77.c21
-rw-r--r--drivers/i2c/chips/lm78.c30
-rw-r--r--drivers/i2c/chips/lm80.c16
-rw-r--r--drivers/i2c/chips/lm83.c3
-rw-r--r--drivers/i2c/chips/lm85.c44
-rw-r--r--drivers/i2c/chips/lm87.c31
-rw-r--r--drivers/i2c/chips/lm90.c14
-rw-r--r--drivers/i2c/chips/lm92.c10
-rw-r--r--drivers/i2c/chips/max1619.c3
-rw-r--r--drivers/i2c/chips/pc87360.c29
-rw-r--r--drivers/i2c/chips/pcf8574.c27
-rw-r--r--drivers/i2c/chips/pcf8591.c6
-rw-r--r--drivers/i2c/chips/sis5595.c28
-rw-r--r--drivers/i2c/chips/smsc47m1.c24
-rw-r--r--drivers/i2c/chips/via686a.c21
-rw-r--r--drivers/i2c/chips/w83627hf.c32
-rw-r--r--drivers/i2c/chips/w83781d.c29
-rw-r--r--drivers/i2c/i2c-core.c19
-rw-r--r--include/linux/i2c.h10
-rw-r--r--security/selinux/hooks.c21
33 files changed, 519 insertions, 208 deletions
diff --git a/drivers/i2c/chips/adm1021.c b/drivers/i2c/chips/adm1021.c
index b4e3ee568265ff..9c59a370b6d956 100644
--- a/drivers/i2c/chips/adm1021.c
+++ b/drivers/i2c/chips/adm1021.c
@@ -165,8 +165,10 @@ static ssize_t set_##value(struct device *dev, const char *buf, size_t count) \
struct adm1021_data *data = i2c_get_clientdata(client); \
int temp = simple_strtoul(buf, NULL, 10); \
\
+ down(&data->update_lock); \
data->value = TEMP_TO_REG(temp); \
adm1021_write_value(client, reg, data->value); \
+ up(&data->update_lock); \
return count; \
}
set(temp_max, ADM1021_REG_TOS_W);
diff --git a/drivers/i2c/chips/adm1025.c b/drivers/i2c/chips/adm1025.c
index d9053e37ea2b5f..e0771a3d05c955 100644
--- a/drivers/i2c/chips/adm1025.c
+++ b/drivers/i2c/chips/adm1025.c
@@ -206,9 +206,12 @@ static ssize_t set_in##offset##_min(struct device *dev, const char *buf, \
struct i2c_client *client = to_i2c_client(dev); \
struct adm1025_data *data = i2c_get_clientdata(client); \
long val = simple_strtol(buf, NULL, 10); \
+ \
+ down(&data->update_lock); \
data->in_min[offset] = IN_TO_REG(val, in_scale[offset]); \
i2c_smbus_write_byte_data(client, ADM1025_REG_IN_MIN(offset), \
data->in_min[offset]); \
+ up(&data->update_lock); \
return count; \
} \
static ssize_t set_in##offset##_max(struct device *dev, const char *buf, \
@@ -217,9 +220,12 @@ static ssize_t set_in##offset##_max(struct device *dev, const char *buf, \
struct i2c_client *client = to_i2c_client(dev); \
struct adm1025_data *data = i2c_get_clientdata(client); \
long val = simple_strtol(buf, NULL, 10); \
+ \
+ down(&data->update_lock); \
data->in_max[offset] = IN_TO_REG(val, in_scale[offset]); \
i2c_smbus_write_byte_data(client, ADM1025_REG_IN_MAX(offset), \
data->in_max[offset]); \
+ up(&data->update_lock); \
return count; \
} \
static DEVICE_ATTR(in##offset##_min, S_IWUSR | S_IRUGO, \
@@ -240,9 +246,12 @@ static ssize_t set_temp##offset##_min(struct device *dev, const char *buf, \
struct i2c_client *client = to_i2c_client(dev); \
struct adm1025_data *data = i2c_get_clientdata(client); \
long val = simple_strtol(buf, NULL, 10); \
+ \
+ down(&data->update_lock); \
data->temp_min[offset-1] = TEMP_TO_REG(val); \
i2c_smbus_write_byte_data(client, ADM1025_REG_TEMP_LOW(offset-1), \
data->temp_min[offset-1]); \
+ up(&data->update_lock); \
return count; \
} \
static ssize_t set_temp##offset##_max(struct device *dev, const char *buf, \
@@ -251,9 +260,12 @@ static ssize_t set_temp##offset##_max(struct device *dev, const char *buf, \
struct i2c_client *client = to_i2c_client(dev); \
struct adm1025_data *data = i2c_get_clientdata(client); \
long val = simple_strtol(buf, NULL, 10); \
+ \
+ down(&data->update_lock); \
data->temp_max[offset-1] = TEMP_TO_REG(val); \
i2c_smbus_write_byte_data(client, ADM1025_REG_TEMP_HIGH(offset-1), \
data->temp_max[offset-1]); \
+ up(&data->update_lock); \
return count; \
} \
static DEVICE_ATTR(temp##offset##_min, S_IWUSR | S_IRUGO, \
diff --git a/drivers/i2c/chips/adm1026.c b/drivers/i2c/chips/adm1026.c
index 1a0f4f2220330d..39e2f4a900bf32 100644
--- a/drivers/i2c/chips/adm1026.c
+++ b/drivers/i2c/chips/adm1026.c
@@ -726,10 +726,9 @@ static ssize_t set_in_min(struct device *dev, const char *buf,
{
struct i2c_client *client = to_i2c_client(dev);
struct adm1026_data *data = i2c_get_clientdata(client);
- int val;
+ int val = simple_strtol(buf, NULL, 10);
down(&data->update_lock);
- val = simple_strtol(buf, NULL, 10);
data->in_min[nr] = INS_TO_REG(nr, val);
adm1026_write_value(client, ADM1026_REG_IN_MIN[nr], data->in_min[nr]);
up(&data->update_lock);
@@ -745,10 +744,9 @@ static ssize_t set_in_max(struct device *dev, const char *buf,
{
struct i2c_client *client = to_i2c_client(dev);
struct adm1026_data *data = i2c_get_clientdata(client);
- int val;
+ int val = simple_strtol(buf, NULL, 10);
down(&data->update_lock);
- val = simple_strtol(buf, NULL, 10);
data->in_max[nr] = INS_TO_REG(nr, val);
adm1026_write_value(client, ADM1026_REG_IN_MAX[nr], data->in_max[nr]);
up(&data->update_lock);
@@ -818,10 +816,9 @@ static ssize_t set_in16_min(struct device *dev, const char *buf, size_t count)
{
struct i2c_client *client = to_i2c_client(dev);
struct adm1026_data *data = i2c_get_clientdata(client);
- int val;
+ int val = simple_strtol(buf, NULL, 10);
down(&data->update_lock);
- val = simple_strtol(buf, NULL, 10);
data->in_min[16] = INS_TO_REG(16, val + NEG12_OFFSET);
adm1026_write_value(client, ADM1026_REG_IN_MIN[16], data->in_min[16]);
up(&data->update_lock);
@@ -837,10 +834,9 @@ static ssize_t set_in16_max(struct device *dev, const char *buf, size_t count)
{
struct i2c_client *client = to_i2c_client(dev);
struct adm1026_data *data = i2c_get_clientdata(client);
- int val;
+ int val = simple_strtol(buf, NULL, 10);
down(&data->update_lock);
- val = simple_strtol(buf, NULL, 10);
data->in_max[16] = INS_TO_REG(16, val+NEG12_OFFSET);
adm1026_write_value(client, ADM1026_REG_IN_MAX[16], data->in_max[16]);
up(&data->update_lock);
@@ -873,10 +869,9 @@ static ssize_t set_fan_min(struct device *dev, const char *buf,
{
struct i2c_client *client = to_i2c_client(dev);
struct adm1026_data *data = i2c_get_clientdata(client);
- int val;
+ int val = simple_strtol(buf, NULL, 10);
down(&data->update_lock);
- val = simple_strtol(buf, NULL, 10);
data->fan_min[nr] = FAN_TO_REG(val, data->fan_div[nr]);
adm1026_write_value(client, ADM1026_REG_FAN_MIN(nr),
data->fan_min[nr]);
@@ -1009,10 +1004,9 @@ static ssize_t set_temp_min(struct device *dev, const char *buf,
{
struct i2c_client *client = to_i2c_client(dev);
struct adm1026_data *data = i2c_get_clientdata(client);
- int val;
+ int val = simple_strtol(buf, NULL, 10);
down(&data->update_lock);
- val = simple_strtol(buf, NULL, 10);
data->temp_min[nr] = TEMP_TO_REG(val);
adm1026_write_value(client, ADM1026_REG_TEMP_MIN[nr],
data->temp_min[nr]);
@@ -1029,10 +1023,9 @@ static ssize_t set_temp_max(struct device *dev, const char *buf,
{
struct i2c_client *client = to_i2c_client(dev);
struct adm1026_data *data = i2c_get_clientdata(client);
- int val;
+ int val = simple_strtol(buf, NULL, 10);
down(&data->update_lock);
- val = simple_strtol(buf, NULL, 10);
data->temp_max[nr] = TEMP_TO_REG(val);
adm1026_write_value(client, ADM1026_REG_TEMP_MAX[nr],
data->temp_max[nr]);
@@ -1083,10 +1076,9 @@ static ssize_t set_temp_offset(struct device *dev, const char *buf,
{
struct i2c_client *client = to_i2c_client(dev);
struct adm1026_data *data = i2c_get_clientdata(client);
- int val;
+ int val = simple_strtol(buf, NULL, 10);
down(&data->update_lock);
- val = simple_strtol(buf, NULL, 10);
data->temp_offset[nr] = TEMP_TO_REG(val);
adm1026_write_value(client, ADM1026_REG_TEMP_OFFSET[nr],
data->temp_offset[nr]);
@@ -1136,10 +1128,9 @@ static ssize_t set_temp_auto_point1_temp(struct device *dev, const char *buf,
{
struct i2c_client *client = to_i2c_client(dev);
struct adm1026_data *data = i2c_get_clientdata(client);
- int val;
+ int val = simple_strtol(buf, NULL, 10);
down(&data->update_lock);
- val = simple_strtol(buf, NULL, 10);
data->temp_tmin[nr] = TEMP_TO_REG(val);
adm1026_write_value(client, ADM1026_REG_TEMP_TMIN[nr],
data->temp_tmin[nr]);
@@ -1190,9 +1181,8 @@ static ssize_t set_temp_crit_enable(struct device *dev, const char *buf,
{
struct i2c_client *client = to_i2c_client(dev);
struct adm1026_data *data = i2c_get_clientdata(client);
- int val;
+ int val = simple_strtol(buf, NULL, 10);
- val = simple_strtol(buf, NULL, 10);
if ((val == 1) || (val==0)) {
down(&data->update_lock);
data->config1 = (data->config1 & ~CFG1_THERM_HOT) | (val << 4);
@@ -1223,10 +1213,9 @@ static ssize_t set_temp_crit(struct device *dev, const char *buf,
{
struct i2c_client *client = to_i2c_client(dev);
struct adm1026_data *data = i2c_get_clientdata(client);
- int val;
+ int val = simple_strtol(buf, NULL, 10);
down(&data->update_lock);
- val = simple_strtol(buf, NULL, 10);
data->temp_crit[nr] = TEMP_TO_REG(val);
adm1026_write_value(client, ADM1026_REG_TEMP_THERM[nr],
data->temp_crit[nr]);
@@ -1261,10 +1250,9 @@ static ssize_t set_analog_out_reg(struct device *dev, const char *buf,
{
struct i2c_client *client = to_i2c_client(dev);
struct adm1026_data *data = i2c_get_clientdata(client);
- int val;
+ int val = simple_strtol(buf, NULL, 10);
down(&data->update_lock);
- val = simple_strtol(buf, NULL, 10);
data->analog_out = DAC_TO_REG(val);
adm1026_write_value(client, ADM1026_REG_DAC, data->analog_out);
up(&data->update_lock);
@@ -1317,11 +1305,10 @@ static ssize_t set_alarm_mask(struct device *dev, const char *buf,
{
struct i2c_client *client = to_i2c_client(dev);
struct adm1026_data *data = i2c_get_clientdata(client);
- int val;
+ int val = simple_strtol(buf, NULL, 10);
unsigned long mask;
down(&data->update_lock);
- val = simple_strtol(buf, NULL, 10);
data->alarm_mask = val & 0x7fffffff;
mask = data->alarm_mask
| (data->gpio_mask & 0x10000 ? 0x80000000 : 0);
@@ -1354,11 +1341,10 @@ static ssize_t set_gpio(struct device *dev, const char *buf,
{
struct i2c_client *client = to_i2c_client(dev);
struct adm1026_data *data = i2c_get_clientdata(client);
- int val;
+ int val = simple_strtol(buf, NULL, 10);
long gpio;
down(&data->update_lock);
- val = simple_strtol(buf, NULL, 10);
data->gpio = val & 0x1ffff;
gpio = data->gpio;
adm1026_write_value(client, ADM1026_REG_GPIO_STATUS_0_7,gpio & 0xff);
@@ -1383,11 +1369,10 @@ static ssize_t set_gpio_mask(struct device *dev, const char *buf,
{
struct i2c_client *client = to_i2c_client(dev);
struct adm1026_data *data = i2c_get_clientdata(client);
- int val;
+ int val = simple_strtol(buf, NULL, 10);
long mask;
down(&data->update_lock);
- val = simple_strtol(buf, NULL, 10);
data->gpio_mask = val & 0x1ffff;
mask = data->gpio_mask;
adm1026_write_value(client, ADM1026_REG_GPIO_MASK_0_7,mask & 0xff);
@@ -1411,11 +1396,11 @@ static ssize_t set_pwm_reg(struct device *dev, const char *buf,
{
struct i2c_client *client = to_i2c_client(dev);
struct adm1026_data *data = i2c_get_clientdata(client);
- int val;
if (data->pwm1.enable == 1) {
+ int val = simple_strtol(buf, NULL, 10);
+
down(&data->update_lock);
- val = simple_strtol(buf, NULL, 10);
data->pwm1.pwm = PWM_TO_REG(val);
adm1026_write_value(client, ADM1026_REG_PWM, data->pwm1.pwm);
up(&data->update_lock);
@@ -1432,10 +1417,9 @@ static ssize_t set_auto_pwm_min(struct device *dev, const char *buf,
{
struct i2c_client *client = to_i2c_client(dev);
struct adm1026_data *data = i2c_get_clientdata(client);
- int val;
+ int val = simple_strtol(buf, NULL, 10);
down(&data->update_lock);
- val = simple_strtol(buf, NULL, 10);
data->pwm1.auto_pwm_min = SENSORS_LIMIT(val,0,255);
if (data->pwm1.enable == 2) { /* apply immediately */
data->pwm1.pwm = PWM_TO_REG((data->pwm1.pwm & 0x0f) |
@@ -1459,10 +1443,9 @@ static ssize_t set_pwm_enable(struct device *dev, const char *buf,
{
struct i2c_client *client = to_i2c_client(dev);
struct adm1026_data *data = i2c_get_clientdata(client);
- int val;
+ int val = simple_strtol(buf, NULL, 10);
int old_enable;
- val = simple_strtol(buf, NULL, 10);
if ((val >= 0) && (val < 3)) {
down(&data->update_lock);
old_enable = data->pwm1.enable;
diff --git a/drivers/i2c/chips/adm1031.c b/drivers/i2c/chips/adm1031.c
index fc516c389bb535..d4385a23f79a7d 100644
--- a/drivers/i2c/chips/adm1031.c
+++ b/drivers/i2c/chips/adm1031.c
@@ -254,7 +254,7 @@ set_fan_auto_channel(struct device *dev, const char *buf, size_t count, int nr)
{
struct i2c_client *client = to_i2c_client(dev);
struct adm1031_data *data = i2c_get_clientdata(client);
- int val;
+ int val = simple_strtol(buf, NULL, 10);
u8 reg;
int ret;
u8 old_fan_mode;
@@ -262,7 +262,6 @@ set_fan_auto_channel(struct device *dev, const char *buf, size_t count, int nr)
old_fan_mode = data->conf1;
down(&data->update_lock);
- val = simple_strtol(buf, NULL, 10);
if ((ret = get_fan_auto_nearest(data, nr, val, data->conf1, &reg))) {
up(&data->update_lock);
@@ -327,10 +326,9 @@ set_auto_temp_min(struct device *dev, const char *buf, size_t count, int nr)
{
struct i2c_client *client = to_i2c_client(dev);
struct adm1031_data *data = i2c_get_clientdata(client);
- int val;
+ int val = simple_strtol(buf, NULL, 10);
down(&data->update_lock);
- val = simple_strtol(buf, NULL, 10);
data->auto_temp[nr] = AUTO_TEMP_MIN_TO_REG(val, data->auto_temp[nr]);
adm1031_write_value(client, ADM1031_REG_AUTO_TEMP(nr),
data->auto_temp[nr]);
@@ -348,10 +346,9 @@ set_auto_temp_max(struct device *dev, const char *buf, size_t count, int nr)
{
struct i2c_client *client = to_i2c_client(dev);
struct adm1031_data *data = i2c_get_clientdata(client);
- int val;
+ int val = simple_strtol(buf, NULL, 10);
down(&data->update_lock);
- val = simple_strtol(buf, NULL, 10);
data->temp_max[nr] = AUTO_TEMP_MAX_TO_REG(val, data->auto_temp[nr], data->pwm[nr]);
adm1031_write_value(client, ADM1031_REG_AUTO_TEMP(nr),
data->temp_max[nr]);
@@ -404,10 +401,10 @@ set_pwm(struct device *dev, const char *buf, size_t count, int nr)
{
struct i2c_client *client = to_i2c_client(dev);
struct adm1031_data *data = i2c_get_clientdata(client);
- int val;
+ int val = simple_strtol(buf, NULL, 10);
int reg;
+
down(&data->update_lock);
- val = simple_strtol(buf, NULL, 10);
if ((data->conf1 & ADM1031_CONF1_AUTO_MODE) &&
(((val>>4) & 0xf) != 5)) {
/* In automatic mode, the only PWM accepted is 33% */
@@ -511,10 +508,9 @@ set_fan_min(struct device *dev, const char *buf, size_t count, int nr)
{
struct i2c_client *client = to_i2c_client(dev);
struct adm1031_data *data = i2c_get_clientdata(client);
- int val;
+ int val = simple_strtol(buf, NULL, 10);
down(&data->update_lock);
- val = simple_strtol(buf, NULL, 10);
if (val) {
data->fan_min[nr] =
FAN_TO_REG(val, FAN_DIV_FROM_REG(data->fan_div[nr]));
@@ -530,12 +526,11 @@ set_fan_div(struct device *dev, const char *buf, size_t count, int nr)
{
struct i2c_client *client = to_i2c_client(dev);
struct adm1031_data *data = i2c_get_clientdata(client);
- int val;
+ int val = simple_strtol(buf, NULL, 10);
u8 tmp;
- int old_div = FAN_DIV_FROM_REG(data->fan_div[nr]);
+ int old_div;
int new_min;
- val = simple_strtol(buf, NULL, 10);
tmp = val == 8 ? 0xc0 :
val == 4 ? 0x80 :
val == 2 ? 0x40 :
@@ -543,7 +538,9 @@ set_fan_div(struct device *dev, const char *buf, size_t count, int nr)
0xff;
if (tmp == 0xff)
return -EINVAL;
+
down(&data->update_lock);
+ old_div = FAN_DIV_FROM_REG(data->fan_div[nr]);
data->fan_div[nr] = (tmp & 0xC0) | (0x3f & data->fan_div[nr]);
new_min = data->fan_min[nr] * old_div /
FAN_DIV_FROM_REG(data->fan_div[nr]);
diff --git a/drivers/i2c/chips/asb100.c b/drivers/i2c/chips/asb100.c
index a02d17236e0476..7f899002bc5493 100644
--- a/drivers/i2c/chips/asb100.c
+++ b/drivers/i2c/chips/asb100.c
@@ -246,9 +246,12 @@ static ssize_t set_in_##reg(struct device *dev, const char *buf, \
struct i2c_client *client = to_i2c_client(dev); \
struct asb100_data *data = i2c_get_clientdata(client); \
unsigned long val = simple_strtoul(buf, NULL, 10); \
+ \
+ down(&data->update_lock); \
data->in_##reg[nr] = IN_TO_REG(val); \
asb100_write_value(client, ASB100_REG_IN_##REG(nr), \
data->in_##reg[nr]); \
+ up(&data->update_lock); \
return count; \
}
@@ -329,8 +332,11 @@ static ssize_t set_fan_min(struct device *dev, const char *buf,
struct i2c_client *client = to_i2c_client(dev);
struct asb100_data *data = i2c_get_clientdata(client);
u32 val = simple_strtoul(buf, NULL, 10);
+
+ down(&data->update_lock);
data->fan_min[nr] = FAN_TO_REG(val, DIV_FROM_REG(data->fan_div[nr]));
asb100_write_value(client, ASB100_REG_FAN_MIN(nr), data->fan_min[nr]);
+ up(&data->update_lock);
return count;
}
@@ -343,11 +349,14 @@ static ssize_t set_fan_div(struct device *dev, const char *buf,
{
struct i2c_client *client = to_i2c_client(dev);
struct asb100_data *data = i2c_get_clientdata(client);
- unsigned long min = FAN_FROM_REG(data->fan_min[nr],
- DIV_FROM_REG(data->fan_div[nr]));
+ unsigned long min;
unsigned long val = simple_strtoul(buf, NULL, 10);
int reg;
+ down(&data->update_lock);
+
+ min = FAN_FROM_REG(data->fan_min[nr],
+ DIV_FROM_REG(data->fan_div[nr]));
data->fan_div[nr] = DIV_TO_REG(val);
switch(nr) {
@@ -373,6 +382,9 @@ static ssize_t set_fan_div(struct device *dev, const char *buf,
data->fan_min[nr] =
FAN_TO_REG(min, DIV_FROM_REG(data->fan_div[nr]));
asb100_write_value(client, ASB100_REG_FAN_MIN(nr), data->fan_min[nr]);
+
+ up(&data->update_lock);
+
return count;
}
@@ -450,6 +462,8 @@ static ssize_t set_##reg(struct device *dev, const char *buf, \
struct i2c_client *client = to_i2c_client(dev); \
struct asb100_data *data = i2c_get_clientdata(client); \
unsigned long val = simple_strtoul(buf, NULL, 10); \
+ \
+ down(&data->update_lock); \
switch (nr) { \
case 1: case 2: \
data->reg[nr] = LM75_TEMP_TO_REG(val); \
@@ -460,6 +474,7 @@ static ssize_t set_##reg(struct device *dev, const char *buf, \
} \
asb100_write_value(client, ASB100_REG_TEMP_##REG(nr+1), \
data->reg[nr]); \
+ up(&data->update_lock); \
return count; \
}
@@ -560,9 +575,12 @@ static ssize_t set_pwm1(struct device *dev, const char *buf, size_t count)
struct i2c_client *client = to_i2c_client(dev);
struct asb100_data *data = i2c_get_clientdata(client);
unsigned long val = simple_strtoul(buf, NULL, 10);
+
+ down(&data->update_lock);
data->pwm &= 0x80; /* keep the enable bit */
data->pwm |= (0x0f & ASB100_PWM_TO_REG(val));
asb100_write_value(client, ASB100_REG_PWM1, data->pwm);
+ up(&data->update_lock);
return count;
}
@@ -578,9 +596,12 @@ static ssize_t set_pwm_enable1(struct device *dev, const char *buf,
struct i2c_client *client = to_i2c_client(dev);
struct asb100_data *data = i2c_get_clientdata(client);
unsigned long val = simple_strtoul(buf, NULL, 10);
+
+ down(&data->update_lock);
data->pwm &= 0x0f; /* keep the duty cycle bits */
data->pwm |= (val ? 0x80 : 0x00);
asb100_write_value(client, ASB100_REG_PWM1, data->pwm);
+ up(&data->update_lock);
return count;
}
diff --git a/drivers/i2c/chips/ds1621.c b/drivers/i2c/chips/ds1621.c
index 213c717a756bf1..bb1fefb2162ecc 100644
--- a/drivers/i2c/chips/ds1621.c
+++ b/drivers/i2c/chips/ds1621.c
@@ -153,8 +153,12 @@ static ssize_t set_temp_##suffix(struct device *dev, const char *buf, \
{ \
struct i2c_client *client = to_i2c_client(dev); \
struct ds1621_data *data = ds1621_update_client(dev); \
- data->value = LM75_TEMP_TO_REG(simple_strtoul(buf, NULL, 10)); \
+ u16 val = LM75_TEMP_TO_REG(simple_strtoul(buf, NULL, 10)); \
+ \
+ down(&data->update_lock); \
+ data->value = val; \
ds1621_write_value(client, reg, data->value); \
+ up(&data->update_lock); \
return count; \
}
diff --git a/drivers/i2c/chips/fscher.c b/drivers/i2c/chips/fscher.c
index ad6a0a7467801d..18e33ac59d0cd5 100644
--- a/drivers/i2c/chips/fscher.c
+++ b/drivers/i2c/chips/fscher.c
@@ -464,9 +464,11 @@ static ssize_t set_fan_status(struct i2c_client *client, struct fscher_data *dat
{
/* bits 0..1, 3..7 reserved => mask with 0x04 */
unsigned long v = simple_strtoul(buf, NULL, 10) & 0x04;
+
+ down(&data->update_lock);
data->fan_status[FAN_INDEX_FROM_NUM(nr)] &= ~v;
-
fscher_write_value(client, reg, v);
+ up(&data->update_lock);
return count;
}
@@ -480,9 +482,11 @@ static ssize_t set_pwm(struct i2c_client *client, struct fscher_data *data,
const char *buf, size_t count, int nr, int reg)
{
unsigned long v = simple_strtoul(buf, NULL, 10);
- data->fan_min[FAN_INDEX_FROM_NUM(nr)] = v > 0xff ? 0xff : v;
+ down(&data->update_lock);
+ data->fan_min[FAN_INDEX_FROM_NUM(nr)] = v > 0xff ? 0xff : v;
fscher_write_value(client, reg, data->fan_min[FAN_INDEX_FROM_NUM(nr)]);
+ up(&data->update_lock);
return count;
}
@@ -507,11 +511,14 @@ static ssize_t set_fan_div(struct i2c_client *client, struct fscher_data *data,
return -EINVAL;
}
+ down(&data->update_lock);
+
/* bits 2..7 reserved => mask with 0x03 */
data->fan_ripple[FAN_INDEX_FROM_NUM(nr)] &= ~0x03;
data->fan_ripple[FAN_INDEX_FROM_NUM(nr)] |= v;
fscher_write_value(client, reg, data->fan_ripple[FAN_INDEX_FROM_NUM(nr)]);
+ up(&data->update_lock);
return count;
}
@@ -537,9 +544,11 @@ static ssize_t set_temp_status(struct i2c_client *client, struct fscher_data *da
{
/* bits 2..7 reserved, 0 read only => mask with 0x02 */
unsigned long v = simple_strtoul(buf, NULL, 10) & 0x02;
- data->temp_status[TEMP_INDEX_FROM_NUM(nr)] &= ~v;
+ down(&data->update_lock);
+ data->temp_status[TEMP_INDEX_FROM_NUM(nr)] &= ~v;
fscher_write_value(client, reg, v);
+ up(&data->update_lock);
return count;
}
@@ -592,9 +601,11 @@ static ssize_t set_control(struct i2c_client *client, struct fscher_data *data,
{
/* bits 1..7 reserved => mask with 0x01 */
unsigned long v = simple_strtoul(buf, NULL, 10) & 0x01;
- data->global_control &= ~v;
+ down(&data->update_lock);
+ data->global_control &= ~v;
fscher_write_value(client, reg, v);
+ up(&data->update_lock);
return count;
}
@@ -612,10 +623,12 @@ static ssize_t set_watchdog_control(struct i2c_client *client, struct
{
/* bits 0..3 reserved => mask with 0xf0 */
unsigned long v = simple_strtoul(buf, NULL, 10) & 0xf0;
+
+ down(&data->update_lock);
data->watchdog[2] &= ~0xf0;
data->watchdog[2] |= v;
-
fscher_write_value(client, reg, data->watchdog[2]);
+ up(&data->update_lock);
return count;
}
@@ -630,9 +643,11 @@ static ssize_t set_watchdog_status(struct i2c_client *client, struct fscher_data
{
/* bits 0, 2..7 reserved => mask with 0x02 */
unsigned long v = simple_strtoul(buf, NULL, 10) & 0x02;
- data->watchdog[1] &= ~v;
+ down(&data->update_lock);
+ data->watchdog[1] &= ~v;
fscher_write_value(client, reg, v);
+ up(&data->update_lock);
return count;
}
@@ -645,9 +660,12 @@ static ssize_t show_watchdog_status(struct fscher_data *data, char *buf, int nr)
static ssize_t set_watchdog_preset(struct i2c_client *client, struct fscher_data *data,
const char *buf, size_t count, int nr, int reg)
{
- data->watchdog[0] = simple_strtoul(buf, NULL, 10) & 0xff;
-
+ unsigned long v = simple_strtoul(buf, NULL, 10) & 0xff;
+
+ down(&data->update_lock);
+ data->watchdog[0] = v;
fscher_write_value(client, reg, data->watchdog[0]);
+ up(&data->update_lock);
return count;
}
diff --git a/drivers/i2c/chips/fscpos.c b/drivers/i2c/chips/fscpos.c
index 09216d3711d934..2cac79145c7596 100644
--- a/drivers/i2c/chips/fscpos.c
+++ b/drivers/i2c/chips/fscpos.c
@@ -206,11 +206,13 @@ static ssize_t set_fan_ripple(struct i2c_client *client, struct fscpos_data
return -EINVAL;
}
+ down(&data->update_lock);
/* bits 2..7 reserved => mask with 0x03 */
data->fan_ripple[nr - 1] &= ~0x03;
data->fan_ripple[nr - 1] |= v;
fscpos_write_value(client, reg, data->fan_ripple[nr - 1]);
+ up(&data->update_lock);
return count;
}
@@ -228,8 +230,10 @@ static ssize_t set_pwm(struct i2c_client *client, struct fscpos_data *data,
if (v < 0) v = 0;
if (v > 255) v = 255;
+ down(&data->update_lock);
data->pwm[nr - 1] = v;
fscpos_write_value(client, reg, data->pwm[nr - 1]);
+ up(&data->update_lock);
return count;
}
@@ -271,10 +275,12 @@ static ssize_t set_wdog_control(struct i2c_client *client, struct fscpos_data
{
/* bits 0..3 reserved => mask with 0xf0 */
unsigned long v = simple_strtoul(buf, NULL, 10) & 0xf0;
+
+ down(&data->update_lock);
data->wdog_control &= ~0xf0;
data->wdog_control |= v;
-
fscpos_write_value(client, reg, data->wdog_control);
+ up(&data->update_lock);
return count;
}
@@ -296,9 +302,10 @@ static ssize_t set_wdog_state(struct i2c_client *client, struct fscpos_data
return -EINVAL;
}
+ down(&data->update_lock);
data->wdog_state &= ~v;
-
fscpos_write_value(client, reg, v);
+ up(&data->update_lock);
return count;
}
@@ -310,9 +317,12 @@ static ssize_t show_wdog_preset(struct fscpos_data *data, char *buf)
static ssize_t set_wdog_preset(struct i2c_client *client, struct fscpos_data
*data, const char *buf, size_t count, int reg)
{
- data->wdog_preset = simple_strtoul(buf, NULL, 10) & 0xff;
-
+ unsigned long v = simple_strtoul(buf, NULL, 10) & 0xff;
+
+ down(&data->update_lock);
+ data->wdog_preset = v;
fscpos_write_value(client, reg, data->wdog_preset);
+ up(&data->update_lock);
return count;
}
diff --git a/drivers/i2c/chips/gl518sm.c b/drivers/i2c/chips/gl518sm.c
index a9c40b6f8342f0..c82d6ce2120552 100644
--- a/drivers/i2c/chips/gl518sm.c
+++ b/drivers/i2c/chips/gl518sm.c
@@ -211,8 +211,11 @@ static ssize_t set_##suffix(struct device *dev, const char *buf, \
struct i2c_client *client = to_i2c_client(dev); \
struct gl518_data *data = i2c_get_clientdata(client); \
long val = simple_strtol(buf, NULL, 10); \
+ \
+ down(&data->update_lock); \
data->value = type##_TO_REG(val); \
gl518_write_value(client, reg, data->value); \
+ up(&data->update_lock); \
return count; \
}
@@ -222,11 +225,15 @@ static ssize_t set_##suffix(struct device *dev, const char *buf, \
{ \
struct i2c_client *client = to_i2c_client(dev); \
struct gl518_data *data = i2c_get_clientdata(client); \
- int regvalue = gl518_read_value(client, reg); \
+ int regvalue; \
unsigned long val = simple_strtoul(buf, NULL, 10); \
+ \
+ down(&data->update_lock); \
+ regvalue = gl518_read_value(client, reg); \
data->value = type##_TO_REG(val); \
regvalue = (regvalue & ~mask) | (data->value << shift); \
gl518_write_value(client, reg, regvalue); \
+ up(&data->update_lock); \
return count; \
}
@@ -255,9 +262,12 @@ static ssize_t set_fan_min1(struct device *dev, const char *buf, size_t count)
{
struct i2c_client *client = to_i2c_client(dev);
struct gl518_data *data = i2c_get_clientdata(client);
- int regvalue = gl518_read_value(client, GL518_REG_FAN_LIMIT);
+ int regvalue;
+ unsigned long val = simple_strtoul(buf, NULL, 10);
- data->fan_min[0] = FAN_TO_REG(simple_strtoul(buf, NULL, 10),
+ down(&data->update_lock);
+ regvalue = gl518_read_value(client, GL518_REG_FAN_LIMIT);
+ data->fan_min[0] = FAN_TO_REG(val,
DIV_FROM_REG(data->fan_div[0]));
regvalue = (regvalue & 0x00ff) | (data->fan_min[0] << 8);
gl518_write_value(client, GL518_REG_FAN_LIMIT, regvalue);
@@ -270,6 +280,7 @@ static ssize_t set_fan_min1(struct device *dev, const char *buf, size_t count)
data->beep_mask &= data->alarm_mask;
gl518_write_value(client, GL518_REG_ALARM, data->beep_mask);
+ up(&data->update_lock);
return count;
}
@@ -277,9 +288,12 @@ static ssize_t set_fan_min2(struct device *dev, const char *buf, size_t count)
{
struct i2c_client *client = to_i2c_client(dev);
struct gl518_data *data = i2c_get_clientdata(client);
- int regvalue = gl518_read_value(client, GL518_REG_FAN_LIMIT);
+ int regvalue;
+ unsigned long val = simple_strtoul(buf, NULL, 10);
- data->fan_min[1] = FAN_TO_REG(simple_strtoul(buf, NULL, 10),
+ down(&data->update_lock);
+ regvalue = gl518_read_value(client, GL518_REG_FAN_LIMIT);
+ data->fan_min[1] = FAN_TO_REG(val,
DIV_FROM_REG(data->fan_div[1]));
regvalue = (regvalue & 0xff00) | data->fan_min[1];
gl518_write_value(client, GL518_REG_FAN_LIMIT, regvalue);
@@ -292,6 +306,7 @@ static ssize_t set_fan_min2(struct device *dev, const char *buf, size_t count)
data->beep_mask &= data->alarm_mask;
gl518_write_value(client, GL518_REG_ALARM, data->beep_mask);
+ up(&data->update_lock);
return count;
}
diff --git a/drivers/i2c/chips/gl520sm.c b/drivers/i2c/chips/gl520sm.c
index 652603775772fc..3fd17e46ffc6d4 100644
--- a/drivers/i2c/chips/gl520sm.c
+++ b/drivers/i2c/chips/gl520sm.c
@@ -301,6 +301,8 @@ static ssize_t set_in_min(struct i2c_client *client, struct gl520_data *data, co
long v = simple_strtol(buf, NULL, 10);
u8 r;
+ down(&data->update_lock);
+
if (n == 0)
r = VDD_TO_REG(v);
else
@@ -313,6 +315,7 @@ static ssize_t set_in_min(struct i2c_client *client, struct gl520_data *data, co
else
gl520_write_value(client, reg, r);
+ up(&data->update_lock);
return count;
}
@@ -326,6 +329,8 @@ static ssize_t set_in_max(struct i2c_client *client, struct gl520_data *data, co
else
r = IN_TO_REG(v);
+ down(&data->update_lock);
+
data->in_max[n] = r;
if (n < 4)
@@ -333,6 +338,7 @@ static ssize_t set_in_max(struct i2c_client *client, struct gl520_data *data, co
else
gl520_write_value(client, reg, r);
+ up(&data->update_lock);
return count;
}
@@ -363,8 +369,10 @@ static ssize_t get_fan_off(struct gl520_data *data, char *buf, int n)
static ssize_t set_fan_min(struct i2c_client *client, struct gl520_data *data, const char *buf, size_t count, int n, int reg)
{
unsigned long v = simple_strtoul(buf, NULL, 10);
- u8 r = FAN_TO_REG(v, data->fan_div[n - 1]);
+ u8 r;
+ down(&data->update_lock);
+ r = FAN_TO_REG(v, data->fan_div[n - 1]);
data->fan_min[n - 1] = r;
if (n == 1)
@@ -380,6 +388,7 @@ static ssize_t set_fan_min(struct i2c_client *client, struct gl520_data *data, c
data->beep_mask &= data->alarm_mask;
gl520_write_value(client, GL520_REG_BEEP_MASK, data->beep_mask);
+ up(&data->update_lock);
return count;
}
@@ -398,6 +407,7 @@ static ssize_t set_fan_div(struct i2c_client *client, struct gl520_data *data, c
return -EINVAL;
}
+ down(&data->update_lock);
data->fan_div[n - 1] = r;
if (n == 1)
@@ -405,6 +415,7 @@ static ssize_t set_fan_div(struct i2c_client *client, struct gl520_data *data, c
else
gl520_write_value(client, reg, (gl520_read_value(client, reg) & ~0x30) | (r << 4));
+ up(&data->update_lock);
return count;
}
@@ -412,9 +423,10 @@ static ssize_t set_fan_off(struct i2c_client *client, struct gl520_data *data, c
{
u8 r = simple_strtoul(buf, NULL, 10)?1:0;
+ down(&data->update_lock);
data->fan_off = r;
gl520_write_value(client, reg, (gl520_read_value(client, reg) & ~0x0c) | (r << 2));
-
+ up(&data->update_lock);
return count;
}
@@ -439,22 +451,22 @@ static ssize_t get_temp_max_hyst(struct gl520_data *data, char *buf, int n)
static ssize_t set_temp_max(struct i2c_client *client, struct gl520_data *data, const char *buf, size_t count, int n, int reg)
{
long v = simple_strtol(buf, NULL, 10);
- u8 r = TEMP_TO_REG(v);
-
- data->temp_max[n - 1] = r;
- gl520_write_value(client, reg, r);
+ down(&data->update_lock);
+ data->temp_max[n - 1] = TEMP_TO_REG(v);;
+ gl520_write_value(client, reg, data->temp_max[n - 1]);
+ up(&data->update_lock);
return count;
}
static ssize_t set_temp_max_hyst(struct i2c_client *client, struct gl520_data *data, const char *buf, size_t count, int n, int reg)
{
long v = simple_strtol(buf, NULL, 10);
- u8 r = TEMP_TO_REG(v);
-
- data->temp_max_hyst[n - 1] = r;
- gl520_write_value(client, reg, r);
+ down(&data->update_lock);
+ data->temp_max_hyst[n - 1] = TEMP_TO_REG(v);
+ gl520_write_value(client, reg, data->temp_max_hyst[n - 1]);
+ up(&data->update_lock);
return count;
}
@@ -477,19 +489,22 @@ static ssize_t set_beep_enable(struct i2c_client *client, struct gl520_data *dat
{
u8 r = simple_strtoul(buf, NULL, 10)?0:1;
+ down(&data->update_lock);
data->beep_enable = !r;
gl520_write_value(client, reg, (gl520_read_value(client, reg) & ~0x04) | (r << 2));
-
+ up(&data->update_lock);
return count;
}
static ssize_t set_beep_mask(struct i2c_client *client, struct gl520_data *data, const char *buf, size_t count, int n, int reg)
{
- u8 r = simple_strtoul(buf, NULL, 10) & data->alarm_mask;
-
+ u8 r = simple_strtoul(buf, NULL, 10);
+
+ down(&data->update_lock);
+ r &= data->alarm_mask;
data->beep_mask = r;
gl520_write_value(client, reg, r);
-
+ up(&data->update_lock);
return count;
}
diff --git a/drivers/i2c/chips/it87.c b/drivers/i2c/chips/it87.c
index bf02ba555a8518..3d484a7aff127b 100644
--- a/drivers/i2c/chips/it87.c
+++ b/drivers/i2c/chips/it87.c
@@ -265,9 +265,12 @@ static ssize_t set_in_min(struct device *dev, const char *buf,
struct i2c_client *client = to_i2c_client(dev);
struct it87_data *data = i2c_get_clientdata(client);
unsigned long val = simple_strtoul(buf, NULL, 10);
+
+ down(&data->update_lock);
data->in_min[nr] = IN_TO_REG(val);
it87_write_value(client, IT87_REG_VIN_MIN(nr),
data->in_min[nr]);
+ up(&data->update_lock);
return count;
}
static ssize_t set_in_max(struct device *dev, const char *buf,
@@ -276,9 +279,12 @@ static ssize_t set_in_max(struct device *dev, const char *buf,
struct i2c_client *client = to_i2c_client(dev);
struct it87_data *data = i2c_get_clientdata(client);
unsigned long val = simple_strtoul(buf, NULL, 10);
+
+ down(&data->update_lock);
data->in_max[nr] = IN_TO_REG(val);
it87_write_value(client, IT87_REG_VIN_MAX(nr),
data->in_max[nr]);
+ up(&data->update_lock);
return count;
}
@@ -356,8 +362,11 @@ static ssize_t set_temp_max(struct device *dev, const char *buf,
struct i2c_client *client = to_i2c_client(dev);
struct it87_data *data = i2c_get_clientdata(client);
int val = simple_strtol(buf, NULL, 10);
+
+ down(&data->update_lock);
data->temp_high[nr] = TEMP_TO_REG(val);
it87_write_value(client, IT87_REG_TEMP_HIGH(nr), data->temp_high[nr]);
+ up(&data->update_lock);
return count;
}
static ssize_t set_temp_min(struct device *dev, const char *buf,
@@ -366,8 +375,11 @@ static ssize_t set_temp_min(struct device *dev, const char *buf,
struct i2c_client *client = to_i2c_client(dev);
struct it87_data *data = i2c_get_clientdata(client);
int val = simple_strtol(buf, NULL, 10);
+
+ down(&data->update_lock);
data->temp_low[nr] = TEMP_TO_REG(val);
it87_write_value(client, IT87_REG_TEMP_LOW(nr), data->temp_low[nr]);
+ up(&data->update_lock);
return count;
}
#define show_temp_offset(offset) \
@@ -408,9 +420,11 @@ show_temp_offset(3);
static ssize_t show_sensor(struct device *dev, char *buf, int nr)
{
struct it87_data *data = it87_update_device(dev);
- if (data->sensor & (1 << nr))
+ u8 reg = data->sensor; /* In case the value is updated while we use it */
+
+ if (reg & (1 << nr))
return sprintf(buf, "3\n"); /* thermal diode */
- if (data->sensor & (8 << nr))
+ if (reg & (8 << nr))
return sprintf(buf, "2\n"); /* thermistor */
return sprintf(buf, "0\n"); /* disabled */
}
@@ -421,6 +435,8 @@ static ssize_t set_sensor(struct device *dev, const char *buf,
struct it87_data *data = i2c_get_clientdata(client);
int val = simple_strtol(buf, NULL, 10);
+ down(&data->update_lock);
+
data->sensor &= ~(1 << nr);
data->sensor &= ~(8 << nr);
/* 3 = thermal diode; 2 = thermistor; 0 = disabled */
@@ -428,9 +444,12 @@ static ssize_t set_sensor(struct device *dev, const char *buf,
data->sensor |= 1 << nr;
else if (val == 2)
data->sensor |= 8 << nr;
- else if (val != 0)
+ else if (val != 0) {
+ up(&data->update_lock);
return -EINVAL;
+ }
it87_write_value(client, IT87_REG_TEMP_ENABLE, data->sensor);
+ up(&data->update_lock);
return count;
}
#define show_sensor_offset(offset) \
@@ -484,8 +503,11 @@ static ssize_t set_fan_min(struct device *dev, const char *buf,
struct i2c_client *client = to_i2c_client(dev);
struct it87_data *data = i2c_get_clientdata(client);
int val = simple_strtol(buf, NULL, 10);
+
+ down(&data->update_lock);
data->fan_min[nr] = FAN_TO_REG(val, DIV_FROM_REG(data->fan_div[nr]));
it87_write_value(client, IT87_REG_FAN_MIN(nr), data->fan_min[nr]);
+ up(&data->update_lock);
return count;
}
static ssize_t set_fan_div(struct device *dev, const char *buf,
@@ -495,7 +517,10 @@ static ssize_t set_fan_div(struct device *dev, const char *buf,
struct it87_data *data = i2c_get_clientdata(client);
int val = simple_strtol(buf, NULL, 10);
int i, min[3];
- u8 old = it87_read_value(client, IT87_REG_FAN_DIV);
+ u8 old;
+
+ down(&data->update_lock);
+ old = it87_read_value(client, IT87_REG_FAN_DIV);
for (i = 0; i < 3; i++)
min[i] = FAN_FROM_REG(data->fan_min[i], DIV_FROM_REG(data->fan_div[i]));
@@ -522,6 +547,7 @@ static ssize_t set_fan_div(struct device *dev, const char *buf,
data->fan_min[i]=FAN_TO_REG(min[i], DIV_FROM_REG(data->fan_div[i]));
it87_write_value(client, IT87_REG_FAN_MIN(i), data->fan_min[i]);
}
+ up(&data->update_lock);
return count;
}
static ssize_t set_pwm_enable(struct device *dev, const char *buf,
@@ -531,6 +557,8 @@ static ssize_t set_pwm_enable(struct device *dev, const char *buf,
struct it87_data *data = i2c_get_clientdata(client);
int val = simple_strtol(buf, NULL, 10);
+ down(&data->update_lock);
+
if (val == 0) {
int tmp;
/* make sure the fan is on when in on/off mode */
@@ -545,9 +573,12 @@ static ssize_t set_pwm_enable(struct device *dev, const char *buf,
it87_write_value(client, IT87_REG_FAN_MAIN_CTRL, data->fan_main_ctrl);
/* set saved pwm value, clear FAN_CTLX PWM mode bit */
it87_write_value(client, IT87_REG_PWM(nr), PWM_TO_REG(data->manual_pwm_ctl[nr]));
- } else
+ } else {
+ up(&data->update_lock);
return -EINVAL;
+ }
+ up(&data->update_lock);
return count;
}
static ssize_t set_pwm(struct device *dev, const char *buf,
@@ -560,10 +591,11 @@ static ssize_t set_pwm(struct device *dev, const char *buf,
if (val < 0 || val > 255)
return -EINVAL;
+ down(&data->update_lock);
data->manual_pwm_ctl[nr] = val;
if (data->fan_main_ctrl & (1 << nr))
it87_write_value(client, IT87_REG_PWM(nr), PWM_TO_REG(data->manual_pwm_ctl[nr]));
-
+ up(&data->update_lock);
return count;
}
diff --git a/drivers/i2c/chips/lm63.c b/drivers/i2c/chips/lm63.c
index a8cf806ee5c055..14cc5af0373936 100644
--- a/drivers/i2c/chips/lm63.c
+++ b/drivers/i2c/chips/lm63.c
@@ -191,11 +191,14 @@ static ssize_t set_fan1_low(struct device *dev, const char *buf,
struct i2c_client *client = to_i2c_client(dev);
struct lm63_data *data = i2c_get_clientdata(client);
unsigned long val = simple_strtoul(buf, NULL, 10);
+
+ down(&data->update_lock);
data->fan1_low = FAN_TO_REG(val);
i2c_smbus_write_byte_data(client, LM63_REG_TACH_LIMIT_LSB,
data->fan1_low & 0xFF);
i2c_smbus_write_byte_data(client, LM63_REG_TACH_LIMIT_MSB,
data->fan1_low >> 8);
+ up(&data->update_lock);
return count;
}
@@ -217,10 +220,12 @@ static ssize_t set_pwm1(struct device *dev, const char *buf, size_t count)
return -EPERM;
val = simple_strtoul(buf, NULL, 10);
+ down(&data->update_lock);
data->pwm1_value = val <= 0 ? 0 :
val >= 255 ? 2 * data->pwm1_freq :
(val * data->pwm1_freq * 2 + 127) / 255;
i2c_smbus_write_byte_data(client, LM63_REG_PWM_VALUE, data->pwm1_value);
+ up(&data->update_lock);
return count;
}
@@ -256,8 +261,11 @@ static ssize_t set_##value(struct device *dev, const char *buf, \
struct i2c_client *client = to_i2c_client(dev); \
struct lm63_data *data = i2c_get_clientdata(client); \
long val = simple_strtol(buf, NULL, 10); \
+ \
+ down(&data->update_lock); \
data->value = TEMP8_TO_REG(val); \
i2c_smbus_write_byte_data(client, reg, data->value); \
+ up(&data->update_lock); \
return count; \
}
#define set_temp11(value, reg_msb, reg_lsb) \
@@ -267,9 +275,12 @@ static ssize_t set_##value(struct device *dev, const char *buf, \
struct i2c_client *client = to_i2c_client(dev); \
struct lm63_data *data = i2c_get_clientdata(client); \
long val = simple_strtol(buf, NULL, 10); \
+ \
+ down(&data->update_lock); \
data->value = TEMP11_TO_REG(val); \
i2c_smbus_write_byte_data(client, reg_msb, data->value >> 8); \
i2c_smbus_write_byte_data(client, reg_lsb, data->value & 0xff); \
+ up(&data->update_lock); \
return count; \
}
set_temp8(temp1_high, LM63_REG_LOCAL_HIGH);
@@ -292,10 +303,14 @@ static ssize_t set_temp2_crit_hyst(struct device *dev, const char *buf,
{
struct i2c_client *client = to_i2c_client(dev);
struct lm63_data *data = i2c_get_clientdata(client);
- int hyst = TEMP8_FROM_REG(data->temp2_crit) -
- simple_strtol(buf, NULL, 10);
+ long val = simple_strtol(buf, NULL, 10);
+ long hyst;
+
+ down(&data->update_lock);
+ hyst = TEMP8_FROM_REG(data->temp2_crit) - val;
i2c_smbus_write_byte_data(client, LM63_REG_REMOTE_TCRIT_HYST,
HYST_TO_REG(hyst));
+ up(&data->update_lock);
return count;
}
diff --git a/drivers/i2c/chips/lm75.c b/drivers/i2c/chips/lm75.c
index 6605397e5425b4..0e86cc89398171 100644
--- a/drivers/i2c/chips/lm75.c
+++ b/drivers/i2c/chips/lm75.c
@@ -90,8 +90,11 @@ static ssize_t set_##value(struct device *dev, const char *buf, size_t count) \
struct i2c_client *client = to_i2c_client(dev); \
struct lm75_data *data = i2c_get_clientdata(client); \
int temp = simple_strtoul(buf, NULL, 10); \
+ \
+ down(&data->update_lock); \
data->value = LM75_TEMP_TO_REG(temp); \
lm75_write_value(client, reg, data->value); \
+ up(&data->update_lock); \
return count; \
}
set(temp_max, LM75_REG_TEMP_OS);
diff --git a/drivers/i2c/chips/lm77.c b/drivers/i2c/chips/lm77.c
index 26a0c4a11e621a..f56b7a37de759b 100644
--- a/drivers/i2c/chips/lm77.c
+++ b/drivers/i2c/chips/lm77.c
@@ -138,8 +138,12 @@ static ssize_t set_##value(struct device *dev, const char *buf, size_t count) \
{ \
struct i2c_client *client = to_i2c_client(dev); \
struct lm77_data *data = i2c_get_clientdata(client); \
- data->value = simple_strtoul(buf, NULL, 10); \
+ long val = simple_strtoul(buf, NULL, 10); \
+ \
+ down(&data->update_lock); \
+ data->value = val; \
lm77_write_value(client, reg, LM77_TEMP_TO_REG(data->value)); \
+ up(&data->update_lock); \
return count; \
}
@@ -152,9 +156,13 @@ static ssize_t set_temp_crit_hyst(struct device *dev, const char *buf, size_t co
{
struct i2c_client *client = to_i2c_client(dev);
struct lm77_data *data = i2c_get_clientdata(client);
- data->temp_hyst = data->temp_crit - simple_strtoul(buf, NULL, 10);
+ unsigned long val = simple_strtoul(buf, NULL, 10);
+
+ down(&data->update_lock);
+ data->temp_hyst = data->temp_crit - val;
lm77_write_value(client, LM77_REG_TEMP_HYST,
LM77_TEMP_TO_REG(data->temp_hyst));
+ up(&data->update_lock);
return count;
}
@@ -163,13 +171,18 @@ static ssize_t set_temp_crit(struct device *dev, const char *buf, size_t count)
{
struct i2c_client *client = to_i2c_client(dev);
struct lm77_data *data = i2c_get_clientdata(client);
- int oldcrithyst = data->temp_crit - data->temp_hyst;
- data->temp_crit = simple_strtoul(buf, NULL, 10);
+ long val = simple_strtoul(buf, NULL, 10);
+ int oldcrithyst;
+
+ down(&data->update_lock);
+ oldcrithyst = data->temp_crit - data->temp_hyst;
+ data->temp_crit = val;
data->temp_hyst = data->temp_crit - oldcrithyst;
lm77_write_value(client, LM77_REG_TEMP_CRIT,
LM77_TEMP_TO_REG(data->temp_crit));
lm77_write_value(client, LM77_REG_TEMP_HYST,
LM77_TEMP_TO_REG(data->temp_hyst));
+ up(&data->update_lock);
return count;
}
diff --git a/drivers/i2c/chips/lm78.c b/drivers/i2c/chips/lm78.c
index 1e0950d8d2c6c6..6d52d14eb31c92 100644
--- a/drivers/i2c/chips/lm78.c
+++ b/drivers/i2c/chips/lm78.c
@@ -200,8 +200,11 @@ static ssize_t set_in_min(struct device *dev, const char *buf,
struct i2c_client *client = to_i2c_client(dev);
struct lm78_data *data = i2c_get_clientdata(client);
unsigned long val = simple_strtoul(buf, NULL, 10);
+
+ down(&data->update_lock);
data->in_min[nr] = IN_TO_REG(val);
lm78_write_value(client, LM78_REG_IN_MIN(nr), data->in_min[nr]);
+ up(&data->update_lock);
return count;
}
@@ -211,8 +214,11 @@ static ssize_t set_in_max(struct device *dev, const char *buf,
struct i2c_client *client = to_i2c_client(dev);
struct lm78_data *data = i2c_get_clientdata(client);
unsigned long val = simple_strtoul(buf, NULL, 10);
+
+ down(&data->update_lock);
data->in_max[nr] = IN_TO_REG(val);
lm78_write_value(client, LM78_REG_IN_MAX(nr), data->in_max[nr]);
+ up(&data->update_lock);
return count;
}
@@ -275,8 +281,11 @@ static ssize_t set_temp_over(struct device *dev, const char *buf, size_t count)
struct i2c_client *client = to_i2c_client(dev);
struct lm78_data *data = i2c_get_clientdata(client);
long val = simple_strtol(buf, NULL, 10);
+
+ down(&data->update_lock);
data->temp_over = TEMP_TO_REG(val);
lm78_write_value(client, LM78_REG_TEMP_OVER, data->temp_over);
+ up(&data->update_lock);
return count;
}
@@ -291,8 +300,11 @@ static ssize_t set_temp_hyst(struct device *dev, const char *buf, size_t count)
struct i2c_client *client = to_i2c_client(dev);
struct lm78_data *data = i2c_get_clientdata(client);
long val = simple_strtol(buf, NULL, 10);
+
+ down(&data->update_lock);
data->temp_hyst = TEMP_TO_REG(val);
lm78_write_value(client, LM78_REG_TEMP_HYST, data->temp_hyst);
+ up(&data->update_lock);
return count;
}
@@ -323,8 +335,11 @@ static ssize_t set_fan_min(struct device *dev, const char *buf,
struct i2c_client *client = to_i2c_client(dev);
struct lm78_data *data = i2c_get_clientdata(client);
unsigned long val = simple_strtoul(buf, NULL, 10);
+
+ down(&data->update_lock);
data->fan_min[nr] = FAN_TO_REG(val, DIV_FROM_REG(data->fan_div[nr]));
lm78_write_value(client, LM78_REG_FAN_MIN(nr), data->fan_min[nr]);
+ up(&data->update_lock);
return count;
}
@@ -343,10 +358,14 @@ static ssize_t set_fan_div(struct device *dev, const char *buf,
{
struct i2c_client *client = to_i2c_client(dev);
struct lm78_data *data = i2c_get_clientdata(client);
- unsigned long min = FAN_FROM_REG(data->fan_min[nr],
- DIV_FROM_REG(data->fan_div[nr]));
unsigned long val = simple_strtoul(buf, NULL, 10);
- int reg = lm78_read_value(client, LM78_REG_VID_FANDIV);
+ unsigned long min;
+ u8 reg;
+
+ down(&data->update_lock);
+ min = FAN_FROM_REG(data->fan_min[nr],
+ DIV_FROM_REG(data->fan_div[nr]));
+
switch (val) {
case 1: data->fan_div[nr] = 0; break;
case 2: data->fan_div[nr] = 1; break;
@@ -355,9 +374,11 @@ static ssize_t set_fan_div(struct device *dev, const char *buf,
default:
dev_err(&client->dev, "fan_div value %ld not "
"supported. Choose one of 1, 2, 4 or 8!\n", val);
+ up(&data->update_lock);
return -EINVAL;
}
+ reg = lm78_read_value(client, LM78_REG_VID_FANDIV);
switch (nr) {
case 0:
reg = (reg & 0xcf) | (data->fan_div[nr] << 4);
@@ -367,9 +388,12 @@ static ssize_t set_fan_div(struct device *dev, const char *buf,
break;
}
lm78_write_value(client, LM78_REG_VID_FANDIV, reg);
+
data->fan_min[nr] =
FAN_TO_REG(min, DIV_FROM_REG(data->fan_div[nr]));
lm78_write_value(client, LM78_REG_FAN_MIN(nr), data->fan_min[nr]);
+ up(&data->update_lock);
+
return count;
}
diff --git a/drivers/i2c/chips/lm80.c b/drivers/i2c/chips/lm80.c
index 0df1fffddd1943..a72f431971bb63 100644
--- a/drivers/i2c/chips/lm80.c
+++ b/drivers/i2c/chips/lm80.c
@@ -190,8 +190,11 @@ static ssize_t set_in_##suffix(struct device *dev, const char *buf, \
struct i2c_client *client = to_i2c_client(dev); \
struct lm80_data *data = i2c_get_clientdata(client); \
long val = simple_strtol(buf, NULL, 10); \
+ \
+ down(&data->update_lock);\
data->value = IN_TO_REG(val); \
lm80_write_value(client, reg, data->value); \
+ up(&data->update_lock);\
return count; \
}
set_in(min0, in_min[0], LM80_REG_IN_MIN(0));
@@ -237,8 +240,11 @@ static ssize_t set_fan_##suffix(struct device *dev, const char *buf, \
struct i2c_client *client = to_i2c_client(dev); \
struct lm80_data *data = i2c_get_clientdata(client); \
long val = simple_strtoul(buf, NULL, 10); \
+ \
+ down(&data->update_lock);\
data->value = FAN_TO_REG(val, DIV_FROM_REG(data->div)); \
lm80_write_value(client, reg, data->value); \
+ up(&data->update_lock);\
return count; \
}
set_fan(min1, fan_min[0], LM80_REG_FAN_MIN(1), fan_div[0]);
@@ -253,15 +259,14 @@ static ssize_t set_fan_div(struct device *dev, const char *buf,
{
struct i2c_client *client = to_i2c_client(dev);
struct lm80_data *data = i2c_get_clientdata(client);
- unsigned long min, val;
+ unsigned long min, val = simple_strtoul(buf, NULL, 10);
u8 reg;
/* Save fan_min */
+ down(&data->update_lock);
min = FAN_FROM_REG(data->fan_min[nr],
DIV_FROM_REG(data->fan_div[nr]));
- val = simple_strtoul(buf, NULL, 10);
-
switch (val) {
case 1: data->fan_div[nr] = 0; break;
case 2: data->fan_div[nr] = 1; break;
@@ -270,6 +275,7 @@ static ssize_t set_fan_div(struct device *dev, const char *buf,
default:
dev_err(&client->dev, "fan_div value %ld not "
"supported. Choose one of 1, 2, 4 or 8!\n", val);
+ up(&data->update_lock);
return -EINVAL;
}
@@ -280,6 +286,7 @@ static ssize_t set_fan_div(struct device *dev, const char *buf,
/* Restore fan_min */
data->fan_min[nr] = FAN_TO_REG(min, DIV_FROM_REG(data->fan_div[nr]));
lm80_write_value(client, LM80_REG_FAN_MIN(nr + 1), data->fan_min[nr]);
+ up(&data->update_lock);
return count;
}
@@ -317,8 +324,11 @@ static ssize_t set_temp_##suffix(struct device *dev, const char *buf, \
struct i2c_client *client = to_i2c_client(dev); \
struct lm80_data *data = i2c_get_clientdata(client); \
long val = simple_strtoul(buf, NULL, 10); \
+ \
+ down(&data->update_lock); \
data->value = TEMP_LIMIT_TO_REG(val); \
lm80_write_value(client, reg, data->value); \
+ up(&data->update_lock); \
return count; \
}
set_temp(hot_max, temp_hot_max, LM80_REG_TEMP_HOT_MAX);
diff --git a/drivers/i2c/chips/lm83.c b/drivers/i2c/chips/lm83.c
index 6a4c345325a0f3..3dafe60766ad9d 100644
--- a/drivers/i2c/chips/lm83.c
+++ b/drivers/i2c/chips/lm83.c
@@ -177,8 +177,11 @@ static ssize_t set_temp_##suffix(struct device *dev, const char *buf, \
struct i2c_client *client = to_i2c_client(dev); \
struct lm83_data *data = i2c_get_clientdata(client); \
long val = simple_strtol(buf, NULL, 10); \
+ \
+ down(&data->update_lock); \
data->value = TEMP_TO_REG(val); \
i2c_smbus_write_byte_data(client, reg, data->value); \
+ up(&data->update_lock); \
return count; \
}
set_temp(high1, temp_high[0], LM83_REG_W_LOCAL_HIGH);
diff --git a/drivers/i2c/chips/lm85.c b/drivers/i2c/chips/lm85.c
index e08000b948b2f6..b1a0dc5f6b34fc 100644
--- a/drivers/i2c/chips/lm85.c
+++ b/drivers/i2c/chips/lm85.c
@@ -416,10 +416,9 @@ static ssize_t set_fan_min(struct device *dev, const char *buf,
{
struct i2c_client *client = to_i2c_client(dev);
struct lm85_data *data = i2c_get_clientdata(client);
- int val;
+ long val = simple_strtol(buf, NULL, 10);
down(&data->update_lock);
- val = simple_strtol(buf, NULL, 10);
data->fan_min[nr] = FAN_TO_REG(val);
lm85_write_value(client, LM85_REG_FAN_MIN(nr), data->fan_min[nr]);
up(&data->update_lock);
@@ -499,10 +498,9 @@ static ssize_t set_pwm(struct device *dev, const char *buf,
{
struct i2c_client *client = to_i2c_client(dev);
struct lm85_data *data = i2c_get_clientdata(client);
- int val;
+ long val = simple_strtol(buf, NULL, 10);
down(&data->update_lock);
- val = simple_strtol(buf, NULL, 10);
data->pwm[nr] = PWM_TO_REG(val);
lm85_write_value(client, LM85_REG_PWM(nr), data->pwm[nr]);
up(&data->update_lock);
@@ -560,10 +558,9 @@ static ssize_t set_in_min(struct device *dev, const char *buf,
{
struct i2c_client *client = to_i2c_client(dev);
struct lm85_data *data = i2c_get_clientdata(client);
- int val;
+ long val = simple_strtol(buf, NULL, 10);
down(&data->update_lock);
- val = simple_strtol(buf, NULL, 10);
data->in_min[nr] = INS_TO_REG(nr, val);
lm85_write_value(client, LM85_REG_IN_MIN(nr), data->in_min[nr]);
up(&data->update_lock);
@@ -579,10 +576,9 @@ static ssize_t set_in_max(struct device *dev, const char *buf,
{
struct i2c_client *client = to_i2c_client(dev);
struct lm85_data *data = i2c_get_clientdata(client);
- int val;
+ long val = simple_strtol(buf, NULL, 10);
down(&data->update_lock);
- val = simple_strtol(buf, NULL, 10);
data->in_max[nr] = INS_TO_REG(nr, val);
lm85_write_value(client, LM85_REG_IN_MAX(nr), data->in_max[nr]);
up(&data->update_lock);
@@ -643,10 +639,9 @@ static ssize_t set_temp_min(struct device *dev, const char *buf,
{
struct i2c_client *client = to_i2c_client(dev);
struct lm85_data *data = i2c_get_clientdata(client);
- int val;
+ long val = simple_strtol(buf, NULL, 10);
down(&data->update_lock);
- val = simple_strtol(buf, NULL, 10);
data->temp_min[nr] = TEMP_TO_REG(val);
lm85_write_value(client, LM85_REG_TEMP_MIN(nr), data->temp_min[nr]);
up(&data->update_lock);
@@ -662,10 +657,9 @@ static ssize_t set_temp_max(struct device *dev, const char *buf,
{
struct i2c_client *client = to_i2c_client(dev);
struct lm85_data *data = i2c_get_clientdata(client);
- int val;
+ long val = simple_strtol(buf, NULL, 10);
down(&data->update_lock);
- val = simple_strtol(buf, NULL, 10);
data->temp_max[nr] = TEMP_TO_REG(val);
lm85_write_value(client, LM85_REG_TEMP_MAX(nr), data->temp_max[nr]);
up(&data->update_lock);
@@ -718,10 +712,9 @@ static ssize_t set_pwm_auto_channels(struct device *dev, const char *buf,
{
struct i2c_client *client = to_i2c_client(dev);
struct lm85_data *data = i2c_get_clientdata(client);
- int val;
+ long val = simple_strtol(buf, NULL, 10);
down(&data->update_lock);
- val = simple_strtol(buf, NULL, 10);
data->autofan[nr].config = (data->autofan[nr].config & (~0xe0))
| ZONE_TO_REG(val) ;
lm85_write_value(client, LM85_REG_AFAN_CONFIG(nr),
@@ -739,10 +732,9 @@ static ssize_t set_pwm_auto_pwm_min(struct device *dev, const char *buf,
{
struct i2c_client *client = to_i2c_client(dev);
struct lm85_data *data = i2c_get_clientdata(client);
- int val;
+ long val = simple_strtol(buf, NULL, 10);
down(&data->update_lock);
- val = simple_strtol(buf, NULL, 10);
data->autofan[nr].min_pwm = PWM_TO_REG(val);
lm85_write_value(client, LM85_REG_AFAN_MINPWM(nr),
data->autofan[nr].min_pwm);
@@ -759,10 +751,9 @@ static ssize_t set_pwm_auto_pwm_minctl(struct device *dev, const char *buf,
{
struct i2c_client *client = to_i2c_client(dev);
struct lm85_data *data = i2c_get_clientdata(client);
- int val;
+ long val = simple_strtol(buf, NULL, 10);
down(&data->update_lock);
- val = simple_strtol(buf, NULL, 10);
data->autofan[nr].min_off = val;
lm85_write_value(client, LM85_REG_AFAN_SPIKE1, data->smooth[0]
| data->syncpwm3
@@ -783,10 +774,9 @@ static ssize_t set_pwm_auto_pwm_freq(struct device *dev, const char *buf,
{
struct i2c_client *client = to_i2c_client(dev);
struct lm85_data *data = i2c_get_clientdata(client);
- int val;
+ long val = simple_strtol(buf, NULL, 10);
down(&data->update_lock);
- val = simple_strtol(buf, NULL, 10);
data->autofan[nr].freq = FREQ_TO_REG(val);
lm85_write_value(client, LM85_REG_AFAN_RANGE(nr),
(data->zone[nr].range << 4)
@@ -865,10 +855,10 @@ static ssize_t set_temp_auto_temp_off(struct device *dev, const char *buf,
{
struct i2c_client *client = to_i2c_client(dev);
struct lm85_data *data = i2c_get_clientdata(client);
- int min, val;
+ int min;
+ long val = simple_strtol(buf, NULL, 10);
down(&data->update_lock);
- val = simple_strtol(buf, NULL, 10);
min = TEMP_FROM_REG(data->zone[nr].limit);
data->zone[nr].off_desired = TEMP_TO_REG(val);
data->zone[nr].hyst = HYST_TO_REG(min - val);
@@ -895,10 +885,9 @@ static ssize_t set_temp_auto_temp_min(struct device *dev, const char *buf,
{
struct i2c_client *client = to_i2c_client(dev);
struct lm85_data *data = i2c_get_clientdata(client);
- int val;
+ long val = simple_strtol(buf, NULL, 10);
down(&data->update_lock);
- val = simple_strtol(buf, NULL, 10);
data->zone[nr].limit = TEMP_TO_REG(val);
lm85_write_value(client, LM85_REG_AFAN_LIMIT(nr),
data->zone[nr].limit);
@@ -939,11 +928,11 @@ static ssize_t set_temp_auto_temp_max(struct device *dev, const char *buf,
{
struct i2c_client *client = to_i2c_client(dev);
struct lm85_data *data = i2c_get_clientdata(client);
- int min, val;
+ int min;
+ long val = simple_strtol(buf, NULL, 10);
down(&data->update_lock);
min = TEMP_FROM_REG(data->zone[nr].limit);
- val = simple_strtol(buf, NULL, 10);
data->zone[nr].max_desired = TEMP_TO_REG(val);
data->zone[nr].range = RANGE_TO_REG(
val - min);
@@ -963,10 +952,9 @@ static ssize_t set_temp_auto_temp_crit(struct device *dev, const char *buf,
{
struct i2c_client *client = to_i2c_client(dev);
struct lm85_data *data = i2c_get_clientdata(client);
- int val;
+ long val = simple_strtol(buf, NULL, 10);
down(&data->update_lock);
- val = simple_strtol(buf, NULL, 10);
data->zone[nr].critical = TEMP_TO_REG(val);
lm85_write_value(client, LM85_REG_AFAN_CRITICAL(nr),
data->zone[nr].critical);
diff --git a/drivers/i2c/chips/lm87.c b/drivers/i2c/chips/lm87.c
index 49d92326faab5f..98cabd66506376 100644
--- a/drivers/i2c/chips/lm87.c
+++ b/drivers/i2c/chips/lm87.c
@@ -252,9 +252,12 @@ static void set_in_min(struct device *dev, const char *buf, int nr)
struct i2c_client *client = to_i2c_client(dev);
struct lm87_data *data = i2c_get_clientdata(client);
long val = simple_strtol(buf, NULL, 10);
+
+ down(&data->update_lock);
data->in_min[nr] = IN_TO_REG(val, data->in_scale[nr]);
lm87_write_value(client, nr<6 ? LM87_REG_IN_MIN(nr) :
LM87_REG_AIN_MIN(nr-6), data->in_min[nr]);
+ up(&data->update_lock);
}
static void set_in_max(struct device *dev, const char *buf, int nr)
@@ -262,9 +265,12 @@ static void set_in_max(struct device *dev, const char *buf, int nr)
struct i2c_client *client = to_i2c_client(dev);
struct lm87_data *data = i2c_get_clientdata(client);
long val = simple_strtol(buf, NULL, 10);
+
+ down(&data->update_lock);
data->in_max[nr] = IN_TO_REG(val, data->in_scale[nr]);
lm87_write_value(client, nr<6 ? LM87_REG_IN_MAX(nr) :
LM87_REG_AIN_MAX(nr-6), data->in_max[nr]);
+ up(&data->update_lock);
}
#define set_in(offset) \
@@ -320,8 +326,11 @@ static void set_temp_low(struct device *dev, const char *buf, int nr)
struct i2c_client *client = to_i2c_client(dev);
struct lm87_data *data = i2c_get_clientdata(client);
long val = simple_strtol(buf, NULL, 10);
+
+ down(&data->update_lock);
data->temp_low[nr] = TEMP_TO_REG(val);
lm87_write_value(client, LM87_REG_TEMP_LOW[nr], data->temp_low[nr]);
+ up(&data->update_lock);
}
static void set_temp_high(struct device *dev, const char *buf, int nr)
@@ -329,8 +338,11 @@ static void set_temp_high(struct device *dev, const char *buf, int nr)
struct i2c_client *client = to_i2c_client(dev);
struct lm87_data *data = i2c_get_clientdata(client);
long val = simple_strtol(buf, NULL, 10);
+
+ down(&data->update_lock);
data->temp_high[nr] = TEMP_TO_REG(val);
lm87_write_value(client, LM87_REG_TEMP_HIGH[nr], data->temp_high[nr]);
+ up(&data->update_lock);
}
#define set_temp(offset) \
@@ -398,9 +410,12 @@ static void set_fan_min(struct device *dev, const char *buf, int nr)
struct i2c_client *client = to_i2c_client(dev);
struct lm87_data *data = i2c_get_clientdata(client);
long val = simple_strtol(buf, NULL, 10);
+
+ down(&data->update_lock);
data->fan_min[nr] = FAN_TO_REG(val,
FAN_DIV_FROM_REG(data->fan_div[nr]));
lm87_write_value(client, LM87_REG_FAN_MIN(nr), data->fan_min[nr]);
+ up(&data->update_lock);
}
/* Note: we save and restore the fan minimum here, because its value is
@@ -413,16 +428,21 @@ static ssize_t set_fan_div(struct device *dev, const char *buf,
struct i2c_client *client = to_i2c_client(dev);
struct lm87_data *data = i2c_get_clientdata(client);
long val = simple_strtol(buf, NULL, 10);
- unsigned long min = FAN_FROM_REG(data->fan_min[nr],
- FAN_DIV_FROM_REG(data->fan_div[nr]));
+ unsigned long min;
u8 reg;
+ down(&data->update_lock);
+ min = FAN_FROM_REG(data->fan_min[nr],
+ FAN_DIV_FROM_REG(data->fan_div[nr]));
+
switch (val) {
case 1: data->fan_div[nr] = 0; break;
case 2: data->fan_div[nr] = 1; break;
case 4: data->fan_div[nr] = 2; break;
case 8: data->fan_div[nr] = 3; break;
- default: return -EINVAL;
+ default:
+ up(&data->update_lock);
+ return -EINVAL;
}
reg = lm87_read_value(client, LM87_REG_VID_FAN_DIV);
@@ -439,6 +459,8 @@ static ssize_t set_fan_div(struct device *dev, const char *buf,
data->fan_min[nr] = FAN_TO_REG(min, val);
lm87_write_value(client, LM87_REG_FAN_MIN(nr),
data->fan_min[nr]);
+ up(&data->update_lock);
+
return count;
}
@@ -499,8 +521,11 @@ static ssize_t set_aout(struct device *dev, const char *buf, size_t count)
struct i2c_client *client = to_i2c_client(dev);
struct lm87_data *data = i2c_get_clientdata(client);
long val = simple_strtol(buf, NULL, 10);
+
+ down(&data->update_lock);
data->aout = AOUT_TO_REG(val);
lm87_write_value(client, LM87_REG_AOUT, data->aout);
+ up(&data->update_lock);
return count;
}
static DEVICE_ATTR(aout_output, S_IRUGO | S_IWUSR, show_aout, set_aout);
diff --git a/drivers/i2c/chips/lm90.c b/drivers/i2c/chips/lm90.c
index 02e22b128b0453..2c00ff83babcee 100644
--- a/drivers/i2c/chips/lm90.c
+++ b/drivers/i2c/chips/lm90.c
@@ -239,11 +239,14 @@ static ssize_t set_##value(struct device *dev, const char *buf, \
struct i2c_client *client = to_i2c_client(dev); \
struct lm90_data *data = i2c_get_clientdata(client); \
long val = simple_strtol(buf, NULL, 10); \
+ \
+ down(&data->update_lock); \
if (data->kind == adt7461) \
data->value = TEMP1_TO_REG_ADT7461(val); \
else \
data->value = TEMP1_TO_REG(val); \
i2c_smbus_write_byte_data(client, reg, data->value); \
+ up(&data->update_lock); \
return count; \
}
#define set_temp2(value, regh, regl) \
@@ -253,12 +256,15 @@ static ssize_t set_##value(struct device *dev, const char *buf, \
struct i2c_client *client = to_i2c_client(dev); \
struct lm90_data *data = i2c_get_clientdata(client); \
long val = simple_strtol(buf, NULL, 10); \
+ \
+ down(&data->update_lock); \
if (data->kind == adt7461) \
data->value = TEMP2_TO_REG_ADT7461(val); \
else \
data->value = TEMP2_TO_REG(val); \
i2c_smbus_write_byte_data(client, regh, data->value >> 8); \
i2c_smbus_write_byte_data(client, regl, data->value & 0xff); \
+ up(&data->update_lock); \
return count; \
}
set_temp1(temp_low1, LM90_REG_W_LOCAL_LOW);
@@ -283,10 +289,14 @@ static ssize_t set_temp_hyst1(struct device *dev, const char *buf,
{
struct i2c_client *client = to_i2c_client(dev);
struct lm90_data *data = i2c_get_clientdata(client);
- int hyst = TEMP1_FROM_REG(data->temp_crit1) -
- simple_strtol(buf, NULL, 10);
+ long val = simple_strtol(buf, NULL, 10);
+ long hyst;
+
+ down(&data->update_lock);
+ hyst = TEMP1_FROM_REG(data->temp_crit1) - val;
i2c_smbus_write_byte_data(client, LM90_REG_W_TCRIT_HYST,
HYST_TO_REG(hyst));
+ up(&data->update_lock);
return count;
}
diff --git a/drivers/i2c/chips/lm92.c b/drivers/i2c/chips/lm92.c
index 3c9d0ef8eca79e..fe6e83d70a72b2 100644
--- a/drivers/i2c/chips/lm92.c
+++ b/drivers/i2c/chips/lm92.c
@@ -157,8 +157,11 @@ static ssize_t set_##value(struct device *dev, const char *buf, \
struct i2c_client *client = to_i2c_client(dev); \
struct lm92_data *data = i2c_get_clientdata(client); \
long val = simple_strtol(buf, NULL, 10); \
+ \
+ down(&data->update_lock); \
data->value = TEMP_TO_REG(val); \
i2c_smbus_write_word_data(client, reg, swab16(data->value)); \
+ up(&data->update_lock); \
return count; \
}
set_temp(temp1_crit, LM92_REG_TEMP_CRIT);
@@ -189,10 +192,13 @@ static ssize_t set_temp1_crit_hyst(struct device *dev, const char *buf,
{
struct i2c_client *client = to_i2c_client(dev);
struct lm92_data *data = i2c_get_clientdata(client);
- data->temp1_hyst = TEMP_FROM_REG(data->temp1_crit) -
- simple_strtol(buf, NULL, 10);
+ long val = simple_strtol(buf, NULL, 10);
+
+ down(&data->update_lock);
+ data->temp1_hyst = TEMP_FROM_REG(data->temp1_crit) - val;
i2c_smbus_write_word_data(client, LM92_REG_TEMP_HYST,
swab16(TEMP_TO_REG(data->temp1_hyst)));
+ up(&data->update_lock);
return count;
}
diff --git a/drivers/i2c/chips/max1619.c b/drivers/i2c/chips/max1619.c
index e6f080163b82e9..5afa961a5e106a 100644
--- a/drivers/i2c/chips/max1619.c
+++ b/drivers/i2c/chips/max1619.c
@@ -141,8 +141,11 @@ static ssize_t set_##value(struct device *dev, const char *buf, \
struct i2c_client *client = to_i2c_client(dev); \
struct max1619_data *data = i2c_get_clientdata(client); \
long val = simple_strtol(buf, NULL, 10); \
+ \
+ down(&data->update_lock); \
data->value = TEMP_TO_REG(val); \
i2c_smbus_write_byte_data(client, reg, data->value); \
+ up(&data->update_lock); \
return count; \
}
diff --git a/drivers/i2c/chips/pc87360.c b/drivers/i2c/chips/pc87360.c
index bc15f70efe1335..6d94c36c9218c5 100644
--- a/drivers/i2c/chips/pc87360.c
+++ b/drivers/i2c/chips/pc87360.c
@@ -259,6 +259,7 @@ static ssize_t set_fan_min(struct device *dev, const char *buf,
struct pc87360_data *data = i2c_get_clientdata(client);
long fan_min = simple_strtol(buf, NULL, 10);
+ down(&data->update_lock);
fan_min = FAN_TO_REG(fan_min, FAN_DIV_FROM_REG(data->fan_status[nr]));
/* If it wouldn't fit, change clock divisor */
@@ -275,6 +276,7 @@ static ssize_t set_fan_min(struct device *dev, const char *buf,
/* Write new divider, preserve alarm bits */
pc87360_write_value(data, LD_FAN, NO_BANK, PC87360_REG_FAN_STATUS(nr),
data->fan_status[nr] & 0xF9);
+ up(&data->update_lock);
return count;
}
@@ -336,10 +338,13 @@ static ssize_t set_pwm##offset(struct device *dev, const char *buf, \
struct i2c_client *client = to_i2c_client(dev); \
struct pc87360_data *data = i2c_get_clientdata(client); \
long val = simple_strtol(buf, NULL, 10); \
+ \
+ down(&data->update_lock); \
data->pwm[offset-1] = PWM_TO_REG(val, \
FAN_CONFIG_INVERT(data->fan_conf, offset-1)); \
pc87360_write_value(data, LD_FAN, NO_BANK, PC87360_REG_PWM(offset-1), \
data->pwm[offset-1]); \
+ up(&data->update_lock); \
return count; \
} \
static DEVICE_ATTR(pwm##offset, S_IWUSR | S_IRUGO, \
@@ -378,9 +383,12 @@ static ssize_t set_in##offset##_min(struct device *dev, const char *buf, \
struct i2c_client *client = to_i2c_client(dev); \
struct pc87360_data *data = i2c_get_clientdata(client); \
long val = simple_strtol(buf, NULL, 10); \
+ \
+ down(&data->update_lock); \
data->in_min[offset] = IN_TO_REG(val, data->in_vref); \
pc87360_write_value(data, LD_IN, offset, PC87365_REG_IN_MIN, \
data->in_min[offset]); \
+ up(&data->update_lock); \
return count; \
} \
static ssize_t set_in##offset##_max(struct device *dev, const char *buf, \
@@ -389,10 +397,13 @@ static ssize_t set_in##offset##_max(struct device *dev, const char *buf, \
struct i2c_client *client = to_i2c_client(dev); \
struct pc87360_data *data = i2c_get_clientdata(client); \
long val = simple_strtol(buf, NULL, 10); \
+ \
+ down(&data->update_lock); \
data->in_max[offset] = IN_TO_REG(val, \
data->in_vref); \
pc87360_write_value(data, LD_IN, offset, PC87365_REG_IN_MAX, \
data->in_max[offset]); \
+ up(&data->update_lock); \
return count; \
} \
static DEVICE_ATTR(in##offset##_input, S_IRUGO, \
@@ -451,9 +462,12 @@ static ssize_t set_temp##offset##_min(struct device *dev, const char *buf, \
struct i2c_client *client = to_i2c_client(dev); \
struct pc87360_data *data = i2c_get_clientdata(client); \
long val = simple_strtol(buf, NULL, 10); \
+ \
+ down(&data->update_lock); \
data->in_min[offset+7] = IN_TO_REG(val, data->in_vref); \
pc87360_write_value(data, LD_IN, offset+7, PC87365_REG_TEMP_MIN, \
data->in_min[offset+7]); \
+ up(&data->update_lock); \
return count; \
} \
static ssize_t set_temp##offset##_max(struct device *dev, const char *buf, \
@@ -462,9 +476,12 @@ static ssize_t set_temp##offset##_max(struct device *dev, const char *buf, \
struct i2c_client *client = to_i2c_client(dev); \
struct pc87360_data *data = i2c_get_clientdata(client); \
long val = simple_strtol(buf, NULL, 10); \
+ \
+ down(&data->update_lock); \
data->in_max[offset+7] = IN_TO_REG(val, data->in_vref); \
pc87360_write_value(data, LD_IN, offset+7, PC87365_REG_TEMP_MAX, \
data->in_max[offset+7]); \
+ up(&data->update_lock); \
return count; \
} \
static ssize_t set_temp##offset##_crit(struct device *dev, const char *buf, \
@@ -473,9 +490,12 @@ static ssize_t set_temp##offset##_crit(struct device *dev, const char *buf, \
struct i2c_client *client = to_i2c_client(dev); \
struct pc87360_data *data = i2c_get_clientdata(client); \
long val = simple_strtol(buf, NULL, 10); \
+ \
+ down(&data->update_lock); \
data->in_crit[offset-4] = IN_TO_REG(val, data->in_vref); \
pc87360_write_value(data, LD_IN, offset+7, PC87365_REG_TEMP_CRIT, \
data->in_crit[offset-4]); \
+ up(&data->update_lock); \
return count; \
} \
static DEVICE_ATTR(temp##offset##_input, S_IRUGO, \
@@ -552,9 +572,12 @@ static ssize_t set_temp##offset##_min(struct device *dev, const char *buf, \
struct i2c_client *client = to_i2c_client(dev); \
struct pc87360_data *data = i2c_get_clientdata(client); \
long val = simple_strtol(buf, NULL, 10); \
+ \
+ down(&data->update_lock); \
data->temp_min[offset-1] = TEMP_TO_REG(val); \
pc87360_write_value(data, LD_TEMP, offset-1, PC87365_REG_TEMP_MIN, \
data->temp_min[offset-1]); \
+ up(&data->update_lock); \
return count; \
} \
static ssize_t set_temp##offset##_max(struct device *dev, const char *buf, \
@@ -563,9 +586,12 @@ static ssize_t set_temp##offset##_max(struct device *dev, const char *buf, \
struct i2c_client *client = to_i2c_client(dev); \
struct pc87360_data *data = i2c_get_clientdata(client); \
long val = simple_strtol(buf, NULL, 10); \
+ \
+ down(&data->update_lock); \
data->temp_max[offset-1] = TEMP_TO_REG(val); \
pc87360_write_value(data, LD_TEMP, offset-1, PC87365_REG_TEMP_MAX, \
data->temp_max[offset-1]); \
+ up(&data->update_lock); \
return count; \
} \
static ssize_t set_temp##offset##_crit(struct device *dev, const char *buf, \
@@ -574,9 +600,12 @@ static ssize_t set_temp##offset##_crit(struct device *dev, const char *buf, \
struct i2c_client *client = to_i2c_client(dev); \
struct pc87360_data *data = i2c_get_clientdata(client); \
long val = simple_strtol(buf, NULL, 10); \
+ \
+ down(&data->update_lock); \
data->temp_crit[offset-1] = TEMP_TO_REG(val); \
pc87360_write_value(data, LD_TEMP, offset-1, PC87365_REG_TEMP_CRIT, \
data->temp_crit[offset-1]); \
+ up(&data->update_lock); \
return count; \
} \
static DEVICE_ATTR(temp##offset##_input, S_IRUGO, \
diff --git a/drivers/i2c/chips/pcf8574.c b/drivers/i2c/chips/pcf8574.c
index ea68e6d16d5df2..48b4e22eaffe27 100644
--- a/drivers/i2c/chips/pcf8574.c
+++ b/drivers/i2c/chips/pcf8574.c
@@ -56,7 +56,6 @@ SENSORS_INSMOD_2(pcf8574, pcf8574a);
/* Each client has this additional data */
struct pcf8574_data {
struct i2c_client client;
- struct semaphore update_lock;
u8 read, write; /* Register values */
};
@@ -65,7 +64,6 @@ static int pcf8574_attach_adapter(struct i2c_adapter *adapter);
static int pcf8574_detect(struct i2c_adapter *adapter, int address, int kind);
static int pcf8574_detach_client(struct i2c_client *client);
static void pcf8574_init_client(struct i2c_client *client);
-static struct pcf8574_data *pcf8574_update_client(struct device *dev);
/* This is the driver that will be inserted */
static struct i2c_driver pcf8574_driver = {
@@ -80,7 +78,9 @@ static struct i2c_driver pcf8574_driver = {
/* following are the sysfs callback functions */
static ssize_t show_read(struct device *dev, char *buf)
{
- struct pcf8574_data *data = pcf8574_update_client(dev);
+ struct i2c_client *client = to_i2c_client(dev);
+ struct pcf8574_data *data = i2c_get_clientdata(client);
+ data->read = i2c_smbus_read_byte(client);
return sprintf(buf, "%u\n", data->read);
}
@@ -97,7 +97,12 @@ static ssize_t set_write(struct device *dev, const char *buf,
{
struct i2c_client *client = to_i2c_client(dev);
struct pcf8574_data *data = i2c_get_clientdata(client);
- data->write = simple_strtoul(buf, NULL, 10);
+ unsigned long val = simple_strtoul(buf, NULL, 10);
+
+ if (val > 0xff)
+ return -EINVAL;
+
+ data->write = val;
i2c_smbus_write_byte(client, data->write);
return count;
}
@@ -157,7 +162,6 @@ int pcf8574_detect(struct i2c_adapter *adapter, int address, int kind)
/* Fill in the remaining client fields and put it into the global list */
strlcpy(new_client->name, client_name, I2C_NAME_SIZE);
- init_MUTEX(&data->update_lock);
/* Tell the I2C layer a new client has arrived */
if ((err = i2c_attach_client(new_client)))
@@ -202,19 +206,6 @@ static void pcf8574_init_client(struct i2c_client *client)
i2c_smbus_write_byte(client, data->write);
}
-static struct pcf8574_data *pcf8574_update_client(struct device *dev)
-{
- struct i2c_client *client = to_i2c_client(dev);
- struct pcf8574_data *data = i2c_get_clientdata(client);
-
- down(&data->update_lock);
- dev_dbg(&client->dev, "Starting pcf8574 update\n");
- data->read = i2c_smbus_read_byte(client);
- up(&data->update_lock);
-
- return data;
-}
-
static int __init pcf8574_init(void)
{
return i2c_add_driver(&pcf8574_driver);
diff --git a/drivers/i2c/chips/pcf8591.c b/drivers/i2c/chips/pcf8591.c
index 6c7dc052bacd35..b6b927d8b37262 100644
--- a/drivers/i2c/chips/pcf8591.c
+++ b/drivers/i2c/chips/pcf8591.c
@@ -144,11 +144,15 @@ static ssize_t set_out0_enable(struct device *dev, const char *buf, size_t count
{
struct i2c_client *client = to_i2c_client(dev);
struct pcf8591_data *data = i2c_get_clientdata(client);
- if (simple_strtoul(buf, NULL, 10))
+ unsigned long val = simple_strtoul(buf, NULL, 10);
+
+ down(&data->update_lock);
+ if (val)
data->control |= PCF8591_CONTROL_AOEF;
else
data->control &= ~PCF8591_CONTROL_AOEF;
i2c_smbus_write_byte(client, data->control);
+ up(&data->update_lock);
return count;
}
diff --git a/drivers/i2c/chips/sis5595.c b/drivers/i2c/chips/sis5595.c
index 178f01fb4fb43f..7ea84532df322b 100644
--- a/drivers/i2c/chips/sis5595.c
+++ b/drivers/i2c/chips/sis5595.c
@@ -232,8 +232,11 @@ static ssize_t set_in_min(struct device *dev, const char *buf,
struct i2c_client *client = to_i2c_client(dev);
struct sis5595_data *data = i2c_get_clientdata(client);
unsigned long val = simple_strtoul(buf, NULL, 10);
+
+ down(&data->update_lock);
data->in_min[nr] = IN_TO_REG(val);
sis5595_write_value(client, SIS5595_REG_IN_MIN(nr), data->in_min[nr]);
+ up(&data->update_lock);
return count;
}
@@ -243,8 +246,11 @@ static ssize_t set_in_max(struct device *dev, const char *buf,
struct i2c_client *client = to_i2c_client(dev);
struct sis5595_data *data = i2c_get_clientdata(client);
unsigned long val = simple_strtoul(buf, NULL, 10);
+
+ down(&data->update_lock);
data->in_max[nr] = IN_TO_REG(val);
sis5595_write_value(client, SIS5595_REG_IN_MAX(nr), data->in_max[nr]);
+ up(&data->update_lock);
return count;
}
@@ -305,8 +311,11 @@ static ssize_t set_temp_over(struct device *dev, const char *buf, size_t count)
struct i2c_client *client = to_i2c_client(dev);
struct sis5595_data *data = i2c_get_clientdata(client);
long val = simple_strtol(buf, NULL, 10);
+
+ down(&data->update_lock);
data->temp_over = TEMP_TO_REG(val);
sis5595_write_value(client, SIS5595_REG_TEMP_OVER, data->temp_over);
+ up(&data->update_lock);
return count;
}
@@ -321,8 +330,11 @@ static ssize_t set_temp_hyst(struct device *dev, const char *buf, size_t count)
struct i2c_client *client = to_i2c_client(dev);
struct sis5595_data *data = i2c_get_clientdata(client);
long val = simple_strtol(buf, NULL, 10);
+
+ down(&data->update_lock);
data->temp_hyst = TEMP_TO_REG(val);
sis5595_write_value(client, SIS5595_REG_TEMP_HYST, data->temp_hyst);
+ up(&data->update_lock);
return count;
}
@@ -353,8 +365,11 @@ static ssize_t set_fan_min(struct device *dev, const char *buf,
struct i2c_client *client = to_i2c_client(dev);
struct sis5595_data *data = i2c_get_clientdata(client);
unsigned long val = simple_strtoul(buf, NULL, 10);
+
+ down(&data->update_lock);
data->fan_min[nr] = FAN_TO_REG(val, DIV_FROM_REG(data->fan_div[nr]));
sis5595_write_value(client, SIS5595_REG_FAN_MIN(nr), data->fan_min[nr]);
+ up(&data->update_lock);
return count;
}
@@ -373,10 +388,15 @@ static ssize_t set_fan_div(struct device *dev, const char *buf,
{
struct i2c_client *client = to_i2c_client(dev);
struct sis5595_data *data = i2c_get_clientdata(client);
- unsigned long min = FAN_FROM_REG(data->fan_min[nr],
- DIV_FROM_REG(data->fan_div[nr]));
+ unsigned long min;
unsigned long val = simple_strtoul(buf, NULL, 10);
- int reg = sis5595_read_value(client, SIS5595_REG_FANDIV);
+ int reg;
+
+ down(&data->update_lock);
+ min = FAN_FROM_REG(data->fan_min[nr],
+ DIV_FROM_REG(data->fan_div[nr]));
+ reg = sis5595_read_value(client, SIS5595_REG_FANDIV);
+
switch (val) {
case 1: data->fan_div[nr] = 0; break;
case 2: data->fan_div[nr] = 1; break;
@@ -385,6 +405,7 @@ static ssize_t set_fan_div(struct device *dev, const char *buf,
default:
dev_err(&client->dev, "fan_div value %ld not "
"supported. Choose one of 1, 2, 4 or 8!\n", val);
+ up(&data->update_lock);
return -EINVAL;
}
@@ -400,6 +421,7 @@ static ssize_t set_fan_div(struct device *dev, const char *buf,
data->fan_min[nr] =
FAN_TO_REG(min, DIV_FROM_REG(data->fan_div[nr]));
sis5595_write_value(client, SIS5595_REG_FAN_MIN(nr), data->fan_min[nr]);
+ up(&data->update_lock);
return count;
}
diff --git a/drivers/i2c/chips/smsc47m1.c b/drivers/i2c/chips/smsc47m1.c
index 8d22390378d79a..0e12ca3694131f 100644
--- a/drivers/i2c/chips/smsc47m1.c
+++ b/drivers/i2c/chips/smsc47m1.c
@@ -195,16 +195,20 @@ static ssize_t set_fan_min(struct device *dev, const char *buf,
{
struct i2c_client *client = to_i2c_client(dev);
struct smsc47m1_data *data = i2c_get_clientdata(client);
+ long rpmdiv, val = simple_strtol(buf, NULL, 10);
- long rpmdiv = simple_strtol(buf, NULL, 10)
- * DIV_FROM_REG(data->fan_div[nr]);
+ down(&data->update_lock);
+ rpmdiv = val * DIV_FROM_REG(data->fan_div[nr]);
- if (983040 > 192 * rpmdiv || 2 * rpmdiv > 983040)
+ if (983040 > 192 * rpmdiv || 2 * rpmdiv > 983040) {
+ up(&data->update_lock);
return -EINVAL;
+ }
data->fan_preload[nr] = 192 - ((983040 + rpmdiv / 2) / rpmdiv);
smsc47m1_write_value(client, SMSC47M1_REG_FAN_PRELOAD(nr),
data->fan_preload[nr]);
+ up(&data->update_lock);
return count;
}
@@ -224,12 +228,16 @@ static ssize_t set_fan_div(struct device *dev, const char *buf,
if (new_div == old_div) /* No change */
return count;
+
+ down(&data->update_lock);
switch (new_div) {
case 1: data->fan_div[nr] = 0; break;
case 2: data->fan_div[nr] = 1; break;
case 4: data->fan_div[nr] = 2; break;
case 8: data->fan_div[nr] = 3; break;
- default: return -EINVAL;
+ default:
+ up(&data->update_lock);
+ return -EINVAL;
}
tmp = smsc47m1_read_value(client, SMSC47M1_REG_FANDIV) & 0x0F;
@@ -242,6 +250,7 @@ static ssize_t set_fan_div(struct device *dev, const char *buf,
data->fan_preload[nr] = SENSORS_LIMIT(tmp, 0, 191);
smsc47m1_write_value(client, SMSC47M1_REG_FAN_PRELOAD(nr),
data->fan_preload[nr]);
+ up(&data->update_lock);
return count;
}
@@ -257,11 +266,13 @@ static ssize_t set_pwm(struct device *dev, const char *buf,
if (val < 0 || val > 255)
return -EINVAL;
+ down(&data->update_lock);
data->pwm[nr] &= 0x81; /* Preserve additional bits */
data->pwm[nr] |= PWM_TO_REG(val);
-
smsc47m1_write_value(client, SMSC47M1_REG_PWM(nr),
data->pwm[nr]);
+ up(&data->update_lock);
+
return count;
}
@@ -276,11 +287,12 @@ static ssize_t set_pwm_en(struct device *dev, const char *buf,
if (val != 0 && val != 1)
return -EINVAL;
+ down(&data->update_lock);
data->pwm[nr] &= 0xFE; /* preserve the other bits */
data->pwm[nr] |= !val;
-
smsc47m1_write_value(client, SMSC47M1_REG_PWM(nr),
data->pwm[nr]);
+ up(&data->update_lock);
return count;
}
diff --git a/drivers/i2c/chips/via686a.c b/drivers/i2c/chips/via686a.c
index e6978b2682b8dd..9b948f4531f5ad 100644
--- a/drivers/i2c/chips/via686a.c
+++ b/drivers/i2c/chips/via686a.c
@@ -363,9 +363,12 @@ static ssize_t set_in_min(struct device *dev, const char *buf,
struct i2c_client *client = to_i2c_client(dev);
struct via686a_data *data = i2c_get_clientdata(client);
unsigned long val = simple_strtoul(buf, NULL, 10);
+
+ down(&data->update_lock);
data->in_min[nr] = IN_TO_REG(val,nr);
via686a_write_value(client, VIA686A_REG_IN_MIN(nr),
data->in_min[nr]);
+ up(&data->update_lock);
return count;
}
static ssize_t set_in_max(struct device *dev, const char *buf,
@@ -373,9 +376,12 @@ static ssize_t set_in_max(struct device *dev, const char *buf,
struct i2c_client *client = to_i2c_client(dev);
struct via686a_data *data = i2c_get_clientdata(client);
unsigned long val = simple_strtoul(buf, NULL, 10);
+
+ down(&data->update_lock);
data->in_max[nr] = IN_TO_REG(val,nr);
via686a_write_value(client, VIA686A_REG_IN_MAX(nr),
data->in_max[nr]);
+ up(&data->update_lock);
return count;
}
#define show_in_offset(offset) \
@@ -434,8 +440,11 @@ static ssize_t set_temp_over(struct device *dev, const char *buf,
struct i2c_client *client = to_i2c_client(dev);
struct via686a_data *data = i2c_get_clientdata(client);
int val = simple_strtol(buf, NULL, 10);
+
+ down(&data->update_lock);
data->temp_over[nr] = TEMP_TO_REG(val);
via686a_write_value(client, VIA686A_REG_TEMP_OVER(nr), data->temp_over[nr]);
+ up(&data->update_lock);
return count;
}
static ssize_t set_temp_hyst(struct device *dev, const char *buf,
@@ -443,8 +452,11 @@ static ssize_t set_temp_hyst(struct device *dev, const char *buf,
struct i2c_client *client = to_i2c_client(dev);
struct via686a_data *data = i2c_get_clientdata(client);
int val = simple_strtol(buf, NULL, 10);
+
+ down(&data->update_lock);
data->temp_hyst[nr] = TEMP_TO_REG(val);
via686a_write_value(client, VIA686A_REG_TEMP_HYST(nr), data->temp_hyst[nr]);
+ up(&data->update_lock);
return count;
}
#define show_temp_offset(offset) \
@@ -502,8 +514,11 @@ static ssize_t set_fan_min(struct device *dev, const char *buf,
struct i2c_client *client = to_i2c_client(dev);
struct via686a_data *data = i2c_get_clientdata(client);
int val = simple_strtol(buf, NULL, 10);
+
+ down(&data->update_lock);
data->fan_min[nr] = FAN_TO_REG(val, DIV_FROM_REG(data->fan_div[nr]));
via686a_write_value(client, VIA686A_REG_FAN_MIN(nr+1), data->fan_min[nr]);
+ up(&data->update_lock);
return count;
}
static ssize_t set_fan_div(struct device *dev, const char *buf,
@@ -511,10 +526,14 @@ static ssize_t set_fan_div(struct device *dev, const char *buf,
struct i2c_client *client = to_i2c_client(dev);
struct via686a_data *data = i2c_get_clientdata(client);
int val = simple_strtol(buf, NULL, 10);
- int old = via686a_read_value(client, VIA686A_REG_FANDIV);
+ int old;
+
+ down(&data->update_lock);
+ old = via686a_read_value(client, VIA686A_REG_FANDIV);
data->fan_div[nr] = DIV_TO_REG(val);
old = (old & 0x0f) | (data->fan_div[1] << 6) | (data->fan_div[0] << 4);
via686a_write_value(client, VIA686A_REG_FANDIV, old);
+ up(&data->update_lock);
return count;
}
diff --git a/drivers/i2c/chips/w83627hf.c b/drivers/i2c/chips/w83627hf.c
index 133e449dc14efa..b1da5ed696d3de 100644
--- a/drivers/i2c/chips/w83627hf.c
+++ b/drivers/i2c/chips/w83627hf.c
@@ -354,10 +354,13 @@ store_in_##reg (struct device *dev, const char *buf, size_t count, int nr) \
u32 val; \
\
val = simple_strtoul(buf, NULL, 10); \
+ \
+ down(&data->update_lock); \
data->in_##reg[nr] = IN_TO_REG(val); \
w83627hf_write_value(client, W83781D_REG_IN_##REG(nr), \
data->in_##reg[nr]); \
\
+ up(&data->update_lock); \
return count; \
}
store_in_reg(MIN, min)
@@ -442,6 +445,9 @@ static ssize_t store_regs_in_min0(struct device *dev,
u32 val;
val = simple_strtoul(buf, NULL, 10);
+
+ down(&data->update_lock);
+
if ((data->vrm_ovt & 0x01) &&
(w83627thf == data->type || w83637hf == data->type))
@@ -452,6 +458,7 @@ static ssize_t store_regs_in_min0(struct device *dev,
data->in_min[0] = IN_TO_REG(val);
w83627hf_write_value(client, W83781D_REG_IN_MIN(0), data->in_min[0]);
+ up(&data->update_lock);
return count;
}
@@ -463,6 +470,9 @@ static ssize_t store_regs_in_max0(struct device *dev,
u32 val;
val = simple_strtoul(buf, NULL, 10);
+
+ down(&data->update_lock);
+
if ((data->vrm_ovt & 0x01) &&
(w83627thf == data->type || w83637hf == data->type))
@@ -473,6 +483,7 @@ static ssize_t store_regs_in_max0(struct device *dev,
data->in_max[0] = IN_TO_REG(val);
w83627hf_write_value(client, W83781D_REG_IN_MAX(0), data->in_max[0]);
+ up(&data->update_lock);
return count;
}
@@ -508,11 +519,14 @@ store_fan_min(struct device *dev, const char *buf, size_t count, int nr)
u32 val;
val = simple_strtoul(buf, NULL, 10);
+
+ down(&data->update_lock);
data->fan_min[nr - 1] =
FAN_TO_REG(val, DIV_FROM_REG(data->fan_div[nr - 1]));
w83627hf_write_value(client, W83781D_REG_FAN_MIN(nr),
data->fan_min[nr - 1]);
+ up(&data->update_lock);
return count;
}
@@ -574,6 +588,8 @@ store_temp_##reg (struct device *dev, const char *buf, size_t count, int nr) \
\
val = simple_strtoul(buf, NULL, 10); \
\
+ down(&data->update_lock); \
+ \
if (nr >= 2) { /* TEMP2 and TEMP3 */ \
data->temp_##reg##_add[nr-2] = LM75_TEMP_TO_REG(val); \
w83627hf_write_value(client, W83781D_REG_TEMP_##REG(nr), \
@@ -584,6 +600,7 @@ store_temp_##reg (struct device *dev, const char *buf, size_t count, int nr) \
data->temp_##reg); \
} \
\
+ up(&data->update_lock); \
return count; \
}
store_temp_reg(OVER, max);
@@ -692,6 +709,8 @@ store_beep_reg(struct device *dev, const char *buf, size_t count,
val = simple_strtoul(buf, NULL, 10);
+ down(&data->update_lock);
+
if (update_mask == BEEP_MASK) { /* We are storing beep_mask */
data->beep_mask = BEEP_MASK_TO_REG(val);
w83627hf_write_value(client, W83781D_REG_BEEP_INTS1,
@@ -708,6 +727,7 @@ store_beep_reg(struct device *dev, const char *buf, size_t count,
w83627hf_write_value(client, W83781D_REG_BEEP_INTS2,
val2 | data->beep_enable << 7);
+ up(&data->update_lock);
return count;
}
@@ -752,12 +772,15 @@ store_fan_div_reg(struct device *dev, const char *buf, size_t count, int nr)
struct w83627hf_data *data = i2c_get_clientdata(client);
unsigned long min;
u8 reg;
+ unsigned long val = simple_strtoul(buf, NULL, 10);
+
+ down(&data->update_lock);
/* Save fan_min */
min = FAN_FROM_REG(data->fan_min[nr],
DIV_FROM_REG(data->fan_div[nr]));
- data->fan_div[nr] = DIV_TO_REG(simple_strtoul(buf, NULL, 10));
+ data->fan_div[nr] = DIV_TO_REG(val);
reg = (w83627hf_read_value(client, nr==2 ? W83781D_REG_PIN : W83781D_REG_VID_FANDIV)
& (nr==0 ? 0xcf : 0x3f))
@@ -773,6 +796,7 @@ store_fan_div_reg(struct device *dev, const char *buf, size_t count, int nr)
data->fan_min[nr] = FAN_TO_REG(min, DIV_FROM_REG(data->fan_div[nr]));
w83627hf_write_value(client, W83781D_REG_FAN_MIN(nr+1), data->fan_min[nr]);
+ up(&data->update_lock);
return count;
}
@@ -815,6 +839,8 @@ store_pwm_reg(struct device *dev, const char *buf, size_t count, int nr)
val = simple_strtoul(buf, NULL, 10);
+ down(&data->update_lock);
+
if (data->type == w83627thf) {
/* bits 0-3 are reserved in 627THF */
data->pwm[nr - 1] = PWM_TO_REG(val) & 0xf0;
@@ -830,6 +856,7 @@ store_pwm_reg(struct device *dev, const char *buf, size_t count, int nr)
data->pwm[nr - 1]);
}
+ up(&data->update_lock);
return count;
}
@@ -871,6 +898,8 @@ store_sensor_reg(struct device *dev, const char *buf, size_t count, int nr)
val = simple_strtoul(buf, NULL, 10);
+ down(&data->update_lock);
+
switch (val) {
case 1: /* PII/Celeron diode */
tmp = w83627hf_read_value(client, W83781D_REG_SCFG1);
@@ -903,6 +932,7 @@ store_sensor_reg(struct device *dev, const char *buf, size_t count, int nr)
break;
}
+ up(&data->update_lock);
return count;
}
diff --git a/drivers/i2c/chips/w83781d.c b/drivers/i2c/chips/w83781d.c
index 628d769cf47516..4954e465c4199c 100644
--- a/drivers/i2c/chips/w83781d.c
+++ b/drivers/i2c/chips/w83781d.c
@@ -296,9 +296,12 @@ static ssize_t store_in_##reg (struct device *dev, const char *buf, size_t count
u32 val; \
\
val = simple_strtoul(buf, NULL, 10) / 10; \
+ \
+ down(&data->update_lock); \
data->in_##reg[nr] = IN_TO_REG(val); \
w83781d_write_value(client, W83781D_REG_IN_##REG(nr), data->in_##reg[nr]); \
\
+ up(&data->update_lock); \
return count; \
}
store_in_reg(MIN, min);
@@ -363,11 +366,14 @@ store_fan_min(struct device *dev, const char *buf, size_t count, int nr)
u32 val;
val = simple_strtoul(buf, NULL, 10);
+
+ down(&data->update_lock);
data->fan_min[nr - 1] =
FAN_TO_REG(val, DIV_FROM_REG(data->fan_div[nr - 1]));
w83781d_write_value(client, W83781D_REG_FAN_MIN(nr),
data->fan_min[nr - 1]);
+ up(&data->update_lock);
return count;
}
@@ -426,6 +432,8 @@ static ssize_t store_temp_##reg (struct device *dev, const char *buf, size_t cou
\
val = simple_strtol(buf, NULL, 10); \
\
+ down(&data->update_lock); \
+ \
if (nr >= 2) { /* TEMP2 and TEMP3 */ \
data->temp_##reg##_add[nr-2] = LM75_TEMP_TO_REG(val); \
w83781d_write_value(client, W83781D_REG_TEMP_##REG(nr), \
@@ -436,6 +444,7 @@ static ssize_t store_temp_##reg (struct device *dev, const char *buf, size_t cou
data->temp_##reg); \
} \
\
+ up(&data->update_lock); \
return count; \
}
store_temp_reg(OVER, max);
@@ -548,6 +557,8 @@ store_beep_reg(struct device *dev, const char *buf, size_t count,
val = simple_strtoul(buf, NULL, 10);
+ down(&data->update_lock);
+
if (update_mask == BEEP_MASK) { /* We are storing beep_mask */
data->beep_mask = BEEP_MASK_TO_REG(val, data->type);
w83781d_write_value(client, W83781D_REG_BEEP_INTS1,
@@ -567,6 +578,7 @@ store_beep_reg(struct device *dev, const char *buf, size_t count,
w83781d_write_value(client, W83781D_REG_BEEP_INTS2,
val2 | data->beep_enable << 7);
+ up(&data->update_lock);
return count;
}
@@ -609,13 +621,15 @@ store_fan_div_reg(struct device *dev, const char *buf, size_t count, int nr)
struct w83781d_data *data = i2c_get_clientdata(client);
unsigned long min;
u8 reg;
+ unsigned long val = simple_strtoul(buf, NULL, 10);
+ down(&data->update_lock);
+
/* Save fan_min */
min = FAN_FROM_REG(data->fan_min[nr],
DIV_FROM_REG(data->fan_div[nr]));
- data->fan_div[nr] = DIV_TO_REG(simple_strtoul(buf, NULL, 10),
- data->type);
+ data->fan_div[nr] = DIV_TO_REG(val, data->type);
reg = (w83781d_read_value(client, nr==2 ? W83781D_REG_PIN : W83781D_REG_VID_FANDIV)
& (nr==0 ? 0xcf : 0x3f))
@@ -634,6 +648,7 @@ store_fan_div_reg(struct device *dev, const char *buf, size_t count, int nr)
data->fan_min[nr] = FAN_TO_REG(min, DIV_FROM_REG(data->fan_div[nr]));
w83781d_write_value(client, W83781D_REG_FAN_MIN(nr+1), data->fan_min[nr]);
+ up(&data->update_lock);
return count;
}
@@ -680,9 +695,10 @@ store_pwm_reg(struct device *dev, const char *buf, size_t count, int nr)
val = simple_strtoul(buf, NULL, 10);
+ down(&data->update_lock);
data->pwm[nr - 1] = PWM_TO_REG(val);
w83781d_write_value(client, W83781D_REG_PWM(nr), data->pwm[nr - 1]);
-
+ up(&data->update_lock);
return count;
}
@@ -695,6 +711,8 @@ store_pwmenable_reg(struct device *dev, const char *buf, size_t count, int nr)
val = simple_strtoul(buf, NULL, 10);
+ down(&data->update_lock);
+
switch (val) {
case 0:
case 1:
@@ -710,9 +728,11 @@ store_pwmenable_reg(struct device *dev, const char *buf, size_t count, int nr)
break;
default:
+ up(&data->update_lock);
return -EINVAL;
}
+ up(&data->update_lock);
return count;
}
@@ -774,6 +794,8 @@ store_sensor_reg(struct device *dev, const char *buf, size_t count, int nr)
val = simple_strtoul(buf, NULL, 10);
+ down(&data->update_lock);
+
switch (val) {
case 1: /* PII/Celeron diode */
tmp = w83781d_read_value(client, W83781D_REG_SCFG1);
@@ -805,6 +827,7 @@ store_sensor_reg(struct device *dev, const char *buf, size_t count, int nr)
break;
}
+ up(&data->update_lock);
return count;
}
diff --git a/drivers/i2c/i2c-core.c b/drivers/i2c/i2c-core.c
index e62a91a45a291e..9011627d7eb030 100644
--- a/drivers/i2c/i2c-core.c
+++ b/drivers/i2c/i2c-core.c
@@ -1236,22 +1236,6 @@ s32 i2c_smbus_xfer(struct i2c_adapter * adapter, u16 addr, unsigned short flags,
}
-/* You should always define `functionality'; the 'else' is just for
- backward compatibility. */
-u32 i2c_get_functionality (struct i2c_adapter *adap)
-{
- if (adap->algo->functionality)
- return adap->algo->functionality(adap);
- else
- return 0xffffffff;
-}
-
-int i2c_check_functionality (struct i2c_adapter *adap, u32 func)
-{
- u32 adap_func = i2c_get_functionality (adap);
- return (func & adap_func) == func;
-}
-
EXPORT_SYMBOL(i2c_add_adapter);
EXPORT_SYMBOL(i2c_del_adapter);
EXPORT_SYMBOL(i2c_add_driver);
@@ -1283,9 +1267,6 @@ EXPORT_SYMBOL(i2c_smbus_write_word_data);
EXPORT_SYMBOL(i2c_smbus_write_block_data);
EXPORT_SYMBOL(i2c_smbus_read_i2c_block_data);
-EXPORT_SYMBOL(i2c_get_functionality);
-EXPORT_SYMBOL(i2c_check_functionality);
-
MODULE_AUTHOR("Simon G. Vogl <simon@tk.uni-linz.ac.at>");
MODULE_DESCRIPTION("I2C-Bus main module");
MODULE_LICENSE("GPL");
diff --git a/include/linux/i2c.h b/include/linux/i2c.h
index 9f2ae600683c63..ebcd745f4cd6f7 100644
--- a/include/linux/i2c.h
+++ b/include/linux/i2c.h
@@ -368,10 +368,16 @@ extern void i2c_put_adapter(struct i2c_adapter *adap);
/* Return the functionality mask */
-extern u32 i2c_get_functionality (struct i2c_adapter *adap);
+static inline u32 i2c_get_functionality(struct i2c_adapter *adap)
+{
+ return adap->algo->functionality(adap);
+}
/* Return 1 if adapter supports everything we need, 0 if not. */
-extern int i2c_check_functionality (struct i2c_adapter *adap, u32 func);
+static inline int i2c_check_functionality(struct i2c_adapter *adap, u32 func)
+{
+ return (func & i2c_get_functionality(adap)) == func;
+}
/*
* I2C Message - used for pure i2c transaction, also from /dev interface
diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c
index 8c5dd09a89b407..8a2cc75b394859 100644
--- a/security/selinux/hooks.c
+++ b/security/selinux/hooks.c
@@ -877,18 +877,8 @@ static int inode_doinit_with_dentry(struct inode *inode, struct dentry *opt_dent
isec->initialized = 1;
out:
- if (inode->i_sock) {
- struct socket *sock = SOCKET_I(inode);
- if (sock->sk) {
- isec->sclass = socket_type_to_security_class(sock->sk->sk_family,
- sock->sk->sk_type,
- sock->sk->sk_protocol);
- } else {
- isec->sclass = SECCLASS_SOCKET;
- }
- } else {
+ if (isec->sclass == SECCLASS_FILE)
isec->sclass = inode_mode_to_security_class(inode->i_mode);
- }
if (hold_sem)
up(&isec->sem);
@@ -2979,18 +2969,15 @@ out:
static void selinux_socket_post_create(struct socket *sock, int family,
int type, int protocol, int kern)
{
- int err;
struct inode_security_struct *isec;
struct task_security_struct *tsec;
- err = inode_doinit(SOCK_INODE(sock));
- if (err < 0)
- return;
isec = SOCK_INODE(sock)->i_security;
tsec = current->security;
isec->sclass = socket_type_to_security_class(family, type, protocol);
isec->sid = kern ? SECINITSID_KERNEL : tsec->sid;
+ isec->initialized = 1;
return;
}
@@ -3158,14 +3145,12 @@ static int selinux_socket_accept(struct socket *sock, struct socket *newsock)
if (err)
return err;
- err = inode_doinit(SOCK_INODE(newsock));
- if (err < 0)
- return err;
newisec = SOCK_INODE(newsock)->i_security;
isec = SOCK_INODE(sock)->i_security;
newisec->sclass = isec->sclass;
newisec->sid = isec->sid;
+ newisec->initialized = 1;
return 0;
}