I am writing a simple driver, which could register an interrupt and handle it.
I am using the request_irq
function but it returns this error:
genirq: Flags mismatch irq 29. 00004004 (irq-test) vs. 00000004 (e000d000.spi)
- code -16 , EIO 5 , EINVAL 22
This is the simple module code:
#define IRQ_Number 29
static irqreturn_t irq_handler( int irq, void *dev_id )
{
static int mycount = 0;
printk("Interrupt! = %d\n", mycount);
mycount++;
return IRQ_HANDLED;
}
static int __init my_init(void)
{
unsigned int irq;
int ret;
irq = IRQ_Number;
ret = request_irq(irq, irq_handler , IRQF_NO_SUSPEND; , "irq-test", NULL);
if(ret != 0) {
printk("ERROR: IRQ request failed %d", irq);
printk(" - code %d , EIO %d , EINVAL %d\n", ret, EIO, EINVAL);
}
return 0;
}
static void __exit my_exit(void)
{
unsigned int irq;
irq=IRQ_Number;
free_irq(irq, NULL);
printk(KERN_INFO "my module: ----> exit\n" );
}
And this the output from cat /proc/interrupts
:
CPU0 CPU1
16: 1 0 GIC-0 27 Edge gt
17: 0 0 GIC-0 43 Level ttc_clockevent
18: 140949401 1430637760 GIC-0 29 Edge twd
19: 0 0 GIC-0 37 Level arm-pmu
20: 0 0 GIC-0 38 Level arm-pmu
21: 43 0 GIC-0 39 Level f8007100.adc
23: 7 0 GIC-0 57 Level cdns-i2c
25: 0 0 GIC-0 35 Level f800c000.ocmc
26: 332 0 GIC-0 59 Level xuartps
27: 14833917 0 GIC-0 58 Level e0006000.spi
28: 2 0 GIC-0 81 Level e0007000.spi
29: 0 0 GIC-0 51 Level e000d000.spi
30: 3654689 0 GIC-0 54 Level eth0
31: 637 0 GIC-0 56 Level mmc0
32: 0 0 GIC-0 45 Level f8003000.dmac
33: 0 0 GIC-0 46 Level f8003000.dmac
34: 0 0 GIC-0 47 Level f8003000.dmac
35: 0 0 GIC-0 48 Level f8003000.dmac
36: 0 0 GIC-0 49 Level f8003000.dmac
37: 0 0 GIC-0 72 Level f8003000.dmac
38: 0 0 GIC-0 73 Level f8003000.dmac
39: 0 0 GIC-0 74 Level f8003000.dmac
40: 0 0 GIC-0 75 Level f8003000.dmac
41: 0 0 GIC-0 40 Level f8007000.devcfg
48: 0 0 GIC-0 41 Edge f8005000.watchdog
IPI1: 0 0 Timer broadcast interrupts
IPI2: 371883 12507844 Rescheduling interrupts
IPI3: 4 1 Function call interrupts
IPI4: 0 0 CPU stop interrupts
IPI5: 2632663 10068764 IRQ work interrupts
IPI6: 0 0 completion interrupts
I tried changing flags to 0 and IRQF_SHARED
, but got the same error!
A return value of -16
means error 16, which is EBUSY
a.k.a. "device or resource busy". You are trying to request IRQ 29, and you can clearly see that IRQ 29 is already registered by e000d000.spi
. This means that whoever wrote the code for that driver decided not to use IRQF_SHARED
, and therefore you cannot request it, even if you specify that flag. Use another number to request a different interrupt line, or avoid loading the driver that takes exclusive control of that line.
Also, I'm not sure why you are also printing the two values of EIO
and EINVAL
, but those are just error numbers without any context, not something that is being returned by the function.