为了简短文章长度,一些检查和调试信息被删除
1. 在xxx_init()中会调用i2c_add_driver()函数
static int __init ltr559_init(void)
{
return i2c_add_driver(<r_ps_driver);//ltr_ps_driver是一个struct i2c_driver
}
static void __exit ltr559_exit(void)
{
i2c_del_driver(<r_ps_driver);
}
module_init(ltr559_init);
module_exit(ltr559_exit);
2. i2c_add_driver
是一个宏命令,调用 i2c_register_driver
/************************* include/linux/i2c.h *******************************/
#define i2c_add_driver(driver) \
i2c_register_driver(THIS_MODULE, driver)
3. i2c_register_driver
在一些 i2c_adapter 相关总线实例, 一个 i2c_driver 可以被一个或多个 i2c_client 设备节点使用去访问 i2c_slave_chip
该函数
/********************** kernel/drivers/i2c/i2c_core.c ************************/
int i2c_register_driver(struct module *owner, struct i2c_driver *driver)
{
int res;
/*在驱动模块初始化完成后才可以注册 */
if (unlikely(WARN_ON(!i2c_bus_type.p)))
return -EAGAIN;
/* 添加该驱动到i2c驱动链表上 */
driver->driver.owner = owner;
driver->driver.bus = &i2c_bus_type;
/* 当注册完成,驱动代码将调用probe()去匹配设备 */
res = driver_register(&driver->driver);
INIT_LIST_HEAD(&driver->clients);
i2c_for_each_dev(driver, __process_new_driver);
return 0;
}
4. driver_register
主要的工作还是由 bus_add_driver 来操作
/*************************** kernel/driver/base/driver.c **************************/
int driver_register(struct device_driver *drv)
{
int ret;
struct device_driver *other;
BUG_ON(!drv->bus->p);
other = driver_find(drv->name, drv->bus);//通过driver_name在bus上查找该driver,正常返回0
ret = bus_add_driver(drv); //主要
ret = driver_add_groups(drv, drv->groups);
if (ret) {
bus_remove_driver(drv);
return ret;
}
kobject_uevent(&drv->p->kobj, KOBJ_ADD);
return ret;
}
5. bus_add_driver
/**************** kernel/driver/base/bus.c **********************************/
int bus_add_driver(struct device_driver *drv)
{
struct bus_type *bus;
struct driver_private *priv;
int error = 0;
bus = bus_get(drv->bus);
priv = kzalloc(sizeof(*priv), GFP_KERNEL);
klist_init(&priv->klist_devices, NULL, NULL);
priv->driver = drv;
drv->p = priv;
priv->kobj.kset = bus->p->drivers_kset;
error = kobject_init_and_add(&priv->kobj, &driver_ktype, NULL,
"%s", drv->name);
klist_add_tail(&priv->knode_bus, &bus->p->klist_drivers);
if (drv->bus->p->drivers_autoprobe) {
error = driver_attach(drv); //尝试绑定
}
module_add_driver(drv->owner, drv);
error = driver_create_file(drv, &driver_attr_uevent); //为驱动创建文件,继续调用sysfs_create_file()
error = driver_add_attrs(bus, drv);
if (!drv->suppress_bind_attrs) {
error = add_bind_files(drv);
}
return 0;
}
6. driver_attach
/**
* driver_attach - try to bind driver to devices.
* @drv: driver.
*
* Walk the list of devices that the bus has on it and try to
* match the driver with each one. If driver_probe_device()
* returns 0 and the @dev->driver is set, we've found a
* compatible pair.
*/
int driver_attach(struct device_driver *drv)
{
return bus_for_each_dev(drv->bus, NULL, drv, __driver_attach);
}
7. bus_for_each_dev
参数 fn 就是__driver_attach()函数
/**
* bus_for_each_dev - device iterator.
* @bus: bus type.
* @start: device to start iterating from.
* @data: data for the callback.
* @fn: function to be called for each device.
*/
int bus_for_each_dev(struct bus_type *bus, struct device *start,
void *data, int (*fn)(struct device *, void *))
{
struct klist_iter i;
struct device *dev;
int error = 0;
if (!bus || !bus->p)
return -EINVAL;
klist_iter_init_node(&bus->p->klist_devices, &i,
(start ? &start->p->knode_bus : NULL));
while ((dev = next_device(&i)) && !error)
error = fn(dev, data);
klist_iter_exit(&i);
return error;
}
8. __driver_attach
static int __driver_attach(struct device *dev, void *data)
{
struct device_driver *drv = data;
if (!driver_match_device(drv, dev))
return 0;
if (dev->parent) /* 如果是被usb接口调用,父设备也要上锁*/
device_lock(dev->parent);
device_lock(dev);
if (!dev->driver)
driver_probe_device(drv, dev); //
device_unlock(dev);
if (dev->parent)
device_unlock(dev->parent);
return 0;
}
9. driver_probe_device
如果设备没有注册,则该函数返回 -ENODEV , probe 成功 返回 1 ,失败 返回 0 。该函数被调用时,设备一定要上锁
/********************** kernel/drivers/base/dd.c *********************************
* driver_probe_device - attempt to bind device & driver together
* @drv: driver to bind a device to
* @dev: device to try to bind to the driver
*/
int driver_probe_device(struct device_driver *drv, struct device *dev)
{
int ret = 0;
if (!device_is_registered(dev)) //判断设备是否注册
return -ENODEV;
pm_runtime_barrier(dev);
ret = really_probe(dev, drv);
pm_request_idle(dev);
return ret;
}
10. really_probe
/********************** kernel/drivers/base/dd.c *********************************/
static int really_probe(struct device *dev, struct device_driver *drv)
{
int ret = 0;
atomic_inc(&probe_count);
WARN_ON(!list_empty(&dev->devres_head));
dev->driver = drv;
ret = pinctrl_bind_pins(dev);
if (ret)
goto probe_failed;
if (driver_sysfs_add(dev)) {
printk(KERN_ERR "%s: driver_sysfs_add(%s) failed\n",
__func__, dev_name(dev));
goto probe_failed;
}
if (dev->bus->probe) {
ret = dev->bus->probe(dev);
if (ret)
goto probe_failed;
} else if (drv->probe) {
ret = drv->probe(dev); //这里才是正在调用驱动中实现的probe函数
if (ret)
goto probe_failed;
}
driver_bound(dev);
ret = 1;
goto done;
probe_failed:
devres_release_all(dev);
driver_sysfs_remove(dev);
dev->driver = NULL;
dev_set_drvdata(dev, NULL);
if (ret == -EPROBE_DEFER) {
/* Driver requested deferred probing */
dev_info(dev, "Driver %s requests probe deferral\n", drv->name);
driver_deferred_probe_add(dev);
} else if (ret != -ENODEV && ret != -ENXIO) {
/* driver matched but the probe failed */
printk(KERN_WARNING
"%s: probe of %s failed with error %d\n",
drv->name, dev_name(dev), ret);
} else {
pr_debug("%s: probe of %s rejects match %d\n",
drv->name, dev_name(dev), ret);
}
/*
* Ignore errors returned by ->probe so that the next driver can try
* its luck.
*/
ret = 0;
done:
atomic_dec(&probe_count);
wake_up(&probe_waitqueue);
return ret;
}