diff options
| author | Greg Kroah-Hartman <gregkh@suse.de> | 2005-12-06 18:33:15 -0500 |
|---|---|---|
| committer | Greg Kroah-Hartman <gregkh@suse.de> | 2006-01-06 01:16:25 -0500 |
| commit | 79472132f555ae1e912699e116e5c82f338872f6 (patch) | |
| tree | 5f2b69e43b8797cab242f6524f6bb0d55694c849 /drivers/i2c | |
| parent | d82c0bf88fa97c1993ea9d6051488e7cb012b440 (diff) | |
[PATCH] I2C: move i2c-dev to use dynamic class devices
i2c-dev doesn't use the reference counting logic of struct class_device so move
it to the dynamic method. This makes the code paths simpler and the driver
smaller.
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
Cc: Jean Delvare <khali@linux-fr.org>
Diffstat (limited to 'drivers/i2c')
| -rw-r--r-- | drivers/i2c/i2c-dev.c | 50 |
1 files changed, 20 insertions, 30 deletions
diff --git a/drivers/i2c/i2c-dev.c b/drivers/i2c/i2c-dev.c index e140dd7d6a0c..ad6e04fc2c03 100644 --- a/drivers/i2c/i2c-dev.c +++ b/drivers/i2c/i2c-dev.c | |||
| @@ -42,8 +42,7 @@ static struct i2c_client i2cdev_client_template; | |||
| 42 | struct i2c_dev { | 42 | struct i2c_dev { |
| 43 | int minor; | 43 | int minor; |
| 44 | struct i2c_adapter *adap; | 44 | struct i2c_adapter *adap; |
| 45 | struct class_device class_dev; | 45 | struct class_device *class_dev; |
| 46 | struct completion released; /* FIXME, we need a class_device_unregister() */ | ||
| 47 | }; | 46 | }; |
| 48 | #define to_i2c_dev(d) container_of(d, struct i2c_dev, class_dev) | 47 | #define to_i2c_dev(d) container_of(d, struct i2c_dev, class_dev) |
| 49 | 48 | ||
| @@ -105,7 +104,10 @@ static void return_i2c_dev(struct i2c_dev *i2c_dev) | |||
| 105 | 104 | ||
| 106 | static ssize_t show_adapter_name(struct class_device *class_dev, char *buf) | 105 | static ssize_t show_adapter_name(struct class_device *class_dev, char *buf) |
| 107 | { | 106 | { |
| 108 | struct i2c_dev *i2c_dev = to_i2c_dev(class_dev); | 107 | struct i2c_dev *i2c_dev = i2c_dev_get_by_minor(MINOR(class_dev->devt)); |
| 108 | |||
| 109 | if (!i2c_dev) | ||
| 110 | return -ENODEV; | ||
| 109 | return sprintf(buf, "%s\n", i2c_dev->adap->name); | 111 | return sprintf(buf, "%s\n", i2c_dev->adap->name); |
| 110 | } | 112 | } |
| 111 | static CLASS_DEVICE_ATTR(name, S_IRUGO, show_adapter_name, NULL); | 113 | static CLASS_DEVICE_ATTR(name, S_IRUGO, show_adapter_name, NULL); |
| @@ -408,21 +410,12 @@ static struct file_operations i2cdev_fops = { | |||
| 408 | .release = i2cdev_release, | 410 | .release = i2cdev_release, |
| 409 | }; | 411 | }; |
| 410 | 412 | ||
| 411 | static void release_i2c_dev(struct class_device *dev) | 413 | static struct class *i2c_dev_class; |
| 412 | { | ||
| 413 | struct i2c_dev *i2c_dev = to_i2c_dev(dev); | ||
| 414 | complete(&i2c_dev->released); | ||
| 415 | } | ||
| 416 | |||
| 417 | static struct class i2c_dev_class = { | ||
| 418 | .name = "i2c-dev", | ||
| 419 | .release = &release_i2c_dev, | ||
| 420 | }; | ||
| 421 | 414 | ||
| 422 | static int i2cdev_attach_adapter(struct i2c_adapter *adap) | 415 | static int i2cdev_attach_adapter(struct i2c_adapter *adap) |
| 423 | { | 416 | { |
| 424 | struct i2c_dev *i2c_dev; | 417 | struct i2c_dev *i2c_dev; |
| 425 | int retval; | 418 | struct device *dev; |
| 426 | 419 | ||
| 427 | i2c_dev = get_free_i2c_dev(adap); | 420 | i2c_dev = get_free_i2c_dev(adap); |
| 428 | if (IS_ERR(i2c_dev)) | 421 | if (IS_ERR(i2c_dev)) |
| @@ -434,21 +427,20 @@ static int i2cdev_attach_adapter(struct i2c_adapter *adap) | |||
| 434 | /* register this i2c device with the driver core */ | 427 | /* register this i2c device with the driver core */ |
| 435 | i2c_dev->adap = adap; | 428 | i2c_dev->adap = adap; |
| 436 | if (adap->dev.parent == &platform_bus) | 429 | if (adap->dev.parent == &platform_bus) |
| 437 | i2c_dev->class_dev.dev = &adap->dev; | 430 | dev = &adap->dev; |
| 438 | else | 431 | else |
| 439 | i2c_dev->class_dev.dev = adap->dev.parent; | 432 | dev = adap->dev.parent; |
| 440 | i2c_dev->class_dev.class = &i2c_dev_class; | 433 | i2c_dev->class_dev = class_device_create(i2c_dev_class, NULL, |
| 441 | i2c_dev->class_dev.devt = MKDEV(I2C_MAJOR, i2c_dev->minor); | 434 | MKDEV(I2C_MAJOR, i2c_dev->minor), |
| 442 | snprintf(i2c_dev->class_dev.class_id, BUS_ID_SIZE, "i2c-%d", i2c_dev->minor); | 435 | dev, "i2c-%d", i2c_dev->minor); |
| 443 | retval = class_device_register(&i2c_dev->class_dev); | 436 | if (!i2c_dev->class_dev) |
| 444 | if (retval) | ||
| 445 | goto error; | 437 | goto error; |
| 446 | class_device_create_file(&i2c_dev->class_dev, &class_device_attr_name); | 438 | class_device_create_file(i2c_dev->class_dev, &class_device_attr_name); |
| 447 | return 0; | 439 | return 0; |
| 448 | error: | 440 | error: |
| 449 | return_i2c_dev(i2c_dev); | 441 | return_i2c_dev(i2c_dev); |
| 450 | kfree(i2c_dev); | 442 | kfree(i2c_dev); |
| 451 | return retval; | 443 | return -ENODEV; |
| 452 | } | 444 | } |
| 453 | 445 | ||
| 454 | static int i2cdev_detach_adapter(struct i2c_adapter *adap) | 446 | static int i2cdev_detach_adapter(struct i2c_adapter *adap) |
| @@ -459,10 +451,8 @@ static int i2cdev_detach_adapter(struct i2c_adapter *adap) | |||
| 459 | if (!i2c_dev) | 451 | if (!i2c_dev) |
| 460 | return -ENODEV; | 452 | return -ENODEV; |
| 461 | 453 | ||
| 462 | init_completion(&i2c_dev->released); | ||
| 463 | return_i2c_dev(i2c_dev); | 454 | return_i2c_dev(i2c_dev); |
| 464 | class_device_unregister(&i2c_dev->class_dev); | 455 | class_device_destroy(i2c_dev_class, MKDEV(I2C_MAJOR, i2c_dev->minor)); |
| 465 | wait_for_completion(&i2c_dev->released); | ||
| 466 | kfree(i2c_dev); | 456 | kfree(i2c_dev); |
| 467 | 457 | ||
| 468 | pr_debug("i2c-dev: adapter [%s] unregistered\n", adap->name); | 458 | pr_debug("i2c-dev: adapter [%s] unregistered\n", adap->name); |
| @@ -507,8 +497,8 @@ static int __init i2c_dev_init(void) | |||
| 507 | if (res) | 497 | if (res) |
| 508 | goto out; | 498 | goto out; |
| 509 | 499 | ||
| 510 | res = class_register(&i2c_dev_class); | 500 | i2c_dev_class = class_create(THIS_MODULE, "i2c-dev"); |
| 511 | if (res) | 501 | if (IS_ERR(i2c_dev_class)) |
| 512 | goto out_unreg_chrdev; | 502 | goto out_unreg_chrdev; |
| 513 | 503 | ||
| 514 | res = i2c_add_driver(&i2cdev_driver); | 504 | res = i2c_add_driver(&i2cdev_driver); |
| @@ -518,7 +508,7 @@ static int __init i2c_dev_init(void) | |||
| 518 | return 0; | 508 | return 0; |
| 519 | 509 | ||
| 520 | out_unreg_class: | 510 | out_unreg_class: |
| 521 | class_unregister(&i2c_dev_class); | 511 | class_destroy(i2c_dev_class); |
| 522 | out_unreg_chrdev: | 512 | out_unreg_chrdev: |
| 523 | unregister_chrdev(I2C_MAJOR, "i2c"); | 513 | unregister_chrdev(I2C_MAJOR, "i2c"); |
| 524 | out: | 514 | out: |
| @@ -529,7 +519,7 @@ out: | |||
| 529 | static void __exit i2c_dev_exit(void) | 519 | static void __exit i2c_dev_exit(void) |
| 530 | { | 520 | { |
| 531 | i2c_del_driver(&i2cdev_driver); | 521 | i2c_del_driver(&i2cdev_driver); |
| 532 | class_unregister(&i2c_dev_class); | 522 | class_destroy(i2c_dev_class); |
| 533 | unregister_chrdev(I2C_MAJOR,"i2c"); | 523 | unregister_chrdev(I2C_MAJOR,"i2c"); |
| 534 | } | 524 | } |
| 535 | 525 | ||
