aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGreg Kroah-Hartman <gregkh@suse.de>2005-12-06 18:33:15 -0500
committerGreg Kroah-Hartman <gregkh@suse.de>2006-01-06 01:16:25 -0500
commit79472132f555ae1e912699e116e5c82f338872f6 (patch)
tree5f2b69e43b8797cab242f6524f6bb0d55694c849
parentd82c0bf88fa97c1993ea9d6051488e7cb012b440 (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.c50
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;
42struct i2c_dev { 42struct 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
106static ssize_t show_adapter_name(struct class_device *class_dev, char *buf) 105static 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}
111static CLASS_DEVICE_ATTR(name, S_IRUGO, show_adapter_name, NULL); 113static 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
411static void release_i2c_dev(struct class_device *dev) 413static struct class *i2c_dev_class;
412{
413 struct i2c_dev *i2c_dev = to_i2c_dev(dev);
414 complete(&i2c_dev->released);
415}
416
417static struct class i2c_dev_class = {
418 .name = "i2c-dev",
419 .release = &release_i2c_dev,
420};
421 414
422static int i2cdev_attach_adapter(struct i2c_adapter *adap) 415static 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;
448error: 440error:
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
454static int i2cdev_detach_adapter(struct i2c_adapter *adap) 446static 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
520out_unreg_class: 510out_unreg_class:
521 class_unregister(&i2c_dev_class); 511 class_destroy(i2c_dev_class);
522out_unreg_chrdev: 512out_unreg_chrdev:
523 unregister_chrdev(I2C_MAJOR, "i2c"); 513 unregister_chrdev(I2C_MAJOR, "i2c");
524out: 514out:
@@ -529,7 +519,7 @@ out:
529static void __exit i2c_dev_exit(void) 519static 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