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>
This commit is contained in:
Родитель
352da9820e
Коммит
729d6dd571
|
@ -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.
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче