diff options
Diffstat (limited to 'drivers/i2c/i2c-dev.c')
| -rw-r--r-- | drivers/i2c/i2c-dev.c | 63 |
1 files changed, 23 insertions, 40 deletions
diff --git a/drivers/i2c/i2c-dev.c b/drivers/i2c/i2c-dev.c index 8af0bd1424d2..ed7eed388bae 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); |
| @@ -474,21 +464,14 @@ static int i2cdev_detach_client(struct i2c_client *client) | |||
| 474 | return 0; | 464 | return 0; |
| 475 | } | 465 | } |
| 476 | 466 | ||
| 477 | static int i2cdev_command(struct i2c_client *client, unsigned int cmd, | ||
| 478 | void *arg) | ||
| 479 | { | ||
| 480 | return -1; | ||
| 481 | } | ||
| 482 | |||
| 483 | static struct i2c_driver i2cdev_driver = { | 467 | static struct i2c_driver i2cdev_driver = { |
| 484 | .owner = THIS_MODULE, | 468 | .driver = { |
| 485 | .name = "dev_driver", | 469 | .name = "dev_driver", |
| 470 | }, | ||
| 486 | .id = I2C_DRIVERID_I2CDEV, | 471 | .id = I2C_DRIVERID_I2CDEV, |
| 487 | .flags = I2C_DF_NOTIFY, | ||
| 488 | .attach_adapter = i2cdev_attach_adapter, | 472 | .attach_adapter = i2cdev_attach_adapter, |
| 489 | .detach_adapter = i2cdev_detach_adapter, | 473 | .detach_adapter = i2cdev_detach_adapter, |
| 490 | .detach_client = i2cdev_detach_client, | 474 | .detach_client = i2cdev_detach_client, |
| 491 | .command = i2cdev_command, | ||
| 492 | }; | 475 | }; |
| 493 | 476 | ||
| 494 | static struct i2c_client i2cdev_client_template = { | 477 | static struct i2c_client i2cdev_client_template = { |
| @@ -507,8 +490,8 @@ static int __init i2c_dev_init(void) | |||
| 507 | if (res) | 490 | if (res) |
| 508 | goto out; | 491 | goto out; |
| 509 | 492 | ||
| 510 | res = class_register(&i2c_dev_class); | 493 | i2c_dev_class = class_create(THIS_MODULE, "i2c-dev"); |
| 511 | if (res) | 494 | if (IS_ERR(i2c_dev_class)) |
| 512 | goto out_unreg_chrdev; | 495 | goto out_unreg_chrdev; |
| 513 | 496 | ||
| 514 | res = i2c_add_driver(&i2cdev_driver); | 497 | res = i2c_add_driver(&i2cdev_driver); |
| @@ -518,7 +501,7 @@ static int __init i2c_dev_init(void) | |||
| 518 | return 0; | 501 | return 0; |
| 519 | 502 | ||
| 520 | out_unreg_class: | 503 | out_unreg_class: |
| 521 | class_unregister(&i2c_dev_class); | 504 | class_destroy(i2c_dev_class); |
| 522 | out_unreg_chrdev: | 505 | out_unreg_chrdev: |
| 523 | unregister_chrdev(I2C_MAJOR, "i2c"); | 506 | unregister_chrdev(I2C_MAJOR, "i2c"); |
| 524 | out: | 507 | out: |
| @@ -529,7 +512,7 @@ out: | |||
| 529 | static void __exit i2c_dev_exit(void) | 512 | static void __exit i2c_dev_exit(void) |
| 530 | { | 513 | { |
| 531 | i2c_del_driver(&i2cdev_driver); | 514 | i2c_del_driver(&i2cdev_driver); |
| 532 | class_unregister(&i2c_dev_class); | 515 | class_destroy(i2c_dev_class); |
| 533 | unregister_chrdev(I2C_MAJOR,"i2c"); | 516 | unregister_chrdev(I2C_MAJOR,"i2c"); |
| 534 | } | 517 | } |
| 535 | 518 | ||
