]> err.no Git - linux-2.6/blobdiff - drivers/i2c/i2c-dev.c
Merge git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux-2.6.git
[linux-2.6] / drivers / i2c / i2c-dev.c
index 7360f9c37256c69cf9f9dd0191638a40afe62d6d..393e679d9faac4f1a8351b69376ffc656474871d 100644 (file)
@@ -182,6 +182,24 @@ static ssize_t i2cdev_write (struct file *file, const char __user *buf, size_t c
        return ret;
 }
 
+static int i2cdev_check(struct device *dev, void *addrp)
+{
+       struct i2c_client *client = i2c_verify_client(dev);
+
+       if (!client || client->addr != *(unsigned int *)addrp)
+               return 0;
+
+       return dev->driver ? -EBUSY : 0;
+}
+
+/* This address checking function differs from the one in i2c-core
+   in that it considers an address with a registered device, but no
+   driver bound to it, as NOT busy. */
+static int i2cdev_check_addr(struct i2c_adapter *adapter, unsigned int addr)
+{
+       return device_for_each_child(&adapter->dev, &addr, i2cdev_check);
+}
+
 static int i2cdev_ioctl(struct inode *inode, struct file *file,
                unsigned int cmd, unsigned long arg)
 {
@@ -213,8 +231,9 @@ static int i2cdev_ioctl(struct inode *inode, struct file *file,
                if ((arg > 0x3ff) ||
                    (((client->flags & I2C_M_TEN) == 0) && arg > 0x7f))
                        return -EINVAL;
-               if ((cmd == I2C_SLAVE) && i2c_check_addr(client->adapter,arg))
+               if (cmd == I2C_SLAVE && i2cdev_check_addr(client->adapter, arg))
                        return -EBUSY;
+               /* REVISIT: address could become busy later */
                client->addr = arg;
                return 0;
        case I2C_TENBIT: