简单的中断服务程序:返回的request_irq错误code -22 [英] Simple interrupt handler: request_irq returns error code -22

查看:7210
本文介绍了简单的中断服务程序:返回的request_irq错误code -22的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我写一个简单的内核模块,它可以注册一个中断,并处理它。
然而,当我尝试通过调用函数的request_irq注册的中断,
它返回错误code -22:


  

错误:无法要求IRQ 30 - code -22,EIO 5,EINVAL 22


我相信,这个错误code等于EINVAL(无效参数)

请告诉我,我做错了。这里是一个模块:

 的#include< Linux的/ init.h中>
#包括LT&; Linux的/ - module.h中GT;
#包括LT&; Linux的/ irq.h>
#包括LT&; Linux的/ io.h>
#包括LT&; Linux的/ irqdomain.h>
#包括LT&; Linux的/ interrupt.h>
#包括LT&; Linux的/ of.h>
#包括LT&; Linux的/ of_address.h>#包括LT&; ASM / exception.h>
#包括LT&; ASM /马赫/ irq.h>无效int068_interrupt(INT IRQ,无效*的dev_id,结构pt_regs *暂存器)
{
    printk的(中断应该有处理\\ n);
}静态INT __init
clcdint_init(无效)
{
    无符号整型IRQ;
    无符号整型irqflags;
    INT RET;    IRQ = 68;
    irqflags = IRQF_SHARED | IRQF_NO_SUSPEND;    RET =的request_irq(IRQ,int068_interrupt,
            irqflagsclcdint-int068,NULL);    如果(保留!= 0){
            printk的(错误:无法请求IRQ%D,IRQ);
            printk的( - code%D,EIO%D,EINVAL%d个\\ N,RET,EIO,EINVAL);
    }    printk的(CLCDINT_INIT \\ n);
    返回0;
}宏module_init(clcdint_init);静态无效__exit
clcdint_exit(无效)
{
    无符号整型IRQ;
    IRQ = 68;
    free_irq(IRQ,NULL);
    printk的(CLCDINT_EXIT \\ n);
}宏module_exit(clcdint_exit);


解决方案

您不能共享中断行处理(IRQF_SHARED标志上)时,通过(在的request_irq()调用的最后参数)空上下文。

要理解为什么考虑以下情形:您有两个相同的网卡共享相同的IRQ。相同的驱动程序将通过相同的中断处理函数,相同的IRQ号和相同的描述。没有办法区分注册的两个实例,除了通过上下文参数

因此​​,作为precaution,你不能,如果你通过IRQF_SHARED标志传递一个NULL上下文参数。

I am writing a simple kernel module, which could register an interrupt and handle it. However, when I try to register interrupt by calling the request_irq function, it returns error code -22 :

ERROR: Cannot request IRQ 30 - code -22 , EIO 5 , EINVAL 22

I believe, this error code is equal to EINVAL (invalid argument)

Please tell me, what I am doing wrong. Here is a module:

#include <linux/init.h>
#include <linux/module.h>
#include <linux/irq.h>
#include <linux/io.h>
#include <linux/irqdomain.h>
#include <linux/interrupt.h>
#include <linux/of.h>
#include <linux/of_address.h>

#include <asm/exception.h>
#include <asm/mach/irq.h>

void int068_interrupt(int irq, void *dev_id, struct pt_regs *regs)
{
    printk("Interrupt should be handled there\n");
}

static int __init
clcdint_init(void)
{
    unsigned int irq;
    unsigned int irqflags;
    int ret;

    irq=68;
    irqflags=IRQF_SHARED | IRQF_NO_SUSPEND;

    ret = request_irq(irq, int068_interrupt,
            irqflags, "clcdint-int068", NULL);

    if (ret!=0) {
            printk("ERROR: Cannot request IRQ %d", irq);
            printk(" - code %d , EIO %d , EINVAL %d\n", ret, EIO, EINVAL);
    }

    printk("CLCDINT_INIT\n");
    return 0;
}

module_init(clcdint_init);

static void __exit
clcdint_exit(void)
{
    unsigned int irq;
    irq=68;
    free_irq(irq, NULL);
    printk("CLCDINT_EXIT\n");
}

module_exit(clcdint_exit);

解决方案

You can't pass a NULL context (last parameters of the request_irq() call) when dealing with a shared interrupt line (IRQF_SHARED flag is on).

To understand why consider the following scenario: you have two identical network cards sharing the same IRQ. The same driver will pass the same interrupt handler function, the same irq number and the same description. There is no way to distinguish the two instances of the registration except via the context parameter.

Therefore, as a precaution, you can't pass a NULL context parameter if you pass the IRQF_SHARED flag.

这篇关于简单的中断服务程序:返回的request_irq错误code -22的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆