diff options
-rw-r--r-- | drivers/hwmon/tmp102.c | 38 |
1 files changed, 28 insertions, 10 deletions
diff --git a/drivers/hwmon/tmp102.c b/drivers/hwmon/tmp102.c index 0da695d800c5..8013895a1faf 100644 --- a/drivers/hwmon/tmp102.c +++ b/drivers/hwmon/tmp102.c | |||
@@ -50,6 +50,7 @@ | |||
50 | struct tmp102 { | 50 | struct tmp102 { |
51 | struct device *hwmon_dev; | 51 | struct device *hwmon_dev; |
52 | struct mutex lock; | 52 | struct mutex lock; |
53 | u16 config_orig; | ||
53 | unsigned long last_update; | 54 | unsigned long last_update; |
54 | int temp[3]; | 55 | int temp[3]; |
55 | }; | 56 | }; |
@@ -177,21 +178,27 @@ static int __devinit tmp102_probe(struct i2c_client *client, | |||
177 | } | 178 | } |
178 | i2c_set_clientdata(client, tmp102); | 179 | i2c_set_clientdata(client, tmp102); |
179 | 180 | ||
181 | status = tmp102_read_reg(client, TMP102_CONF_REG); | ||
182 | if (status < 0) { | ||
183 | dev_err(&client->dev, "error reading config register\n"); | ||
184 | goto fail_free; | ||
185 | } | ||
186 | tmp102->config_orig = status; | ||
180 | status = tmp102_write_reg(client, TMP102_CONF_REG, TMP102_CONFIG); | 187 | status = tmp102_write_reg(client, TMP102_CONF_REG, TMP102_CONFIG); |
181 | if (status < 0) { | 188 | if (status < 0) { |
182 | dev_err(&client->dev, "error writing config register\n"); | 189 | dev_err(&client->dev, "error writing config register\n"); |
183 | goto fail0; | 190 | goto fail_restore_config; |
184 | } | 191 | } |
185 | status = tmp102_read_reg(client, TMP102_CONF_REG); | 192 | status = tmp102_read_reg(client, TMP102_CONF_REG); |
186 | if (status < 0) { | 193 | if (status < 0) { |
187 | dev_err(&client->dev, "error reading config register\n"); | 194 | dev_err(&client->dev, "error reading config register\n"); |
188 | goto fail0; | 195 | goto fail_restore_config; |
189 | } | 196 | } |
190 | status &= ~TMP102_CONFIG_RD_ONLY; | 197 | status &= ~TMP102_CONFIG_RD_ONLY; |
191 | if (status != TMP102_CONFIG) { | 198 | if (status != TMP102_CONFIG) { |
192 | dev_err(&client->dev, "config settings did not stick\n"); | 199 | dev_err(&client->dev, "config settings did not stick\n"); |
193 | status = -ENODEV; | 200 | status = -ENODEV; |
194 | goto fail0; | 201 | goto fail_restore_config; |
195 | } | 202 | } |
196 | tmp102->last_update = jiffies - HZ; | 203 | tmp102->last_update = jiffies - HZ; |
197 | mutex_init(&tmp102->lock); | 204 | mutex_init(&tmp102->lock); |
@@ -199,21 +206,24 @@ static int __devinit tmp102_probe(struct i2c_client *client, | |||
199 | status = sysfs_create_group(&client->dev.kobj, &tmp102_attr_group); | 206 | status = sysfs_create_group(&client->dev.kobj, &tmp102_attr_group); |
200 | if (status) { | 207 | if (status) { |
201 | dev_dbg(&client->dev, "could not create sysfs files\n"); | 208 | dev_dbg(&client->dev, "could not create sysfs files\n"); |
202 | goto fail0; | 209 | goto fail_restore_config; |
203 | } | 210 | } |
204 | tmp102->hwmon_dev = hwmon_device_register(&client->dev); | 211 | tmp102->hwmon_dev = hwmon_device_register(&client->dev); |
205 | if (IS_ERR(tmp102->hwmon_dev)) { | 212 | if (IS_ERR(tmp102->hwmon_dev)) { |
206 | dev_dbg(&client->dev, "unable to register hwmon device\n"); | 213 | dev_dbg(&client->dev, "unable to register hwmon device\n"); |
207 | status = PTR_ERR(tmp102->hwmon_dev); | 214 | status = PTR_ERR(tmp102->hwmon_dev); |
208 | goto fail1; | 215 | goto fail_remove_sysfs; |
209 | } | 216 | } |
210 | 217 | ||
211 | dev_info(&client->dev, "initialized\n"); | 218 | dev_info(&client->dev, "initialized\n"); |
212 | 219 | ||
213 | return 0; | 220 | return 0; |
214 | fail1: | 221 | |
222 | fail_remove_sysfs: | ||
215 | sysfs_remove_group(&client->dev.kobj, &tmp102_attr_group); | 223 | sysfs_remove_group(&client->dev.kobj, &tmp102_attr_group); |
216 | fail0: | 224 | fail_restore_config: |
225 | tmp102_write_reg(client, TMP102_CONF_REG, tmp102->config_orig); | ||
226 | fail_free: | ||
217 | i2c_set_clientdata(client, NULL); | 227 | i2c_set_clientdata(client, NULL); |
218 | kfree(tmp102); | 228 | kfree(tmp102); |
219 | 229 | ||
@@ -224,11 +234,19 @@ static int __devexit tmp102_remove(struct i2c_client *client) | |||
224 | { | 234 | { |
225 | struct tmp102 *tmp102 = i2c_get_clientdata(client); | 235 | struct tmp102 *tmp102 = i2c_get_clientdata(client); |
226 | 236 | ||
227 | /* shutdown the chip */ | ||
228 | tmp102_write_reg(client, TMP102_CONF_REG, TMP102_CONF_SD); | ||
229 | |||
230 | hwmon_device_unregister(tmp102->hwmon_dev); | 237 | hwmon_device_unregister(tmp102->hwmon_dev); |
231 | sysfs_remove_group(&client->dev.kobj, &tmp102_attr_group); | 238 | sysfs_remove_group(&client->dev.kobj, &tmp102_attr_group); |
239 | |||
240 | /* Stop monitoring if device was stopped originally */ | ||
241 | if (tmp102->config_orig & TMP102_CONF_SD) { | ||
242 | int config; | ||
243 | |||
244 | config = tmp102_read_reg(client, TMP102_CONF_REG); | ||
245 | if (config >= 0) | ||
246 | tmp102_write_reg(client, TMP102_CONF_REG, | ||
247 | config | TMP102_CONF_SD); | ||
248 | } | ||
249 | |||
232 | i2c_set_clientdata(client, NULL); | 250 | i2c_set_clientdata(client, NULL); |
233 | kfree(tmp102); | 251 | kfree(tmp102); |
234 | 252 | ||