linuxkerneldriverirq

request_irq returns -16 (-EBUSY)


Here is my problem. I'm currently updating the kernel of an arm embedded Linux machine, going from 4.1 to 4.14.73.

I'm facing a problem with a driver. With kernel 4.1, right before registering the irq with request_irq, the flag IRQF_VALID would be set for the driver by set_irq_flags.

As documented here,

set_irq_flags is ARM specific with custom flags which have genirq equivalents. Convert drivers to use the genirq interfaces directly, so we can kill off set_irq_flags. The translation of flags is as follows:

IRQF_VALID -> !IRQ_NOREQUEST

IRQF_PROBE -> !IRQ_NOPROBE

IRQF_NOAUTOEN -> IRQ_NOAUTOEN

Consequently, I replaced set_irq_flags with an irq_clear_status_flags(irq, IRQ_NOREQUEST).

Thing is, now the request_irq call returns -16 (-EBUSY), and I have no idea why. I checked every single irq being requested (at runtime), and they are all different from the one requested by this driver.

I also noticed this line on the log:

genirq: Flags mismatch irq 40. 00000004 (digitalGPIO) vs. 00000000 ((null))

I'm very puzzled from the (null) device name.

What am I doing wrong?

I hope I included enough context informations.


Solution

  • In the end, as obvious, the IRQ was indeed already registered as not shared way before my module was being loaded.

    This was due to a change in the kernel I'm using, which is an Altera revision based on the linux kernel. They changed the behaviour of the driver associated to this IRQ in a previous kernel update.

    What I can't understand is why the previous request was being logged as (null) instead of the correct name. The only way to show the correct informations about who previously requested the IRQ would be to set it as shared directly in the Altera kernel.