linux那些事儿之我是i2c -- Gsenser(三)

来源:互联网 发布:vip域名后缀可以备案 编辑:程序博客网 时间:2024/04/30 18:02
3.是谁掀起了你的盖头来?
    对linux驱动模型有一点了解的兄弟知道,一个驱动,特别是挂上总线的驱动,
真正开始执行都是始于probe函数。我们这里的lis3lv02d_i2c驱动,是挂在系统的i2c总线上的,
因而也就会从probe开始执行。那么是谁来调用这个probe内?就好像驱动通过总线介绍,嫁给了设备,
那到底是哪个设备去掀起驱动的红盖头呢?我们从i2c_register_driver看开去。
代码在kernel/driver/i2c/i2c-core.c中:
 872 /*
 873  * An i2c_driver is used with one or more i2c_client (device) nodes to access
 874  * i2c slave chips, on a bus instance associated with some i2c_adapter.
 875  */
 876
 877 int i2c_register_driver(struct module *owner, struct i2c_driver *driver)
 878 {
 879   int res;
 880
 881   /* Can't register until after driver model init */
 882   if (unlikely(WARN_ON(!i2c_bus_type.p)))
 883     return -EAGAIN;
 884
 885   /* add the driver to the list of i2c drivers in the driver core */
 886   driver->driver.owner = owner;
 887   driver->driver.bus = &i2c_bus_type;
 888
 889   /* When registration returns, the driver core
 890    * will have called probe() for all matching-but-unbound devices.
 891    */
 892   res = driver_register(&driver->driver);
 893   if (res)
 894     return res;
 895
 896   pr_debug("i2c-core: driver [%s] registered\n", driver->driver.name);
 897
 898   INIT_LIST_HEAD(&driver->clients);
 899   /* Walk the adapters that are already present */
 900   mutex_lock(&core_lock);
 901   bus_for_each_dev(&i2c_bus_type, NULL, driver, __attach_adapter);
 902   mutex_unlock(&core_lock);
 903 ///WTT DEBUG
 904 printk("***** WTT DEBUG i2c_register_driver to return 0\n");
 905 ///WTT DEBUG
 906   return 0;
 907 }
 908 EXPORT_SYMBOL(i2c_register_driver);
 此函数中第887行,driver->driver.bus = &i2c_bus_type;
 将i2c_driver->device_driver.bus 赋值为&i2c_bus_type
 那么这个&i2c_bus_type是在哪里定义的呢?
 代码在kernel/driver/i2c/i2c-core.c中:
 233 struct bus_type i2c_bus_type = {
 234   .name   = "i2c",
 235   .match    = i2c_device_match,
 236   .probe    = i2c_device_probe,
 237   .remove   = i2c_device_remove,
 238   .shutdown = i2c_device_shutdown,
 239   .suspend  = i2c_device_suspend,
 240   .resume   = i2c_device_resume,
 241 };
 242 EXPORT_SYMBOL_GPL(i2c_bus_type);
 struct bus_type 是linux中定义的总线类型,所有的总线都需要定义这么一个结构体,
 用来储存总线的名称以及一些相关的API。
 从字面上看,可以看到相关的API有:
    设备匹配,主要是将驱动和设备进行匹配。
    设备移除、关闭、挂起、恢复。
    还有设备挂载(探测),是设备驱动probe的调用者,
也就是这节寻寻觅觅的掀起盖头的那位了。
那么这些函数都是怎么执行的呢?这个就跟伟大的Linux设备模型息息相关了。
具体的代码实现细节我没有跟读过,知识了解一些操作的结果和过程。
大致是这样的, 892   res = driver_register(&driver->driver);,我们把这个驱动,
注册到了i2c_bus_type总线上。当该总线上有新的设备添加i2c_add_device,
又或者有新的驱动注册i2c_add_driver,那么i2c_device_match就会被执行,我们来看这个函数:
也在i2c-core中
  66 static int i2c_device_match(struct device *dev, struct device_driver *drv)
  67 {
  68   struct i2c_client *client = i2c_verify_client(dev);
  69   struct i2c_driver *driver;
  70
  71   if (!client)
  72     return 0;
  73
  74   driver = to_i2c_driver(drv);
  75 ///WTT DEBUG
  76   printk("***** WTT DEBUG i2c_device_match : driver name=%s\n",driver->id_table->name);
  77 ///WTT DEBUG
  78   /* match on an id table if there is one */
  79   if (driver->id_table)
  80     return i2c_match_id(driver->id_table, client) != NULL;
  81
  82   return 0;
  83 }
 我们看到,这个函数所要match的是驱动和设备的id—table。
 我们跟着第80行,进入i2c_match_id:
  55 static const struct i2c_device_id *i2c_match_id(const struct i2c_device_id *id,
  56             const struct i2c_client *client)
  57 {
  58   while (id->name[0]) {
  59     if (strcmp(client->name, id->name) == 0)
  60       return id;
  61     id++;
  62   }
  63   return NULL;
  64 }
  这个函数应该没什么问题,大致意思就是比较从driver来的id中的name和client中的name。
 
  client哪里来?这里先留个悬念,下节再细说,我们先往下看。
 
 刚刚我们说完了i2c_device_match,接着来说说掀起盖头来的那位i2c_device_probe,
 他是在什么时候被调用的呢?是在i2c_device_match调用完成后被调用的。
 i2c-bus在检测到有新的设备和驱动后,会主动去调用i2c_device_match,将两者做匹配,
 一旦匹配成功,就会去调用i2c_device_probe。
 就好比男孩(device)和女孩(driver),去bus相亲,相中了(match),就步入婚姻殿堂,
 而一般,掀盖头都是要用装备的,不是徒手去掀,用什么?用秤杆,所谓称心如意!
 而这里的i2c_device_probe就好比是秤杆,去解开驱动的probe面纱。
 把上述的match和probe加上调试语句,就可以看出相对关系:
[    3.416687] ***** WTT DEBUG i2c_device_match : dismatch drv:lis3lv02d    client:tpo_touch
[    3.424652] ***** WTT DEBUG i2c_device_match : driver name=lis3lv02d
[    3.431030] ***** WTT DEBUG i2c_device_match : dismatch drv:lis3lv02d    client:elan_touch
[    3.439056] ***** WTT DEBUG i2c_device_match : driver name=lis3lv02d
[    3.445434] ***** WTT DEBUG i2c_device_match : dismatch drv:lis3lv02d    client:lis3lv02d
[    3.453369] ***** WTT DEBUG i2c_device_probe : driver name=lis3lv02d
[    3.445434]王八绿豆对上眼了,那就去掀盖头吧,[    3.453369] ***** WTT DEBUG i2c_device_probe : driver name=lis3lv02d。
他们都是总线上的API,都是由总线去调用的,

When i2c_bus_type was registered in linux kernel,in kernel/driver/base/bus.c
__device_attach and __driver_attach

///these functions will be called when one driver want to bind with device .
And function driver_match_device will call bus_type.match
And driver_probe_device will call bus_type.probe


话说秤杆有了,去挑起盖头咯,挑起前,还有些事情需要做,
比如,夫妻双方做个婚前体检,再次核实身份,诸如此类。
见i2c_device_probe代码,也在i2c-core中:
 102 static int i2c_device_probe_count = 0;
 103 static int i2c_device_probe(struct device *dev)
 104 {
 105   struct i2c_client *client = i2c_verify_client(dev);
 106   struct i2c_driver *driver;
 107   int status;
 108
 109   if (!client)
 110     return 0;
 111
 112   driver = to_i2c_driver(dev->driver);
 113 ///WTT DEBUG
 114   printk("***** WTT DEBUG i2c_device_probe : driver name=%s\n",driver->id_table->name);
 115 ///WTT DEBUG
 116   if (!driver->probe || !driver->id_table)
 117     return -ENODEV;
 118   client->driver = driver;
 119   if (!device_can_wakeup(&client->dev))
 120     device_init_wakeup(&client->dev,
 121           client->flags & I2C_CLIENT_WAKE);
 122   dev_dbg(dev, "probe\n");
 123 ///WTT DEBUG
 124   printk("***** WTT DEBUG i2c_device_probe_count = %d\n",i2c_device_probe_count);
 125   i2c_device_probe_count++;
 126   printk("***** WTT DEBUG device to probe is %s\n",client->name);
 127 ///WTT DEBUG
 128   status = driver->probe(client, i2c_match_id(driver->id_table, client));
 129
 130   if (status)
 131     client->driver = NULL;
 132   return status;
 133 }
 先看i2c_verify_client,
 251 /**
 252  * i2c_verify_client - return parameter as i2c_client, or NULL
 253  * @dev: device, probably from some driver model iterator
 254  *
 255  * When traversing the driver model tree, perhaps using driver model
 256  * iterators like @device_for_each_child(), you can't assume very much
 257  * about the nodes you find.  Use this function to avoid oopses caused
 258  * by wrongly treating some non-I2C device as an i2c_client.
 259  */
 260 struct i2c_client *i2c_verify_client(struct device *dev)
 261 {
 262   return (dev->type == &i2c_client_type)
 263       ? to_i2c_client(dev)
 264       : NULL;
 265 }
 266 EXPORT_SYMBOL(i2c_verify_client);
 就是想检查一下,client是不是真的i2c_client_type类型。
 就好比男孩(device)想找个女孩(driver),但是相亲时没注意,找了个人妖,
 所以就要婚前检查一下,i2c_verify_client就是起这个作用的,核实一下是不是真的i2c_client_type。
 中间部分都是一些简单的初始化。
 再看128行,status = driver->probe(client, i2c_match_id(driver->id_table, client));
 终于要先去驱动的盖头了,掀起前,还是再检查一下吧,看看我们到你配不配,乙方万一以后后悔,
 linux里走到这一步,要是不匹配,顶多返回而已。现实中一旦选择,那就要一辈子不离不弃,相濡以沫。
 走到这里,终于走到驱动的probe了,也就是第2节中的300行:lis3lv02d_i2c_probe
 probe函数,在一般情况下,是一个驱动在挂上总线并被调用后最先执行的函数,旨在做一些初始化工作,比如申请中断,map内存地址,申请结构体等等。
 到此为止,我们算是走完了这个驱动的挂载和启动,不过先不急着往下看,我们还有点小尾巴尚未解决:
他的参数是什么?一个是struct i2c_client *client,另一个是 const struct i2c_device_id *id。


原创粉丝点击