aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJean Delvare <khali@linux-fr.org>2010-05-27 13:58:59 -0400
committerJean Delvare <khali@linux-fr.org>2010-05-27 13:58:59 -0400
commit38806bda6b7c8473c47a967a514260c1a1c32c2e (patch)
treee52a767e565e0f6361c34a77418b6cd68e292b70
parent8d4dee98b10050db9c32a449e460a2f69bb558ec (diff)
hwmon: (tmp102) Don't always stop chip at exit
Only stop the chip at driver exit if it was stopped when driver was loaded. Leave it running otherwise. Also restore the device configuration if probe failed, to not leave the system in a dangling state. Signed-off-by: Jean Delvare <khali@linux-fr.org> Cc: Steven King <sfking@fdwdc.com>
-rw-r--r--drivers/hwmon/tmp102.c38
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 @@
50struct tmp102 { 50struct 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;
214fail1: 221
222fail_remove_sysfs:
215 sysfs_remove_group(&client->dev.kobj, &tmp102_attr_group); 223 sysfs_remove_group(&client->dev.kobj, &tmp102_attr_group);
216fail0: 224fail_restore_config:
225 tmp102_write_reg(client, TMP102_CONF_REG, tmp102->config_orig);
226fail_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