四、i2c driver注册
在分析i2c driver的时候,有必要先分析一下i2c架构的初始化,代码如下:
static int __init i2c_init(void)
{
int retval;
retval = bus_register(&i2c_bus_type);
if (retval)
return retval;
retval = class_register(&i2c_adapter_class);
if (retval)
goto bus_err;
retval = i2c_add_driver(&dummy_driver);
if (retval)
goto class_err;
return 0;
class_err:
class_unregister(&i2c_adapter_class);
bus_err:
bus_unregister(&i2c_bus_type);
return retval;
}
subsys_initcall(i2c_init);
很明显,i2c_init()会在系统初始化的时候被调用.
在i2c_init中,先注册了i2c_bus_type的bus,i2c_adapter_class的class.然后再调用i2c_add_driver()注册了一个i2c driver。
I2c_bus_type结构如下:
static struct bus_type i2c_bus_type = {
.name = "i2c",
.dev_attrs = i2c_dev_attrs,
.match = i2c_device_match,
.uevent = i2c_device_uevent,
.probe = i2c_device_probe,
.remove = i2c_device_remove,
.shutdown = i2c_device_shutdown,
.suspend = i2c_device_suspend,
.resume = i2c_device_resume,
};
从上面的初始化函数里也看到了,注册i2c driver的接口为i2c_add_driver().代码如下:
static inline int i2c_add_driver(struct i2c_driver *driver)
{
return i2c_register_driver(THIS_MODULE, driver);
}
继续跟踪:
int i2c_register_driver(struct module *owner, struct i2c_driver *driver)
{
int res;
/* new style driver methods can't mix with legacy ones */
//如果是一个newstyle的driver.但又定义了attach_adapter/detach_adapter.非法
if (is_newstyle_driver(driver)) {
if (driver->attach_adapter || 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 */
//关联到i2c_bus_types
driver->driver.owner = owner;
driver->driver.bus = &i2c_bus_type;
/* for new style drivers, when registration returns the driver core
* will have called probe() for all matching-but-unbound devices.
*/
//注册内嵌的driver
res = driver_register(&driver->driver);
if (res)
return res;
mutex_lock(&core_lock);
pr_debug("i2c-core: driver [%s] registered/n", driver->driver.name);
/* legacy drivers scan i2c busses directly */
//遍历所有的adapter,对其都调用driver->attach_adapter
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);
}
mutex_unlock(&core_lock);
return 0;
}
这里也有两种形式的区分,对于第一种,只需要将内嵌的driver注册就可以了,对于legacy的情况,对每一个adapter都调用driver->attach_adapter().
现在,我们可以将adapter和i2c driver关联起来考虑一下了:
1、如果是news style形式的,在注册adapter的时候,将它上面的i2c设备转换成了struct client。struct client->dev->bus又指定了和i2c driver同一个bus,因此它们可以发生probe.
2、如果是legacy形式,就直接找到对应的对象,调用driver->attach_adapter().
五、i2c_bus_type的相关操作
I2c_bus_type的操作主要存在于new-style形式的驱动中.接下来分析一下对应的probe过程:
5.1、match过程分析
Match对应的操作函数为i2c_device_match().代码如下
static int i2c_device_match(struct device *dev, struct device_driver *drv)
{
struct i2c_client *client = to_i2c_client(dev);
struct i2c_driver *driver = to_i2c_driver(drv);
/* make legacy i2c drivers bypass driver model probing entirely;
* such drivers scan each i2c adapter/bus themselves.
*/
if (!is_newstyle_driver(driver))
return 0;
/* match on an id table if there is one */
if (driver->id_table)
return i2c_match_id(driver->id_table, client) != NULL;
return 0;
}
如果该驱动不是一个new-style形式的.或者driver没有定义匹配的id_table.都会匹配失败.
继续跟踪进i2c_match_id():
static const struct i2c_device_id *i2c_match_id(const struct i2c_device_id *id,
const struct i2c_client *client)
{
while (id->name[0]) {
if (strcmp(client->name, id->name) == 0)
return id;
id++;
}
return NULL;
}
由此可见.如果client的名字和driver->id_table[]中的名称匹配即为成功.
5.2、probe过程分析
Probe对应的函数为: i2c_device_probe()
static int i2c_device_probe(struct device *dev)
{
struct i2c_client *client = to_i2c_client(dev);
struct i2c_driver *driver = to_i2c_driver(dev->driver);
const struct i2c_device_id *id;
int status;
if (!driver->probe)
return -ENODEV;
client->driver = driver;
dev_dbg(dev, "probe/n");
if (driver->id_table)
id = i2c_match_id(driver->id_table, client);
else
id = NULL;
status = driver->probe(client, id);
if (status)
client->driver = NULL;
return status;
}
这个函数也很简单,就是将probe流程回溯到i2c driver的probe()。
阅读(852) | 评论(0) | 转发(0) |