加入收藏 | 设为首页 | 会员中心 | 我要投稿 宿州站长网 (https://www.0557zz.com/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 教程 > 正文

基于Linux 3.10.49内核的gpio步骤分析

发布时间:2021-12-07 16:07:30 所属栏目:教程 来源:互联网
导读:Linux kernel 3.10.49+ 在这里, 我们说说linux 是怎么通过platform_driver驱动代码匹配到platform_device的. static const struct of_device_id ***_gpio_of_match[] = { { .compatible = ******,***-gpio, }, // 这个字符串就是dts里的compatible字符串 {}

Linux kernel 3.10.49+
在这里, 我们说说linux 是怎么通过platform_driver驱动代码匹配到platform_device的.
static const struct of_device_id ***_gpio_of_match[] = {
    { .compatible = "******,***-gpio", },        // 这个字符串就是dts里的compatible字符串
    {}
 };
MODULE_DEVICE_TABLE(of, ***_gpio_of_match);
 static struct platform_driver ***_gpio_driver = {
    .probe = ***_gpio_probe,                    // 匹配完成后, 运行的probe函数, 可以做一些初始化.
    .driver = {
        .name = "***_gpio",
        .owner = THIS_MODULE,
        .of_match_table = ***_gpio_of_match,
    },
 };
 module_platform_driver(***_gpio_driver);
 
 1. drivers/gpio/gpio-***.c : module_platform_driver(***_gpio_driver);  // gpio驱动入口
 
2. include/linux/platform_device.h 宏 : module_platform_driver
    #define module_platform_driver(__platform_driver)
        module_driver(__platform_driver, platform_driver_register,
                platform_driver_unregister)
 
 3. drivers/base/platform.c : platform_driver_register(...)
    drv->driver.bus = &platform_bus_type;
    drv->driver.bus = &platform_bus_type;
    if (drv->probe)
        drv->driver.probe = platform_drv_probe;    // 后面会使用.
    if (drv->remove)
        drv->driver.remove = platform_drv_remove;
    if (drv->shutdown)
        drv->driver.shutdown = platform_drv_shutdown;
    return driver_register(&drv->driver);
 
 4. drivers/base/driver.c : driver_register(...)
    ...
    ret = bus_add_driver(drv);
    ...
 
 5. drivers/base/bus.c : bus_add_driver(...)
    ...
        error = driver_attach(drv);
    ...
 
 6. drivers/base/bus.c : driver_attach(...)
    int driver_attach(struct device_driver *drv)
    {
        return bus_for_each_dev(drv->bus, NULL, drv, __driver_attach);
    }
 
 7. drivers/base/dd.c : bus_for_each_dev(...)
    ...
    klist_iter_init_node(&bus->p->klist_devices, &i,
                  (start ? &start->p->knode_bus : NULL));
    while ((dev = next_device(&i)) && !error)    // 这个就是全局变量中, 所有已经进行过注册的device.
                                                  // 在上一篇 基于Linux 3.10.49内核 从dts文件里注册platform_device流程分析 已介绍过 http://www.linuxidc.com/Linux/2017-10/147522.htm
        error = fn(dev, data);          // fn 就是 __driver_attach 函数指针. 轮询device进行匹配.
    klist_iter_exit(&i);
    ...
   
 8. drivers/base/dd.c : __driver_attach(...)
    ...
    if (!driver_match_device(drv, dev)) // 匹配成功, 返加非0, 否则返回0. // 跳到第8-1-1步
        return 0;
 
    if (dev->parent)    /* Needed for USB */  // 有父设备, 父设备也就加锁
        device_lock(dev->parent);
    device_lock(dev);        // 设备加锁
    if (!dev->driver)        // 如果device没有驱动程序, 就driver_probe_device
        driver_probe_device(drv, dev);          //  跳到第8-2-1步
    device_unlock(dev);      // 设备释放锁
    if (dev->parent)          // 有父设备, 父设备也就释放锁
        device_unlock(dev->parent);
 
    return 0
 
 8-1-1. drivers/base/base.h : driver_match_device(...)
    static inline int driver_match_device(struct device_driver *drv,
                          struct device *dev)
    {
        return drv->bus->match ? drv->bus->match(dev, drv) : 1;
    }
    // drv->bus 就是 第三步的 drv->driver.bus = &platform_bus_type;
    // 也就是相当于platform_bus_type->match(dev, drv);
    // struct bus_type platform_bus_type = {    // drivers/base/platform.c
    //    .name        = "platform",
    //    .dev_attrs    = platform_dev_attrs,
    //    .match        = platform_match,
    //    .uevent        = platform_uevent,
    //    .pm        = &platform_dev_pm_ops,
    // };
    // EXPORT_SYMBOL_GPL(platform_bus_type);
    // 也就是platform_match(dev, drv);
   
 8-1-2. drivers/base/platform.c : platform_match(...)
    static int platform_match(struct device *dev, struct device_driver *drv)
    {
        ...
        if (of_driver_match_device(dev, drv))
            return 1;
        ...
    }
   
 8-1-3. include/linux/of_device.h : of_driver_match_device(...)
    static inline int of_driver_match_device(struct device *dev,
                          const struct device_driver *drv)

(编辑:宿州站长网)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

推荐文章