Using interrupts in a linux device driver

Hello!
I am developing a GPT linux device driver for a specific project we have. I have a working driver that can configure, start and stop the timer, and various other things. The next thing I need is to trigger an interrupt on an input capture event. The input capture works and I have enabled the IC1IE flag in the GPT.

The linux-device-driver registers the irq routine using the following snippet:

uint8_t minor_num = 1;
uint8_t* minor_num_p = &minor_num;
if (request_irq(IRQ_NUMBER, irq_handler, IRQF_SHARED, "gpt_device", (void *)(minor_num_p))) {
        printk(KERN_ALERT "FAILED TO SETUP IRQ ");
        goto fail;
}

The irq_handler function is a simple printk statement for now.

In /proc/interrupts the handler seems to have been registered as there is a new entry:

 IRQ_NUMBER:          0          0          0          0          0          0     GICv3 442 Level     gpt_device

The device-tree entry for the gpt has an interrupts parameters:

    lsio_gpt1: gpt@5d150000 {
        interrupts = <GIC_SPI 18 IRQ_TYPE_LEVEL_HIGH>;    
       ....
    };

I believe this one should be 18 since the apalis iMX8 datasheet says that the ALT3 function is _IO18.

I am very unsure of the IRQ_NUMBER for the linux-device-driver (a bit for the device-tree as well). According to the i.MX8QM reference manual, GPT1_INT is 113, but I have not gotten the interrupt to work yet. Is there another value I should use? Or are there any other settings that I need to set in hardware? I tried to look into the GIC and IRQ_STEER as those where the ones that seemed to control the interrupts, but they seem to be more for the m4 cores. I am used to having to modify an NVIC when working on interrupts, but have not found anything like that for the iMX8QM

Hardware details:
Apalis IMX8QM using the ixoraV1.2 board

Best regards,

Hi @aleksw

I guess you want to get the interrupt for GPT1 if I understand you correctly not for a GPIO, right?

According to the reference manual that would be GIC_SPI 113 as you write. However, you have to subtract 32 to map with the NXP Linux numbering. So it would be:

    lsio_gpt1: gpt@5d150000 {
        interrupts = <GIC_SPI 81 IRQ_TYPE_LEVEL_HIGH>;    
       ....
    };

Regards,
Stefan

Thanks for your response @stefan_e.tx!

Alrighty, I didnt know about the subtraction of 32. Then the values of the device-tree actually makes a lot more sense.
But what number should I use for ny linux driver then? I tried to use 81 as the IRQ_NUMBER in the request_irq(), but then I get this error:

[    5.484001] genirq: Flags mismatch irq 81. 00000084 (gpt_device) vs. 00000004  (5b040000.ethernet)

Hi @aleksw

You shouldn’t just put a number in there. The device has several interrupt controllers that’s why you have to use the device tree to get to the right number. Use e.g. platform_get_irq_byname to get the correct interrupt:

I would recommend you to get familiar with device trees, else it will be hard to succeed with the driver. I can recommend you Bootlin as a training partner for these topics:

Regards,
Stefan

Hello @aleksw,

I hope you are doing well. May I know if you were able to make any progress on this topic?