aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/i2c/i2c-dev.c
diff options
context:
space:
mode:
authorJean Delvare <khali@linux-fr.org>2007-11-15 13:24:01 -0500
committerJean Delvare <khali@hyperion.delvare>2007-11-15 13:24:01 -0500
commitbd4217d8c6ef48425c8d6b28d2e089a83e01af04 (patch)
tree0c399bdc4497ced5f168fa224a2c4c5ca63cfb5e /drivers/i2c/i2c-dev.c
parent907135aaa0cc120a347222c8f274ecc5ca0db641 (diff)
i2c-dev: Unbound new-style i2c clients aren't busy
Let i2c-dev deal properly with new-style i2c clients. Instead of considering them always busy, it needs to check wether a driver is bound to them or not. This is still not completely correct, as the client could become busy later, but the same problem already existed before new-style clients were introduced. We'll want to fix it someday. Signed-off-by: Jean Delvare <khali@linux-fr.org> Acked-by: David Brownell <dbrownell@users.sourceforge.net>
Diffstat (limited to 'drivers/i2c/i2c-dev.c')
-rw-r--r--drivers/i2c/i2c-dev.c26
1 files changed, 25 insertions, 1 deletions
diff --git a/drivers/i2c/i2c-dev.c b/drivers/i2c/i2c-dev.c
index 7360f9c3725..c21ae20ae36 100644
--- a/drivers/i2c/i2c-dev.c
+++ b/drivers/i2c/i2c-dev.c
@@ -182,6 +182,29 @@ 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
185/* This address checking function differs from the one in i2c-core
186 in that it considers an address with a registered device, but no
187 bounded driver, as NOT busy. */
188static int i2cdev_check_addr(struct i2c_adapter *adapter, unsigned int addr)
189{
190 struct list_head *item;
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}
207
185static int i2cdev_ioctl(struct inode *inode, struct file *file, 208static int i2cdev_ioctl(struct inode *inode, struct file *file,
186 unsigned int cmd, unsigned long arg) 209 unsigned int cmd, unsigned long arg)
187{ 210{
@@ -213,8 +236,9 @@ static int i2cdev_ioctl(struct inode *inode, struct file *file,
213 if ((arg > 0x3ff) || 236 if ((arg > 0x3ff) ||
214 (((client->flags & I2C_M_TEN) == 0) && arg > 0x7f)) 237 (((client->flags & I2C_M_TEN) == 0) && arg > 0x7f))
215 return -EINVAL; 238 return -EINVAL;
216 if ((cmd == I2C_SLAVE) && i2c_check_addr(client->adapter,arg)) 239 if (cmd == I2C_SLAVE && i2cdev_check_addr(client->adapter, arg))
217 return -EBUSY; 240 return -EBUSY;
241 /* REVISIT: address could become busy later */
218 client->addr = arg; 242 client->addr = arg;
219 return 0; 243 return 0;
220 case I2C_TENBIT: 244 case I2C_TENBIT: