加入收藏 | 设为首页 | 会员中心 | 我要投稿 宿州站长网 (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字符串 {}

    {
        return of_match_device(drv->of_match_table, dev) != NULL;  // 也就是***_gpio_of_match
    }
    of_match_device(...) --> of_match_node(...)
    of_match_node(...) --> __of_match_node(...)
    static const struct of_device_id *__of_match_node(const struct of_device_id *matches,
                            const struct device_node *node)  // matches 就是drv->of_match_table, 也就是***_gpio_of_match
    {
        if (!matches)
            return NULL;
   
        while (matches->name[0] || matches->type[0] || matches->compatible[0]) {
            int match = 1;
            if (matches->name[0])
                match &= node->name
                    && !strcmp(matches->name, node->name);
            if (matches->type[0])
                match &= node->type
                    && !strcmp(matches->type, node->type);
            if (matches->compatible[0])
                match &= __of_device_is_compatible(node,    // 匹配 compatible
                                    matches->compatible);    // ***_gpio_of_match.compatible 与 device node 的 compatible 匹配
            if (match)
                return matches;
            matches++;
        }
        return NULL;
    }
 
    static int __of_device_is_compatible(const struct device_node *device,
                          const char *compat)
    {
        const char* cp;
        int cplen, l;
   
        cp = __of_get_property(device, "compatible", &cplen);  // 这里就是获取device的compatible的字符串信息
        if (cp == NULL)
            return 0;
        while (cplen > 0) {
            if (of_compat_cmp(cp, compat, strlen(compat)) == 0)  // 对比device的compatible的字符串信息和driver的compatible的字符串信息是否相等
                return 1;
            l = strlen(cp) + 1;
            cp += l;
            cplen -= l;
        }
   
        return 0;
    }
 
 8-2-1. drivers/base/dd.c : driver_probe_device(...)
    driver_probe_device(...) --> really_probe(...)
 
 8-2-2. drivers/base/dd.c : really_probe(...)
    ...
    dev->driver = drv;  // 驱动 赋值给 设备.
    pinctrl_bind_pins();    // 跳到第8-2-2-1-1步
    ...
    if (dev->bus->probe) {
        ret = dev->bus->probe(dev);
        if (ret)
            goto probe_failed;
    } else if (drv->probe) {
        ret = drv->probe(dev);  // 前面platform_driver_register(...)时  drv->driver.probe = platform_drv_probe, 所以进入platform_drv_probe
                                // 跳到第8-2-2-2-1步
        if (ret)
            goto probe_failed;
    }
    driver_bound(dev);          // 驱动挷定设备
 
8-2-2-1-1. drivers/base/pinctrl.c : pinctrl_bind_pins(...)
    dev->pins = devm_kzalloc(dev, sizeof(*(dev->pins)), GFP_KERNEL);
    if (!dev->pins)
        return -ENOMEM;
 
    dev->pins->p = devm_pinctrl_get(dev);  // 调用 pinctrl_get(...) --> create_pinctrl(...)
                                            // 又进入到pinctrl子系统代码中
                                            // 在create_pinctrl(...)里
                                            // p->states, p->dt_maps都为空, 只有pinctrl-0的dts节点设备才不为空, 具体查看, pinctrl驱动初始化
                                            // 具体查看 基于linux 3.10.49内核的pinctrl流程分析 补充 已介绍过  http://www.linuxidc.com/Linux/2017-10/147521p2.htm

(编辑:宿州站长网)

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

推荐文章