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 | |
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>
-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 | ||