@@ -1059,6 +1059,9 @@ void i2c_unregister_device(struct i2c_client *client)
if (IS_ERR_OR_NULL(client))
return;
+ if (test_and_set_bit(I2C_CLIENT_UNREGISTERING, &client->flags))
+ return;
+
if (client->dev.of_node) {
of_node_clear_flag(client->dev.of_node, OF_POPULATED);
of_node_put(client->dev.of_node);
@@ -1354,7 +1357,6 @@ delete_device_store(struct device *dev, struct device_attribute *attr,
return -EINVAL;
}
- mutex_lock(&core_lock);
/* Make sure the device was added through sysfs */
child_dev = device_find_child(&adap->dev, &addr, __i2c_find_user_addr);
if (child_dev) {
@@ -1364,7 +1366,6 @@ delete_device_store(struct device *dev, struct device_attribute *attr,
dev_err(dev, "Can't find userspace-created device at %#x\n", addr);
count = -ENOENT;
}
- mutex_unlock(&core_lock);
return count;
}
@@ -1745,10 +1746,8 @@ void i2c_del_adapter(struct i2c_adapter *adap)
* we can't remove the dummy devices during the first pass: they
* could have been instantiated by real devices wishing to clean
* them up properly, so we give them a chance to do that first. */
- mutex_lock(&core_lock);
device_for_each_child(&adap->dev, NULL, __unregister_client);
device_for_each_child(&adap->dev, NULL, __unregister_dummy);
- mutex_unlock(&core_lock);
/* device name is gone after device_unregister */
dev_dbg(&adap->dev, "adapter [%s] unregistered\n", adap->name);
@@ -2002,12 +2001,10 @@ static int __i2c_unregister_detected_client(struct device *dev, void *argp)
*/
void i2c_del_driver(struct i2c_driver *driver)
{
- mutex_lock(&core_lock);
/* Satisfy __must_check, function can't fail */
if (driver_for_each_device(&driver->driver, NULL, NULL,
__i2c_unregister_detected_client)) {
}
- mutex_unlock(&core_lock);
driver_unregister(&driver->driver);
pr_debug("driver [%s] unregistered\n", driver->driver.name);
@@ -325,7 +325,7 @@ struct i2c_driver {
* managing the device.
*/
struct i2c_client {
- unsigned short flags; /* div., see below */
+ unsigned long flags; /* div., see below */
#define I2C_CLIENT_PEC 0x04 /* Use Packet Error Checking */
#define I2C_CLIENT_TEN 0x10 /* we have a ten bit chip address */
/* Must equal I2C_M_TEN below */
@@ -336,6 +336,8 @@ struct i2c_client {
#define I2C_CLIENT_USER 0x200 /* client was userspace-created */
#define I2C_CLIENT_SCCB 0x9000 /* Use Omnivision SCCB protocol */
/* Must match I2C_M_STOP|IGNORE_NAK */
+/* following flags are bit numbers */
+#define I2C_CLIENT_UNREGISTERING 31 /* client is being unregistered */
unsigned short addr; /* chip address - NOTE: 7bit */
/* addresses are stored in the */