diff options
| -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); |
