pinctrl子系统和GPIO子系统的匹配——of_match_device

个人声明:转发请注明出处,个人原创,实属不易。本人水平有限,文章若有不妥之处,还请留言批评指正,不胜感激。

  1. pinctrl子系统和GPIO子系统匹配的开始时刻是在执行imx6ul_pinctrl_probe内的of_match_device函数,of_match_device在device.c文件下。
	static int imx6ul_pinctrl_probe(struct platform_device *pdev)
	{
		const struct of_device_id *match;
		/*此信息就会在pinctrl_register向系统注册结构体之前的imx_pinctrl_desc->pctlops使用
		pinctrl_info保存了platform_device下的设备和imx6ul_pinctrl_of_match匹配表的匹配结果,即最佳匹配的of_device_id
		而of_device_id就是platform驱动框架下开发人员必须定义的设备匹配表
		*/
		struct imx_pinctrl_soc_info *pinctrl_info;    
	
		match = of_match_device(imx6ul_pinctrl_of_match, &pdev->dev);
	
		if (!match)
			return -ENODEV;
	
		pinctrl_info = (struct imx_pinctrl_soc_info *) match->data;
	
		return imx_pinctrl_probe(pdev, pinctrl_info);
	}
  1. of_match_device函数
/*
 * of_match_device - Tell if a struct device matches an of_device_id list
 * @ids: array of of device match structures to search in
 * @dev: the of device structure to match against
 *
 * Used by a driver to check whether an platform_device present in the
 * system is in its list of supported devices.
 */
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_match_device - Tell if a struct device matches an of_device_id list”,意思就是:告知一个设备(设备结构体)是否匹配了of_device_id列表中的设备。

如果匹配表或者设备没有对应的节点,返回NULL,匹配失败。否则,继续执行非常重要的of_match_node函数。

3.of_match_node函数(\drivers\of\base.c)
of_match_node是一个宏,真正执行的是**__of_match_node**这个函数。

 __of_match_node(matches, dev->of_node);
	{
		……
		for (; matches->name[0] || matches->type[0] || matches->compatible[0]; matches++) {
				score = __of_device_is_compatible(node, matches->compatible,matches->type, matches->name);
				if (score > best_score) {
					best_match = matches;
					best_score = score;
				}
			}
		return best_match;
	}

可以看出其匹配的方式有三种(任意一种都可以):name、type和compatible,这三种方式的最佳匹配是通过score分数来判定的,匹配完成返回score最大对应的matches。

4.score计算函数__of_device_is_compatible()
通过__of_device_is_compatible计算这三种方式和对应节点node的匹配分数,最后返回分数最高的匹配,最佳匹配就是三种方式都匹配上了!!!

Return:
0:没有对应的匹配
正整数:有对应匹配

而且当你的 compatible 或 type 或 name 为 NULL or “”(空字符串),可以任意匹配,即肯定可以匹配成功。

/*
 * Returns 0 for no match, and a positive integer on match. The return value is a relative score
 * with larger values indicating better matches.
 *
 * __of_device_is_compatible() - Check if the node matches given constraints
 * @device: pointer to node
 * @compat: required compatible string, NULL or "" for any match
 * @type: required device_type value, NULL or "" for any match
 * @name: required node name, NULL or "" for any match
 */

而且这三种方式的匹配有以下优先级:Compatible > type > name > not (啥也没有)

/* Compatible match has highest priority */
/* Matching type is better than matching name */
/* Matching name is a bit better than not */

当匹配属性的字符串为NULL或者""空字符串时,直接跳到下一个优先级去匹配。

/*
Checks if the given @compat, @type and @name strings match the properties of the given @device. 
A constraints can be skipped by passing NULL or an empty string as the constraint.
*/

你可能感兴趣的:(linux,内核,arm)