diff options
Diffstat (limited to 'drivers/hwmon/lm95241.c')
-rw-r--r-- | drivers/hwmon/lm95241.c | 112 |
1 files changed, 47 insertions, 65 deletions
diff --git a/drivers/hwmon/lm95241.c b/drivers/hwmon/lm95241.c index 091d95f38aaa..e34f9e402a2c 100644 --- a/drivers/hwmon/lm95241.c +++ b/drivers/hwmon/lm95241.c | |||
@@ -87,25 +87,11 @@ I2C_CLIENT_INSMOD_1(lm95241); | |||
87 | (val_h)) * 1000 + (val_l) * 1000 / 256) | 87 | (val_h)) * 1000 + (val_l) * 1000 / 256) |
88 | 88 | ||
89 | /* Functions declaration */ | 89 | /* Functions declaration */ |
90 | static int lm95241_attach_adapter(struct i2c_adapter *adapter); | ||
91 | static int lm95241_detect(struct i2c_adapter *adapter, int address, | ||
92 | int kind); | ||
93 | static void lm95241_init_client(struct i2c_client *client); | 90 | static void lm95241_init_client(struct i2c_client *client); |
94 | static int lm95241_detach_client(struct i2c_client *client); | ||
95 | static struct lm95241_data *lm95241_update_device(struct device *dev); | 91 | static struct lm95241_data *lm95241_update_device(struct device *dev); |
96 | 92 | ||
97 | /* Driver data (common to all clients) */ | ||
98 | static struct i2c_driver lm95241_driver = { | ||
99 | .driver = { | ||
100 | .name = "lm95241", | ||
101 | }, | ||
102 | .attach_adapter = lm95241_attach_adapter, | ||
103 | .detach_client = lm95241_detach_client, | ||
104 | }; | ||
105 | |||
106 | /* Client data (each client gets its own) */ | 93 | /* Client data (each client gets its own) */ |
107 | struct lm95241_data { | 94 | struct lm95241_data { |
108 | struct i2c_client client; | ||
109 | struct device *hwmon_dev; | 95 | struct device *hwmon_dev; |
110 | struct mutex update_lock; | 96 | struct mutex update_lock; |
111 | unsigned long last_updated, rate; /* in jiffies */ | 97 | unsigned long last_updated, rate; /* in jiffies */ |
@@ -323,42 +309,16 @@ static const struct attribute_group lm95241_group = { | |||
323 | .attrs = lm95241_attributes, | 309 | .attrs = lm95241_attributes, |
324 | }; | 310 | }; |
325 | 311 | ||
326 | /* Init/exit code */ | 312 | /* Return 0 if detection is successful, -ENODEV otherwise */ |
327 | static int lm95241_attach_adapter(struct i2c_adapter *adapter) | 313 | static int lm95241_detect(struct i2c_client *new_client, int kind, |
314 | struct i2c_board_info *info) | ||
328 | { | 315 | { |
329 | if (!(adapter->class & I2C_CLASS_HWMON)) | 316 | struct i2c_adapter *adapter = new_client->adapter; |
330 | return 0; | 317 | int address = new_client->addr; |
331 | return i2c_probe(adapter, &addr_data, lm95241_detect); | ||
332 | } | ||
333 | |||
334 | /* | ||
335 | * The following function does more than just detection. If detection | ||
336 | * succeeds, it also registers the new chip. | ||
337 | */ | ||
338 | static int lm95241_detect(struct i2c_adapter *adapter, int address, int kind) | ||
339 | { | ||
340 | struct i2c_client *new_client; | ||
341 | struct lm95241_data *data; | ||
342 | int err = 0; | ||
343 | const char *name = ""; | 318 | const char *name = ""; |
344 | 319 | ||
345 | if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) | 320 | if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) |
346 | goto exit; | 321 | return -ENODEV; |
347 | |||
348 | data = kzalloc(sizeof(struct lm95241_data), GFP_KERNEL); | ||
349 | if (!data) { | ||
350 | err = -ENOMEM; | ||
351 | goto exit; | ||
352 | } | ||
353 | |||
354 | /* The common I2C client data is placed right before the | ||
355 | LM95241-specific data. */ | ||
356 | new_client = &data->client; | ||
357 | i2c_set_clientdata(new_client, data); | ||
358 | new_client->addr = address; | ||
359 | new_client->adapter = adapter; | ||
360 | new_client->driver = &lm95241_driver; | ||
361 | new_client->flags = 0; | ||
362 | 322 | ||
363 | /* | 323 | /* |
364 | * Now we do the remaining detection. A negative kind means that | 324 | * Now we do the remaining detection. A negative kind means that |
@@ -378,7 +338,7 @@ static int lm95241_detect(struct i2c_adapter *adapter, int address, int kind) | |||
378 | dev_dbg(&adapter->dev, | 338 | dev_dbg(&adapter->dev, |
379 | "LM95241 detection failed at 0x%02x.\n", | 339 | "LM95241 detection failed at 0x%02x.\n", |
380 | address); | 340 | address); |
381 | goto exit_free; | 341 | return -ENODEV; |
382 | } | 342 | } |
383 | } | 343 | } |
384 | 344 | ||
@@ -392,23 +352,32 @@ static int lm95241_detect(struct i2c_adapter *adapter, int address, int kind) | |||
392 | 352 | ||
393 | if (kind <= 0) { /* identification failed */ | 353 | if (kind <= 0) { /* identification failed */ |
394 | dev_info(&adapter->dev, "Unsupported chip\n"); | 354 | dev_info(&adapter->dev, "Unsupported chip\n"); |
395 | goto exit_free; | 355 | return -ENODEV; |
396 | } | 356 | } |
397 | } | 357 | } |
398 | } | 358 | } |
399 | 359 | ||
360 | /* Fill the i2c board info */ | ||
400 | if (kind == lm95241) | 361 | if (kind == lm95241) |
401 | name = "lm95241"; | 362 | name = "lm95241"; |
363 | strlcpy(info->type, name, I2C_NAME_SIZE); | ||
364 | return 0; | ||
365 | } | ||
402 | 366 | ||
403 | /* We can fill in the remaining client fields */ | 367 | static int lm95241_probe(struct i2c_client *new_client, |
404 | strlcpy(new_client->name, name, I2C_NAME_SIZE); | 368 | const struct i2c_device_id *id) |
405 | data->valid = 0; | 369 | { |
406 | mutex_init(&data->update_lock); | 370 | struct lm95241_data *data; |
371 | int err; | ||
407 | 372 | ||
408 | /* Tell the I2C layer a new client has arrived */ | 373 | data = kzalloc(sizeof(struct lm95241_data), GFP_KERNEL); |
409 | err = i2c_attach_client(new_client); | 374 | if (!data) { |
410 | if (err) | 375 | err = -ENOMEM; |
411 | goto exit_free; | 376 | goto exit; |
377 | } | ||
378 | |||
379 | i2c_set_clientdata(new_client, data); | ||
380 | mutex_init(&data->update_lock); | ||
412 | 381 | ||
413 | /* Initialize the LM95241 chip */ | 382 | /* Initialize the LM95241 chip */ |
414 | lm95241_init_client(new_client); | 383 | lm95241_init_client(new_client); |
@@ -416,7 +385,7 @@ static int lm95241_detect(struct i2c_adapter *adapter, int address, int kind) | |||
416 | /* Register sysfs hooks */ | 385 | /* Register sysfs hooks */ |
417 | err = sysfs_create_group(&new_client->dev.kobj, &lm95241_group); | 386 | err = sysfs_create_group(&new_client->dev.kobj, &lm95241_group); |
418 | if (err) | 387 | if (err) |
419 | goto exit_detach; | 388 | goto exit_free; |
420 | 389 | ||
421 | data->hwmon_dev = hwmon_device_register(&new_client->dev); | 390 | data->hwmon_dev = hwmon_device_register(&new_client->dev); |
422 | if (IS_ERR(data->hwmon_dev)) { | 391 | if (IS_ERR(data->hwmon_dev)) { |
@@ -428,8 +397,6 @@ static int lm95241_detect(struct i2c_adapter *adapter, int address, int kind) | |||
428 | 397 | ||
429 | exit_remove_files: | 398 | exit_remove_files: |
430 | sysfs_remove_group(&new_client->dev.kobj, &lm95241_group); | 399 | sysfs_remove_group(&new_client->dev.kobj, &lm95241_group); |
431 | exit_detach: | ||
432 | i2c_detach_client(new_client); | ||
433 | exit_free: | 400 | exit_free: |
434 | kfree(data); | 401 | kfree(data); |
435 | exit: | 402 | exit: |
@@ -456,18 +423,14 @@ static void lm95241_init_client(struct i2c_client *client) | |||
456 | data->model); | 423 | data->model); |
457 | } | 424 | } |
458 | 425 | ||
459 | static int lm95241_detach_client(struct i2c_client *client) | 426 | static int lm95241_remove(struct i2c_client *client) |
460 | { | 427 | { |
461 | struct lm95241_data *data = i2c_get_clientdata(client); | 428 | struct lm95241_data *data = i2c_get_clientdata(client); |
462 | int err; | ||
463 | 429 | ||
464 | hwmon_device_unregister(data->hwmon_dev); | 430 | hwmon_device_unregister(data->hwmon_dev); |
465 | sysfs_remove_group(&client->dev.kobj, &lm95241_group); | 431 | sysfs_remove_group(&client->dev.kobj, &lm95241_group); |
466 | 432 | ||
467 | err = i2c_detach_client(client); | 433 | i2c_set_clientdata(client, NULL); |
468 | if (err) | ||
469 | return err; | ||
470 | |||
471 | kfree(data); | 434 | kfree(data); |
472 | return 0; | 435 | return 0; |
473 | } | 436 | } |
@@ -509,6 +472,25 @@ static struct lm95241_data *lm95241_update_device(struct device *dev) | |||
509 | return data; | 472 | return data; |
510 | } | 473 | } |
511 | 474 | ||
475 | /* Driver data (common to all clients) */ | ||
476 | static const struct i2c_device_id lm95241_id[] = { | ||
477 | { "lm95241", lm95241 }, | ||
478 | { } | ||
479 | }; | ||
480 | MODULE_DEVICE_TABLE(i2c, lm95241_id); | ||
481 | |||
482 | static struct i2c_driver lm95241_driver = { | ||
483 | .class = I2C_CLASS_HWMON, | ||
484 | .driver = { | ||
485 | .name = "lm95241", | ||
486 | }, | ||
487 | .probe = lm95241_probe, | ||
488 | .remove = lm95241_remove, | ||
489 | .id_table = lm95241_id, | ||
490 | .detect = lm95241_detect, | ||
491 | .address_data = &addr_data, | ||
492 | }; | ||
493 | |||
512 | static int __init sensors_lm95241_init(void) | 494 | static int __init sensors_lm95241_init(void) |
513 | { | 495 | { |
514 | return i2c_add_driver(&lm95241_driver); | 496 | return i2c_add_driver(&lm95241_driver); |