diff options
author | Dave Young <hidave.darkstar@gmail.com> | 2008-07-14 16:38:19 -0400 |
---|---|---|
committer | Jean Delvare <khali@mahadeva.delvare> | 2008-07-14 16:38:19 -0400 |
commit | 7f101a97866e2687a455ecffeb96bcf317c8482a (patch) | |
tree | 3f6fdb853e7b58862a789ceb329c4e97fd07bb8d /drivers/i2c/i2c-core.c | |
parent | bce7f793daec3e65ec5c5705d2457b81fe7b5725 (diff) |
i2c: Use class_for_each_device
Use class_for_each_device for iteration.
Signed-off-by: Dave Young <hidave.darkstar@gmail.com>
Signed-off-by: Jean Delvare <khali@linux-fr.org>
Diffstat (limited to 'drivers/i2c/i2c-core.c')
-rw-r--r-- | drivers/i2c/i2c-core.c | 92 |
1 files changed, 48 insertions, 44 deletions
diff --git a/drivers/i2c/i2c-core.c b/drivers/i2c/i2c-core.c index d0175f4f8fc6..f489683fd15f 100644 --- a/drivers/i2c/i2c-core.c +++ b/drivers/i2c/i2c-core.c | |||
@@ -35,7 +35,6 @@ | |||
35 | #include <linux/completion.h> | 35 | #include <linux/completion.h> |
36 | #include <linux/hardirq.h> | 36 | #include <linux/hardirq.h> |
37 | #include <linux/irqflags.h> | 37 | #include <linux/irqflags.h> |
38 | #include <linux/semaphore.h> | ||
39 | #include <asm/uaccess.h> | 38 | #include <asm/uaccess.h> |
40 | 39 | ||
41 | #include "i2c-core.h" | 40 | #include "i2c-core.h" |
@@ -646,6 +645,16 @@ EXPORT_SYMBOL(i2c_del_adapter); | |||
646 | 645 | ||
647 | /* ------------------------------------------------------------------------- */ | 646 | /* ------------------------------------------------------------------------- */ |
648 | 647 | ||
648 | static int __attach_adapter(struct device *dev, void *data) | ||
649 | { | ||
650 | struct i2c_adapter *adapter = to_i2c_adapter(dev); | ||
651 | struct i2c_driver *driver = data; | ||
652 | |||
653 | driver->attach_adapter(adapter); | ||
654 | |||
655 | return 0; | ||
656 | } | ||
657 | |||
649 | /* | 658 | /* |
650 | * An i2c_driver is used with one or more i2c_client (device) nodes to access | 659 | * An i2c_driver is used with one or more i2c_client (device) nodes to access |
651 | * i2c slave chips, on a bus instance associated with some i2c_adapter. There | 660 | * i2c slave chips, on a bus instance associated with some i2c_adapter. There |
@@ -686,21 +695,49 @@ int i2c_register_driver(struct module *owner, struct i2c_driver *driver) | |||
686 | pr_debug("i2c-core: driver [%s] registered\n", driver->driver.name); | 695 | pr_debug("i2c-core: driver [%s] registered\n", driver->driver.name); |
687 | 696 | ||
688 | /* legacy drivers scan i2c busses directly */ | 697 | /* legacy drivers scan i2c busses directly */ |
689 | if (driver->attach_adapter) { | 698 | if (driver->attach_adapter) |
690 | struct i2c_adapter *adapter; | 699 | class_for_each_device(&i2c_adapter_class, driver, |
700 | __attach_adapter); | ||
691 | 701 | ||
692 | down(&i2c_adapter_class.sem); | 702 | mutex_unlock(&core_lock); |
693 | list_for_each_entry(adapter, &i2c_adapter_class.devices, | 703 | return 0; |
694 | dev.node) { | 704 | } |
695 | driver->attach_adapter(adapter); | 705 | EXPORT_SYMBOL(i2c_register_driver); |
706 | |||
707 | static int __detach_adapter(struct device *dev, void *data) | ||
708 | { | ||
709 | struct i2c_adapter *adapter = to_i2c_adapter(dev); | ||
710 | struct i2c_driver *driver = data; | ||
711 | |||
712 | /* Have a look at each adapter, if clients of this driver are still | ||
713 | * attached. If so, detach them to be able to kill the driver | ||
714 | * afterwards. | ||
715 | */ | ||
716 | if (driver->detach_adapter) { | ||
717 | if (driver->detach_adapter(adapter)) | ||
718 | dev_err(&adapter->dev, | ||
719 | "detach_adapter failed for driver [%s]\n", | ||
720 | driver->driver.name); | ||
721 | } else { | ||
722 | struct list_head *item, *_n; | ||
723 | struct i2c_client *client; | ||
724 | |||
725 | list_for_each_safe(item, _n, &adapter->clients) { | ||
726 | client = list_entry(item, struct i2c_client, list); | ||
727 | if (client->driver != driver) | ||
728 | continue; | ||
729 | dev_dbg(&adapter->dev, | ||
730 | "detaching client [%s] at 0x%02x\n", | ||
731 | client->name, client->addr); | ||
732 | if (driver->detach_client(client)) | ||
733 | dev_err(&adapter->dev, "detach_client " | ||
734 | "failed for client [%s] at 0x%02x\n", | ||
735 | client->name, client->addr); | ||
696 | } | 736 | } |
697 | up(&i2c_adapter_class.sem); | ||
698 | } | 737 | } |
699 | 738 | ||
700 | mutex_unlock(&core_lock); | ||
701 | return 0; | 739 | return 0; |
702 | } | 740 | } |
703 | EXPORT_SYMBOL(i2c_register_driver); | ||
704 | 741 | ||
705 | /** | 742 | /** |
706 | * i2c_del_driver - unregister I2C driver | 743 | * i2c_del_driver - unregister I2C driver |
@@ -709,46 +746,13 @@ EXPORT_SYMBOL(i2c_register_driver); | |||
709 | */ | 746 | */ |
710 | void i2c_del_driver(struct i2c_driver *driver) | 747 | void i2c_del_driver(struct i2c_driver *driver) |
711 | { | 748 | { |
712 | struct list_head *item2, *_n; | ||
713 | struct i2c_client *client; | ||
714 | struct i2c_adapter *adap; | ||
715 | |||
716 | mutex_lock(&core_lock); | 749 | mutex_lock(&core_lock); |
717 | 750 | ||
718 | /* new-style driver? */ | 751 | /* new-style driver? */ |
719 | if (is_newstyle_driver(driver)) | 752 | if (is_newstyle_driver(driver)) |
720 | goto unregister; | 753 | goto unregister; |
721 | 754 | ||
722 | /* Have a look at each adapter, if clients of this driver are still | 755 | class_for_each_device(&i2c_adapter_class, driver, __detach_adapter); |
723 | * attached. If so, detach them to be able to kill the driver | ||
724 | * afterwards. | ||
725 | */ | ||
726 | down(&i2c_adapter_class.sem); | ||
727 | list_for_each_entry(adap, &i2c_adapter_class.devices, dev.node) { | ||
728 | if (driver->detach_adapter) { | ||
729 | if (driver->detach_adapter(adap)) { | ||
730 | dev_err(&adap->dev, "detach_adapter failed " | ||
731 | "for driver [%s]\n", | ||
732 | driver->driver.name); | ||
733 | } | ||
734 | } else { | ||
735 | list_for_each_safe(item2, _n, &adap->clients) { | ||
736 | client = list_entry(item2, struct i2c_client, list); | ||
737 | if (client->driver != driver) | ||
738 | continue; | ||
739 | dev_dbg(&adap->dev, "detaching client [%s] " | ||
740 | "at 0x%02x\n", client->name, | ||
741 | client->addr); | ||
742 | if (driver->detach_client(client)) { | ||
743 | dev_err(&adap->dev, "detach_client " | ||
744 | "failed for client [%s] at " | ||
745 | "0x%02x\n", client->name, | ||
746 | client->addr); | ||
747 | } | ||
748 | } | ||
749 | } | ||
750 | } | ||
751 | up(&i2c_adapter_class.sem); | ||
752 | 756 | ||
753 | unregister: | 757 | unregister: |
754 | driver_unregister(&driver->driver); | 758 | driver_unregister(&driver->driver); |