diff options
-rw-r--r-- | drivers/hwmon/atxp1.c | 109 |
1 files changed, 52 insertions, 57 deletions
diff --git a/drivers/hwmon/atxp1.c b/drivers/hwmon/atxp1.c index 01c17e387f03..d191118ba0cb 100644 --- a/drivers/hwmon/atxp1.c +++ b/drivers/hwmon/atxp1.c | |||
@@ -46,21 +46,32 @@ static const unsigned short normal_i2c[] = { 0x37, 0x4e, I2C_CLIENT_END }; | |||
46 | 46 | ||
47 | I2C_CLIENT_INSMOD_1(atxp1); | 47 | I2C_CLIENT_INSMOD_1(atxp1); |
48 | 48 | ||
49 | static int atxp1_attach_adapter(struct i2c_adapter * adapter); | 49 | static int atxp1_probe(struct i2c_client *client, |
50 | static int atxp1_detach_client(struct i2c_client * client); | 50 | const struct i2c_device_id *id); |
51 | static int atxp1_remove(struct i2c_client *client); | ||
51 | static struct atxp1_data * atxp1_update_device(struct device *dev); | 52 | static struct atxp1_data * atxp1_update_device(struct device *dev); |
52 | static int atxp1_detect(struct i2c_adapter *adapter, int address, int kind); | 53 | static int atxp1_detect(struct i2c_client *client, int kind, |
54 | struct i2c_board_info *info); | ||
55 | |||
56 | static const struct i2c_device_id atxp1_id[] = { | ||
57 | { "atxp1", atxp1 }, | ||
58 | { } | ||
59 | }; | ||
60 | MODULE_DEVICE_TABLE(i2c, atxp1_id); | ||
53 | 61 | ||
54 | static struct i2c_driver atxp1_driver = { | 62 | static struct i2c_driver atxp1_driver = { |
63 | .class = I2C_CLASS_HWMON, | ||
55 | .driver = { | 64 | .driver = { |
56 | .name = "atxp1", | 65 | .name = "atxp1", |
57 | }, | 66 | }, |
58 | .attach_adapter = atxp1_attach_adapter, | 67 | .probe = atxp1_probe, |
59 | .detach_client = atxp1_detach_client, | 68 | .remove = atxp1_remove, |
69 | .id_table = atxp1_id, | ||
70 | .detect = atxp1_detect, | ||
71 | .address_data = &addr_data, | ||
60 | }; | 72 | }; |
61 | 73 | ||
62 | struct atxp1_data { | 74 | struct atxp1_data { |
63 | struct i2c_client client; | ||
64 | struct device *hwmon_dev; | 75 | struct device *hwmon_dev; |
65 | struct mutex update_lock; | 76 | struct mutex update_lock; |
66 | unsigned long last_updated; | 77 | unsigned long last_updated; |
@@ -263,35 +274,16 @@ static const struct attribute_group atxp1_group = { | |||
263 | }; | 274 | }; |
264 | 275 | ||
265 | 276 | ||
266 | static int atxp1_attach_adapter(struct i2c_adapter *adapter) | 277 | /* Return 0 if detection is successful, -ENODEV otherwise */ |
278 | static int atxp1_detect(struct i2c_client *new_client, int kind, | ||
279 | struct i2c_board_info *info) | ||
267 | { | 280 | { |
268 | if (!(adapter->class & I2C_CLASS_HWMON)) | 281 | struct i2c_adapter *adapter = new_client->adapter; |
269 | return 0; | ||
270 | return i2c_probe(adapter, &addr_data, &atxp1_detect); | ||
271 | }; | ||
272 | 282 | ||
273 | static int atxp1_detect(struct i2c_adapter *adapter, int address, int kind) | ||
274 | { | ||
275 | struct i2c_client * new_client; | ||
276 | struct atxp1_data * data; | ||
277 | int err = 0; | ||
278 | u8 temp; | 283 | u8 temp; |
279 | 284 | ||
280 | if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) | 285 | if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) |
281 | goto exit; | 286 | return -ENODEV; |
282 | |||
283 | if (!(data = kzalloc(sizeof(struct atxp1_data), GFP_KERNEL))) { | ||
284 | err = -ENOMEM; | ||
285 | goto exit; | ||
286 | } | ||
287 | |||
288 | new_client = &data->client; | ||
289 | i2c_set_clientdata(new_client, data); | ||
290 | |||
291 | new_client->addr = address; | ||
292 | new_client->adapter = adapter; | ||
293 | new_client->driver = &atxp1_driver; | ||
294 | new_client->flags = 0; | ||
295 | 287 | ||
296 | /* Detect ATXP1, checking if vendor ID registers are all zero */ | 288 | /* Detect ATXP1, checking if vendor ID registers are all zero */ |
297 | if (!((i2c_smbus_read_byte_data(new_client, 0x3e) == 0) && | 289 | if (!((i2c_smbus_read_byte_data(new_client, 0x3e) == 0) && |
@@ -305,35 +297,46 @@ static int atxp1_detect(struct i2c_adapter *adapter, int address, int kind) | |||
305 | 297 | ||
306 | if (!((i2c_smbus_read_byte_data(new_client, 0x10) == temp) && | 298 | if (!((i2c_smbus_read_byte_data(new_client, 0x10) == temp) && |
307 | (i2c_smbus_read_byte_data(new_client, 0x11) == temp) )) | 299 | (i2c_smbus_read_byte_data(new_client, 0x11) == temp) )) |
308 | goto exit_free; | 300 | return -ENODEV; |
309 | } | 301 | } |
310 | 302 | ||
311 | /* Get VRM */ | 303 | /* Get VRM */ |
312 | data->vrm = vid_which_vrm(); | 304 | temp = vid_which_vrm(); |
313 | 305 | ||
314 | if ((data->vrm != 90) && (data->vrm != 91)) { | 306 | if ((temp != 90) && (temp != 91)) { |
315 | dev_err(&new_client->dev, "Not supporting VRM %d.%d\n", | 307 | dev_err(&adapter->dev, "atxp1: Not supporting VRM %d.%d\n", |
316 | data->vrm / 10, data->vrm % 10); | 308 | temp / 10, temp % 10); |
317 | goto exit_free; | 309 | return -ENODEV; |
318 | } | 310 | } |
319 | 311 | ||
320 | strncpy(new_client->name, "atxp1", I2C_NAME_SIZE); | 312 | strlcpy(info->type, "atxp1", I2C_NAME_SIZE); |
321 | |||
322 | data->valid = 0; | ||
323 | 313 | ||
324 | mutex_init(&data->update_lock); | 314 | return 0; |
315 | } | ||
325 | 316 | ||
326 | err = i2c_attach_client(new_client); | 317 | static int atxp1_probe(struct i2c_client *new_client, |
318 | const struct i2c_device_id *id) | ||
319 | { | ||
320 | struct atxp1_data *data; | ||
321 | int err; | ||
327 | 322 | ||
328 | if (err) | 323 | data = kzalloc(sizeof(struct atxp1_data), GFP_KERNEL); |
329 | { | 324 | if (!data) { |
330 | dev_err(&new_client->dev, "Attach client error.\n"); | 325 | err = -ENOMEM; |
331 | goto exit_free; | 326 | goto exit; |
332 | } | 327 | } |
333 | 328 | ||
329 | /* Get VRM */ | ||
330 | data->vrm = vid_which_vrm(); | ||
331 | |||
332 | i2c_set_clientdata(new_client, data); | ||
333 | data->valid = 0; | ||
334 | |||
335 | mutex_init(&data->update_lock); | ||
336 | |||
334 | /* Register sysfs hooks */ | 337 | /* Register sysfs hooks */ |
335 | if ((err = sysfs_create_group(&new_client->dev.kobj, &atxp1_group))) | 338 | if ((err = sysfs_create_group(&new_client->dev.kobj, &atxp1_group))) |
336 | goto exit_detach; | 339 | goto exit_free; |
337 | 340 | ||
338 | data->hwmon_dev = hwmon_device_register(&new_client->dev); | 341 | data->hwmon_dev = hwmon_device_register(&new_client->dev); |
339 | if (IS_ERR(data->hwmon_dev)) { | 342 | if (IS_ERR(data->hwmon_dev)) { |
@@ -348,30 +351,22 @@ static int atxp1_detect(struct i2c_adapter *adapter, int address, int kind) | |||
348 | 351 | ||
349 | exit_remove_files: | 352 | exit_remove_files: |
350 | sysfs_remove_group(&new_client->dev.kobj, &atxp1_group); | 353 | sysfs_remove_group(&new_client->dev.kobj, &atxp1_group); |
351 | exit_detach: | ||
352 | i2c_detach_client(new_client); | ||
353 | exit_free: | 354 | exit_free: |
354 | kfree(data); | 355 | kfree(data); |
355 | exit: | 356 | exit: |
356 | return err; | 357 | return err; |
357 | }; | 358 | }; |
358 | 359 | ||
359 | static int atxp1_detach_client(struct i2c_client * client) | 360 | static int atxp1_remove(struct i2c_client *client) |
360 | { | 361 | { |
361 | struct atxp1_data * data = i2c_get_clientdata(client); | 362 | struct atxp1_data * data = i2c_get_clientdata(client); |
362 | int err; | ||
363 | 363 | ||
364 | hwmon_device_unregister(data->hwmon_dev); | 364 | hwmon_device_unregister(data->hwmon_dev); |
365 | sysfs_remove_group(&client->dev.kobj, &atxp1_group); | 365 | sysfs_remove_group(&client->dev.kobj, &atxp1_group); |
366 | 366 | ||
367 | err = i2c_detach_client(client); | 367 | kfree(data); |
368 | |||
369 | if (err) | ||
370 | dev_err(&client->dev, "Failed to detach client.\n"); | ||
371 | else | ||
372 | kfree(data); | ||
373 | 368 | ||
374 | return err; | 369 | return 0; |
375 | }; | 370 | }; |
376 | 371 | ||
377 | static int __init atxp1_init(void) | 372 | static int __init atxp1_init(void) |