JJJ-2 init_IRQ
void __init init_IRQ(void)
{int ret;if (IS_ENABLED(CONFIG_OF) && !machine_desc->init_irq)irqchip_init();else // init_irq成员定义为imx6ul_init_irq,会走这个分支machine_desc->init_irq(); if (IS_ENABLED(CONFIG_OF) && IS_ENABLED(CONFIG_CACHE_L2X0) &&(machine_desc->l2c_aux_mask || machine_desc->l2c_aux_val)) {if (!outer_cache.write_sec)outer_cache.write_sec = machine_desc->l2c_write_sec;ret = l2x0_of_init(machine_desc->l2c_aux_val,machine_desc->l2c_aux_mask);if (ret)pr_err("L2C: failed to init: %d\n", ret);}
}
看imx6ul_init_irq
static void __init imx6ul_init_irq(void)
{imx_gpc_check_dt();imx_init_revision_from_anatop();imx_src_init();irqchip_init();
}
看imx_gpc_check_dt
void __init imx_gpc_check_dt(void)
{struct device_node *np;// 应该是定义在 imx6ul.dtsinp = of_find_compatible_node(NULL, NULL, "fsl,imx6q-gpc");if (WARN_ON(!np))return;if (WARN_ON(!of_find_property(np, "interrupt-controller", NULL))) {pr_warn("Outdated DT detected, suspend/resume will NOT work\n");/* map GPC, so that at least CPUidle and WARs keep working */gpc_base = of_iomap(np, 0);}
}设备节点如下:
gpc: gpc@020dc000 {compatible = "fsl,imx6ul-gpc", "fsl,imx6q-gpc";reg = <0x020dc000 0x4000>;interrupt-controller;#interrupt-cells = <3>;interrupts = <GIC_SPI 89 IRQ_TYPE_LEVEL_HIGH>;interrupt-parent = <&intc>;fsl,mf-mix-wakeup-irq = <0x7c00000 0x7d00 0x0 0x1400640>;};
看 imx_init_revision_from_anatop
void __init imx_init_revision_from_anatop(void)
{struct device_node *np;void __iomem *anatop_base;unsigned int revision;u32 digprog;u16 offset = ANADIG_DIGPROG;np = of_find_compatible_node(NULL, NULL, "fsl,imx6q-anatop");anatop_base = of_iomap(np, 0);WARN_ON(!anatop_base);if (of_device_is_compatible(np, "fsl,imx6sl-anatop")) // 不会走这个分支offset = ANADIG_DIGPROG_IMX6SL;if (of_device_is_compatible(np, "fsl,imx7d-anatop")) // 不会走这个分支offset = ANADIG_DIGPROG_IMX7D;根据offset偏移然后去读寄存器的值digprog = readl_relaxed(anatop_base + offset);iounmap(anatop_base);switch (digprog & 0xff) {case 0:if (digprog >> 8 & 0x01)revision = IMX_CHIP_REVISION_2_0;elserevision = IMX_CHIP_REVISION_1_0;break;case 1:revision = IMX_CHIP_REVISION_1_1;break;case 2:revision = IMX_CHIP_REVISION_1_2;break;case 3:revision = IMX_CHIP_REVISION_1_3;break;case 4:revision = IMX_CHIP_REVISION_1_4;break;case 5:/** i.MX6DQ TO1.5 is defined as Rev 1.3 in Data Sheet, marked* as 'D' in Part Number last character.*/revision = IMX_CHIP_REVISION_1_5;break;default:/** Fail back to return raw register value instead of 0xff.* It will be easy know version information in SOC if it* can't recongized by known version. And some chip like* i.MX7D soc digprog value match linux version format,* needn't map again and direct use register value.*/revision = digprog & 0xff;}mxc_set_cpu_type(digprog >> 16 & 0xff);imx_set_soc_revision(revision);
}
看 mxc_set_cpu_type
// 判断 cpu类型,赋值给 soc_id 字串
void mxc_set_cpu_type(unsigned int type)
{__mxc_cpu_type = type;
}
看 mxc_set_arch_type
// 判断arch,似乎没怎么用到
void mxc_set_arch_type(unsigned int type)
{__mxc_arch_type = type;
}
看 imx_src_init
void __init imx_src_init(void)
{struct device_node *np;u32 val;np = of_find_compatible_node(NULL, NULL, "fsl,imx51-src");if (!np)return;src_base = of_iomap(np, 0);WARN_ON(!src_base);//这个if没跑到if (cpu_is_imx7d()) {val = readl_relaxed(src_base + SRC_M4RCR);if (((val & BIT(3)) == BIT(3)) && !(val & BIT(0)))m4_is_enabled = true;elsem4_is_enabled = false;return;}// 详见下imx_reset_controller.of_node = np;if (IS_ENABLED(CONFIG_RESET_CONTROLLER))reset_controller_register(&imx_reset_controller);/** force warm reset sources to generate cold reset* for a more reliable restart*/spin_lock(&src_lock);val = readl_relaxed(src_base + SRC_SCR);/* bit 4 is m4c_non_sclr_rst on i.MX6SX */if (cpu_is_imx6sx() && ((val &(1 << BP_SRC_SCR_SW_OPEN_VG_RST)) == 0))m4_is_enabled = true;elsem4_is_enabled = false;val &= ~(1 << BP_SRC_SCR_WARM_RESET_ENABLE);writel_relaxed(val, src_base + SRC_SCR);spin_unlock(&src_lock);
}
linux reset framework介绍
compatible 为 “fsl,imx51-src” 对应的节点为:
imx6ul.dtsisrc: src@020d8000 {compatible = "fsl,imx6ul-src", "fsl,imx51-src";reg = <0x020d8000 0x4000>;interrupts = <GIC_SPI 91 IRQ_TYPE_LEVEL_HIGH>,<GIC_SPI 96 IRQ_TYPE_LEVEL_HIGH>;#reset-cells = <1>;};
看 irqchip_init
void __init irqchip_init(void)
{of_irq_init(__irqchip_of_table);// 空函数acpi_irq_init();
}
看
/*** of_irq_init - Scan and init matching interrupt controllers in DT* @matches: 0 terminated array of nodes to match and init function to call** This function scans the device tree for matching interrupt controller nodes,* and calls their initialization functions in order with parents first.*/
void __init of_irq_init(const struct of_device_id *matches)
{struct device_node *np, *parent = NULL;struct intc_desc *desc, *temp_desc;struct list_head intc_desc_list, intc_parent_list;INIT_LIST_HEAD(&intc_desc_list);INIT_LIST_HEAD(&intc_parent_list);// 遍历所有的node,寻找定义了interrupt-controller属性的node,如果定义了interrupt-controller属性则说明该node就是一个中断控制器。详细分析见下for_each_matching_node(np, matches) {if (!of_find_property(np, "interrupt-controller", NULL) ||!of_device_is_available(np))continue;/** Here, we allocate and populate an intc_desc with the node* pointer, interrupt-parent device_node etc.*/desc = kzalloc(sizeof(*desc), GFP_KERNEL);if (WARN_ON(!desc))goto err;// 此处会有两个node符合条件,分别为interrupt-controller和gpcdesc->dev = np;desc->interrupt_parent = of_irq_find_parent(np);if (desc->interrupt_parent == np)desc->interrupt_parent = NULL;list_add_tail(&desc->list, &intc_desc_list);}/** The root irq controller is the one without an interrupt-parent.* That one goes first, followed by the controllers that reference it,* followed by the ones that reference the 2nd level controllers, etc.*/while (!list_empty(&intc_desc_list)) {/** Process all controllers with the current 'parent'.* First pass will be looking for NULL as the parent.* The assumption is that NULL parent means a root controller.*/list_for_each_entry_safe(desc, temp_desc, &intc_desc_list, list) {const struct of_device_id *match;int ret;// typedef int (*of_irq_init_cb_t)(struct device_node *, struct device_node *);of_irq_init_cb_t irq_init_cb;if (desc->interrupt_parent != parent)continue;list_del(&desc->list);// 传入一个node设备树节点,让它与给定的一组的matches匹配,返回其中最合适的matchesmatch = of_match_node(matches, desc->dev);if (WARN(!match->data,"of_irq_init: no init function for %s\n",match->compatible)) {kfree(desc);continue;}pr_debug("of_irq_init: init %s @ %p, parent %p\n",match->compatible,desc->dev, desc->interrupt_parent);//jl_test 能走到这儿的也只有两个节点,分别为interrupt-controller和gpcpr_err("irq_test:%s:%d:node_name=%s:compatible=%s\n", __func__, __LINE__, desc->dev->name, match->compatible);irq_init_cb = (of_irq_init_cb_t)match->data;// gic_of_init 和 imx_gpc_init 接下来要重点分析这两个函数了,见3ret = irq_init_cb(desc->dev, desc->interrupt_parent);if (ret) {kfree(desc);continue;}/** This one is now set up; add it to the parent list so* its children can get processed in a subsequent pass.*/list_add_tail(&desc->list, &intc_parent_list);}/* Get the next pending parent that might have children */desc = list_first_entry_or_null(&intc_parent_list,typeof(*desc), list);if (!desc) {pr_err("of_irq_init: children remain, but no parents\n");break;}list_del(&desc->list);parent = desc->dev;kfree(desc);}list_for_each_entry_safe(desc, temp_desc, &intc_parent_list, list) {list_del(&desc->list);kfree(desc);}
err:list_for_each_entry_safe(desc, temp_desc, &intc_desc_list, list) {list_del(&desc->list);kfree(desc);}
}
关于reset framework 详见这篇
关于for_each_matching_node,详见这篇
相关文章:
JJJ-2 init_IRQ
void __init init_IRQ(void) {int ret;if (IS_ENABLED(CONFIG_OF) && !machine_desc->init_irq)irqchip_init();else // init_irq成员定义为imx6ul_init_irq,会走这个分支machine_desc->init_irq(); if (IS_ENABLED(CONFIG_OF) && IS_ENABLED…...

【NLP实战】基于Bert和双向LSTM的情感分类【下篇】
文章目录前言简介第一部分关于pytorch lightning保存模型的机制关于如何读取保存好的模型完善测试代码第二部分第一次训练出的模型的过拟合问题如何解决过拟合后记前言 本文涉及的代码全由博主自己完成,可以随意拿去做参考。如对代码有不懂的地方请联系博主。 博主…...

程序设计方法学
体育竞技分析 问题分析 体育竞技分析 需求:毫厘是多少? 如何科学分析体育竞技比赛? 输入:球员的水平 输出:可预测的比赛成绩 体育竞技分析:模拟N场比赛 计算思维:抽象 自动化 模拟&am…...

Hadoop之Yarn篇
目录 编辑 Yarn的工作机制: 全流程作业: Yarn的调度器与调度算法: FIFO调度器(先进先出): 容量调度器(Capacity Scheduler): 容量调度器资源分配算法࿱…...

Spring Cloud Nacos使用总结
目录 安装Nacos服务器 服务发现与消费 服务发现与消费-添加依赖 服务发现-配置文件 服务发现-注解 服务发现-Controller 服务消费-配置文件 服务消费-注解与Ribbon消费代码 服务消费-运行 配置管理 配置管理-添加依赖 配置管理-配置文件 配置管理-注解 配置管理-…...

目标检测框架yolov5环境搭建
目前,目标检测框架中,yolov5 是很火的,它基于pytorch框架,集成opencv等框架,项目地址:https://github.com/ultralytics/yolov5,对我来说,机器学习、深度学习才开始接触,本…...

Vulnhub:Digitalworld.local (JOY)靶机
kali:192.168.111.111 靶机:192.168.111.130 信息收集 端口扫描 nmap -A -v -sV -T5 -p- --scripthttp-enum 192.168.111.130 使用enum4linux枚举目标smb服务,发现两个系统用户 enum4linux -a 192.168.111.130 ftp可以匿名登陆ÿ…...

STL源码剖析-六大部件, 部件的关系,复杂度, 区间表示
C标准库-体系结构与内核分析 根据源代码来分析 介绍 自学C侯捷老师的STL源码剖析的个人笔记,方便以后进行学习,查询。 为什么要学STL?按侯捷老师的话来说就是:使用一个东西,却不明白它的道理,不高明&…...
总有一个可用的连接,metaIPC1.2进入智能连接新时代
概述 metaIPC有1.0和2.0两个产品系列,2.0版本是可视对讲IPC,1.0新版本1.2在全面兼容ICE规范基础上进行了扩展,使metaIPC1.2进入智能化连接新时代。 metaIPC1.2在host/stun/turn/srs/zlm/janus/freeswitch等p2p/sfu/mcu进行全方位连通测试&a…...
棋盘问题c
在一个给定形状的棋盘(形状可能是不规则的)上面摆放棋子,棋子没有区别。要求摆放时任意的两个棋子不能放在棋盘中的同一行或者同一列,请编程求解对于给定形状和大小的棋盘,摆放k个棋子的所有可行的摆放方案C。 Input …...
华纳云:Linux系统下怎么创建普通用户并更改用户组
本篇内容主要讲解“Linux系统下怎么创建普通用户并更改用户组”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“Linux系统下怎么创建普通用户并更改用户组”吧! 要求 项目做权限管理,不用root部…...

「她时代」背后的欧拉力量
2018年大热电视剧《北京女子图鉴》,讲述了一群在北京打拼的职业女性,她们背井离乡,被现实包裹,被压力、责任困扰,但依旧用倔强的个性、不屈的进取心和深厚的知识技能努力营造、交织出一片励志的天空,既激昂…...
kubespray v2.21.0 在线部署 kubernetes v1.24.0 集群【2】
文章目录创建 虚拟机模板虚拟机名称配置静态地址配置代理yum 配置配置主机名安装 git安装 docker安装 ansible配置内核参数安装 k8s定制安装新增节点配置主机名配置代理配置互信更新 inventory报错kubespray v2.21.0 部署 kubernetes v1.24.0 集群 【1】在 Rocky linux 8.7 使用…...

聚焦运营商信创运维,美信时代监控易四大亮点值得一试!
2021年11月《“十四五”信息通信行业发展规划》提出,到2025年,我国将建立高速泛在、集成互联、智能绿色、安全可靠的新型数字基础设施体系。 此《规划》让我国运营商信创进一步加速,中国移动、中国电信、中国联通等都先后加入信创大军&#x…...
[python刷题模板] 博弈入门-记忆化搜索/dp/打表
[python刷题模板] 博弈入门-记忆化搜索/dp/打表 一、 算法&数据结构1. 描述2. 复杂度分析3. 常见应用4. 常用优化二、 模板代码1. 打表贪心的博弈2. 464. 我能赢吗3. Nim游戏--最最基础版n1。三、其他四、更多例题五、参考链接一、 算法&数据结构 1. 描述 博弈一直没…...

I2C通信
一、理论上了解I2C时序 I2C写数据时序如图: 通过解析器解析I2C通信如上图(SCL和SDA反了)。 1---起始信号 2、3---应答信号ACK 5---停止信号 起始信号:SCL线是高电平时,SDA线从高电平向低电平切换。 停…...

【Linux】man什么都搜不了,No manual entry for xxx的解决方案
本文首发于 慕雪的寒舍 man什么都搜不了,No manual entry for xxx的解决方案 系统 CentOS 7.6 1.问题描述 今天查手册的时候,发现man什么都查不了。不管是系统接口还是函数,都显示没有入口文档(No manual entry for)…...

STM32 库函数 GPIO_SetBits、GPIO_ResetBits、GPIO_WriteBit、GPIO_Write 区别
问题:当我使用STM32库函数对 I/O 口进行赋值时,在头文件中发现有四个相关的函数可以做这个操作,那么它们有什么区别呢? 一、GPIO_SetBits //eg: GPIO_SetBits(GPIOA, GPIO_Pin_1 | GPIO_Pin_2);解释:置位(置1)选择的数…...

在 RISC-V Linux 内核中添加模块
在 RISC-V Linux 内核中添加模块 flyfish 本例以添加helloworld字符设备为例 一 源码配置 1 源码 源码文件helloworld.c拷贝到 drivers/char 目录中 源码主要是输出Hello world init 2 Kconfig 打开drivers/char 目录下的Kconfig文件 在endmenu之前加上 config HELLO…...

利用AOP实现统一功能处理
目录 一、实现用户登录校验 实现自定义拦截器 将自定义的拦截器添加到框架的配置中,并且设置拦截的规则 二、实现统一异常处理 三、实现统一数据格式封装 一、实现用户登录校验 在之前的项目中,在需要验证用户登录的部分,每次都需要利…...

深度学习在微纳光子学中的应用
深度学习在微纳光子学中的主要应用方向 深度学习与微纳光子学的结合主要集中在以下几个方向: 逆向设计 通过神经网络快速预测微纳结构的光学响应,替代传统耗时的数值模拟方法。例如设计超表面、光子晶体等结构。 特征提取与优化 从复杂的光学数据中自…...

装饰模式(Decorator Pattern)重构java邮件发奖系统实战
前言 现在我们有个如下的需求,设计一个邮件发奖的小系统, 需求 1.数据验证 → 2. 敏感信息加密 → 3. 日志记录 → 4. 实际发送邮件 装饰器模式(Decorator Pattern)允许向一个现有的对象添加新的功能,同时又不改变其…...

Flask RESTful 示例
目录 1. 环境准备2. 安装依赖3. 修改main.py4. 运行应用5. API使用示例获取所有任务获取单个任务创建新任务更新任务删除任务 中文乱码问题: 下面创建一个简单的Flask RESTful API示例。首先,我们需要创建环境,安装必要的依赖,然后…...

SCAU期末笔记 - 数据分析与数据挖掘题库解析
这门怎么题库答案不全啊日 来简单学一下子来 一、选择题(可多选) 将原始数据进行集成、变换、维度规约、数值规约是在以下哪个步骤的任务?(C) A. 频繁模式挖掘 B.分类和预测 C.数据预处理 D.数据流挖掘 A. 频繁模式挖掘:专注于发现数据中…...
测试markdown--肇兴
day1: 1、去程:7:04 --11:32高铁 高铁右转上售票大厅2楼,穿过候车厅下一楼,上大巴车 ¥10/人 **2、到达:**12点多到达寨子,买门票,美团/抖音:¥78人 3、中饭&a…...

什么是库存周转?如何用进销存系统提高库存周转率?
你可能听说过这样一句话: “利润不是赚出来的,是管出来的。” 尤其是在制造业、批发零售、电商这类“货堆成山”的行业,很多企业看着销售不错,账上却没钱、利润也不见了,一翻库存才发现: 一堆卖不动的旧货…...

江苏艾立泰跨国资源接力:废料变黄金的绿色供应链革命
在华东塑料包装行业面临限塑令深度调整的背景下,江苏艾立泰以一场跨国资源接力的创新实践,重新定义了绿色供应链的边界。 跨国回收网络:废料变黄金的全球棋局 艾立泰在欧洲、东南亚建立再生塑料回收点,将海外废弃包装箱通过标准…...
ffmpeg(四):滤镜命令
FFmpeg 的滤镜命令是用于音视频处理中的强大工具,可以完成剪裁、缩放、加水印、调色、合成、旋转、模糊、叠加字幕等复杂的操作。其核心语法格式一般如下: ffmpeg -i input.mp4 -vf "滤镜参数" output.mp4或者带音频滤镜: ffmpeg…...
VTK如何让部分单位不可见
最近遇到一个需求,需要让一个vtkDataSet中的部分单元不可见,查阅了一些资料大概有以下几种方式 1.通过颜色映射表来进行,是最正规的做法 vtkNew<vtkLookupTable> lut; //值为0不显示,主要是最后一个参数,透明度…...

EtherNet/IP转DeviceNet协议网关详解
一,设备主要功能 疆鸿智能JH-DVN-EIP本产品是自主研发的一款EtherNet/IP从站功能的通讯网关。该产品主要功能是连接DeviceNet总线和EtherNet/IP网络,本网关连接到EtherNet/IP总线中做为从站使用,连接到DeviceNet总线中做为从站使用。 在自动…...