RFC PATCH add set_value locking

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Greetings,

This patch adds locking around set operations that access 
data->something and go out to the chip.

for:
asb100, max1619, ds1621, pcf8574, fscher, pcf8591, fscpos, 
sis5595, gl518sm, via686a, gl520sm, w83627hf, w83781d

as separate files from: 
  http://scatter.mine.nu/lmsensors/lock-on-set/

Sign-off-by: Grant Coady <gcoady at gmail.com>


diff -Nur linux-2.6.12-rc1-mm3/drivers/i2c/chips/asb100.c linux-2.6.12-rc1-mm3b/drivers/i2c/chips/asb100.c
--- linux-2.6.12-rc1-mm3/drivers/i2c/chips/asb100.c	2005-03-23 06:34:25.000000000 +1100
+++ linux-2.6.12-rc1-mm3b/drivers/i2c/chips/asb100.c	2005-03-26 11:40:20.000000000 +1100
@@ -246,9 +246,12 @@
 	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,12 @@
 	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 +350,14 @@
 {
 	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 +383,9 @@
 	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 +463,8 @@
 	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 +475,7 @@
 	} \
 	asb100_write_value(client, ASB100_REG_TEMP_##REG(nr+1), \
 			data->reg[nr]); \
+	up(&data->update_lock); \
 	return count; \
 }
 
@@ -560,9 +576,12 @@
 	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 +597,12 @@
 	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 -Nur linux-2.6.12-rc1-mm3/drivers/i2c/chips/ds1621.c linux-2.6.12-rc1-mm3b/drivers/i2c/chips/ds1621.c
--- linux-2.6.12-rc1-mm3/drivers/i2c/chips/ds1621.c	2005-03-23 06:34:25.000000000 +1100
+++ linux-2.6.12-rc1-mm3b/drivers/i2c/chips/ds1621.c	2005-03-26 11:40:20.000000000 +1100
@@ -153,8 +153,11 @@
 {									\
 	struct i2c_client *client = to_i2c_client(dev);			\
 	struct ds1621_data *data = ds1621_update_client(dev);		\
+\
+	down(&data->update_lock);					\
 	data->value = LM75_TEMP_TO_REG(simple_strtoul(buf, NULL, 10));	\
 	ds1621_write_value(client, reg, data->value);			\
+	up(&data->update_lock);						\
 	return count;							\
 }
 
diff -Nur linux-2.6.12-rc1-mm3/drivers/i2c/chips/fscher.c linux-2.6.12-rc1-mm3b/drivers/i2c/chips/fscher.c
--- linux-2.6.12-rc1-mm3/drivers/i2c/chips/fscher.c	2005-03-23 06:34:25.000000000 +1100
+++ linux-2.6.12-rc1-mm3b/drivers/i2c/chips/fscher.c	2005-03-26 11:40:20.000000000 +1100
@@ -464,9 +464,11 @@
 {
 	/* 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 @@
 		       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;
 }
 
@@ -497,6 +501,8 @@
 	/* supported values: 2, 4, 8 */
 	unsigned long v = simple_strtoul(buf, NULL, 10);
 
+	down(&data->update_lock);
+
 	switch (v) {
 	case 2: v = 1; break;
 	case 4: v = 2; break;
@@ -504,14 +510,16 @@
 	default:
 		dev_err(&client->dev, "fan_div value %ld not "
 			 "supported. Choose one of 2, 4 or 8!\n", v);
+		up(&data->update_lock);
 		return -EINVAL;
 	}
 
 	/* 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 +545,11 @@
 {
 	/* 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 +602,11 @@
 {
 	/* 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 +624,12 @@
 {
 	/* 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 +644,11 @@
 {
 	/* 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 +661,10 @@
 static ssize_t set_watchdog_preset(struct i2c_client *client, struct fscher_data *data,
 				   const char *buf, size_t count, int nr, int reg)
 {
+	down(&data->update_lock);
 	data->watchdog[0] = simple_strtoul(buf, NULL, 10) & 0xff;
-
 	fscher_write_value(client, reg, data->watchdog[0]);
+	up(&data->update_lock);
 	return count;
 }
 
diff -Nur linux-2.6.12-rc1-mm3/drivers/i2c/chips/fscpos.c linux-2.6.12-rc1-mm3b/drivers/i2c/chips/fscpos.c
--- linux-2.6.12-rc1-mm3/drivers/i2c/chips/fscpos.c	2005-03-23 06:34:25.000000000 +1100
+++ linux-2.6.12-rc1-mm3b/drivers/i2c/chips/fscpos.c	2005-03-26 11:40:20.000000000 +1100
@@ -206,11 +206,13 @@
 		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 @@
 	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,13 @@
 {
 	/* 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 +303,11 @@
 		return -EINVAL;
 	}
 
+	down(&data->update_lock);
 	data->wdog_state &= ~v;
 	
 	fscpos_write_value(client, reg, v);
+	up(&data->update_lock);
 	return count;
 }
 
diff -Nur linux-2.6.12-rc1-mm3/drivers/i2c/chips/gl518sm.c linux-2.6.12-rc1-mm3b/drivers/i2c/chips/gl518sm.c
--- linux-2.6.12-rc1-mm3/drivers/i2c/chips/gl518sm.c	2005-03-23 06:34:25.000000000 +1100
+++ linux-2.6.12-rc1-mm3b/drivers/i2c/chips/gl518sm.c	2005-03-26 11:40:20.000000000 +1100
@@ -211,8 +211,11 @@
 	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 @@
 {									\
 	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,7 +262,10 @@
 {
 	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;
+
+	down(&data->update_lock);
+	regvalue = gl518_read_value(client, GL518_REG_FAN_LIMIT);
 
 	data->fan_min[0] = FAN_TO_REG(simple_strtoul(buf, NULL, 10),
 		DIV_FROM_REG(data->fan_div[0]));
@@ -270,6 +280,7 @@
 	data->beep_mask &= data->alarm_mask;
 	gl518_write_value(client, GL518_REG_ALARM, data->beep_mask);
 
+	up(&data->update_lock);
 	return count;
 }
 
@@ -277,8 +288,10 @@
 {
 	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;
 
+	down(&data->update_lock);
+	regvalue = gl518_read_value(client, GL518_REG_FAN_LIMIT);
 	data->fan_min[1] = FAN_TO_REG(simple_strtoul(buf, NULL, 10),
 		DIV_FROM_REG(data->fan_div[1]));
 	regvalue = (regvalue & 0xff00) | data->fan_min[1];
@@ -292,6 +305,7 @@
 	data->beep_mask &= data->alarm_mask;
 	gl518_write_value(client, GL518_REG_ALARM, data->beep_mask);
 
+	up(&data->update_lock);
 	return count;
 }
 
diff -Nur linux-2.6.12-rc1-mm3/drivers/i2c/chips/gl520sm.c linux-2.6.12-rc1-mm3b/drivers/i2c/chips/gl520sm.c
--- linux-2.6.12-rc1-mm3/drivers/i2c/chips/gl520sm.c	2005-03-23 06:34:25.000000000 +1100
+++ linux-2.6.12-rc1-mm3b/drivers/i2c/chips/gl520sm.c	2005-03-26 11:40:20.000000000 +1100
@@ -299,6 +299,8 @@
 static ssize_t set_in_min(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);
+
+	down(&data->update_lock);
 	u8 r;
 
 	if (n == 0)
@@ -313,12 +315,15 @@
 	else
 		gl520_write_value(client, reg, r);
 
+	up(&data->update_lock);
 	return count;
 }
 
 static ssize_t set_in_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);
+
+	down(&data->update_lock);
 	u8 r;
 
 	if (n == 0)
@@ -333,6 +338,7 @@
 	else
 		gl520_write_value(client, reg, r);
 
+	up(&data->update_lock);
 	return count;
 }
 
@@ -363,6 +369,8 @@
 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);
+
+	down(&data->update_lock);
 	u8 r = FAN_TO_REG(v, data->fan_div[n - 1]);
 
 	data->fan_min[n - 1] = r;
@@ -380,12 +388,15 @@
 	data->beep_mask &= data->alarm_mask;
 	gl520_write_value(client, GL520_REG_BEEP_MASK, data->beep_mask);
 
+	up(&data->update_lock);
 	return count;
 }
 
 static ssize_t set_fan_div(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);
+
+	down(&data->update_lock);
 	u8 r;
 
 	switch (v) {
@@ -394,17 +405,22 @@
 	case 4: r = 2; break;
 	case 8: r = 3; break;
 	default:
-		dev_err(&client->dev, "fan_div value %ld not supported. Choose one of 1, 2, 4 or 8!\n", v);
+		dev_err(&client->dev, "fan_div value %ld not supported. "
+				"Choose one of 1, 2, 4 or 8!\n", v);
+		up(&data->update_lock);
 		return -EINVAL;
 	}
 
 	data->fan_div[n - 1] = r;
 
 	if (n == 1)
-		gl520_write_value(client, reg, (gl520_read_value(client, reg) & ~0xc0) | (r << 6));
+		gl520_write_value(client, reg, (gl520_read_value(client, reg) 
+					& ~0xc0) | (r << 6));
 	else
-		gl520_write_value(client, reg, (gl520_read_value(client, reg) & ~0x30) | (r << 4));
+		gl520_write_value(client, reg, (gl520_read_value(client, reg) 
+					& ~0x30) | (r << 4));
 
+	up(&data->update_lock);
 	return count;
 }
 
@@ -412,9 +428,12 @@
 {
 	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));
+	gl520_write_value(client, reg, (gl520_read_value(client, reg) 
+				& ~0x0c) | (r << 2));
 
+	up(&data->update_lock);
 	return count;
 }
 
@@ -439,22 +458,28 @@
 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);
+
+	down(&data->update_lock);
 	u8 r = TEMP_TO_REG(v);
 
 	data->temp_max[n - 1] = r;
 	gl520_write_value(client, reg, r);
 
+	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);
+
+	down(&data->update_lock);
 	u8 r = TEMP_TO_REG(v);
 
 	data->temp_max_hyst[n - 1] = r;
 	gl520_write_value(client, reg, r);
 
+	up(&data->update_lock);
 	return count;
 }
 
@@ -477,19 +502,24 @@
 {
 	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));
+	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)
 {
+	down(&data->update_lock);
 	u8 r = simple_strtoul(buf, NULL, 10) & data->alarm_mask;
 
 	data->beep_mask = r;
 	gl520_write_value(client, reg, r);
 
+	up(&data->update_lock);
 	return count;
 }
 
diff -Nur linux-2.6.12-rc1-mm3/drivers/i2c/chips/max1619.c linux-2.6.12-rc1-mm3b/drivers/i2c/chips/max1619.c
--- linux-2.6.12-rc1-mm3/drivers/i2c/chips/max1619.c	2005-03-23 06:34:25.000000000 +1100
+++ linux-2.6.12-rc1-mm3b/drivers/i2c/chips/max1619.c	2005-03-26 11:40:20.000000000 +1100
@@ -141,8 +141,11 @@
 	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 -Nur linux-2.6.12-rc1-mm3/drivers/i2c/chips/pcf8574.c linux-2.6.12-rc1-mm3b/drivers/i2c/chips/pcf8574.c
--- linux-2.6.12-rc1-mm3/drivers/i2c/chips/pcf8574.c	2005-03-23 06:34:26.000000000 +1100
+++ linux-2.6.12-rc1-mm3b/drivers/i2c/chips/pcf8574.c	2005-03-26 11:40:20.000000000 +1100
@@ -97,8 +97,11 @@
 {
 	struct i2c_client *client = to_i2c_client(dev);
 	struct pcf8574_data *data = i2c_get_clientdata(client);
+
+	down(&data->update_lock);
 	data->write = simple_strtoul(buf, NULL, 10);
 	i2c_smbus_write_byte(client, data->write);
+	up(&data->update_lock);
 	return count;
 }
 
diff -Nur linux-2.6.12-rc1-mm3/drivers/i2c/chips/pcf8591.c linux-2.6.12-rc1-mm3b/drivers/i2c/chips/pcf8591.c
--- linux-2.6.12-rc1-mm3/drivers/i2c/chips/pcf8591.c	2005-03-23 06:34:26.000000000 +1100
+++ linux-2.6.12-rc1-mm3b/drivers/i2c/chips/pcf8591.c	2005-03-26 11:40:20.000000000 +1100
@@ -124,8 +124,11 @@
 	struct i2c_client *client = to_i2c_client(dev);
 	struct pcf8591_data *data = i2c_get_clientdata(client);
 	if ((value = (simple_strtoul(buf, NULL, 10) + 5) / 10) <= 255) {
+
+		down(&data->update_lock);
 		data->aout = value;
 		i2c_smbus_write_byte_data(client, data->control, data->aout);
+		up(&data->update_lock);
 		return count;
 	}
 	return -EINVAL;
@@ -144,11 +147,14 @@
 {
 	struct i2c_client *client = to_i2c_client(dev);
 	struct pcf8591_data *data = i2c_get_clientdata(client);
+
+	down(&data->update_lock);
 	if (simple_strtoul(buf, NULL, 10))
 		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 -Nur linux-2.6.12-rc1-mm3/drivers/i2c/chips/sis5595.c linux-2.6.12-rc1-mm3b/drivers/i2c/chips/sis5595.c
--- linux-2.6.12-rc1-mm3/drivers/i2c/chips/sis5595.c	2005-03-23 06:34:26.000000000 +1100
+++ linux-2.6.12-rc1-mm3b/drivers/i2c/chips/sis5595.c	2005-03-26 11:40:20.000000000 +1100
@@ -232,8 +232,11 @@
 	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 @@
 	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 @@
 	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 @@
 	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 @@
 	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,14 @@
 {
 	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 +404,7 @@
 	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 +420,7 @@
 	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 -Nur linux-2.6.12-rc1-mm3/drivers/i2c/chips/via686a.c linux-2.6.12-rc1-mm3b/drivers/i2c/chips/via686a.c
--- linux-2.6.12-rc1-mm3/drivers/i2c/chips/via686a.c	2005-03-23 06:34:26.000000000 +1100
+++ linux-2.6.12-rc1-mm3b/drivers/i2c/chips/via686a.c	2005-03-26 11:40:20.000000000 +1100
@@ -363,9 +363,12 @@
 	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 @@
 	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 @@
 	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 @@
 	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 @@
 	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,13 @@
 	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);
 	int 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 -Nur linux-2.6.12-rc1-mm3/drivers/i2c/chips/w83627hf.c linux-2.6.12-rc1-mm3b/drivers/i2c/chips/w83627hf.c
--- linux-2.6.12-rc1-mm3/drivers/i2c/chips/w83627hf.c	2005-03-26 07:26:41.000000000 +1100
+++ linux-2.6.12-rc1-mm3b/drivers/i2c/chips/w83627hf.c	2005-03-26 11:40:20.000000000 +1100
@@ -354,10 +354,13 @@
 	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 @@
 	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 @@
 		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 @@
 	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 @@
 		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 @@
 	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;
 }
 
@@ -573,6 +587,8 @@
 	u32 val; \
 	 \
 	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); \
@@ -584,6 +600,7 @@
 			data->temp_##reg); \
 	} \
 	 \
+	up(&data->update_lock); \
 	return count; \
 }
 store_temp_reg(OVER, max);
@@ -692,6 +709,8 @@
 
 	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 @@
 	w83627hf_write_value(client, W83781D_REG_BEEP_INTS2,
 			    val2 | data->beep_enable << 7);
 
+	up(&data->update_lock);
 	return count;
 }
 
@@ -753,6 +773,8 @@
 	unsigned long min;
 	u8 reg;
 
+	down(&data->update_lock);
+
 	/* Save fan_min */
 	min = FAN_FROM_REG(data->fan_min[nr],
 			   DIV_FROM_REG(data->fan_div[nr]));
@@ -773,6 +795,7 @@
 	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 +838,8 @@
 
 	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 +855,7 @@
 				     data->pwm[nr - 1]);
 	}
 
+	up(&data->update_lock);
 	return count;
 }
 
@@ -871,6 +897,8 @@
 
 	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 +931,7 @@
 		break;
 	}
 
+	up(&data->update_lock);
 	return count;
 }
 
diff -Nur linux-2.6.12-rc1-mm3/drivers/i2c/chips/w83781d.c linux-2.6.12-rc1-mm3b/drivers/i2c/chips/w83781d.c
--- linux-2.6.12-rc1-mm3/drivers/i2c/chips/w83781d.c	2005-03-23 06:34:26.000000000 +1100
+++ linux-2.6.12-rc1-mm3b/drivers/i2c/chips/w83781d.c	2005-03-26 11:40:20.000000000 +1100
@@ -302,9 +302,12 @@
 	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);
@@ -369,11 +372,14 @@
 	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;
 }
 
@@ -431,6 +437,8 @@
 	s32 val; \
 	 \
 	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); \
@@ -442,6 +450,7 @@
 			data->temp_##reg); \
 	} \
 	 \
+	up(&data->update_lock); \
 	return count; \
 }
 store_temp_reg(OVER, max);
@@ -554,6 +563,8 @@
 
 	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,
@@ -573,6 +584,7 @@
 	w83781d_write_value(client, W83781D_REG_BEEP_INTS2,
 			    val2 | data->beep_enable << 7);
 
+	up(&data->update_lock);
 	return count;
 }
 
@@ -616,6 +628,8 @@
 	unsigned long min;
 	u8 reg;
 
+	down(&data->update_lock);
+	
 	/* Save fan_min */
 	min = FAN_FROM_REG(data->fan_min[nr],
 			   DIV_FROM_REG(data->fan_div[nr]));
@@ -640,6 +654,7 @@
 	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;
 }
 
@@ -686,9 +701,12 @@
 
 	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;
 }
 
@@ -701,6 +719,8 @@
 
 	val = simple_strtoul(buf, NULL, 10);
 
+	down(&data->update_lock);
+
 	switch (val) {
 	case 0:
 	case 1:
@@ -716,9 +736,11 @@
 		break;
 
 	default:
+		up(&data->update_lock);
 		return -EINVAL;
 	}
 
+	up(&data->update_lock);
 	return count;
 }
 
@@ -780,6 +802,8 @@
 
 	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);
@@ -811,6 +835,7 @@
 		break;
 	}
 
+	up(&data->update_lock);
 	return count;
 }
 
@@ -859,6 +884,8 @@
 	struct w83781d_data *data = i2c_get_clientdata(client);
 	u32 val, i;
 
+	down(&data->update_lock);
+
 	for (i = 0; i < count; i++) {
 		val = simple_strtoul(buf + count, NULL, 10);
 
@@ -869,6 +896,7 @@
 				    data->rt[nr - 1][i]);
 	}
 
+	up(&data->update_lock);
 	return count;
 }
 



[Index of Archives]     [Linux Kernel]     [Linux Hardware Monitoring]     [Linux USB Devel]     [Linux Audio Users]     [Linux Kernel]     [Linux SCSI]     [Yosemite Backpacking]

  Powered by Linux