diff options
| -rw-r--r-- | drivers/hwmon/lm92.c | 98 |
1 files changed, 40 insertions, 58 deletions
diff --git a/drivers/hwmon/lm92.c b/drivers/hwmon/lm92.c index c31942e08246..b2e00c5a7eec 100644 --- a/drivers/hwmon/lm92.c +++ b/drivers/hwmon/lm92.c | |||
| @@ -1,6 +1,6 @@ | |||
| 1 | /* | 1 | /* |
| 2 | * lm92 - Hardware monitoring driver | 2 | * lm92 - Hardware monitoring driver |
| 3 | * Copyright (C) 2005 Jean Delvare <khali@linux-fr.org> | 3 | * Copyright (C) 2005-2008 Jean Delvare <khali@linux-fr.org> |
| 4 | * | 4 | * |
| 5 | * Based on the lm90 driver, with some ideas taken from the lm_sensors | 5 | * Based on the lm90 driver, with some ideas taken from the lm_sensors |
| 6 | * lm92 driver as well. | 6 | * lm92 driver as well. |
| @@ -96,7 +96,6 @@ static struct i2c_driver lm92_driver; | |||
| 96 | 96 | ||
| 97 | /* Client data (each client gets its own) */ | 97 | /* Client data (each client gets its own) */ |
| 98 | struct lm92_data { | 98 | struct lm92_data { |
| 99 | struct i2c_client client; | ||
| 100 | struct device *hwmon_dev; | 99 | struct device *hwmon_dev; |
| 101 | struct mutex update_lock; | 100 | struct mutex update_lock; |
| 102 | char valid; /* zero until following fields are valid */ | 101 | char valid; /* zero until following fields are valid */ |
| @@ -319,32 +318,15 @@ static const struct attribute_group lm92_group = { | |||
| 319 | .attrs = lm92_attributes, | 318 | .attrs = lm92_attributes, |
| 320 | }; | 319 | }; |
| 321 | 320 | ||
| 322 | /* The following function does more than just detection. If detection | 321 | /* Return 0 if detection is successful, -ENODEV otherwise */ |
| 323 | succeeds, it also registers the new chip. */ | 322 | static int lm92_detect(struct i2c_client *new_client, int kind, |
| 324 | static int lm92_detect(struct i2c_adapter *adapter, int address, int kind) | 323 | struct i2c_board_info *info) |
| 325 | { | 324 | { |
| 326 | struct i2c_client *new_client; | 325 | struct i2c_adapter *adapter = new_client->adapter; |
| 327 | struct lm92_data *data; | ||
| 328 | int err = 0; | ||
| 329 | char *name; | ||
| 330 | 326 | ||
| 331 | if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA | 327 | if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA |
| 332 | | I2C_FUNC_SMBUS_WORD_DATA)) | 328 | | I2C_FUNC_SMBUS_WORD_DATA)) |
| 333 | goto exit; | 329 | return -ENODEV; |
| 334 | |||
| 335 | if (!(data = kzalloc(sizeof(struct lm92_data), GFP_KERNEL))) { | ||
| 336 | err = -ENOMEM; | ||
| 337 | goto exit; | ||
| 338 | } | ||
| 339 | |||
| 340 | /* Fill in enough client fields so that we can read from the chip, | ||
| 341 | which is required for identication */ | ||
| 342 | new_client = &data->client; | ||
| 343 | i2c_set_clientdata(new_client, data); | ||
| 344 | new_client->addr = address; | ||
| 345 | new_client->adapter = adapter; | ||
| 346 | new_client->driver = &lm92_driver; | ||
| 347 | new_client->flags = 0; | ||
| 348 | 330 | ||
| 349 | /* A negative kind means that the driver was loaded with no force | 331 | /* A negative kind means that the driver was loaded with no force |
| 350 | parameter (default), so we must identify the chip. */ | 332 | parameter (default), so we must identify the chip. */ |
| @@ -364,34 +346,36 @@ static int lm92_detect(struct i2c_adapter *adapter, int address, int kind) | |||
| 364 | kind = lm92; /* No separate prefix */ | 346 | kind = lm92; /* No separate prefix */ |
| 365 | } | 347 | } |
| 366 | else | 348 | else |
| 367 | goto exit_free; | 349 | return -ENODEV; |
| 368 | } else | ||
| 369 | if (kind == 0) /* Default to an LM92 if forced */ | ||
| 370 | kind = lm92; | ||
| 371 | |||
| 372 | /* Give it the proper name */ | ||
| 373 | if (kind == lm92) { | ||
| 374 | name = "lm92"; | ||
| 375 | } else { /* Supposedly cannot happen */ | ||
| 376 | dev_dbg(&new_client->dev, "Kind out of range?\n"); | ||
| 377 | goto exit_free; | ||
| 378 | } | 350 | } |
| 379 | 351 | ||
| 380 | /* Fill in the remaining client fields */ | 352 | strlcpy(info->type, "lm92", I2C_NAME_SIZE); |
| 381 | strlcpy(new_client->name, name, I2C_NAME_SIZE); | 353 | |
| 354 | return 0; | ||
| 355 | } | ||
| 356 | |||
| 357 | static int lm92_probe(struct i2c_client *new_client, | ||
| 358 | const struct i2c_device_id *id) | ||
| 359 | { | ||
| 360 | struct lm92_data *data; | ||
| 361 | int err; | ||
| 362 | |||
| 363 | data = kzalloc(sizeof(struct lm92_data), GFP_KERNEL); | ||
| 364 | if (!data) { | ||
| 365 | err = -ENOMEM; | ||
| 366 | goto exit; | ||
| 367 | } | ||
| 368 | |||
| 369 | i2c_set_clientdata(new_client, data); | ||
| 382 | data->valid = 0; | 370 | data->valid = 0; |
| 383 | mutex_init(&data->update_lock); | 371 | mutex_init(&data->update_lock); |
| 384 | 372 | ||
| 385 | /* Tell the i2c subsystem a new client has arrived */ | ||
| 386 | if ((err = i2c_attach_client(new_client))) | ||
| 387 | goto exit_free; | ||
| 388 | |||
| 389 | /* Initialize the chipset */ | 373 | /* Initialize the chipset */ |
| 390 | lm92_init_client(new_client); | 374 | lm92_init_client(new_client); |
| 391 | 375 | ||
| 392 | /* Register sysfs hooks */ | 376 | /* Register sysfs hooks */ |
| 393 | if ((err = sysfs_create_group(&new_client->dev.kobj, &lm92_group))) | 377 | if ((err = sysfs_create_group(&new_client->dev.kobj, &lm92_group))) |
| 394 | goto exit_detach; | 378 | goto exit_free; |
| 395 | 379 | ||
| 396 | data->hwmon_dev = hwmon_device_register(&new_client->dev); | 380 | data->hwmon_dev = hwmon_device_register(&new_client->dev); |
| 397 | if (IS_ERR(data->hwmon_dev)) { | 381 | if (IS_ERR(data->hwmon_dev)) { |
| @@ -403,32 +387,19 @@ static int lm92_detect(struct i2c_adapter *adapter, int address, int kind) | |||
| 403 | 387 | ||
| 404 | exit_remove: | 388 | exit_remove: |
| 405 | sysfs_remove_group(&new_client->dev.kobj, &lm92_group); | 389 | sysfs_remove_group(&new_client->dev.kobj, &lm92_group); |
| 406 | exit_detach: | ||
| 407 | i2c_detach_client(new_client); | ||
| 408 | exit_free: | 390 | exit_free: |
| 409 | kfree(data); | 391 | kfree(data); |
| 410 | exit: | 392 | exit: |
| 411 | return err; | 393 | return err; |
| 412 | } | 394 | } |
| 413 | 395 | ||
| 414 | static int lm92_attach_adapter(struct i2c_adapter *adapter) | 396 | static int lm92_remove(struct i2c_client *client) |
| 415 | { | ||
| 416 | if (!(adapter->class & I2C_CLASS_HWMON)) | ||
| 417 | return 0; | ||
| 418 | return i2c_probe(adapter, &addr_data, lm92_detect); | ||
| 419 | } | ||
| 420 | |||
| 421 | static int lm92_detach_client(struct i2c_client *client) | ||
| 422 | { | 397 | { |
| 423 | struct lm92_data *data = i2c_get_clientdata(client); | 398 | struct lm92_data *data = i2c_get_clientdata(client); |
| 424 | int err; | ||
| 425 | 399 | ||
| 426 | hwmon_device_unregister(data->hwmon_dev); | 400 | hwmon_device_unregister(data->hwmon_dev); |
| 427 | sysfs_remove_group(&client->dev.kobj, &lm92_group); | 401 | sysfs_remove_group(&client->dev.kobj, &lm92_group); |
| 428 | 402 | ||
| 429 | if ((err = i2c_detach_client(client))) | ||
| 430 | return err; | ||
| 431 | |||
| 432 | kfree(data); | 403 | kfree(data); |
| 433 | return 0; | 404 | return 0; |
| 434 | } | 405 | } |
| @@ -438,12 +409,23 @@ static int lm92_detach_client(struct i2c_client *client) | |||
| 438 | * Module and driver stuff | 409 | * Module and driver stuff |
| 439 | */ | 410 | */ |
| 440 | 411 | ||
| 412 | static const struct i2c_device_id lm92_id[] = { | ||
| 413 | { "lm92", lm92 }, | ||
| 414 | /* max6635 could be added here */ | ||
| 415 | { } | ||
| 416 | }; | ||
| 417 | MODULE_DEVICE_TABLE(i2c, lm92_id); | ||
| 418 | |||
| 441 | static struct i2c_driver lm92_driver = { | 419 | static struct i2c_driver lm92_driver = { |
| 420 | .class = I2C_CLASS_HWMON, | ||
| 442 | .driver = { | 421 | .driver = { |
| 443 | .name = "lm92", | 422 | .name = "lm92", |
| 444 | }, | 423 | }, |
| 445 | .attach_adapter = lm92_attach_adapter, | 424 | .probe = lm92_probe, |
| 446 | .detach_client = lm92_detach_client, | 425 | .remove = lm92_remove, |
| 426 | .id_table = lm92_id, | ||
| 427 | .detect = lm92_detect, | ||
| 428 | .address_data = &addr_data, | ||
| 447 | }; | 429 | }; |
| 448 | 430 | ||
| 449 | static int __init sensors_lm92_init(void) | 431 | static int __init sensors_lm92_init(void) |
