diff options
author | Jean Delvare <khali@linux-fr.org> | 2009-06-19 10:58:18 -0400 |
---|---|---|
committer | Jean Delvare <khali@linux-fr.org> | 2009-06-19 10:58:18 -0400 |
commit | 729d6dd571464954f625e6b80950d9e4e3bd94f7 (patch) | |
tree | faf8ada32b03c8bc07e1ddb8ec0d26d6440b6d98 /drivers/i2c | |
parent | 352da9820e5506e3b8496e6052a2ad9c488efae8 (diff) |
i2c: Get rid of the legacy binding model
We converted all the legacy i2c drivers so we can finally get rid of
the legacy binding model. Hooray!
Signed-off-by: Jean Delvare <khali@linux-fr.org>
Cc: David Brownell <dbrownell@users.sourceforge.net>
Diffstat (limited to 'drivers/i2c')
-rw-r--r-- | drivers/i2c/i2c-core.c | 83 |
1 files changed, 7 insertions, 76 deletions
diff --git a/drivers/i2c/i2c-core.c b/drivers/i2c/i2c-core.c index fc18fdbffd3f..dc8bc9131447 100644 --- a/drivers/i2c/i2c-core.c +++ b/drivers/i2c/i2c-core.c | |||
@@ -43,6 +43,7 @@ static DEFINE_IDR(i2c_adapter_idr); | |||
43 | 43 | ||
44 | #define is_newstyle_driver(d) ((d)->probe || (d)->remove || (d)->detect) | 44 | #define is_newstyle_driver(d) ((d)->probe || (d)->remove || (d)->detect) |
45 | 45 | ||
46 | static int i2c_attach_client(struct i2c_client *client); | ||
46 | static int i2c_detect(struct i2c_adapter *adapter, struct i2c_driver *driver); | 47 | static int i2c_detect(struct i2c_adapter *adapter, struct i2c_driver *driver); |
47 | 48 | ||
48 | /* ------------------------------------------------------------------------- */ | 49 | /* ------------------------------------------------------------------------- */ |
@@ -83,10 +84,6 @@ static int i2c_device_uevent(struct device *dev, struct kobj_uevent_env *env) | |||
83 | { | 84 | { |
84 | struct i2c_client *client = to_i2c_client(dev); | 85 | struct i2c_client *client = to_i2c_client(dev); |
85 | 86 | ||
86 | /* by definition, legacy drivers can't hotplug */ | ||
87 | if (dev->driver) | ||
88 | return 0; | ||
89 | |||
90 | if (add_uevent_var(env, "MODALIAS=%s%s", | 87 | if (add_uevent_var(env, "MODALIAS=%s%s", |
91 | I2C_MODULE_PREFIX, client->name)) | 88 | I2C_MODULE_PREFIX, client->name)) |
92 | return -ENOMEM; | 89 | return -ENOMEM; |
@@ -455,7 +452,7 @@ static int i2c_register_adapter(struct i2c_adapter *adap) | |||
455 | 452 | ||
456 | dev_dbg(&adap->dev, "adapter [%s] registered\n", adap->name); | 453 | dev_dbg(&adap->dev, "adapter [%s] registered\n", adap->name); |
457 | 454 | ||
458 | /* create pre-declared device nodes for new-style drivers */ | 455 | /* create pre-declared device nodes */ |
459 | if (adap->nr < __i2c_first_dynamic_bus_num) | 456 | if (adap->nr < __i2c_first_dynamic_bus_num) |
460 | i2c_scan_static_board_info(adap); | 457 | i2c_scan_static_board_info(adap); |
461 | 458 | ||
@@ -617,26 +614,9 @@ int i2c_del_adapter(struct i2c_adapter *adap) | |||
617 | if (res) | 614 | if (res) |
618 | goto out_unlock; | 615 | goto out_unlock; |
619 | 616 | ||
620 | /* detach any active clients. This must be done first, because | 617 | /* Detach any active clients */ |
621 | * it can fail; in which case we give up. */ | ||
622 | list_for_each_entry_safe_reverse(client, _n, &adap->clients, list) { | 618 | list_for_each_entry_safe_reverse(client, _n, &adap->clients, list) { |
623 | struct i2c_driver *driver; | 619 | i2c_unregister_device(client); |
624 | |||
625 | driver = client->driver; | ||
626 | |||
627 | /* new style, follow standard driver model */ | ||
628 | if (!driver || is_newstyle_driver(driver)) { | ||
629 | i2c_unregister_device(client); | ||
630 | continue; | ||
631 | } | ||
632 | |||
633 | /* legacy drivers create and remove clients themselves */ | ||
634 | if ((res = driver->detach_client(client))) { | ||
635 | dev_err(&adap->dev, "detach_client failed for client " | ||
636 | "[%s] at address 0x%02x\n", client->name, | ||
637 | client->addr); | ||
638 | goto out_unlock; | ||
639 | } | ||
640 | } | 620 | } |
641 | 621 | ||
642 | /* clean up the sysfs representation */ | 622 | /* clean up the sysfs representation */ |
@@ -680,11 +660,7 @@ static int __attach_adapter(struct device *dev, void *data) | |||
680 | 660 | ||
681 | /* | 661 | /* |
682 | * An i2c_driver is used with one or more i2c_client (device) nodes to access | 662 | * An i2c_driver is used with one or more i2c_client (device) nodes to access |
683 | * i2c slave chips, on a bus instance associated with some i2c_adapter. There | 663 | * i2c slave chips, on a bus instance associated with some i2c_adapter. |
684 | * are two models for binding the driver to its device: "new style" drivers | ||
685 | * follow the standard Linux driver model and just respond to probe() calls | ||
686 | * issued if the driver core sees they match(); "legacy" drivers create device | ||
687 | * nodes themselves. | ||
688 | */ | 664 | */ |
689 | 665 | ||
690 | int i2c_register_driver(struct module *owner, struct i2c_driver *driver) | 666 | int i2c_register_driver(struct module *owner, struct i2c_driver *driver) |
@@ -695,21 +671,11 @@ int i2c_register_driver(struct module *owner, struct i2c_driver *driver) | |||
695 | if (unlikely(WARN_ON(!i2c_bus_type.p))) | 671 | if (unlikely(WARN_ON(!i2c_bus_type.p))) |
696 | return -EAGAIN; | 672 | return -EAGAIN; |
697 | 673 | ||
698 | /* new style driver methods can't mix with legacy ones */ | ||
699 | if (is_newstyle_driver(driver)) { | ||
700 | if (driver->detach_adapter || driver->detach_client) { | ||
701 | printk(KERN_WARNING | ||
702 | "i2c-core: driver [%s] is confused\n", | ||
703 | driver->driver.name); | ||
704 | return -EINVAL; | ||
705 | } | ||
706 | } | ||
707 | |||
708 | /* add the driver to the list of i2c drivers in the driver core */ | 674 | /* add the driver to the list of i2c drivers in the driver core */ |
709 | driver->driver.owner = owner; | 675 | driver->driver.owner = owner; |
710 | driver->driver.bus = &i2c_bus_type; | 676 | driver->driver.bus = &i2c_bus_type; |
711 | 677 | ||
712 | /* for new style drivers, when registration returns the driver core | 678 | /* When registration returns, the driver core |
713 | * will have called probe() for all matching-but-unbound devices. | 679 | * will have called probe() for all matching-but-unbound devices. |
714 | */ | 680 | */ |
715 | res = driver_register(&driver->driver); | 681 | res = driver_register(&driver->driver); |
@@ -748,29 +714,11 @@ static int __detach_adapter(struct device *dev, void *data) | |||
748 | if (is_newstyle_driver(driver)) | 714 | if (is_newstyle_driver(driver)) |
749 | return 0; | 715 | return 0; |
750 | 716 | ||
751 | /* Have a look at each adapter, if clients of this driver are still | ||
752 | * attached. If so, detach them to be able to kill the driver | ||
753 | * afterwards. | ||
754 | */ | ||
755 | if (driver->detach_adapter) { | 717 | if (driver->detach_adapter) { |
756 | if (driver->detach_adapter(adapter)) | 718 | if (driver->detach_adapter(adapter)) |
757 | dev_err(&adapter->dev, | 719 | dev_err(&adapter->dev, |
758 | "detach_adapter failed for driver [%s]\n", | 720 | "detach_adapter failed for driver [%s]\n", |
759 | driver->driver.name); | 721 | driver->driver.name); |
760 | } else { | ||
761 | struct i2c_client *client, *_n; | ||
762 | |||
763 | list_for_each_entry_safe(client, _n, &adapter->clients, list) { | ||
764 | if (client->driver != driver) | ||
765 | continue; | ||
766 | dev_dbg(&adapter->dev, | ||
767 | "detaching client [%s] at 0x%02x\n", | ||
768 | client->name, client->addr); | ||
769 | if (driver->detach_client(client)) | ||
770 | dev_err(&adapter->dev, "detach_client " | ||
771 | "failed for client [%s] at 0x%02x\n", | ||
772 | client->name, client->addr); | ||
773 | } | ||
774 | } | 722 | } |
775 | 723 | ||
776 | return 0; | 724 | return 0; |
@@ -812,7 +760,7 @@ static int i2c_check_addr(struct i2c_adapter *adapter, int addr) | |||
812 | return device_for_each_child(&adapter->dev, &addr, __i2c_check_addr); | 760 | return device_for_each_child(&adapter->dev, &addr, __i2c_check_addr); |
813 | } | 761 | } |
814 | 762 | ||
815 | int i2c_attach_client(struct i2c_client *client) | 763 | static int i2c_attach_client(struct i2c_client *client) |
816 | { | 764 | { |
817 | struct i2c_adapter *adapter = client->adapter; | 765 | struct i2c_adapter *adapter = client->adapter; |
818 | int res; | 766 | int res; |
@@ -854,23 +802,6 @@ out_err: | |||
854 | "(%d)\n", client->name, client->addr, res); | 802 | "(%d)\n", client->name, client->addr, res); |
855 | return res; | 803 | return res; |
856 | } | 804 | } |
857 | EXPORT_SYMBOL(i2c_attach_client); | ||
858 | |||
859 | int i2c_detach_client(struct i2c_client *client) | ||
860 | { | ||
861 | struct i2c_adapter *adapter = client->adapter; | ||
862 | |||
863 | mutex_lock(&adapter->clist_lock); | ||
864 | list_del(&client->list); | ||
865 | mutex_unlock(&adapter->clist_lock); | ||
866 | |||
867 | init_completion(&client->released); | ||
868 | device_unregister(&client->dev); | ||
869 | wait_for_completion(&client->released); | ||
870 | |||
871 | return 0; | ||
872 | } | ||
873 | EXPORT_SYMBOL(i2c_detach_client); | ||
874 | 805 | ||
875 | /** | 806 | /** |
876 | * i2c_use_client - increments the reference count of the i2c client structure | 807 | * i2c_use_client - increments the reference count of the i2c client structure |