Loading drivers/i2c/i2c-core.c +48 −44 Original line number Diff line number Diff line Loading @@ -35,7 +35,6 @@ #include <linux/completion.h> #include <linux/hardirq.h> #include <linux/irqflags.h> #include <linux/semaphore.h> #include <asm/uaccess.h> #include "i2c-core.h" Loading Loading @@ -646,6 +645,16 @@ EXPORT_SYMBOL(i2c_del_adapter); /* ------------------------------------------------------------------------- */ static int __attach_adapter(struct device *dev, void *data) { struct i2c_adapter *adapter = to_i2c_adapter(dev); struct i2c_driver *driver = data; driver->attach_adapter(adapter); return 0; } /* * An i2c_driver is used with one or more i2c_client (device) nodes to access * i2c slave chips, on a bus instance associated with some i2c_adapter. There Loading Loading @@ -686,69 +695,64 @@ int i2c_register_driver(struct module *owner, struct i2c_driver *driver) pr_debug("i2c-core: driver [%s] registered\n", driver->driver.name); /* legacy drivers scan i2c busses directly */ if (driver->attach_adapter) { struct i2c_adapter *adapter; down(&i2c_adapter_class.sem); list_for_each_entry(adapter, &i2c_adapter_class.devices, dev.node) { driver->attach_adapter(adapter); } up(&i2c_adapter_class.sem); } if (driver->attach_adapter) class_for_each_device(&i2c_adapter_class, driver, __attach_adapter); mutex_unlock(&core_lock); return 0; } EXPORT_SYMBOL(i2c_register_driver); /** * i2c_del_driver - unregister I2C driver * @driver: the driver being unregistered * Context: can sleep */ void i2c_del_driver(struct i2c_driver *driver) static int __detach_adapter(struct device *dev, void *data) { struct list_head *item2, *_n; struct i2c_client *client; struct i2c_adapter *adap; mutex_lock(&core_lock); /* new-style driver? */ if (is_newstyle_driver(driver)) goto unregister; struct i2c_adapter *adapter = to_i2c_adapter(dev); struct i2c_driver *driver = data; /* Have a look at each adapter, if clients of this driver are still * attached. If so, detach them to be able to kill the driver * afterwards. */ down(&i2c_adapter_class.sem); list_for_each_entry(adap, &i2c_adapter_class.devices, dev.node) { if (driver->detach_adapter) { if (driver->detach_adapter(adap)) { dev_err(&adap->dev, "detach_adapter failed " "for driver [%s]\n", if (driver->detach_adapter(adapter)) dev_err(&adapter->dev, "detach_adapter failed for driver [%s]\n", driver->driver.name); } } else { list_for_each_safe(item2, _n, &adap->clients) { client = list_entry(item2, struct i2c_client, list); struct list_head *item, *_n; struct i2c_client *client; list_for_each_safe(item, _n, &adapter->clients) { client = list_entry(item, struct i2c_client, list); if (client->driver != driver) continue; dev_dbg(&adap->dev, "detaching client [%s] " "at 0x%02x\n", client->name, client->addr); if (driver->detach_client(client)) { dev_err(&adap->dev, "detach_client " "failed for client [%s] at " "0x%02x\n", client->name, client->addr); } dev_dbg(&adapter->dev, "detaching client [%s] at 0x%02x\n", client->name, client->addr); if (driver->detach_client(client)) dev_err(&adapter->dev, "detach_client " "failed for client [%s] at 0x%02x\n", client->name, client->addr); } } return 0; } up(&i2c_adapter_class.sem); /** * i2c_del_driver - unregister I2C driver * @driver: the driver being unregistered * Context: can sleep */ void i2c_del_driver(struct i2c_driver *driver) { mutex_lock(&core_lock); /* new-style driver? */ if (is_newstyle_driver(driver)) goto unregister; class_for_each_device(&i2c_adapter_class, driver, __detach_adapter); unregister: driver_unregister(&driver->driver); Loading Loading
drivers/i2c/i2c-core.c +48 −44 Original line number Diff line number Diff line Loading @@ -35,7 +35,6 @@ #include <linux/completion.h> #include <linux/hardirq.h> #include <linux/irqflags.h> #include <linux/semaphore.h> #include <asm/uaccess.h> #include "i2c-core.h" Loading Loading @@ -646,6 +645,16 @@ EXPORT_SYMBOL(i2c_del_adapter); /* ------------------------------------------------------------------------- */ static int __attach_adapter(struct device *dev, void *data) { struct i2c_adapter *adapter = to_i2c_adapter(dev); struct i2c_driver *driver = data; driver->attach_adapter(adapter); return 0; } /* * An i2c_driver is used with one or more i2c_client (device) nodes to access * i2c slave chips, on a bus instance associated with some i2c_adapter. There Loading Loading @@ -686,69 +695,64 @@ int i2c_register_driver(struct module *owner, struct i2c_driver *driver) pr_debug("i2c-core: driver [%s] registered\n", driver->driver.name); /* legacy drivers scan i2c busses directly */ if (driver->attach_adapter) { struct i2c_adapter *adapter; down(&i2c_adapter_class.sem); list_for_each_entry(adapter, &i2c_adapter_class.devices, dev.node) { driver->attach_adapter(adapter); } up(&i2c_adapter_class.sem); } if (driver->attach_adapter) class_for_each_device(&i2c_adapter_class, driver, __attach_adapter); mutex_unlock(&core_lock); return 0; } EXPORT_SYMBOL(i2c_register_driver); /** * i2c_del_driver - unregister I2C driver * @driver: the driver being unregistered * Context: can sleep */ void i2c_del_driver(struct i2c_driver *driver) static int __detach_adapter(struct device *dev, void *data) { struct list_head *item2, *_n; struct i2c_client *client; struct i2c_adapter *adap; mutex_lock(&core_lock); /* new-style driver? */ if (is_newstyle_driver(driver)) goto unregister; struct i2c_adapter *adapter = to_i2c_adapter(dev); struct i2c_driver *driver = data; /* Have a look at each adapter, if clients of this driver are still * attached. If so, detach them to be able to kill the driver * afterwards. */ down(&i2c_adapter_class.sem); list_for_each_entry(adap, &i2c_adapter_class.devices, dev.node) { if (driver->detach_adapter) { if (driver->detach_adapter(adap)) { dev_err(&adap->dev, "detach_adapter failed " "for driver [%s]\n", if (driver->detach_adapter(adapter)) dev_err(&adapter->dev, "detach_adapter failed for driver [%s]\n", driver->driver.name); } } else { list_for_each_safe(item2, _n, &adap->clients) { client = list_entry(item2, struct i2c_client, list); struct list_head *item, *_n; struct i2c_client *client; list_for_each_safe(item, _n, &adapter->clients) { client = list_entry(item, struct i2c_client, list); if (client->driver != driver) continue; dev_dbg(&adap->dev, "detaching client [%s] " "at 0x%02x\n", client->name, client->addr); if (driver->detach_client(client)) { dev_err(&adap->dev, "detach_client " "failed for client [%s] at " "0x%02x\n", client->name, client->addr); } dev_dbg(&adapter->dev, "detaching client [%s] at 0x%02x\n", client->name, client->addr); if (driver->detach_client(client)) dev_err(&adapter->dev, "detach_client " "failed for client [%s] at 0x%02x\n", client->name, client->addr); } } return 0; } up(&i2c_adapter_class.sem); /** * i2c_del_driver - unregister I2C driver * @driver: the driver being unregistered * Context: can sleep */ void i2c_del_driver(struct i2c_driver *driver) { mutex_lock(&core_lock); /* new-style driver? */ if (is_newstyle_driver(driver)) goto unregister; class_for_each_device(&i2c_adapter_class, driver, __detach_adapter); unregister: driver_unregister(&driver->driver); Loading