• 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的初始化过程也说完了。

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

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

  • 相关阅读:
    leetcode Super Ugly Number
    leetcode Find Median from Data Stream
    leetcode Remove Invalid Parentheses
    leetcode Range Sum Query
    leetcode Range Sum Query
    leetcode Minimum Height Trees
    hdu 3836 Equivalent Sets
    hdu 1269 迷宫城堡
    hud 2586 How far away ?
    poj 1330 Nearest Common Ancestors
  • 原文地址:https://www.cnblogs.com/lknlfy/p/3265108.html
Copyright © 2020-2023  润新知