aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
Diffstat (limited to 'drivers')
-rw-r--r--drivers/i2c/i2c-core.c78
-rw-r--r--drivers/i2c/i2c-dev.c29
2 files changed, 58 insertions, 49 deletions
diff --git a/drivers/i2c/i2c-core.c b/drivers/i2c/i2c-core.c
index ddd1b83f44d4..c8bbd672226b 100644
--- a/drivers/i2c/i2c-core.c
+++ b/drivers/i2c/i2c-core.c
@@ -199,6 +199,25 @@ static struct bus_type i2c_bus_type = {
199 .resume = i2c_device_resume, 199 .resume = i2c_device_resume,
200}; 200};
201 201
202
203/**
204 * i2c_verify_client - return parameter as i2c_client, or NULL
205 * @dev: device, probably from some driver model iterator
206 *
207 * When traversing the driver model tree, perhaps using driver model
208 * iterators like @device_for_each_child(), you can't assume very much
209 * about the nodes you find. Use this function to avoid oopses caused
210 * by wrongly treating some non-I2C device as an i2c_client.
211 */
212struct i2c_client *i2c_verify_client(struct device *dev)
213{
214 return (dev->bus == &i2c_bus_type)
215 ? to_i2c_client(dev)
216 : NULL;
217}
218EXPORT_SYMBOL(i2c_verify_client);
219
220
202/** 221/**
203 * i2c_new_device - instantiate an i2c device for use with a new style driver 222 * i2c_new_device - instantiate an i2c device for use with a new style driver
204 * @adap: the adapter managing the device 223 * @adap: the adapter managing the device
@@ -670,28 +689,19 @@ EXPORT_SYMBOL(i2c_del_driver);
670 689
671/* ------------------------------------------------------------------------- */ 690/* ------------------------------------------------------------------------- */
672 691
673static int __i2c_check_addr(struct i2c_adapter *adapter, unsigned int addr) 692static int __i2c_check_addr(struct device *dev, void *addrp)
674{ 693{
675 struct list_head *item; 694 struct i2c_client *client = i2c_verify_client(dev);
676 struct i2c_client *client; 695 int addr = *(int *)addrp;
677 696
678 list_for_each(item,&adapter->clients) { 697 if (client && client->addr == addr)
679 client = list_entry(item, struct i2c_client, list); 698 return -EBUSY;
680 if (client->addr == addr)
681 return -EBUSY;
682 }
683 return 0; 699 return 0;
684} 700}
685 701
686static int i2c_check_addr(struct i2c_adapter *adapter, int addr) 702static int i2c_check_addr(struct i2c_adapter *adapter, int addr)
687{ 703{
688 int rval; 704 return device_for_each_child(&adapter->dev, &addr, __i2c_check_addr);
689
690 mutex_lock(&adapter->clist_lock);
691 rval = __i2c_check_addr(adapter, addr);
692 mutex_unlock(&adapter->clist_lock);
693
694 return rval;
695} 705}
696 706
697int i2c_attach_client(struct i2c_client *client) 707int i2c_attach_client(struct i2c_client *client)
@@ -700,7 +710,7 @@ int i2c_attach_client(struct i2c_client *client)
700 int res = 0; 710 int res = 0;
701 711
702 mutex_lock(&adapter->clist_lock); 712 mutex_lock(&adapter->clist_lock);
703 if (__i2c_check_addr(client->adapter, client->addr)) { 713 if (i2c_check_addr(client->adapter, client->addr)) {
704 res = -EBUSY; 714 res = -EBUSY;
705 goto out_unlock; 715 goto out_unlock;
706 } 716 }
@@ -804,24 +814,28 @@ void i2c_release_client(struct i2c_client *client)
804} 814}
805EXPORT_SYMBOL(i2c_release_client); 815EXPORT_SYMBOL(i2c_release_client);
806 816
817struct i2c_cmd_arg {
818 unsigned cmd;
819 void *arg;
820};
821
822static int i2c_cmd(struct device *dev, void *_arg)
823{
824 struct i2c_client *client = i2c_verify_client(dev);
825 struct i2c_cmd_arg *arg = _arg;
826
827 if (client && client->driver && client->driver->command)
828 client->driver->command(client, arg->cmd, arg->arg);
829 return 0;
830}
831
807void i2c_clients_command(struct i2c_adapter *adap, unsigned int cmd, void *arg) 832void i2c_clients_command(struct i2c_adapter *adap, unsigned int cmd, void *arg)
808{ 833{
809 struct list_head *item; 834 struct i2c_cmd_arg cmd_arg;
810 struct i2c_client *client;
811 835
812 mutex_lock(&adap->clist_lock); 836 cmd_arg.cmd = cmd;
813 list_for_each(item,&adap->clients) { 837 cmd_arg.arg = arg;
814 client = list_entry(item, struct i2c_client, list); 838 device_for_each_child(&adap->dev, &cmd_arg, i2c_cmd);
815 if (!try_module_get(client->driver->driver.owner))
816 continue;
817 if (NULL != client->driver->command) {
818 mutex_unlock(&adap->clist_lock);
819 client->driver->command(client,cmd,arg);
820 mutex_lock(&adap->clist_lock);
821 }
822 module_put(client->driver->driver.owner);
823 }
824 mutex_unlock(&adap->clist_lock);
825} 839}
826EXPORT_SYMBOL(i2c_clients_command); 840EXPORT_SYMBOL(i2c_clients_command);
827 841
@@ -1087,7 +1101,7 @@ i2c_new_probed_device(struct i2c_adapter *adap,
1087 } 1101 }
1088 1102
1089 /* Check address availability */ 1103 /* Check address availability */
1090 if (__i2c_check_addr(adap, addr_list[i])) { 1104 if (i2c_check_addr(adap, addr_list[i])) {
1091 dev_dbg(&adap->dev, "Address 0x%02x already in " 1105 dev_dbg(&adap->dev, "Address 0x%02x already in "
1092 "use, not probing\n", addr_list[i]); 1106 "use, not probing\n", addr_list[i]);
1093 continue; 1107 continue;
diff --git a/drivers/i2c/i2c-dev.c b/drivers/i2c/i2c-dev.c
index df540d5dfaf4..393e679d9faa 100644
--- a/drivers/i2c/i2c-dev.c
+++ b/drivers/i2c/i2c-dev.c
@@ -182,27 +182,22 @@ static ssize_t i2cdev_write (struct file *file, const char __user *buf, size_t c
182 return ret; 182 return ret;
183} 183}
184 184
185static int i2cdev_check(struct device *dev, void *addrp)
186{
187 struct i2c_client *client = i2c_verify_client(dev);
188
189 if (!client || client->addr != *(unsigned int *)addrp)
190 return 0;
191
192 return dev->driver ? -EBUSY : 0;
193}
194
185/* This address checking function differs from the one in i2c-core 195/* This address checking function differs from the one in i2c-core
186 in that it considers an address with a registered device, but no 196 in that it considers an address with a registered device, but no
187 bound driver, as NOT busy. */ 197 driver bound to it, as NOT busy. */
188static int i2cdev_check_addr(struct i2c_adapter *adapter, unsigned int addr) 198static int i2cdev_check_addr(struct i2c_adapter *adapter, unsigned int addr)
189{ 199{
190 struct list_head *item; 200 return device_for_each_child(&adapter->dev, &addr, i2cdev_check);
191 struct i2c_client *client;
192 int res = 0;
193
194 mutex_lock(&adapter->clist_lock);
195 list_for_each(item, &adapter->clients) {
196 client = list_entry(item, struct i2c_client, list);
197 if (client->addr == addr) {
198 if (client->driver)
199 res = -EBUSY;
200 break;
201 }
202 }
203 mutex_unlock(&adapter->clist_lock);
204
205 return res;
206} 201}
207 202
208static int i2cdev_ioctl(struct inode *inode, struct file *file, 203static int i2cdev_ioctl(struct inode *inode, struct file *file,