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:
parent
352da9820e
commit
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
|
What: fscher and fscpos drivers
|
||||||
When: June 2009
|
When: June 2009
|
||||||
Why: Deprecated by the new fschmd driver.
|
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
|
that can't be distinguished by protocol probing, or which need some board
|
||||||
specific information to operate correctly.
|
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
|
Device/Driver Binding
|
||||||
longer document it here.
|
---------------------
|
||||||
|
|
||||||
|
|
||||||
Standard Driver Model Binding ("New Style")
|
|
||||||
-------------------------------------------
|
|
||||||
|
|
||||||
System infrastructure, typically board-specific initialization code or
|
System infrastructure, typically board-specific initialization code or
|
||||||
boot firmware, reports what I2C devices exist. For example, there may be
|
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
|
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
|
detect supported devices automatically. This is how the legacy model
|
||||||
was working, and is now available as an extension to the standard
|
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
|
You simply have to define a detect callback which will attempt to
|
||||||
identify supported devices (returning 0 for supported ones and -ENODEV
|
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)
|
#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);
|
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);
|
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",
|
if (add_uevent_var(env, "MODALIAS=%s%s",
|
||||||
I2C_MODULE_PREFIX, client->name))
|
I2C_MODULE_PREFIX, client->name))
|
||||||
return -ENOMEM;
|
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);
|
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)
|
if (adap->nr < __i2c_first_dynamic_bus_num)
|
||||||
i2c_scan_static_board_info(adap);
|
i2c_scan_static_board_info(adap);
|
||||||
|
|
||||||
|
@ -617,26 +614,9 @@ int i2c_del_adapter(struct i2c_adapter *adap)
|
||||||
if (res)
|
if (res)
|
||||||
goto out_unlock;
|
goto out_unlock;
|
||||||
|
|
||||||
/* detach any active clients. This must be done first, because
|
/* Detach any active clients */
|
||||||
* it can fail; in which case we give up. */
|
|
||||||
list_for_each_entry_safe_reverse(client, _n, &adap->clients, list) {
|
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);
|
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;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* clean up the sysfs representation */
|
/* 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
|
* 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
|
* i2c slave chips, on a bus instance associated with some i2c_adapter.
|
||||||
* 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.
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
int i2c_register_driver(struct module *owner, struct i2c_driver *driver)
|
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)))
|
if (unlikely(WARN_ON(!i2c_bus_type.p)))
|
||||||
return -EAGAIN;
|
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 */
|
/* add the driver to the list of i2c drivers in the driver core */
|
||||||
driver->driver.owner = owner;
|
driver->driver.owner = owner;
|
||||||
driver->driver.bus = &i2c_bus_type;
|
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.
|
* will have called probe() for all matching-but-unbound devices.
|
||||||
*/
|
*/
|
||||||
res = driver_register(&driver->driver);
|
res = driver_register(&driver->driver);
|
||||||
|
@ -748,29 +714,11 @@ static int __detach_adapter(struct device *dev, void *data)
|
||||||
if (is_newstyle_driver(driver))
|
if (is_newstyle_driver(driver))
|
||||||
return 0;
|
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) {
|
||||||
if (driver->detach_adapter(adapter))
|
if (driver->detach_adapter(adapter))
|
||||||
dev_err(&adapter->dev,
|
dev_err(&adapter->dev,
|
||||||
"detach_adapter failed for driver [%s]\n",
|
"detach_adapter failed for driver [%s]\n",
|
||||||
driver->driver.name);
|
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;
|
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);
|
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;
|
struct i2c_adapter *adapter = client->adapter;
|
||||||
int res;
|
int res;
|
||||||
|
@ -854,23 +802,6 @@ out_err:
|
||||||
"(%d)\n", client->name, client->addr, res);
|
"(%d)\n", client->name, client->addr, res);
|
||||||
return 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
|
* 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)
|
* @class: What kind of i2c device we instantiate (for detect)
|
||||||
* @attach_adapter: Callback for bus addition (for legacy drivers)
|
* @attach_adapter: Callback for bus addition (for legacy drivers)
|
||||||
* @detach_adapter: Callback for bus removal (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
|
||||||
* @probe: Callback for device binding (new-style drivers)
|
* @remove: Callback for device unbinding
|
||||||
* @remove: Callback for device unbinding (new-style drivers)
|
|
||||||
* @shutdown: Callback for device shutdown
|
* @shutdown: Callback for device shutdown
|
||||||
* @suspend: Callback for device suspend
|
* @suspend: Callback for device suspend
|
||||||
* @resume: Callback for device resume
|
* @resume: Callback for device resume
|
||||||
|
@ -137,26 +136,14 @@ struct i2c_driver {
|
||||||
int id;
|
int id;
|
||||||
unsigned int class;
|
unsigned int class;
|
||||||
|
|
||||||
/* Notifies the driver that a new bus has appeared. This routine
|
/* Notifies the driver that a new bus has appeared or is about to be
|
||||||
* can be used by the driver to test if the bus meets its conditions
|
* removed. You should avoid using this if you can, it will probably
|
||||||
* & seek for the presence of the chip(s) it supports. If found, it
|
* be removed in a near future.
|
||||||
* registers the client(s) that are on the bus to the i2c admin. via
|
|
||||||
* i2c_attach_client. (LEGACY I2C DRIVERS ONLY)
|
|
||||||
*/
|
*/
|
||||||
int (*attach_adapter)(struct i2c_adapter *);
|
int (*attach_adapter)(struct i2c_adapter *);
|
||||||
int (*detach_adapter)(struct i2c_adapter *);
|
int (*detach_adapter)(struct i2c_adapter *);
|
||||||
|
|
||||||
/* tells the driver that a client is about to be deleted & gives it
|
/* Standard driver model interfaces */
|
||||||
* 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)
|
|
||||||
*/
|
|
||||||
int (*probe)(struct i2c_client *, const struct i2c_device_id *);
|
int (*probe)(struct i2c_client *, const struct i2c_device_id *);
|
||||||
int (*remove)(struct i2c_client *);
|
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.
|
* that, such as chip type, configuration, associated IRQ, and so on.
|
||||||
*
|
*
|
||||||
* i2c_board_info is used to build tables of information listing I2C devices
|
* 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
|
* 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
|
* For mainboards this is done statically using i2c_register_board_info();
|
||||||
* i2c_register_board_info(); bus numbers identify adapters that aren't
|
* bus numbers identify adapters that aren't yet available. For add-on boards,
|
||||||
* yet available. For add-on boards, i2c_new_device() does this dynamically
|
* i2c_new_device() does this dynamically with the adapter already known.
|
||||||
* with the adapter already known.
|
|
||||||
*/
|
*/
|
||||||
struct i2c_board_info {
|
struct i2c_board_info {
|
||||||
char type[I2C_NAME_SIZE];
|
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);
|
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 struct i2c_client *i2c_use_client(struct i2c_client *client);
|
||||||
extern void i2c_release_client(struct i2c_client *client);
|
extern void i2c_release_client(struct i2c_client *client);
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue