I'm trying to set up an interrupt-handler within a kernel-module that gets triggered by a gpio-interrupt, but it seems that I don't use the request_irq()
-function right...
I'm getting my irq-number via gpio_to_irq()
and this seems to work.
Then I'm calling
request_irq(irqNumber, handler, 0, "GPIO_Test", NULL);
but It returns -22, Invalid parameters.
I think it might be the handler-function because I'm not sure about it's signature - Sometimes it's defined as void handler (int irq, void *dev_id, struct pt_regs *regs)
, sometimes as static irqreturn_t handler(int irq, void *data)
- Which one is the correct one to use in this case and why are there these two totally different variations?
I tried both, but always got the same Invalid-parameters-error.
The compiler gives me a warning about the return-type of my handler-function: when using:
static irqreturn_t handler(int irq, void *data)
{
/*interrupt-handling*/
return IRQ_HANDLED;
}
»irq_handler_t« expected, but argument has type »enum irqreturn_t (* (*)(int, void *))(int, void *)«
...and when using:
void handler (int irq, void *dev_id, struct pt_regs *regs){/*interrupt-handling*/}
»irq_handler_t« expected, but argument has type »void (*)(int, void *, struct pt_regs *)«
Thank you for your support ;)
The issue (-EINVAL
) isn't being caused by the handler
, as there's no way for the kernel to determine its signature at runtime.
Also, handler
is never called while requesting an IRQ via request_irq()
(unless CONFIG_DEBUG_SHIRQ_FIXME
is defined, and [with the wrong signature] that would only lead to undefined behaviour AFTER parameter validation, not before, so it would be very unlikely to return an -EINVAL
at this point).
There are 4 key points that are validated before an IRQ is properly setup:
irqflags
- You've none set, that passes the check.irq_to_desc()
- Will perform a lookup over irq_desc_tree
for irq
. Will return -EINVAL
if not found. Otherwise, returns a pointer to an irq descriptor structure (struct irq_desc *
)irq_settings_can_request()
- Check if the IRQ can be requested. You can easily rule out this by calling int can_request_irq(unsigned int irq, unsigned long irqflags)
before request_irq()
.handler
- Will check if handler
is NULL
. In your case, it is not.So basically you've only two possible checks that may be causing the issue, and one of them you can rule out using can_request_irq()
before calling request_irq()
, but, unfortunately, this won't be possible to do under a module, because can_request_irq
symbol isn't exported.
But if you've the patience and the time, you can build a new image with that code built-in, just see if can_request_irq()
check passes. If it does, the only check that is causing the issue is irq_to_desc()
, meaning that irq
is invalid.
Can't extend this answer much more, as there's no more information I can work with from your question, but I hope it helps you to get in the right track.
By the way, just to point out the typedef
of irq_handler_t
in the case it may be useful:
include/linux/interrupt.h:92
(on 4.5 tree):
typedef irqreturn_t (*irq_handler_t)(int, void *);
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With