Commit bd4217d8c6ef48425c8d6b28d2e089a83e01af04

Authored by Jean Delvare
Committed by Jean Delvare
1 parent 907135aaa0

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>

Showing 1 changed file with 25 additions and 1 deletions Side-by-side Diff

drivers/i2c/i2c-dev.c
... ... @@ -182,6 +182,29 @@
182 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. */
  188 +static 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 +
185 208 static int i2cdev_ioctl(struct inode *inode, struct file *file,
186 209 unsigned int cmd, unsigned long arg)
187 210 {
188 211  
... ... @@ -213,8 +236,9 @@
213 236 if ((arg > 0x3ff) ||
214 237 (((client->flags & I2C_M_TEN) == 0) && arg > 0x7f))
215 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 240 return -EBUSY;
  241 + /* REVISIT: address could become busy later */
218 242 client->addr = arg;
219 243 return 0;
220 244 case I2C_TENBIT: