• Linux设备驱动剖析之IIC(二)


    953行,适配器的编号大于MAX_ID_MASK是不行的,MAX_ID_MASK是一个宏,展开后的值为61。

    957至968行,关于管理小整形ID数的,没怎么了解,略过。

    974行,调用i2c_register_adapter函数注册IIC适配器,下面是它的定义:

    00000837 static int i2c_register_adapter(struct i2c_adapter *adap)
    00000838 {
    00000839     int res = 0;
    00000840 
    00000841     /* Can't register until after driver model init */
    00000842     if (unlikely(WARN_ON(!i2c_bus_type.p))) {
    00000843         res = -EAGAIN;
    00000844         goto out_list;
    00000845     }
    00000846 
    00000847     rt_mutex_init(&adap->bus_lock);
    00000848     mutex_init(&adap->userspace_clients_lock);
    00000849     INIT_LIST_HEAD(&adap->userspace_clients);
    00000850 
    00000851     /* Set default timeout to 1 second if not already set */
    00000852     if (adap->timeout == 0)
    00000853         adap->timeout = HZ;
    00000854 
    00000855     dev_set_name(&adap->dev, "i2c-%d", adap->nr);
    00000856     adap->dev.bus = &i2c_bus_type;
    00000857     adap->dev.type = &i2c_adapter_type;
    00000858     res = device_register(&adap->dev);
    00000859     if (res)
    00000860         goto out_list;
    00000861 
    00000862     dev_dbg(&adap->dev, "adapter [%s] registered
    ", adap->name);
    00000863 
    00000864 #ifdef CONFIG_I2C_COMPAT
    00000865     res = class_compat_create_link(i2c_adapter_compat_class, &adap->dev,
    00000866                        adap->dev.parent);
    00000867     if (res)
    00000868         dev_warn(&adap->dev,
    00000869              "Failed to create compatibility class link
    ");
    00000870 #endif
    00000871 
    00000872     /* create pre-declared device nodes */
    00000873     if (adap->nr < __i2c_first_dynamic_bus_num)
    00000874         i2c_scan_static_board_info(adap);
    00000875 
    00000876     /* Notify drivers */
    00000877     mutex_lock(&core_lock);
    00000878     bus_for_each_drv(&i2c_bus_type, NULL, adap, __process_new_adapter);
    00000879     mutex_unlock(&core_lock);
    00000880 
    00000881     return 0;
    00000882 
    00000883 out_list:
    00000884     mutex_lock(&core_lock);
    00000885     idr_remove(&i2c_adapter_idr, adap->nr);
    00000886     mutex_unlock(&core_lock);
    00000887     return res;
    00000888 }

    842至845行,i2c_bus_type的私有成员p在IIC子系统初始化时在bus_register函数里已经被初始化了,因此if条件不会成立,可以继续往下走。

    848、849行,之前说struct i2c_adapter时被略过的最后两个成员在这里被初始化。

    852、853行,如果timeout没有设置,那么就给它个默认值HZ。一路走来可以发现,timeout在这里会被设置成HZ。

    858行,注册适配器这个设备。

    864至870行,兼容性方面的,略过。

    874行,调用i2c_scan_static_board_info函数注册所有在板文件里定义的设备,下面看它的定义:

    00000802 static void i2c_scan_static_board_info(struct i2c_adapter *adapter)
    00000803 {
    00000804     struct i2c_devinfo    *devinfo;
    00000805 
    00000806     down_read(&__i2c_board_lock);
    00000807     list_for_each_entry(devinfo, &__i2c_board_list, list) {
    00000808         if (devinfo->busnum == adapter->nr
    00000809                 && !i2c_new_device(adapter,
    00000810                         &devinfo->board_info))
    00000811             dev_err(&adapter->dev,
    00000812                 "Can't create device at 0x%02x
    ",
    00000813                 devinfo->board_info.addr);
    00000814     }
    00000815     up_read(&__i2c_board_lock);
    00000816 }

    807行,遍历__i2c_board_list链表,每找到一个成员就调用i2c_new_device函数创建一个IIC从机设备,下面是i2c_new_device函数的定义:

    00000523 struct i2c_client *
    00000524 i2c_new_device(struct i2c_adapter *adap, struct i2c_board_info const *info)
    00000525 {
    00000526     struct i2c_client    *client;
    00000527     int            status;
    00000528 
    00000529     client = kzalloc(sizeof *client, GFP_KERNEL);
    00000530     if (!client)
    00000531         return NULL;
    00000532 
    00000533     client->adapter = adap;
    00000534 
    00000535     client->dev.platform_data = info->platform_data;
    00000536 
    00000537     if (info->archdata)
    00000538         client->dev.archdata = *info->archdata;
    00000539 
    00000540     client->flags = info->flags;
    00000541     client->addr = info->addr;
    00000542     client->irq = info->irq;
    00000543 
    00000544     strlcpy(client->name, info->type, sizeof(client->name));
    00000545 
    00000546     /* Check for address validity */
    00000547     status = i2c_check_client_addr_validity(client);
    00000548     if (status) {
    00000549         dev_err(&adap->dev, "Invalid %d-bit I2C address 0x%02hx
    ",
    00000550             client->flags & I2C_CLIENT_TEN ? 10 : 7, client->addr);
    00000551         goto out_err_silent;
    00000552     }
    00000553 
    00000554     /* Check for address business */
    00000555     status = i2c_check_addr_busy(adap, client->addr);
    00000556     if (status)
    00000557         goto out_err;
    00000558 
    00000559     client->dev.parent = &client->adapter->dev;
    00000560     client->dev.bus = &i2c_bus_type;
    00000561     client->dev.type = &i2c_client_type;
    00000562 #ifdef CONFIG_OF
    00000563     client->dev.of_node = info->of_node;
    00000564 #endif
    00000565 
    00000566     dev_set_name(&client->dev, "%d-%04x", i2c_adapter_id(adap),
    00000567              client->addr);
    00000568     status = device_register(&client->dev);
    00000569     if (status)
    00000570         goto out_err;
    00000571 
    00000572     dev_dbg(&adap->dev, "client [%s] registered with bus id %s
    ",
    00000573         client->name, dev_name(&client->dev));
    00000574 
    00000575     return client;
    00000576 
    00000577 out_err:
    00000578     dev_err(&adap->dev, "Failed to register i2c client %s at 0x%02x "
    00000579         "(%d)
    ", client->name, client->addr, status);
    00000580 out_err_silent:
    00000581     kfree(client);
    00000582     return NULL;
    00000583 }

    529行,为IIC从机设备结构体申请内存。

    533至542行,一些赋值。

    544行,为client的name成员赋值,IIC总线的match函数能否匹配成功就要看这里了。从这里也可以知道如何让板文件里定义的设备与驱动匹配起来。

    547行,检查IIC从机设备地址的合法性,怎样才合法?如果从机使用十位地址的话,那么地址的最大值不能大于0x3ff;如果使用的是七位地址,那么地址的最大值不能大于0x7f,也不能为0。

    555行,检查当前IIC从机设备的地址有没有被使用,一条IIC总线或者一个IIC适配器上可以挂多个从机设备,靠设备的地址来识别不同的设备,因此一条总线上不能有两个同样地址的设备。

    561行,设备的类型,IIC从机设备在IIC子系统里属于client类型。

    568行,将IIC从机设备注册进系统。

          回到i2c_register_adapter函数,878行,遍历IIC总线上的所有已经注册了的驱动,每找到一个就调用__process_new_adapter函数进行处理,__process_new_adapter函数的定义如下:

    00000832 static int __process_new_adapter(struct device_driver *d, void *data)
    00000833 {
    00000834     return i2c_do_add_adapter(to_i2c_driver(d), data);
    00000835 }

    里面就是调用i2c_do_add_adapter函数:

    00000818 static int i2c_do_add_adapter(struct i2c_driver *driver,
    00000819                   struct i2c_adapter *adap)
    00000820 {
    00000821     /* Detect supported devices on that bus, and instantiate them */
    00000822     i2c_detect(adap, driver);
    00000823 
    00000824     /* Let legacy drivers scan this bus for matching devices */
    00000825     if (driver->attach_adapter) {
    00000826         /* We ignore the return code; if it fails, too bad */
    00000827         driver->attach_adapter(adap);
    00000828     }
    00000829     return 0;
    00000830 }

    822行,检查驱动是否能够与该适配器所在总线上的设备匹配。

    825行,如果驱动的attach_adapter函数有定义就调用之,这主要针对旧的驱动,像i2c-dev.c就是使用这种方式来驱动IIC适配器的,这个函数指针在将来可能会被移除。

          到这里,说完了s3c6410的IIC控制器驱动的初始化过程。下面开始说drivers/i2c/i2c-dev.c这个通用的i2c驱动,首先看它的初始化函数i2c_dev_init:

    00000595 static int __init i2c_dev_init(void)
    00000596 {
    00000597     int res;
    00000598 
    00000599     printk(KERN_INFO "i2c /dev entries driver
    ");
    00000600 
    00000601     res = register_chrdev(I2C_MAJOR, "i2c", &i2cdev_fops);
    00000602     if (res)
    00000603         goto out;
    00000604 
    00000605     i2c_dev_class = class_create(THIS_MODULE, "i2c-dev");
    00000606     if (IS_ERR(i2c_dev_class)) {
    00000607         res = PTR_ERR(i2c_dev_class);
    00000608         goto out_unreg_chrdev;
    00000609     }
    00000610 
    00000611     res = i2c_add_driver(&i2cdev_driver);
    00000612     if (res)
    00000613         goto out_unreg_class;
    00000614 
    00000615     return 0;
    00000616 
    00000617 out_unreg_class:
    00000618     class_destroy(i2c_dev_class);
    00000619 out_unreg_chrdev:
    00000620     unregister_chrdev(I2C_MAJOR, "i2c");
    00000621 out:
    00000622     printk(KERN_ERR "%s: Driver Initialisation failed
    ", __FILE__);
    00000623     return res;
    00000624 }

    601行,注册IIC设备,主设备号为I2C_MAJOR,它的值为89,文件操作结构体对象是i2cdev_fops,定义为:

    00000514 static const struct file_operations i2cdev_fops = {
    00000515     .owner        = THIS_MODULE,
    00000516     .llseek        = no_llseek,
    00000517     .read        = i2cdev_read,
    00000518     .write        = i2cdev_write,
    00000519     .unlocked_ioctl    = i2cdev_ioctl,
    00000520     .open        = i2cdev_open,
    00000521     .release    = i2cdev_release,
    00000522 };

    后面会以i2cdev_ioctl为例说说它的工作过程。

    605至609行,创建IIC设备类,是后面自动创建设备节点的基础。

    611行,添加IIC驱动,起始里面是对i2c_register_driver函数的包装,在include/linux/i2c.h里定义:

    00000434 static inline int i2c_add_driver(struct i2c_driver *driver)
    00000435 {
    00000436     return i2c_register_driver(THIS_MODULE, driver);
    00000437 }

    这样就可以省去写THIS_MODULE,也可以避免忘记写THIS_MODULE。下面看i2c_register_driver函数的定义,在drivers/i2c/i2c-core.c中:

    00001108 int i2c_register_driver(struct module *owner, struct i2c_driver *driver)
    00001109 {
    00001110     int res;
    00001111 
    00001112     /* Can't register until after driver model init */
    00001113     if (unlikely(WARN_ON(!i2c_bus_type.p)))
    00001114         return -EAGAIN;
    00001115 
    00001116     /* add the driver to the list of i2c drivers in the driver core */
    00001117     driver->driver.owner = owner;
    00001118     driver->driver.bus = &i2c_bus_type;
    00001119 
    00001120     /* When registration returns, the driver core
    00001121      * will have called probe() for all matching-but-unbound devices.
    00001122      */
    00001123     res = driver_register(&driver->driver);
    00001124     if (res)
    00001125         return res;
    00001126 
    00001127     pr_debug("i2c-core: driver [%s] registered
    ", driver->driver.name);
    00001128 
    00001129     INIT_LIST_HEAD(&driver->clients);
    00001130     /* Walk the adapters that are already present */
    00001131     mutex_lock(&core_lock);
    00001132     bus_for_each_dev(&i2c_bus_type, NULL, driver, __process_new_driver);
    00001133     mutex_unlock(&core_lock);
    00001134 
    00001135     return 0;
    00001136 }

    1113行,检查IIC总线的私有数据p是否已经初始化,前面已经说过了,在IIC子系统初始化的时候p就已经被初始化了。

    1117、1118行,没什么好说的吧。

    1123行,将该驱动注册进系统,经过一层层调用后会调用IIC总线的match函数。

    1132行,遍历IIC总线上的所有设备,每找到一个就调用__process_new_driver函数进行处理,__process_new_driver函数的定义:

    00001096 static int __process_new_driver(struct device *dev, void *data)
    00001097 {
    00001098     if (dev->type != &i2c_adapter_type)
    00001099         return 0;
    00001100     return i2c_do_add_adapter(data, to_i2c_adapter(dev));
    00001101 }

    1098行,如果设备不是适配器类型,就表示不是要找的设备,直接返回0。否则调用1100行的i2c_do_add_adapter函数,这个函数前面已经说过了,这里就不重复了。

    我们知道,此驱动注册进系统后会导致i2cdev_attach_adapter函数被调用,下面看它的定义:

    00000534 static int i2cdev_attach_adapter(struct i2c_adapter *adap)
    00000535 {
    00000536     struct i2c_dev *i2c_dev;
    00000537     int res;
    00000538 
    00000539     i2c_dev = get_free_i2c_dev(adap);
    00000540     if (IS_ERR(i2c_dev))
    00000541         return PTR_ERR(i2c_dev);
    00000542 
    00000543     /* register this i2c device with the driver core */
    00000544     i2c_dev->dev = device_create(i2c_dev_class, &adap->dev,
    00000545                      MKDEV(I2C_MAJOR, adap->nr), NULL,
    00000546                      "i2c-%d", adap->nr);
    00000547     if (IS_ERR(i2c_dev->dev)) {
    00000548         res = PTR_ERR(i2c_dev->dev);
    00000549         goto error;
    00000550     }
    00000551     res = device_create_file(i2c_dev->dev, &dev_attr_name);
    00000552     if (res)
    00000553         goto error_destroy;
    00000554 
    00000555     pr_debug("i2c-dev: adapter [%s] registered as minor %d
    ",
    00000556          adap->name, adap->nr);
    00000557     return 0;
    00000558 error_destroy:
    00000559     device_destroy(i2c_dev_class, MKDEV(I2C_MAJOR, adap->nr));
    00000560 error:
    00000561     return_i2c_dev(i2c_dev);
    00000562     return res;
    00000563 }

    539行,不要被它的名字所迷惑,看它的定义:

    00000076 static struct i2c_dev *get_free_i2c_dev(struct i2c_adapter *adap)
    00000077 {
    00000078     struct i2c_dev *i2c_dev;
    00000079 
    00000080     if (adap->nr >= I2C_MINORS) {
    00000081         printk(KERN_ERR "i2c-dev: Out of device minors (%d)
    ",
    00000082                adap->nr);
    00000083         return ERR_PTR(-ENODEV);
    00000084     }
    00000085 
    00000086     i2c_dev = kzalloc(sizeof(*i2c_dev), GFP_KERNEL);
    00000087     if (!i2c_dev)
    00000088         return ERR_PTR(-ENOMEM);
    00000089     i2c_dev->adap = adap;
    00000090 
    00000091     spin_lock(&i2c_dev_list_lock);
    00000092     list_add_tail(&i2c_dev->list, &i2c_dev_list);
    00000093     spin_unlock(&i2c_dev_list_lock);
    00000094     return i2c_dev;
    00000095 }

    80至84行,如果适配器的编号大于最大的次设备号,那么就返回出错。I2C_MINORS的值为256。

    86行,为i2c_dev对象申请内存。

    92行,将i2c_dev对象加入到i2c_dev_list链表中。

          回到i2cdev_attach_adapter函数,544行,创建设备节点,主设备号为I2C_MAJOR,次设备号为适配器的编号,设备节点的名字为i2c-x,x的值就是适配器的编号。如果适配器的编号为0,那么就会在/dev下创建一个名为i2c-0的文件,即/dev/i2c-0,但在某些嵌入式Linux平台上没有看到这个文件,而是/dev/i2c/0这种形式,原因在于在启动文件里调用了mdev –s这条命令,导致/dev/i2c-0变成了/dev/i2c/0,不信?把i2c-x的-去掉,变成i2cx,重新编译后启动内核,看生成的是否是/dev/i2cx文件。之所以会造成那样是因为字符‘-’引起的。

    551行,创建设备文件,关于设备模型的,不多说了。

         到此,i2c-dev.c的初始化过程也说完了。

         某某大侠说得对:“内核代码就像酒,有的苦有的烈,这样的滋味你我早晚要体会,请与我举起杯,与内核干杯。”多么形象的比喻!多么可爱的文字!

         不管多“苦”多“累”,既然认定了前方,路还是要走下去的。

  • 相关阅读:
    Spring Boot(二十):使用spring-boot-admin对spring-boot服务进行监控
    spring Boot(十九):使用Spring Boot Actuator监控应用
    Spring Boot(十八):使用Spring Boot集成FastDFS
    Spring Boot(十七):使用Spring Boot上传文件
    Spring Boot(十六):使用Jenkins部署Spring Boot
    Spring Boot(十五):spring boot+jpa+thymeleaf增删改查示例
    Spring Boot(十四):spring boot整合shiro-登录认证和权限管理
    ubuntu18.04使用vscode报pylint is not install错误
    处理程序“PageHandlerFactory-Integrated”在其模块列表中有一个错误模块“Manag
    在SQL Server中,为何都建议禁止 VIA 协议,VIA协议具体内容是什么?
  • 原文地址:https://www.cnblogs.com/lknlfy/p/3265108.html
Copyright © 2020-2023  润新知