diff options
Diffstat (limited to 'drivers/hwmon')
-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) |