diff options
Diffstat (limited to 'drivers')
| -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 | ||
