platform_msi使用

server/2024/12/28 7:46:45/

以下代码是OpenEuler/olk-6.6分支的,和linux实现有区别

1.为设备绑定irq_domain(可选)

如果设备是通过dts/acpi上报的,创建设备的时候就已经绑过了,不需要自己手动绑,只需要设置msi之前判断一下就行

if (!dev->msi.domain) {dev_err(dev, "msi_domain absent\n");return;
}

如果不是通过这两种方式上报的,就比较麻烦。当前项目是通过其他方式上报的,需要自己手动查irq_domain。gic在初始化的时候已经把its注册到了iort里,详见irq-gic-v3-its.c: gic_acpi_parse_madt_its,该函数是解析madt表项的。(当前鲲鹏所有上报都是走acpi,所以没研究dts的,应该也有类似注册its的行为)

static int __init gic_acpi_parse_madt_its(union acpi_subtable_headers *header, const unsigned long end)
{struct acpi_madt_generic_translator *its_entry;struct fwnode_handle *dom_handle;struct its_node *its;struct resourse res;int err;...// 分配its的fwnode_handledom_handle = irq_domain_alloc_fwnode(&res.start);// 将its信息注册到iort的链表中err = iort_register_domain_token(its_entry->translation_id, res.start, dom_handle);...
}

所以设备初始化的时候,就可以通过下面的方式绑定irq_domain

struct irq_domain *domain;
struct fwnode_handle *fwnode;// its_index就是上面注册的translation_id,设备上报的时候要传上来
// bus_token就是DOMAIN_BUS_PLATFORM_MSI,这是platform_msi_create_irq_domain时更新的bus_token.
// 必须保持一致,不然可能找到别的irq_domain
fwnode = iort_find_domain_token(its_index);
domain = irq_find_matching_fwnode(fwnode, bus_token);
dev_set_msi_domain(dev, domain);

2.申请中断号

其中nvec是设备需要申请的中断数量,由硬件决定,write_msi_msg是把在os中申请到的msi资源写入设备寄存器的函数。在第二步irq_domain_activate_irq的时候就会调用write_msi_msg函数。在此之前,需要手动关设备中断,一般写设备某个寄存器就行。

The whole process to setup an IRQ has been split into two steps. The first step, __irq_domain_alloc_irqs() is to allocate IRQ descriptor and required hw resource. The second step, irq_domain_active_irq() is to program the hw with preallocated resources.

platform_msi_domain_alloc_irqs(dev, nvec, write_msi_msg);

3.设备释irq回调

static void free_msis(void *data)
{struct device *dev = (struct device *)data;platform_msi_domain_free_irqs(dev);
}
devm_add_action(dev, free_msis, dev);

4. 获取virq

int virq = msi_get_virq(dev, XXX_MSI_INDEX);

5.设置irq_handler

devm_request_threaded_irq(dev, virq, NULL, intr_proc_thread, IRQF_ONESHOT, "xxx-intr_proc", data);

不需要上半部处理函数传NULL就行,如果需要注意不要有休眠行为。下半部是内核线程,可以休眠。然后手动开设备中断。


http://www.ppmy.cn/server/153849.html

相关文章

爬虫数据存储:Redis、MySQL 与 MongoDB 的对比与实践

爬虫的核心任务是从网络中提取数据,而存储这些数据是流程中不可或缺的一环。根据业务需求的不同,存储的选择可能直接影响数据处理的效率和开发体验。本文将介绍三种常用的存储工具——Redis、MySQL 和 MongoDB,分析它们的特点,并提…

海康RGBD相机使用C++和Opencv采集图像记录

海康RGBD相机使用C和Opencv采集图像记录 RGBD相机型号:MV-EB435i 配置:1.Vs2019 2.Opencv4.6 一、安装客户端 1.下载链接 HiViewer 2.官方Samples 安装后,在帮助-development中,可以看到一些samples,但是这些样例…

windows安装mongodb

一.安装包准备 1.服务端下载 https://www.mongodb.com/try/download/communitya 按需选择,我们这里选择社区版 直接点download浏览器下载可能比较慢,可以尝试copy link后用三方下载软件,会快很多。 2.命令行客户端安装 https://www.mong…

线性代数行列式

目录 二阶与三阶行列式 二元线性方程组与二阶行列式 三阶行列式 全排列和对换 排列及其逆序数 对换 n阶行列式的定义 行列式的性质 二阶与三阶行列式 二元线性方程组与二阶行列式 若是采用消元法解x1、x2的话则得到以下式子 有二阶行列式的规律可得:分…

问题小记-达梦数据库报错“字符串转换出错”处理

最近遇到一个达梦数据库报错“-6111: 字符串转换出错”的问题,这个问题主要是涉及到一条sql语句的执行,在此分享下这个报错的处理过程。 问题表现为:一样的表结构和数据,执行相同的SQL,在Oracle数据库中执行正常&#…

【每日学点鸿蒙知识】线程创建、构造函数中创建变量仍报错、List上下拖拽,调用JS代码、无法选择本地csr文件问题

1、HarmonyOS 如何创建一个单线程? 请问 worker 是单线程还是多线程?如果 worker 不是单线程,如何创建一个单线程呢? ArkTS是单线程模型,所以worker也是单线程,他是在宿主线程上创建的一个子线程&#xf…

指定Bean加载顺序的能力

springboot遵从约定大于配置的原则,极大程度的解决了配置繁琐的问题。在此基础上,又提供了spi机制,用spring.factories可以完成一个小组件的自动装配功能。 在一般业务场景,可能是不需要关心一个bean是如何被注册进spring容器的&…

基于GEE云计算、多源遥感、高光谱遥感技术蓝碳储量估算;红树林植被指数计算及提取

海洋是地球上最大的“碳库”,“蓝碳”即海洋活动以及海洋生物(特别是红树林、盐沼和海草)能够吸收大气中的二氧化碳,并将其固定、储存在海洋中的过程、活动和机制。而维持与提升我国海岸带蓝碳潜力是缓解气候变化的低成本、高效益的方案&…