首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >request_irq失败,因为没有irq描述符

request_irq失败,因为没有irq描述符
EN

Stack Overflow用户
提问于 2019-11-15 00:04:40
回答 1查看 763关注 0票数 0

我有一个Linux系统,我正在连接到定制硬件。(具体来说,这是一个带有FPGA的SoC )。

我正在尝试编写一个内核模块,它将响应来自我设备的中断。它包含对request_irq的调用,但这是通过调用uio_register_device来完成的。当我运行insmod时,它会以“无效的参数”失败。

在浏览代码一段时间之后,我最终在模块init函数中添加了这些行:

代码语言:javascript
复制
struct irq_desc *p;
p = irq_to_desc(89);
if (!p) {
    printk(KERN_ALERT "No descriptor allocated for IRQ number 89!!\n");
}
p = irq_to_desc(121);
if (!p) {
    printk(KERN_ALERT "No descriptor allocated for IRQ number 121!!\n");
}

当然,我在dmesg中看到了这些消息。

在这种情况下我该怎么办?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2019-11-16 04:03:27

我设法弄明白了。要使中断正常工作,需要将虚拟IRQ号(即在request_interrupt中使用的数字)映射到硬件IRQ号。当然,硬件IRQ号并不是唯一的;例如,两个中断控制器的硬件IRQ数可以是0。所以我真正的意思是,你必须把虚拟IRQ数字与irq_domain和硬件IRQ号的组合联系起来。

更重要的是:irq_domains与中断控制器不对应1比1.一个控制器可以有多个域。

因此,让我们精确地定义我们所谓的“映射”IRQ是什么意思:

  1. 每个虚拟IRQ都有一个struct irq_desc。此结构的一些字段映射为指向由中断控制器驱动程序实现的函数。(我不确定Linux在执行任何映射之前接收中断时会做什么)
  2. 每个中断控制器都可以提供一定数量的struct irq_domain,它们本质上是编码硬件IRQ号到虚拟IRQ号之间的映射,并且有一个供驱动程序查找数字的API。
  3. irq_domain结构还包含指向回调的指针,这些回调由中断控制器驱动程序实现。创建新映射时会触发其中一个回调;我认为硬件就是这样配置的,以生成特定的虚拟IRQ。

当您请求中断时,您的ISR将被添加到actions列表中的irq_desc中,前提是irq_desc已被正确初始化。

无论如何,我找到的获得给定硬件IRQ号的虚拟IRQ号的方法(必要时创建一个新的映射)如下:

代码语言:javascript
复制
#include <linux/irqdomain.h> //For irq_domain struct
#include <linux/of.h> //For device tree struct types
#include <linux/irq.h> //Needed by other interrupt-related code

struct device_node *dn;
struct irq_domain *dom;
struct irq_fwspec dummy_fwspec = {
    .param_count = 3,
    .param = {0, 89, 4}
};
int virq;

//Find the Linux irq number
dn = of_find_node_by_name(NULL, "interrupt-controller");
if (!dn) {
    printk(KERN_ERR "Could not find device node for \"interrupt-controller\"\n");
    goto /*error_handler*/;
}
dom = irq_find_host(dn);
if (!dom) {
    printk(KERN_ERR "Could not find irq domain\n");
    goto /*error_handler*/;
}

dummy_fwspec.fwnode = dom->fwnode;
virq = irq_create_fwspec_mapping(&dummy_fwspec);

irq_create_fwspec_mapping将返回一个现有的(映射的)虚拟IRQ号,或者映射一个新的IRQ号。struct irq_fwspec包含执行映射所需的所有信息。fwnode字段必须指向您正在使用的中断控制器;在我的示例中,我使用设备树API找到了正确的值(可能有更好的方法,但我不知道它是什么!)

这个例子是专门针对MPSoC的,我碰巧知道它使用驱动程序(驱动程序/irqchip/irq-gic.c)。我查看了驱动程序的源代码,以确定它在irq_fwspec结构的其他部分中需要什么。具体来说,每个控制器驱动程序都将填充一个struct irq_domain_ops,因此CTRL可以找到您需要满足的回调函数。

在我的具体示例中,我知道gic_irq_domain_alloc将被调用,并且它也将调用gic_irq_domain_translate。这告诉我,第二个数字是硬件IRQ号码,但出于某种原因,它将增加32。因为我想要硬件IRQ编号121,所以我插入了第二个号码的89个。第一个和第三个数字是根据我看到其他人在做什么来猜测的。

如果有人知道更简单的方法,请告诉我

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/58868399

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档