aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/hwmon/adt7411.c
diff options
context:
space:
mode:
authorWolfram Sang <w.sang@pengutronix.de>2010-03-05 16:17:23 -0500
committerJean Delvare <khali@linux-fr.org>2010-03-05 16:17:23 -0500
commit232449850229deeda84194e8a3c93a49ab6a043e (patch)
treef9c6f1f51b2cd1ed84b873e87e500778f5e385e7 /drivers/hwmon/adt7411.c
parentd84ca5b345c2b77ebf053d534ada6af2332a43b6 (diff)
hwmon: (adt7411) Improve locking
Add proper locking for the cached variables. Also get rid of ref_is_vdd, which became obsolete. Signed-off-by: Wolfram Sang <w.sang@pengutronix.de> Signed-off-by: Jean Delvare <khali@linux-fr.org>
Diffstat (limited to 'drivers/hwmon/adt7411.c')
-rw-r--r--drivers/hwmon/adt7411.c21
1 files changed, 14 insertions, 7 deletions
diff --git a/drivers/hwmon/adt7411.c b/drivers/hwmon/adt7411.c
index 9e9246fe2245..3471884e42d2 100644
--- a/drivers/hwmon/adt7411.c
+++ b/drivers/hwmon/adt7411.c
@@ -48,9 +48,9 @@ static const unsigned short normal_i2c[] = { 0x48, 0x4a, 0x4b, I2C_CLIENT_END };
48 48
49struct adt7411_data { 49struct adt7411_data {
50 struct mutex device_lock; /* for "atomic" device accesses */ 50 struct mutex device_lock; /* for "atomic" device accesses */
51 struct mutex update_lock;
51 unsigned long next_update; 52 unsigned long next_update;
52 int vref_cached; 53 int vref_cached;
53 bool ref_is_vdd;
54 struct device *hwmon_dev; 54 struct device *hwmon_dev;
55}; 55};
56 56
@@ -142,18 +142,18 @@ static ssize_t adt7411_show_input(struct device *dev,
142 int val; 142 int val;
143 u8 lsb_reg, lsb_shift; 143 u8 lsb_reg, lsb_shift;
144 144
145 mutex_lock(&data->update_lock);
145 if (time_after_eq(jiffies, data->next_update)) { 146 if (time_after_eq(jiffies, data->next_update)) {
146 val = i2c_smbus_read_byte_data(client, ADT7411_REG_CFG3); 147 val = i2c_smbus_read_byte_data(client, ADT7411_REG_CFG3);
147 if (val < 0) 148 if (val < 0)
148 return val; 149 goto exit_unlock;
149 data->ref_is_vdd = val & ADT7411_CFG3_REF_VDD;
150 150
151 if (data->ref_is_vdd) { 151 if (val & ADT7411_CFG3_REF_VDD) {
152 val = adt7411_read_10_bit(client, 152 val = adt7411_read_10_bit(client,
153 ADT7411_REG_INT_TEMP_VDD_LSB, 153 ADT7411_REG_INT_TEMP_VDD_LSB,
154 ADT7411_REG_VDD_MSB, 2); 154 ADT7411_REG_VDD_MSB, 2);
155 if (val < 0) 155 if (val < 0)
156 return val; 156 goto exit_unlock;
157 157
158 data->vref_cached = val * 7000 / 1024; 158 data->vref_cached = val * 7000 / 1024;
159 } else { 159 } else {
@@ -167,9 +167,13 @@ static ssize_t adt7411_show_input(struct device *dev,
167 lsb_shift = 2 * (nr & 0x03); 167 lsb_shift = 2 * (nr & 0x03);
168 val = adt7411_read_10_bit(client, lsb_reg, 168 val = adt7411_read_10_bit(client, lsb_reg,
169 ADT7411_REG_EXT_TEMP_AIN1_MSB + nr, lsb_shift); 169 ADT7411_REG_EXT_TEMP_AIN1_MSB + nr, lsb_shift);
170 if (val < 0)
171 goto exit_unlock;
170 172
171 return val < 0 ? val : 173 val = sprintf(buf, "%u\n", val * data->vref_cached / 1024);
172 sprintf(buf, "%u\n", val * data->vref_cached / 1024); 174 exit_unlock:
175 mutex_unlock(&data->update_lock);
176 return val;
173} 177}
174 178
175static ssize_t adt7411_show_bit(struct device *dev, 179static ssize_t adt7411_show_bit(struct device *dev,
@@ -199,7 +203,9 @@ static ssize_t adt7411_set_bit(struct device *dev,
199 ret = adt7411_modify_bit(client, s_attr2->index, s_attr2->nr, flag); 203 ret = adt7411_modify_bit(client, s_attr2->index, s_attr2->nr, flag);
200 204
201 /* force update */ 205 /* force update */
206 mutex_lock(&data->update_lock);
202 data->next_update = jiffies; 207 data->next_update = jiffies;
208 mutex_unlock(&data->update_lock);
203 209
204 return ret < 0 ? ret : count; 210 return ret < 0 ? ret : count;
205} 211}
@@ -282,6 +288,7 @@ static int __devinit adt7411_probe(struct i2c_client *client,
282 288
283 i2c_set_clientdata(client, data); 289 i2c_set_clientdata(client, data);
284 mutex_init(&data->device_lock); 290 mutex_init(&data->device_lock);
291 mutex_init(&data->update_lock);
285 292
286 ret = adt7411_modify_bit(client, ADT7411_REG_CFG1, 293 ret = adt7411_modify_bit(client, ADT7411_REG_CFG1,
287 ADT7411_CFG1_START_MONITOR, 1); 294 ADT7411_CFG1_START_MONITOR, 1);