diff options
author | Wolfram Sang <w.sang@pengutronix.de> | 2010-03-05 16:17:23 -0500 |
---|---|---|
committer | Jean Delvare <khali@linux-fr.org> | 2010-03-05 16:17:23 -0500 |
commit | 232449850229deeda84194e8a3c93a49ab6a043e (patch) | |
tree | f9c6f1f51b2cd1ed84b873e87e500778f5e385e7 /drivers/hwmon | |
parent | d84ca5b345c2b77ebf053d534ada6af2332a43b6 (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')
-rw-r--r-- | drivers/hwmon/adt7411.c | 21 |
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 | ||
49 | struct adt7411_data { | 49 | struct 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 | ||
175 | static ssize_t adt7411_show_bit(struct device *dev, | 179 | static 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); |