Subject: i2c: Remove the duplicated i2c drivers list Get rid of the I2C-private list of drivers; instead, use the list already maintained by the driver model core. This is largely inspired from a patch posted by David Brownell back in November 2006. Signed-off-by: Jean Delvare --- Documentation/feature-removal-schedule.txt | 9 ---- drivers/i2c/i2c-core.c | 60 +++++++++++++++++----------- include/linux/i2c.h | 1 - 3 files changed, 37 insertions(+), 33 deletions(-) --- linux-2.6.21-pre.orig/Documentation/feature-removal-schedule.txt 2007-02-13 10:51:00.000000000 +0100 +++ linux-2.6.21-pre/Documentation/feature-removal-schedule.txt 2007-02-13 10:52:24.000000000 +0100 @@ -198,15 +198,6 @@ Who: Jean Delvare --------------------------- -What: i2c_adapter.list -When: July 2007 -Why: Superfluous, this list duplicates the one maintained by the driver - core. -Who: Jean Delvare , - David Brownell - ---------------------------- - What: drivers depending on OBSOLETE_OSS When: options in 2.6.22, code in 2.6.24 Why: OSS drivers with ALSA replacements --- linux-2.6.21-pre.orig/drivers/i2c/i2c-core.c 2007-02-13 10:51:03.000000000 +0100 +++ linux-2.6.21-pre/drivers/i2c/i2c-core.c 2007-02-13 10:52:08.000000000 +0100 @@ -37,7 +37,6 @@ static LIST_HEAD(adapters); -static LIST_HEAD(drivers); static DEFINE_MUTEX(core_lists); static DEFINE_IDR(i2c_adapter_idr); @@ -155,6 +154,21 @@ static struct device_attribute dev_attr_ * --------------------------------------------------- */ +static int i2c_do_add_adapter(struct device_driver *d, void *data) +{ + struct i2c_driver *driver = to_i2c_driver(d); + struct i2c_adapter *adapter = data; + int res; + + if (!driver->attach_adapter) + return 0; + res = driver->attach_adapter(adapter); + if (res) + dev_err(&adapter->dev, "attach_adapter failed (%d) " + "for driver [%s]\n", res, driver->driver.name); + return res; +} + /* ----- * i2c_add_adapter is called from within the algorithm layer, * when a new hw adapter registers. A new device is register to be @@ -163,8 +177,6 @@ static struct device_attribute dev_attr_ int i2c_add_adapter(struct i2c_adapter *adap) { int id, res = 0; - struct list_head *item; - struct i2c_driver *driver; mutex_lock(&core_lists); @@ -207,13 +219,9 @@ int i2c_add_adapter(struct i2c_adapter * dev_dbg(&adap->dev, "adapter [%s] registered\n", adap->name); - /* inform drivers of new adapters */ - list_for_each(item,&drivers) { - driver = list_entry(item, struct i2c_driver, list); - if (driver->attach_adapter) - /* We ignore the return code; if it fails, too bad */ - driver->attach_adapter(adap); - } + /* let drivers scan this bus for matching devices */ + res = bus_for_each_drv(&i2c_bus_type, NULL, adap, + i2c_do_add_adapter); out_unlock: mutex_unlock(&core_lists); @@ -229,12 +237,25 @@ out_list: goto out_unlock; } +static int i2c_do_del_adapter(struct device_driver *d, void *data) +{ + struct i2c_driver *driver = to_i2c_driver(d); + struct i2c_adapter *adapter = data; + int res; + + if (!driver->detach_adapter) + return 0; + res = driver->detach_adapter(adapter); + if (res) + dev_err(&adapter->dev, "detach_adapter failed (%d) " + "for driver [%s]\n", res, driver->driver.name); + return res; +} int i2c_del_adapter(struct i2c_adapter *adap) { struct list_head *item, *_n; struct i2c_adapter *adap_from_list; - struct i2c_driver *driver; struct i2c_client *client; int res = 0; @@ -252,16 +273,11 @@ int i2c_del_adapter(struct i2c_adapter * goto out_unlock; } - list_for_each(item,&drivers) { - driver = list_entry(item, struct i2c_driver, list); - if (driver->detach_adapter) - if ((res = driver->detach_adapter(adap))) { - dev_err(&adap->dev, "detach_adapter failed " - "for driver [%s]\n", - driver->driver.name); - goto out_unlock; - } - } + /* Tell drivers about this removal */ + res = bus_for_each_drv(&i2c_bus_type, NULL, adap, + i2c_do_del_adapter); + if (res) + goto out_unlock; /* detach any active clients. This must be done first, because * it can fail; in which case we give up. */ @@ -318,7 +334,6 @@ int i2c_register_driver(struct module *o mutex_lock(&core_lists); - list_add_tail(&driver->list,&drivers); pr_debug("i2c-core: driver [%s] registered\n", driver->driver.name); /* now look for instances of driver on our adapters */ @@ -377,7 +392,6 @@ int i2c_del_driver(struct i2c_driver *dr } driver_unregister(&driver->driver); - list_del(&driver->list); pr_debug("i2c-core: driver [%s] unregistered\n", driver->driver.name); out_unlock: --- linux-2.6.21-pre.orig/include/linux/i2c.h 2007-02-13 10:51:03.000000000 +0100 +++ linux-2.6.21-pre/include/linux/i2c.h 2007-02-13 10:52:08.000000000 +0100 @@ -136,7 +136,6 @@ struct i2c_driver { int (*command)(struct i2c_client *client,unsigned int cmd, void *arg); struct device_driver driver; - struct list_head list; }; #define to_i2c_driver(d) container_of(d, struct i2c_driver, driver)