linux-i2c驱动 之 i2c设备层的注册过程probe函数如何被调用分析

Linuxi2c驱动的加载过程,分为i2c设备层、i2c adapter层与i2c核心层

i2c设备驱动层也就是我们为特定i2c设备编写的驱动,下面是我自己理解的i2c驱动的注册过程

在我们写的i2c设备驱动中,我们会调用i2c_add_driver()开始i2c设备驱动的注册,该函数调用i2c_register_driver完成所有注册操作

 

 

  1. static inline int i2c_add_driver(struct i2c_driver *driver)  
  2. {  
  3. return i2c_register_driver(THIS_MODULE, driver);  
  4. }  
static inline int i2c_add_driver(struct i2c_driver *driver)
{
return i2c_register_driver(THIS_MODULE, driver);
}

i2c_register_driver会调用driver_register() 来将设备驱动添加到总线的设备驱动链表中

  1. int i2c_register_driver(struct module *owner, struct i2c_driver *driver)  
  2. {  
  3. int res;  
  4. /* Can't register until after driver model init */  
  5. if (unlikely(WARN_ON(!i2c_bus_type.p)))  
  6. return -EAGAIN;  
  7. driver->driver.owner = owner;  
  8. driver->driver.bus = &i2c_bus_type;  
  9. /* When registration returns, the driver core  
  10.  * will have called probe() for all matching-but-unbound devices.  
  11.  */  
  12. res = <STRONG>driver_register</STRONG>(&driver->driver);  
  13. if (res)  
  14. return res;  
  15. pr_debug("i2c-core: driver [%s] registered\n", driver->driver.name);  
  16. INIT_LIST_HEAD(&driver->clients);  
  17. /* Walk the adapters that are already present */  
  18. mutex_lock(&core_lock);  
  19. bus_for_each_dev(&i2c_bus_type, NULL, driver, __attach_adapter);  
  20. mutex_unlock(&core_lock);  
  21. return 0;  
  22. }  
int i2c_register_driver(struct module *owner, struct i2c_driver *driver)
{
int res;
/* Can't register until after driver model init */
if (unlikely(WARN_ON(!i2c_bus_type.p)))
return -EAGAIN;
driver->driver.owner = owner;
driver->driver.bus = &i2c_bus_type;
/* When registration returns, the driver core
 * will have called probe() for all matching-but-unbound devices.
 */
res = driver_register(&driver->driver);
if (res)
return res;
pr_debug("i2c-core: driver [%s] registered\n", driver->driver.name);
INIT_LIST_HEAD(&driver->clients);
/* Walk the adapters that are already present */
mutex_lock(&core_lock);
bus_for_each_dev(&i2c_bus_type, NULL, driver, __attach_adapter);
mutex_unlock(&core_lock);
return 0;
}


driver_register,通过driver_find来判断驱动是否已经注册,然后会调用

bus_add_drive

将设备驱动添加到总线上

  1. int driver_register(struct device_driver *drv)  
  2. {  
  3. int ret;  
  4. struct device_driver *other;  
  5. BUG_ON(!drv->bus->p);  
  6. if ((drv->bus->probe && drv->probe) ||  
  7.     (drv->bus->remove && drv->remove) ||  
  8.     (drv->bus->shutdown && drv->shutdown))  
  9. printk(KERN_WARNING "Driver '%s' needs updating - please use "  
  10. "bus_type methods\n", drv->name);  
  11. other = driver_find(drv->name, drv->bus);  
  12. if (other) {  
  13. put_driver(other);  
  14. printk(KERN_ERR "Error: Driver '%s' is already registered, "  
  15. "aborting...\n", drv->name);  
  16. return -EBUSY;  
  17. }  
  18. ret = <STRONG>bus_add_driver</STRONG>(drv);  
  19. if (ret)  
  20. return ret;  
  21. ret = driver_add_groups(drv, drv->groups);  
  22. if (ret)  
  23. bus_remove_driver(drv);  
  24. return ret;  
  25. }  
int driver_register(struct device_driver *drv)
{
int ret;
struct device_driver *other;
BUG_ON(!drv->bus->p);
if ((drv->bus->probe && drv->probe) ||
    (drv->bus->remove && drv->remove) ||
    (drv->bus->shutdown && drv->shutdown))
printk(KERN_WARNING "Driver '%s' needs updating - please use "
"bus_type methods\n", drv->name);
other = driver_find(drv->name, drv->bus);
if (other) {
put_driver(other);
printk(KERN_ERR "Error: Driver '%s' is already registered, "
"aborting...\n", drv->name);
return -EBUSY;
}
ret = bus_add_driver(drv);
if (ret)
return ret;
ret = driver_add_groups(drv, drv->groups);
if (ret)
bus_remove_driver(drv);
return ret;
}


bus_add_driver中初始化priv->klist_devices的值,并将priv赋值给drv->p

通过调用klist_add_tail(&priv->knode_bus, &bus->p->klist_drivers)将驱动信息保存到总线结构中,在此之前将调用driver_attach()

  1. int bus_add_driver(struct device_driver *drv)  
  2. {  
  3. struct bus_type *bus;  
  4. struct driver_private *priv;  
  5. int error = 0;  
  6. bus = bus_get(drv->bus);  
  7. if (!bus)  
  8. return -EINVAL;  
  9. pr_debug("bus: '%s': add driver %s\n", bus->name, drv->name);  
  10. priv = kzalloc(sizeof(*priv), GFP_KERNEL);  
  11. if (!priv) {  
  12. error = -ENOMEM;  
  13. goto out_put_bus;  
  14. }  
  15. <STRONG>klist_init</STRONG>(&priv->klist_devices, NULL, NULL);  
  16. priv->driver = drv;  
  17. drv->p = priv;  
  18. priv->kobj.kset = bus->p->drivers_kset;  
  19. error = kobject_init_and_add(&priv->kobj, &driver_ktype, NULL,  
  20.      "%s", drv->name);  
  21. if (error)  
  22. goto out_unregister;  
  23. if (drv->bus->p->drivers_autoprobe) {  
  24. error = <STRONG>driver_attach</STRONG>(drv);  
  25. if (error)  
  26. goto out_unregister;  
  27. }  
  28. <STRONG>klist_add_tail</STRONG>(&priv->knode_bus, &bus->p->klist_drivers);  
  29. module_add_driver(drv->owner, drv);  
  30. error = driver_create_file(drv, &driver_attr_uevent);  
  31. if (error) {  
  32. printk(KERN_ERR "%s: uevent attr (%s) failed\n",  
  33. __func__, drv->name);  
  34. }  
  35. error = driver_add_attrs(bus, drv);  
  36. if (error) {  
  37. /* How the hell do we get out of this pickle? Give up */  
  38. printk(KERN_ERR "%s: driver_add_attrs(%s) failed\n",  
  39. __func__, drv->name);  
  40. }  
  41. if (!drv->suppress_bind_attrs) {  
  42. error = add_bind_files(drv);  
  43. if (error) {  
  44. /* Ditto */  
  45. printk(KERN_ERR "%s: add_bind_files(%s) failed\n",  
  46. __func__, drv->name);  
  47. }  
  48. }  
  49. kobject_uevent(&priv->kobj, KOBJ_ADD);  
  50. return 0;  
  51. out_unregister:  
  52. kfree(drv->p);  
  53. drv->p = NULL;  
  54. kobject_put(&priv->kobj);  
  55. out_put_bus:  
  56. bus_put(bus);  
  57. return error;  
  58. }  
int bus_add_driver(struct device_driver *drv)
{
struct bus_type *bus;
struct driver_private *priv;
int error = 0;
bus = bus_get(drv->bus);
if (!bus)
return -EINVAL;
pr_debug("bus: '%s': add driver %s\n", bus->name, drv->name);
priv = kzalloc(sizeof(*priv), GFP_KERNEL);
if (!priv) {
error = -ENOMEM;
goto out_put_bus;
}
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);
if (error)
goto out_unregister;
if (drv->bus->p->drivers_autoprobe) {
error = driver_attach(drv);
if (error)
goto out_unregister;
}
klist_add_tail(&priv->knode_bus, &bus->p->klist_drivers);
module_add_driver(drv->owner, drv);
error = driver_create_file(drv, &driver_attr_uevent);
if (error) {
printk(KERN_ERR "%s: uevent attr (%s) failed\n",
__func__, drv->name);
}
error = driver_add_attrs(bus, drv);
if (error) {
/* How the hell do we get out of this pickle? Give up */
printk(KERN_ERR "%s: driver_add_attrs(%s) failed\n",
__func__, drv->name);
}
if (!drv->suppress_bind_attrs) {
error = add_bind_files(drv);
if (error) {
/* Ditto */
printk(KERN_ERR "%s: add_bind_files(%s) failed\n",
__func__, drv->name);
}
}
kobject_uevent(&priv->kobj, KOBJ_ADD);
return 0;
out_unregister:
kfree(drv->p);
drv->p = NULL;
kobject_put(&priv->kobj);
out_put_bus:
bus_put(bus);
return error;
}


driver_attach中,通过调用bus_for_each_dev,遍历在总线上挂载的所有设备,并对每个设备(dev)调用__driver_attach()

  1. int driver_attach(struct device_driver *drv)  
  2. {  
  3. return bus_for_each_dev(drv->bus, NULL, drv, <STRONG>__driver_attach</STRONG>);  
  4. }  
int driver_attach(struct device_driver *drv)
{
return bus_for_each_dev(drv->bus, NULL, drv, __driver_attach);
}

__driver_attach里会调用driver_match_device()来判断devdrivid是否相同,在i2c驱动里就会调用i2c_bus_type->match程序进行判断,

id相同时,将会调用driver_probe_device()

  1. static int __driver_attach(struct device *dev, void *data)  
  2. {  
  3. struct device_driver *drv = data;  
  4. /*  
  5.  * Lock device and try to bind to it. We drop the error  
  6.  * here and always return 0, because we need to keep trying  
  7.  * to bind to devices and some drivers will return an error  
  8.  * simply if it didn't support the device.  
  9.  *  
  10.  * driver_probe_device() will spit a warning if there  
  11.  * is an error.  
  12.  */  
  13. if (!<STRONG>driver_match_device</STRONG>(drv, dev))  
  14. return 0;  
  15. if (dev->parent) /* Needed for USB */  
  16. down(&dev->parent->sem);  
  17. down(&dev->sem);  
  18. if (!dev->driver)  
  19. <STRONG>driver_probe_device</STRONG>(drv, dev);  
  20. up(&dev->sem);  
  21. if (dev->parent)  
  22. up(&dev->parent->sem);  
  23. return 0;  
  24. }  
static int __driver_attach(struct device *dev, void *data)
{
struct device_driver *drv = data;
/*
 * Lock device and try to bind to it. We drop the error
 * here and always return 0, because we need to keep trying
 * to bind to devices and some drivers will return an error
 * simply if it didn't support the device.
 *
 * driver_probe_device() will spit a warning if there
 * is an error.
 */
if (!driver_match_device(drv, dev))
return 0;
if (dev->parent) /* Needed for USB */
down(&dev->parent->sem);
down(&dev->sem);
if (!dev->driver)
driver_probe_device(drv, dev);
up(&dev->sem);
if (dev->parent)
up(&dev->parent->sem);
return 0;
}


在driver_probe_device(),首先会调用device_is_registered()判断dev是否注册,若没注册则返回;若已经注册,则调用really_probe

  1. int driver_probe_device(struct device_driver *drv, struct device *dev)  
  2. {  
  3. int ret = 0;  
  4. if (!device_is_registered(dev))  
  5. return -ENODEV;  
  6. pr_debug("bus: '%s': %s: matched device %s with driver %s\n",  
  7.  drv->bus->name, __func__, dev_name(dev), drv->name);  
  8. pm_runtime_get_noresume(dev);  
  9. pm_runtime_barrier(dev);  
  10. ret = <STRONG>really_probe</STRONG>(dev, drv);  
  11. pm_runtime_put_sync(dev);  
  12. return ret;  
  13. }  
int driver_probe_device(struct device_driver *drv, struct device *dev)
{
int ret = 0;
if (!device_is_registered(dev))
return -ENODEV;
pr_debug("bus: '%s': %s: matched device %s with driver %s\n",
 drv->bus->name, __func__, dev_name(dev), drv->name);
pm_runtime_get_noresume(dev);
pm_runtime_barrier(dev);
ret = really_probe(dev, drv);
pm_runtime_put_sync(dev);
return ret;
}


在really_probe()里,首先将drv赋值给dev->driver,然后会调用总线的probe函数,在i2c驱动里,

此时将会调用i2c总线的probe函数:i2c_device_probe

  1. static int really_probe(struct device *dev, struct device_driver *drv)  
  2. {  
  3. int ret = 0;  
  4. atomic_inc(&probe_count);  
  5. pr_debug("bus: '%s': %s: probing driver %s with device %s\n",  
  6.  drv->bus->name, __func__, drv->name, dev_name(dev));  
  7. WARN_ON(!list_empty(&dev->devres_head));  
  8. dev->driver = drv;  
  9. if (driver_sysfs_add(dev)) {  
  10. printk(KERN_ERR "%s: driver_sysfs_add(%s) failed\n",  
  11. __func__, dev_name(dev));  
  12. goto probe_failed;  
  13. }  
  14. if (dev->bus->probe)   
  15. {  
  16. //此处调用i2c总线的probe函数  
  17. ret = dev->bus->probe(dev);  
  18. if (ret)  
  19. goto probe_failed;  
  20. }   
  21. else if (drv->probe)   
  22. {  
  23. ret = drv->probe(dev);  
  24. if (ret)  
  25. goto probe_failed;  
  26. }  
  27. driver_bound(dev);  
  28. ret = 1;  
  29. pr_debug("bus: '%s': %s: bound device %s to driver %s\n", drv->bus->name, __func__, dev_name(dev), drv->name);  
  30. goto done;  
  31. probe_failed:  
  32. devres_release_all(dev);  
  33. driver_sysfs_remove(dev);  
  34. dev->driver = NULL;  
  35. if (ret != -ENODEV && ret != -ENXIO)   
  36. {  
  37. /* driver matched but the probe failed */  
  38. printk(KERN_WARNING       "%s: probe of %s failed with error %d\n",       drv->name, dev_name(dev), ret);  
  39. }  
  40. /* * Ignore errors returned by ->probe so that the next driver can try * its luck. */  
  41. ret = 0;  
  42. done:  
  43. atomic_dec(&probe_count);  
  44. wake_up(&probe_waitqueue);  
  45. return ret;  
  46. }  
static int really_probe(struct device *dev, struct device_driver *drv)
{
int ret = 0;
atomic_inc(&probe_count);
pr_debug("bus: '%s': %s: probing driver %s with device %s\n",
 drv->bus->name, __func__, drv->name, dev_name(dev));
WARN_ON(!list_empty(&dev->devres_head));
dev->driver = drv;
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) 
{
//此处调用i2c总线的probe函数
ret = dev->bus->probe(dev);
if (ret)
goto probe_failed;
} 
else if (drv->probe) 
{
ret = drv->probe(dev);
if (ret)
goto probe_failed;
}
driver_bound(dev);
ret = 1;
pr_debug("bus: '%s': %s: bound device %s to driver %s\n", drv->bus->name, __func__, dev_name(dev), drv->name);
goto done;
probe_failed:
devres_release_all(dev);
driver_sysfs_remove(dev);
dev->driver = NULL;
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);
}
/* * 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;
}



i2c_device_probe()里,会根据to_i2c_driver(dev->driver)获取i2c驱动,也就是我们编写的具体的i2c设备驱动的结构体i2c_driver,即

  1. static struct i2c_driver XXX_driver = {  
  2. .driver = {  
  3. .name = "XXXX_name",  
  4. .owner = THIS_MODULE,  
  5. },  
  6. .probe = XXX_probe,  
  7. .remove = XXX_remove,  
  8. .id_table = XXX_id,  
  9. };  
static struct i2c_driver XXX_driver = {
.driver = {
.name = "XXXX_name",
.owner = THIS_MODULE,
},
.probe = XXX_probe,
.remove = XXX_remove,
.id_table = XXX_id,
};


这样就调用了我们驱动的probe()了,这就是我们在驱动里调用i2c_add_driver(),通过driver_register()的一系列调用,最后执行我们所写的probe()

  1. static int i2c_device_probe(struct device *dev)  
  2. {  
  3. struct i2c_client *client = i2c_verify_client(dev);  
  4. struct i2c_driver *driver;  
  5. int status;  
  6. if (!client)  
  7. return 0;  
  8. driver = to_i2c_driver(dev->driver);  
  9. if (!driver->probe || !driver->id_table)  
  10. return -ENODEV;  
  11. client->driver = driver;  
  12. if (!device_can_wakeup(&client->dev))  
  13. device_init_wakeup(&client->dev,  
  14. client->flags & I2C_CLIENT_WAKE);  
  15. dev_dbg(dev, "probe\n");  
  16. status = <STRONG>driver->probe</STRONG>(client, i2c_match_id(driver->id_table, client));//执行我们写的probe函数  
  17. if (status)  
  18. client->driver = NULL;  
  19. return status;  
  20. }  
static int i2c_device_probe(struct device *dev)
{
struct i2c_client *client = i2c_verify_client(dev);
struct i2c_driver *driver;
int status;
if (!client)
return 0;
driver = to_i2c_driver(dev->driver);
if (!driver->probe || !driver->id_table)
return -ENODEV;
client->driver = driver;
if (!device_can_wakeup(&client->dev))
device_init_wakeup(&client->dev,
client->flags & I2C_CLIENT_WAKE);
dev_dbg(dev, "probe\n");
status = driver->probe(client, i2c_match_id(driver->id_table, client));//执行我们写的probe函数
if (status)
client->driver = NULL;
return status;
}


  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值