diff options
author | Jean Delvare <khali@linux-fr.org> | 2009-06-19 16:58:18 +0200 |
---|---|---|
committer | Jean Delvare <khali@linux-fr.org> | 2009-06-19 16:58:18 +0200 |
commit | 729d6dd571464954f625e6b80950d9e4e3bd94f7 (patch) | |
tree | faf8ada32b03c8bc07e1ddb8ec0d26d6440b6d98 | |
parent | 352da9820e5506e3b8496e6052a2ad9c488efae8 (diff) | |
download | lwn-729d6dd571464954f625e6b80950d9e4e3bd94f7.tar.gz lwn-729d6dd571464954f625e6b80950d9e4e3bd94f7.zip |
i2c: Get rid of the legacy binding model
We converted all the legacy i2c drivers so we can finally get rid of
the legacy binding model. Hooray!
Signed-off-by: Jean Delvare <khali@linux-fr.org>
Cc: David Brownell <dbrownell@users.sourceforge.net>
-rw-r--r-- | Documentation/feature-removal-schedule.txt | 9 | ||||
-rw-r--r-- | Documentation/i2c/writing-clients | 16 | ||||
-rw-r--r-- | drivers/i2c/i2c-core.c | 83 | ||||
-rw-r--r-- | include/linux/i2c.h | 39 |
4 files changed, 20 insertions, 127 deletions
diff --git a/Documentation/feature-removal-schedule.txt b/Documentation/feature-removal-schedule.txt index 9163dade0706..f8cd450be9aa 100644 --- a/Documentation/feature-removal-schedule.txt +++ b/Documentation/feature-removal-schedule.txt @@ -368,15 +368,6 @@ Who: Krzysztof Piotr Oledzki <ole@ans.pl> --------------------------- -What: i2c_attach_client(), i2c_detach_client(), i2c_driver->detach_client() -When: 2.6.30 -Check: i2c_attach_client i2c_detach_client -Why: Deprecated by the new (standard) device driver binding model. Use - i2c_driver->probe() and ->remove() instead. -Who: Jean Delvare <khali@linux-fr.org> - ---------------------------- - What: fscher and fscpos drivers When: June 2009 Why: Deprecated by the new fschmd driver. diff --git a/Documentation/i2c/writing-clients b/Documentation/i2c/writing-clients index c1a06f989cf7..7860aafb483d 100644 --- a/Documentation/i2c/writing-clients +++ b/Documentation/i2c/writing-clients @@ -126,19 +126,9 @@ different) configuration information, as do drivers handling chip variants that can't be distinguished by protocol probing, or which need some board specific information to operate correctly. -Accordingly, the I2C stack now has two models for associating I2C devices -with their drivers: the original "legacy" model, and a newer one that's -fully compatible with the Linux 2.6 driver model. These models do not mix, -since the "legacy" model requires drivers to create "i2c_client" device -objects after SMBus style probing, while the Linux driver model expects -drivers to be given such device objects in their probe() routines. -The legacy model is deprecated now and will soon be removed, so we no -longer document it here. - - -Standard Driver Model Binding ("New Style") -------------------------------------------- +Device/Driver Binding +--------------------- System infrastructure, typically board-specific initialization code or boot firmware, reports what I2C devices exist. For example, there may be @@ -201,7 +191,7 @@ a given I2C bus. This is for example the case of hardware monitoring devices on a PC's SMBus. In that case, you may want to let your driver detect supported devices automatically. This is how the legacy model was working, and is now available as an extension to the standard -driver model (so that we can finally get rid of the legacy model.) +driver model. You simply have to define a detect callback which will attempt to identify supported devices (returning 0 for supported ones and -ENODEV diff --git a/drivers/i2c/i2c-core.c b/drivers/i2c/i2c-core.c index fc18fdbffd3f..dc8bc9131447 100644 --- a/drivers/i2c/i2c-core.c +++ b/drivers/i2c/i2c-core.c @@ -43,6 +43,7 @@ static DEFINE_IDR(i2c_adapter_idr); #define is_newstyle_driver(d) ((d)->probe || (d)->remove || (d)->detect) +static int i2c_attach_client(struct i2c_client *client); static int i2c_detect(struct i2c_adapter *adapter, struct i2c_driver *driver); /* ------------------------------------------------------------------------- */ @@ -83,10 +84,6 @@ static int i2c_device_uevent(struct device *dev, struct kobj_uevent_env *env) { struct i2c_client *client = to_i2c_client(dev); - /* by definition, legacy drivers can't hotplug */ - if (dev->driver) - return 0; - if (add_uevent_var(env, "MODALIAS=%s%s", I2C_MODULE_PREFIX, client->name)) return -ENOMEM; @@ -455,7 +452,7 @@ static int i2c_register_adapter(struct i2c_adapter *adap) dev_dbg(&adap->dev, "adapter [%s] registered\n", adap->name); - /* create pre-declared device nodes for new-style drivers */ + /* create pre-declared device nodes */ if (adap->nr < __i2c_first_dynamic_bus_num) i2c_scan_static_board_info(adap); @@ -617,26 +614,9 @@ int i2c_del_adapter(struct i2c_adapter *adap) if (res) goto out_unlock; - /* detach any active clients. This must be done first, because - * it can fail; in which case we give up. */ + /* Detach any active clients */ list_for_each_entry_safe_reverse(client, _n, &adap->clients, list) { - struct i2c_driver *driver; - - driver = client->driver; - - /* new style, follow standard driver model */ - if (!driver || is_newstyle_driver(driver)) { - i2c_unregister_device(client); - continue; - } - - /* legacy drivers create and remove clients themselves */ - if ((res = driver->detach_client(client))) { - dev_err(&adap->dev, "detach_client failed for client " - "[%s] at address 0x%02x\n", client->name, - client->addr); - goto out_unlock; - } + i2c_unregister_device(client); } /* clean up the sysfs representation */ @@ -680,11 +660,7 @@ static int __attach_adapter(struct device *dev, void *data) /* * 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 - * are two models for binding the driver to its device: "new style" drivers - * follow the standard Linux driver model and just respond to probe() calls - * issued if the driver core sees they match(); "legacy" drivers create device - * nodes themselves. + * i2c slave chips, on a bus instance associated with some i2c_adapter. */ int i2c_register_driver(struct module *owner, struct i2c_driver *driver) @@ -695,21 +671,11 @@ int i2c_register_driver(struct module *owner, struct i2c_driver *driver) if (unlikely(WARN_ON(!i2c_bus_type.p))) return -EAGAIN; - /* new style driver methods can't mix with legacy ones */ - if (is_newstyle_driver(driver)) { - if (driver->detach_adapter || driver->detach_client) { - printk(KERN_WARNING - "i2c-core: driver [%s] is confused\n", - driver->driver.name); - return -EINVAL; - } - } - /* add the driver to the list of i2c drivers in the driver core */ driver->driver.owner = owner; driver->driver.bus = &i2c_bus_type; - /* for new style drivers, when registration returns the driver core + /* When registration returns, the driver core * will have called probe() for all matching-but-unbound devices. */ res = driver_register(&driver->driver); @@ -748,29 +714,11 @@ static int __detach_adapter(struct device *dev, void *data) if (is_newstyle_driver(driver)) return 0; - /* 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. - */ if (driver->detach_adapter) { if (driver->detach_adapter(adapter)) dev_err(&adapter->dev, "detach_adapter failed for driver [%s]\n", driver->driver.name); - } else { - struct i2c_client *client, *_n; - - list_for_each_entry_safe(client, _n, &adapter->clients, list) { - if (client->driver != driver) - continue; - 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; @@ -812,7 +760,7 @@ static int i2c_check_addr(struct i2c_adapter *adapter, int addr) return device_for_each_child(&adapter->dev, &addr, __i2c_check_addr); } -int i2c_attach_client(struct i2c_client *client) +static int i2c_attach_client(struct i2c_client *client) { struct i2c_adapter *adapter = client->adapter; int res; @@ -854,23 +802,6 @@ out_err: "(%d)\n", client->name, client->addr, res); return res; } -EXPORT_SYMBOL(i2c_attach_client); - -int i2c_detach_client(struct i2c_client *client) -{ - struct i2c_adapter *adapter = client->adapter; - - mutex_lock(&adapter->clist_lock); - list_del(&client->list); - mutex_unlock(&adapter->clist_lock); - - init_completion(&client->released); - device_unregister(&client->dev); - wait_for_completion(&client->released); - - return 0; -} -EXPORT_SYMBOL(i2c_detach_client); /** * i2c_use_client - increments the reference count of the i2c client structure diff --git a/include/linux/i2c.h b/include/linux/i2c.h index b3f4606afa0e..43a3545670b8 100644 --- a/include/linux/i2c.h +++ b/include/linux/i2c.h @@ -100,9 +100,8 @@ extern s32 i2c_smbus_write_i2c_block_data(struct i2c_client *client, * @class: What kind of i2c device we instantiate (for detect) * @attach_adapter: Callback for bus addition (for legacy drivers) * @detach_adapter: Callback for bus removal (for legacy drivers) - * @detach_client: Callback for device removal (for legacy drivers) - * @probe: Callback for device binding (new-style drivers) - * @remove: Callback for device unbinding (new-style drivers) + * @probe: Callback for device binding + * @remove: Callback for device unbinding * @shutdown: Callback for device shutdown * @suspend: Callback for device suspend * @resume: Callback for device resume @@ -137,26 +136,14 @@ struct i2c_driver { int id; unsigned int class; - /* Notifies the driver that a new bus has appeared. This routine - * can be used by the driver to test if the bus meets its conditions - * & seek for the presence of the chip(s) it supports. If found, it - * registers the client(s) that are on the bus to the i2c admin. via - * i2c_attach_client. (LEGACY I2C DRIVERS ONLY) + /* Notifies the driver that a new bus has appeared or is about to be + * removed. You should avoid using this if you can, it will probably + * be removed in a near future. */ int (*attach_adapter)(struct i2c_adapter *); int (*detach_adapter)(struct i2c_adapter *); - /* tells the driver that a client is about to be deleted & gives it - * the chance to remove its private data. Also, if the client struct - * has been dynamically allocated by the driver in the function above, - * it must be freed here. (LEGACY I2C DRIVERS ONLY) - */ - int (*detach_client)(struct i2c_client *) __deprecated; - - /* Standard driver model interfaces, for "new style" i2c drivers. - * With the driver model, device enumeration is NEVER done by drivers; - * it's done by infrastructure. (NEW STYLE DRIVERS ONLY) - */ + /* Standard driver model interfaces */ int (*probe)(struct i2c_client *, const struct i2c_device_id *); int (*remove)(struct i2c_client *); @@ -248,11 +235,10 @@ static inline void i2c_set_clientdata(struct i2c_client *dev, void *data) * that, such as chip type, configuration, associated IRQ, and so on. * * i2c_board_info is used to build tables of information listing I2C devices - * that are present. This information is used to grow the driver model tree - * for "new style" I2C drivers. For mainboards this is done statically using - * i2c_register_board_info(); bus numbers identify adapters that aren't - * yet available. For add-on boards, i2c_new_device() does this dynamically - * with the adapter already known. + * that are present. This information is used to grow the driver model tree. + * For mainboards this is done statically using i2c_register_board_info(); + * bus numbers identify adapters that aren't yet available. For add-on boards, + * i2c_new_device() does this dynamically with the adapter already known. */ struct i2c_board_info { char type[I2C_NAME_SIZE]; @@ -425,11 +411,6 @@ static inline int i2c_add_driver(struct i2c_driver *driver) return i2c_register_driver(THIS_MODULE, driver); } -/* These are deprecated, your driver should use the standard .probe() - * and .remove() methods instead. */ -extern int __deprecated i2c_attach_client(struct i2c_client *); -extern int __deprecated i2c_detach_client(struct i2c_client *); - extern struct i2c_client *i2c_use_client(struct i2c_client *client); extern void i2c_release_client(struct i2c_client *client); |