OpenEdv-开源电子网

 找回密码
 立即注册
正点原子全套STM32/Linux/FPGA开发资料,上千讲STM32视频教程免费下载...
查看: 6908|回复: 16

iomuxc 节点下的pinctrol结点都会自动配置吗

[复制链接]

50

主题

385

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1126
金钱
1126
注册时间
2014-8-24
在线时间
146 小时
发表于 2021-2-4 07:47:26 | 显示全部楼层 |阅读模式
5金钱
本帖最后由 tao475824827 于 2021-2-4 08:24 编辑


想问个问题,在我们的GPIO的实验中,不管是LED还是Key。
都会在自己的设备树中对应的设备节点 A 中 , 指定一个 pinctrl子节点,
比如
pinctrl-0 = <&pinctrl_inout>;
1.png
同时,“pinctrl_inout” 这个pinctrl子节点会写在 iomuxc节点下,
2.png
但是我想知道,这个pinctrl的配置,是会因为我写在了iomuxc中,所以系统启动的时候会自动配置这几个脚吗?
(这部分我验证了,并不会配置,不知道是机制如此还是我写错了)
(但是我把 pinctrl_inout 这个配置放在其他的结点里比如iic-1这些,就能初始化成功,所以感觉不是所有的iomuxc下的结点都会自动配置)

还是说,在设备A被驱动匹配时,probe运行时,会自动把A的 pinctrl-0 里的配置给初始化掉?
(但是我看我们的demo程序并没有这部分匹配过程,都是在设备树 里 自己的设备里中写了pinctrl-0的配置,然后在驱动里直接GPIO子系统来使用了,节点都是自己根据设备树路径去找到,获取GPIO号,然后直接操作了,并没有在pinctrl的初始化)

谢谢!




最佳答案

查看完整内容[请看2#楼]

我记得好像这样的: iomuxc这个节点probe到后是生成pin控制器的结构体pinctrl_dev,芯片有几个iomuxc控制器对应几个pinctrl_dev,imouxc只会配置hog下的引脚,然后设备树结点都有自己的pinctrl结构体,保存了default,sleep这些状态,接下来就是你说的例如节点A有对应pinctrl,如果用的不是paltform框架写驱动,也没自己手动创建pinctrl挂上去,那么节点A里的pinctrl那些配置是没用的属性,只有platform框架驱动才会进入Probe,才会 ...
找一份喜欢的工作,这样每天工作的8个小时是快乐的。 找一个喜欢的人,这样每天工作之外的16个小时也是快乐的。
正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

3

主题

22

帖子

0

精华

新手上路

积分
45
金钱
45
注册时间
2017-10-25
在线时间
16 小时
发表于 2021-2-4 07:47:27 | 显示全部楼层
我记得好像这样的:
iomuxc这个节点probe到后是生成pin控制器的结构体pinctrl_dev,芯片有几个iomuxc控制器对应几个pinctrl_dev,imouxc只会配置hog下的引脚,然后设备树结点都有自己的pinctrl结构体,保存了default,sleep这些状态,接下来就是你说的例如节点A有对应pinctrl,如果用的不是paltform框架写驱动,也没自己手动创建pinctrl挂上去,那么节点A里的pinctrl那些配置是没用的属性,只有platform框架驱动才会进入Probe,才会创建节点自己的pinctrl并进行引脚配置。
记忆里是这样,不知道哪里有错感谢纠正
回复

使用道具 举报

50

主题

385

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1126
金钱
1126
注册时间
2014-8-24
在线时间
146 小时
 楼主| 发表于 2021-2-5 18:37:40 | 显示全部楼层
自己顶一下
回复

使用道具 举报

50

主题

385

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1126
金钱
1126
注册时间
2014-8-24
在线时间
146 小时
 楼主| 发表于 2021-2-8 06:43:18 | 显示全部楼层

自己顶一下
找一份喜欢的工作,这样每天工作的8个小时是快乐的。 找一个喜欢的人,这样每天工作之外的16个小时也是快乐的。
回复

使用道具 举报

0

主题

3

帖子

0

精华

初级会员

Rank: 2

积分
64
金钱
64
注册时间
2020-5-25
在线时间
25 小时
发表于 2021-2-22 16:32:34 | 显示全部楼层
pinctrl,好像是在匹配后会先进入really_probe函数,该函数会先对设置为default的引脚初始化,再调用真正的驱动probe
回复

使用道具 举报

2

主题

712

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
2178
金钱
2178
注册时间
2018-8-27
在线时间
258 小时
发表于 2021-2-26 13:22:21 | 显示全部楼层
这个pinctrl的初始化在执行驱动的probe函数之前就已经完成了
森罗万象
回复

使用道具 举报

50

主题

385

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1126
金钱
1126
注册时间
2014-8-24
在线时间
146 小时
 楼主| 发表于 2021-2-26 22:26:20 | 显示全部楼层
xiaotaotao 发表于 2021-2-26 13:22
这个pinctrl的初始化在执行驱动的probe函数之前就已经完成了

就是说iomuxc下的寄存器配置都应该会自动配的是吗
找一份喜欢的工作,这样每天工作的8个小时是快乐的。 找一个喜欢的人,这样每天工作之外的16个小时也是快乐的。
回复

使用道具 举报

50

主题

385

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1126
金钱
1126
注册时间
2014-8-24
在线时间
146 小时
 楼主| 发表于 2021-2-26 22:27:36 | 显示全部楼层
carliu 发表于 2021-2-22 16:32
pinctrl,好像是在匹配后会先进入really_probe函数,该函数会先对设置为default的引脚初始化,再调用真正的 ...

很奇怪,如果是先进really_probe,我感觉所有的iomuxc下的配置应该都配了才对,但是我感觉我的这个配置没有配成功。。
找一份喜欢的工作,这样每天工作的8个小时是快乐的。 找一个喜欢的人,这样每天工作之外的16个小时也是快乐的。
回复

使用道具 举报

50

主题

385

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1126
金钱
1126
注册时间
2014-8-24
在线时间
146 小时
 楼主| 发表于 2021-2-27 11:02:13 | 显示全部楼层
我打印跟踪了一下,在启动过程中,iomux里的结点应该是做了初始化的。
imx6ul_pinctrl_probe -> imx_pinctrl_probe -> imx_pinctrl_probe_dt
获取子节点 到 info->functions
获取孙结点 到 info->groups
然后调用 imx_pinctrl_parse_functions

加了打印,dmesg能看到调用了这些结点。

...
[    0.214427] hw-breakpoint: maximum watchpoint size is 8 bytes.
[    0.218192] parse function(0): imx6ul-evk
[    0.218235] group(0): hoggrp-1
[    0.218260] group(1): ledgrp
[    0.218279] group(2): gpioinout
[    0.218301] group(3): max31865
[    0.218321] group(4): ads1256
[    0.218342] group(5): csi1grp
[    0.218363] group(6): enet1grp
[    0.218385] group(7): enet2grp
[    0.218407] group(8): i2c1grp
[    0.218427] group(9): i2c2grp
[    0.218445] group(10): pwm1grp
[    0.218463] group(11): qspigrp
[    0.218484] group(12): sai2grp
[    0.218504] group(13): tscgrp
...



不知道为什么就是不生效,我在系统里用文件io去读取
echo  81 > /sys/class/gpio/export
echo  82 > /sys/class/gpio/export
echo  83 > /sys/class/gpio/export
echo  84 > /sys/class/gpio/export

echo in > /sys/class/gpio/gpio81/direction
echo in > /sys/class/gpio/gpio82/direction
echo in > /sys/class/gpio/gpio83/direction
echo in > /sys/class/gpio/gpio84/direction

cat  /sys/class/gpio/gpio81/value ;\
cat  /sys/class/gpio/gpio82/value ;\
cat  /sys/class/gpio/gpio83/value ;\
cat  /sys/class/gpio/gpio84/value



始终获取不到。



找一份喜欢的工作,这样每天工作的8个小时是快乐的。 找一个喜欢的人,这样每天工作之外的16个小时也是快乐的。
回复

使用道具 举报

50

主题

385

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1126
金钱
1126
注册时间
2014-8-24
在线时间
146 小时
 楼主| 发表于 2021-2-27 22:26:52 | 显示全部楼层
再跟踪看了一下,发现虽然调用了imx_pinctrl_parse_functions进而调用了imx_pinctrl_parse_groups。
但是,并没有地方配置 conf reg。

并且我在系统中直接用devmem来看,这些引脚的conf reg都是没配置的状态,都是默认值 0x1B0B0
找一份喜欢的工作,这样每天工作的8个小时是快乐的。 找一个喜欢的人,这样每天工作之外的16个小时也是快乐的。
回复

使用道具 举报

50

主题

385

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1126
金钱
1126
注册时间
2014-8-24
在线时间
146 小时
 楼主| 发表于 2021-2-28 10:00:30 | 显示全部楼层
iomux里的结点,
通过 imx6ul_pinctrl_probe -> imx_pinctrl_probe -> imx_pinctrl_probe_dt
获取子节点 到 info->functions
获取孙结点 到 info->groups
然后调用 imx_pinctrl_parse_functions

应该只是把一些要配置的值注册了,并没有做真正的寄存器配置。

真正配置寄存器在 imx_pinconf_set  函数里,
我在这里加了打印,发现启动阶段确实并没有对这几个寄存器做配置。



找一份喜欢的工作,这样每天工作的8个小时是快乐的。 找一个喜欢的人,这样每天工作之外的16个小时也是快乐的。
回复

使用道具 举报

3

主题

22

帖子

0

精华

新手上路

积分
45
金钱
45
注册时间
2017-10-25
在线时间
16 小时
发表于 2021-3-2 15:30:05 | 显示全部楼层
本帖最后由 副国级 于 2021-3-2 15:32 编辑

static int really_probe(struct device *dev, struct device_driver *drv)
{
        int ret = -EPROBE_DEFER;
        int local_trigger_count = atomic_read(&deferred_trigger_count);
        bool test_remove = IS_ENABLED(CONFIG_DEBUG_TEST_DRIVER_REMOVE) &&
                           !drv->suppress_bind_attrs;

        if (defer_all_probes) {
                /*
                 * Value of defer_all_probes can be set only by
                 * device_block_probing() which, in turn, will call
                 * wait_for_device_probe() right after that to avoid any races.
                 */
                dev_dbg(dev, "Driver %s force probe deferral\n", drv->name);
                driver_deferred_probe_add(dev);
                return ret;
        }

        ret = device_links_check_suppliers(dev);
        if (ret == -EPROBE_DEFER)
                driver_deferred_probe_add_trigger(dev, local_trigger_count);
        if (ret)
                return ret;

        atomic_inc(&probe_count);
        pr_debug("bus: '%s': %s: probing driver %s with device %s\n",
                 drv->bus->name, __func__, drv->name, dev_name(dev));
        if (!list_empty(&dev->devres_head)) {
                dev_crit(dev, "Resources present before probing\n");
                ret = -EBUSY;
                goto done;
        }

re_probe:
        dev->driver = drv;

        /* If using pinctrl, bind pins now before probing */
        ret = pinctrl_bind_pins(dev);//这里对pin进行配置
.................
}

int pinctrl_bind_pins(struct device *dev)
{
        int ret;

        if (dev->of_node_reused)
                return 0;

        dev->pins = devm_kzalloc(dev, sizeof(*(dev->pins)), GFP_KERNEL);//创建叫pins的dev_info结构体
//struct dev_pin_info {
//        struct pinctrl *p;
//        struct pinctrl_state *default_state;
//        struct pinctrl_state *init_state;
//#ifdef CONFIG_PM
//        struct pinctrl_state *sleep_state;
//        struct pinctrl_state *idle_state;
//#endif
//};
        dev->pins->p = devm_pinctrl_get(dev);//每个节点自己的pinctrl创建
//struct pinctrl *devm_pinctrl_get(struct device *dev)
//{
//        struct pinctrl **ptr, *p;
//        ptr = devres_alloc(devm_pinctrl_release, sizeof(*ptr), GFP_KERNEL);
//        if (!ptr)
//                return ERR_PTR(-ENOMEM);
//        p = pinctrl_get(dev);
//.....
//}

        if (IS_ERR(dev->pins->p)) {
                dev_dbg(dev, "no pinctrl handle\n");
                ret = PTR_ERR(dev->pins->p);
                goto cleanup_alloc;
        }
//下面就是寻找对应的"default“这些配置去设置了
        dev->pins->default_state = pinctrl_lookup_state(dev->pins->p,
                                        PINCTRL_STATE_DEFAULT);
        if (IS_ERR(dev->pins->default_state)) {
                dev_dbg(dev, "no default pinctrl state\n");
                ret = 0;
                goto cleanup_get;
        }

        dev->pins->init_state = pinctrl_lookup_state(dev->pins->p,
                                        PINCTRL_STATE_INIT);
        if (IS_ERR(dev->pins->init_state)) {
                /* Not supplying this state is perfectly legal */
                dev_dbg(dev, "no init pinctrl state\n");

                ret = pinctrl_select_state(dev->pins->p,
                                           dev->pins->default_state);
        } else {
                ret = pinctrl_select_state(dev->pins->p, dev->pins->init_state);
        }

        if (ret) {
                dev_dbg(dev, "failed to activate initial pinctrl state\n");
                goto cleanup_get;
        }
回复

使用道具 举报

3

主题

22

帖子

0

精华

新手上路

积分
45
金钱
45
注册时间
2017-10-25
在线时间
16 小时
发表于 2021-3-2 15:31:40 | 显示全部楼层
所以每个设备树设备节点里,一般没用platform框架驱动,就不会进去probe,也就不会进入really_probe,执行后面这一系列。
回复

使用道具 举报

3

主题

22

帖子

0

精华

新手上路

积分
45
金钱
45
注册时间
2017-10-25
在线时间
16 小时
发表于 2021-3-2 15:35:14 | 显示全部楼层
顺便推荐一个在线看内核源码的网站,里面有各种引用跳转,查询符合,挺方便的
https://elixir.bootlin.com/linux/latest/source
回复

使用道具 举报

50

主题

385

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1126
金钱
1126
注册时间
2014-8-24
在线时间
146 小时
 楼主| 发表于 2021-3-2 17:12:05 | 显示全部楼层
副国级 发表于 2021-3-2 15:35
顺便推荐一个在线看内核源码的网站,里面有各种引用跳转,查询符合,挺方便的
https://elixir.bootlin.com ...

这个好,神器
找一份喜欢的工作,这样每天工作的8个小时是快乐的。 找一个喜欢的人,这样每天工作之外的16个小时也是快乐的。
回复

使用道具 举报

50

主题

385

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1126
金钱
1126
注册时间
2014-8-24
在线时间
146 小时
 楼主| 发表于 2021-3-2 17:12:34 | 显示全部楼层
副国级 发表于 2021-3-2 14:54
我记得好像这样的:
iomuxc这个节点probe到后是生成pin控制器的结构体pinctrl_dev,芯片有几个iomuxc控制 ...

这下明白了,清楚易懂,非常感谢!
找一份喜欢的工作,这样每天工作的8个小时是快乐的。 找一个喜欢的人,这样每天工作之外的16个小时也是快乐的。
回复

使用道具 举报

50

主题

385

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1126
金钱
1126
注册时间
2014-8-24
在线时间
146 小时
 楼主| 发表于 2021-3-9 10:09:28 | 显示全部楼层
实测有效,改成platform框架,所有IO就自动配置了。
找一份喜欢的工作,这样每天工作的8个小时是快乐的。 找一个喜欢的人,这样每天工作之外的16个小时也是快乐的。
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则



关闭

原子哥极力推荐上一条 /2 下一条

正点原子公众号

QQ|手机版|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2024-11-25 21:49

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

快速回复 返回顶部 返回列表