了解“/linux-5.4.31/drivers/of/device.c”中的of_device_get_match_data()

1、打开“drivers/of/base.c”

#define of_prop_cmp(s1, s2) strcmp((s1), (s2))

/*如果s1小于s2,则返回值小于0。

如果s1大于s2,则返回值大于0。

如果s1等于s2,则返回值等于0。*/

//函数功能:根据所给的“设备树的节点np”和“properties名字”在设备树里查找是否有“properties名字”

//np是指向设备树的节点

//name是指向要查找的properties名字

//lenp用来返回properties名字的长度

static struct property *__of_find_property(const struct device_node *np,

   const char *name, int *lenp)

{

struct property *pp;

if (!np)return NULL;

for (pp = np->properties; pp; pp = pp->next)

{

if (of_prop_cmp(pp->name, name) == 0)

{ //如果pp->name等于name,则返回值等于0。

if (lenp) *lenp = pp->length;//保存properties名字的长度

break;

}

}

return pp;//返回property结构指针

}

const char *of_prop_next_string(struct property *prop, const char *cur)

{

const void *curv = cur;

if (!prop)return NULL;//如果prop=NULL,则返回NULL

if (!cur)return prop->value;//如果prop=NULL,则返回prop->value

curv += strlen(cur) + 1;//求cur字符串的长度,包括结束符;

if (curv >= prop->value + prop->length)//所给字符串的长度

return NULL;

return curv;

}

/*函数功能:根据name,在np指向的节点查找name所指向的字符串;返回属性名字的长度

保存在lenp中,并返回属性的指针值*/

static struct property *__of_find_property(const struct device_node *np,

   const char *name, int *lenp)

{

struct property *pp;

if (!np) return NULL;//如果np=NULL,则返回NULL

for (pp = np->properties; pp; pp = pp->next)

{ /*np->properties指向属性*/

if (of_prop_cmp(pp->name, name) == 0)

{

/*根据所给的“设备树的节点np”和“name所指向的名字”在设备树里查找是否有“name所指向的名字”*/

if (lenp) *lenp = pp->length;//返回属性名字的长度

break;

}

}

return pp;

}

/*根据所给的节点查找给定名字的属性

 * Find a property with a given name for a given node

 * and return the value.

 */

const void *__of_get_property(const struct device_node *np,

      const char *name, int *lenp)

{

struct property *pp = __of_find_property(np, name, lenp);

/*函数功能:根据name,在np指向的节点查找name所指向的字符串;返回属性名字的长度

保存在lenp中,并返回属性的指针值*/

return pp ? pp->value : NULL;

//如果pp!=NULL,则返回pp->value

}

//函数功能:如果根据所给的节点查找到了属性名为type,则返回1

static bool __of_node_is_type(const struct device_node *np, const char *type)

{

const char *match = __of_get_property(np, "device_type", NULL);

//根据所给的节点np查找device_type的属性,match=np->value

return np && match && type && !strcmp(match, type);

//np->valuetype相同,返回1

}

//检查节点是否匹配所给的“name”,匹配则返回1;

bool of_node_name_eq(const struct device_node *np, const char *name)

{

const char *node_name;

size_t len;

if (!np)return false;

node_name = kbasename(np->full_name);//从np->full_name中提取名字;

len = strchrnul(node_name, '@') - node_name;//计算节点名字的长度

return (strlen(name) == len) && (strncmp(node_name, name, len) == 0);

//检查是否找到name所指向的字符串,匹配则返回1

}

#define INT_MAX 0x7fffffff

/**

函数功能:检查节点是否匹配所给的“compattypename”;

device: 指向节点的指针;

compat: compatible的缩写,要求匹配的字符串, 也可能是NULL或者是"";

type: 要求匹配的device_type, 也可能是NULL或者是"";

name: 要求匹配的节点名字, 也可能是NULL或者是"";

返回值为0,表示不匹配;返回值大于0,表示匹配;

 * 1. specific compatible && type && name

 * 2. specific compatible && type

 * 3. specific compatible && name

 * 4. specific compatible

 * 5. general compatible && type && name

 * 6. general compatible && type

 * 7. general compatible && name

 * 8. general compatible

 * 9. type && name

 * 10. type

 * 11. name

 */

static int __of_device_is_compatible(const struct device_node *device,

     const char *compat, const char *type, const char *name)

{

struct property *prop;

const char *cp;

int index = 0, score = 0;

/* Compatible匹配具有最高优先级 */

if (compat && compat[0])//如果compat!=NULL,且compat[0]>0,则执行

{

prop = __of_find_property(device, "compatible", NULL);

/*根据所给的“设备树的节点device”和“properties名字compatible”在设备树里查找是否有“compatible”;

返回值是property结构指针

*/

for (cp = of_prop_next_string(prop, NULL); cp;

     cp = of_prop_next_string(prop, cp), index++)

{

/*of_prop_next_string(prop, NULL)执行后cp=prop->value;*/

/*of_prop_next_string(prop, cp)cp=cp+strlen(cp) + 1;指向下一个prop->value*/

if (of_compat_cmp(cp, compat, strlen(compat)) == 0)

{ /*根据所给的“设备树的节点cp”和“compat所指向的名字”在设备树里查找是否有“compat所指向的名字”*/

score = INT_MAX/2 - (index << 2);

break;

}

}

if (!score)return 0;

}

/*匹配type比匹配的name的优先级要高;Matching type is better than matching name */

if (type && type[0])//如果type!=NULL,且type[0]>0,则执行

{

if (!__of_node_is_type(device, type))return 0;

//如果根据所给的device节点查找到了属性名为type,则返回1;

score += 2;

}

/* 要匹配的名字,Matching name is a bit better than not */

if (name && name[0])//如果name!=NULL,且name[0]>0,则执行

{

if (!of_node_name_eq(device, name))return 0;

        //of_node_name_eq()检查节点是否匹配所给的“name”,匹配则返回1;

score++;

}

return score;

}

static

const struct of_device_id *__of_match_node(const struct of_device_id *matches,

   const struct device_node *node)

{

const struct of_device_id *best_match = NULL;

int score, best_score = 0;

if (!matches)

return NULL;

for (; matches->name[0] || matches->type[0] || matches->compatible[0]; matches++) {

score = __of_device_is_compatible(node, matches->compatible,

  matches->type, matches->name);

       /*检查节点是否匹配所给的“compattypename”;*/

if (score > best_score) {

best_match = matches;

best_score = score;

}

}

return best_match;

}

/**判断device_node是否具有匹配的of_match结构

 * of_match_node - Tell if a device_node has a matching of_match structure

 * @matches: array of of device match structures to search in

 * @node: the of device structure to match against

 *

 * Low level utility function used by device matching.

 */

const struct of_device_id *of_match_node(const struct of_device_id *matches,

 const struct device_node *node)

{

const struct of_device_id *match;

unsigned long flags;

raw_spin_lock_irqsave(&devtree_lock, flags);

match = __of_match_node(matches, node);

raw_spin_unlock_irqrestore(&devtree_lock, flags);

return match;

}

2、打开“drivers/of/device.c”

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_node函数查找匹配的设备ID*/

}

const void *of_device_get_match_data(const struct device *dev)

{

const struct of_device_id *match;

match = of_match_device(dev->driver->of_match_table, dev);

if (!match)

return NULL;

return match->data;

}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/15378.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

AD域控粗略了解

一、前提 转眼大四&#xff0c;目前已入职上饶一公司从事运维工程师&#xff0c;这与我之前干的开发有着很大的差异&#xff0c;也学习到了许多新的知识。今天就写下我对于运维工作中常用的功能——域控的理解。 二、为什么要有域控&#xff0c;即域控的作用 首先我们必须要…

Linux(21)——系统日志

目录 一、系统日志架构&#xff1a; 1、系统日志&#xff1a; 2、日志文件类型&#xff1a; 二、查看 syslog 文件&#xff1a; 1、将事件记录到系统&#xff1a; &#xff08;1&#xff09;syslog 设备&#xff1a; &#xff08;2&#xff09;syslog 优先级&#xff1a…

学习数据结构(6)单链表OJ上

1.移除链表元素 解法一&#xff1a;&#xff08;我的做法&#xff09;在遍历的同时移除&#xff0c;代码写法比较复杂 解法二&#xff1a;创建新的链表&#xff0c;遍历原链表&#xff0c;将非val的节点尾插到新链表&#xff0c;注意&#xff0c;如果原链表结尾是val节点需要将…

第433场周赛:变长子数组求和、最多 K 个元素的子序列的最值之和、粉刷房子 Ⅳ、最多 K 个元素的子数组的最值之和

Q1、变长子数组求和 1、题目描述 给你一个长度为 n 的整数数组 nums 。对于 每个 下标 i&#xff08;0 < i < n&#xff09;&#xff0c;定义对应的子数组 nums[start ... i]&#xff08;start max(0, i - nums[i])&#xff09;。 返回为数组中每个下标定义的子数组中…

CSS 伪类(Pseudo-classes)的详细介绍

CSS 伪类详解与示例 在日常的前端开发中&#xff0c;CSS 伪类可以帮助我们非常精准地选择元素或其特定状态&#xff0c;从而达到丰富页面表现的目的。本文将详细介绍以下伪类的使用&#xff1a; 表单相关伪类 :checked、:disabled、:enabled、:in-range、:invalid、:optional、…

Centos挂载镜像制作本地yum源,并补装图形界面

内网环境centos7.9安装图形页面内网环境制作本地yum源 上传镜像到服务器目录 创建目录并挂载镜像 #创建目录 cd /mnt/ mkdir iso#挂载 mount -o loop ./CentOS-7-x86_64-DVD-2009.iso ./iso #前面镜像所在目录&#xff0c;后面所挂载得目录#检查 [rootlocalhost mnt]# df -h…

大模型推理——MLA实现方案

1.整体流程 先上一张图来整体理解下MLA的计算过程 2.实现代码 import math import torch import torch.nn as nn# rms归一化 class RMSNorm(nn.Module):""""""def __init__(self, hidden_size, eps1e-6):super().__init__()self.weight nn.Pa…

Python截图轻量化工具

一、兼容局限性 这是用Python做的截图工具&#xff0c;不过由于使用了ctypes调用了Windows的API, 同时访问了Windows中"C:/Windows/Cursors/"中的.cur光标样式文件, 这个工具只适用于Windows环境&#xff1b; 如果要提升其跨平台性的话&#xff0c;需要考虑替换cty…

链表(LinkedList) 1

上期内容我们讲述了顺序表&#xff0c;知道了顺序表的底层是一段连续的空间进行存储(数组)&#xff0c;在插入元素或者删除元素需要将顺序表中的元素整体移动&#xff0c;时间复杂度是O(n)&#xff0c;效率比较低。因此&#xff0c;在Java的集合结构中又引入了链表来解决这一问…

SpringAI系列 - 使用LangGPT编写高质量的Prompt

目录 一、LangGPT —— 人人都可编写高质量 Prompt二、快速上手2.1 诗人 三、Role 模板3.1 Role 模板3.2 Role 模板使用步骤3.3 更多例子 四、高级用法4.1 变量4.2 命令4.3 Reminder4.4 条件语句4.5 Json or Yaml 方便程序开发 一、LangGPT —— 人人都可编写高质量 Prompt La…

jupyterLab插件开发

jupyter lab安装、配置&#xff1a; jupyter lab安装、配置教程_容器里装jupyterlab-CSDN博客 『Linux笔记』服务器搭建神器JupyterLab_linux_布衣小张-腾讯云开发者社区 Jupyter Lab | 安装、配置、插件推荐、多用户使用教程-腾讯云开发者社区-腾讯云 jupyterLab插件开发教…

使用LLaMA Factory踩坑记录

前置条件&#xff1a;电脑显卡RTX 4080 问题&#xff1a;LLaMA-Factory在运行的时候&#xff0c;弹出未检测到CUDA的报错信息 结论&#xff1a;出现了以上的报错&#xff0c;主要可以归结于以下两个方面&#xff1a; 1、没有安装GPU版本的pytorch&#xff0c;下载的是CPU版本…

『Apisix进阶篇』结合Consul作服务发现实战演练

文章目录 一、引言二、APISIX与Consul集成2.1 环境准备2.2 配置Consul服务发现2.2.1 修改APISIX配置文件2.2.2 重启APISIX 2.3 在路由中使用Consul服务发现2.3.1 创建路由2.3.2 验证路由 2.4 高级配置2.4.1 服务过滤2.4.2 多数据中心支持 三、总结 &#x1f4e3;读完这篇文章里…

SpringBoot速成(八)登录实战:未登录不能访问 P5-P8

1.登录 package com.itheima.springbootconfigfile.controller;import com.itheima.springbootconfigfile.pojo.Result; import com.itheima.springbootconfigfile.pojo.User; import com.itheima.springbootconfigfile.service.UserService;import com.itheima.springbootco…

对接DeepSeek

其实&#xff0c;整个对接过程很简单&#xff0c;就四步&#xff0c;获取key&#xff0c;找到接口文档&#xff0c;接口测试&#xff0c;代码对接。 获取 KEY https://platform.deepseek.com/transactions 直接付款就是了&#xff08;现在官网暂停充值2025年2月7日&#xff0…

ASP.NET Core JWT

目录 Session的缺点 JWT&#xff08;Json Web Token&#xff09; 优点&#xff1a; 登录流程 JWT的基本使用 生成JWT 解码JWT 用JwtSecurityTokenHandler对JWT解码 注意 Session的缺点 对于分布式集群环境&#xff0c;Session数据保存在服务器内存中就不合适了&#…

【MySQL】深度学习数据库开发技术:使用CC++语言访问数据库

**前言&#xff1a;**本节内容介绍使用C/C访问数据库&#xff0c; 包括对数据库的增删查改操作。 主要是学习一些接口的调用&#xff0c; 废话不多说&#xff0c; 开始我们的学习吧&#xff01; ps:本节内容比较容易&#xff0c; 友友们放心观看哦&#xff01; 目录 准备mysql…

postgreSQL16.6源码安装

1.获取源码 从PostgreSQL: File Browser获取tar.bz2或者tar.gz源码 2.解压 tar xf postgresql-version.tar.bz2 roothwz-VMware-Virtual-Platform:/usr/local# tar xf postgresql-16.6.tar.bz2 roothwz-VMware-Virtual-Platform:/usr/local# ll 总计 24324 drwxr-xr-x 12 ro…

音频进阶学习十一——离散傅里叶级数DFS

文章目录 前言一、傅里叶级数1.定义2.周期信号序列3.表达式DFSIDFS参数含义 4.DFS公式解析1&#xff09;右边解析 T T T、 f f f、 ω \omega ω的关系求和公式N的释义求和公式K的释义 e j ( − 2 π k n N ) e^{j(\frac{-2\pi kn}{N})} ej(N−2πkn​)的释义 ∑ n 0 N − 1 e…

【kafka系列】Topic 与 Partition

Kafka 的 Topic&#xff08;主题&#xff09; 和 Partition&#xff08;分区&#xff09; 是数据组织的核心概念&#xff0c;它们的映射关系及在 Broker 上的分布直接影响 Kafka 的性能、扩展性和容错能力。以下是详细解析&#xff1a; 一、Topic 与 Partition 的映射关系 Top…