I am implementing an interrupt handling module using thread irq. I am facing this error:
1983.150961] Shut down eMMC app module init.
[ 1983.151115] genirq: Flags mismatch irq 49. 00000004 (eMMC_power_shutdown_irq_
handler) vs. 00000004 (xuartps)
fio@uz3cg-dgw:~$ (edited)
I am choosing a Flag is #define IRQF_TRIGGER_HIGH 0x00000004 and assign to IRQ number 49 in this case.
Here is my code:
static int __init shutdownemmc_module_init(void)
{
printk("Shut down eMMC app module init. ");
if (request_threaded_irq( IRQ_NO, //IRQ number
(void *) emmc_irq_handler, //IRQ handler (Top half)
emmc_interrupt_thread_fn, //IRQ Thread handler (Bottom half).When the handler function returns IRQ_WAKE_THREAD
IRQF_TRIGGER_HIGH, //Handler will be called in raising edge
"eMMC_power_shutdown_irq_handler", //used to identify the device name using this IRQ
(void *)(emmc_irq_handler))) //device id for shared IRQ
{
pr_err("Cannot register IRQ ");
pr_err(" EIO %d , EINVAL %d\n", EIO, EINVAL);
return 0;
}
pr_info("Interrupt handler...Done!!!\n");
return 0;
}
Could somebody explain what is Flags mismatch irq issue and how I can fix this problem? Thank you, Anh
It is because "xuartps" has already requested the IRQ number and did not request it to be shared.
Extracts from __setup_irq()
in "kernel/irq/manage.c":
/*
* If nobody did set the configuration before, inherit
* the one provided by the requester.
*/
if (irqd_trigger_type_was_set(&desc->irq_data)) {
oldtype = irqd_get_trigger_type(&desc->irq_data);
} else {
oldtype = new->flags & IRQF_TRIGGER_MASK;
irqd_set_trigger_type(&desc->irq_data, oldtype);
}
if (!((old->flags & new->flags) & IRQF_SHARED) ||
(oldtype != (new->flags & IRQF_TRIGGER_MASK)) ||
((old->flags ^ new->flags) & IRQF_ONESHOT))
goto mismatch;
In the above, old
is the existing handler set up by "xuartps". new
is the new handler being set up by your code. In order for the IRQ to be shared, one of the conditions above is that both the old and the new handlers need to request the IRQ with the IRQF_SHARED
flag. However, drivers should only set IRQF_SHARED
if the underlying interrupt is supposed to be shareable; for example: all PCI interrupts are shareable and drivers for PCI devices should request interrupts with IRQF_SHARED
set.
mismatch:
if (!(new->flags & IRQF_PROBE_SHARED)) {
pr_err("Flags mismatch irq %d. %08x (%s) vs. %08x (%s)\n",
irq, new->flags, new->name, old->flags, old->name);
#ifdef CONFIG_DEBUG_SHIRQ
dump_stack();
#endif
}
ret = -EBUSY;
The above is where the "Flags mismatch" message is printed to the kernel log.
If you were not expecting the IRQ to be already requested, check that you are requesting the correct IRQ.
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