pinctrl子系统----从provider出发

在上一篇文章中,dt_to_map_one_config函数中,需要调用具体pinctrl driver向子系统注册的pin desc结构体中的底层硬件配置函数,pin desc结构体是由子系统抽象出的用来描述一个pin controller的结构体。本篇文章从一个具体pinctrl platform driver和由设备树生成中pinctrl platform device的match过程开始,一步步分析pin desc结构体的创建和注册过程。

	pinctrl_0: pinctrl@56000000 {
        compatible = "samsung,s3c2440-pinctrl"
		reg = <0x56000000 0x1000>;
		gpa: gpa {
			gpio-controller;
			#gpio-cells = <2>;  /* 以后想使用gpa bank中的引脚时, 需要2个u32来指定引脚 */
		};
		gpb: gpb {
			gpio-controller;
			#gpio-cells = <2>;
		};
	    uart0_data: uart0-data {
		    samsung,pins = "gph-0", "gph-0";
		    samsung,pin-function = <2>;   
/* 在GPHCON寄存器中gph0,gph1可以设置以下值:0 --- 输入功能 1 --- 输出功能  2 --- 串口功能*/
	    };

	    uart0_sleep: uart0_sleep {
		    samsung,pins = "gph-0", "gph-1";
		    samsung,pin-function = <0>;  
	    };
	};
	serial@50000000 {
	    ......
		pinctrl-names = "default", "sleep";  /* 既是名字, 也称为state(状态) */
		pinctrl-0 = <&uart0_data>;
		pinctrl-1 = <&uart0_sleep>;
	};

linux kernel使用统一设备模型,bus、driver和device形成了设备模型中的铁三角。对于platform这种类型的bus,其铁三角数据是platform_bus_type(表示platform这种类型的bus)、struct platform_device(platform bus上的device)、struct platform_driver(platform bus上的driver)。每次系统增加一个platform_driver或platform_device,platform_bus_type都会启动scan过程,找到相互匹配的platform_driver和platform_device之后,就调用platform_driver的probe函数。

static int platform_match(struct device *dev, struct device_driver *drv)
{
	struct platform_device *pdev = to_platform_device(dev);
	struct platform_driver *pdrv = to_platform_driver(drv);
...
	/* Attempt an OF style match first */
	if (of_driver_match_device(dev, drv))
		return 1;
...
}
static inline int of_driver_match_device(struct device *dev,
					 const struct device_driver *drv)
{
	return of_match_device(drv->of_match_table, dev) != NULL;
}
const struct of_device_id *of_match_device(const struct of_device_id *matches,
					   const struct device *dev)
{
	if ((!matches) || (!dev->of_node))
		return NULL;
	return of_match_node(matches, dev->of_node);
}

OF style的匹配过程主要通过platform_driver的struct of_device_id和platform_device的设备树节点内容进行对比,例子中的pinctrl节点的compatible = "samsung,s3c2440-pinctrl",三星提供的pinctrl-samsung.c文件中的驱动程序可以匹配种类型的pinctrl,当然也支持s3c2440,在该文件中,可以找到对应的struct of_device_id表如下所示,该表用来填充struct platform_driver。

static const struct of_device_id samsung_pinctrl_dt_match[] = {
	{ .compatible = "samsung,exynos3250-pinctrl",
		.data = (void *)exynos3250_pin_ctrl },
...
	{ .compatible = "samsung,s3c2440-pinctrl",
		.data = s3c2440_pin_ctrl },
...
};
static struct platform_
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值