Issues with request_irq on 4.9.30-bone4 kernel on Beaglebone Green

19 views
Skip to first unread message

mike...@gmail.com

unread,
Jul 2, 2017, 5:09:53 PM7/2/17
to BeagleBoard
     I have an issue installing an interrupt handler in a hardware driver, in this specific case for the am3358 e-capture unit eCAP0 on a Beaglebone Green.

I am running a build per https://eewiki.net/display/linuxonarm/BeagleBone+Black, built with a Mainline 4.9.30-bone4 (non real time) kernel and the debian-8.7-minimal-armhf-2017-01-14 file system.

The driver was developed and worked on an earlier 3.8 kernel, but now fails to receive any interrupts under the 4.9 kernel.

The interrupt is registered with a call to:

status = request_irq(31, ecap_interrupt, 0, ECAP_NAME, &ecap_data.devid);

31 is the interrupt number for eCAP0INT per table 6.3 in the am335x-techref.

The call succeeds with a zero status, but the interrupt routine is never called even though events are detected by the eCAP unit.
Furthermore, looking at the /proc/interrupts I see:

 22:        103      INTC  14 Level     49000000.edma_ccerrint
 26:          0      INTC  96 Level     44e07000.gpio
 31:          0  44e07000.gpio   4 Edge      ecap
 33:          0  44e07000.gpio   6 Edge      48060000.mmc cd
 59:          0      INTC  98 Level     4804c000.gpio
 92:          0      INTC  32 Level     481ac000.gpio

Which shows that (1) no interrupts have been detected on IRQ 31, and (2) the third column lists a suspicious "44e07000.gpio" instead of INTC as most other interrupt lines do. The latter leads me to believe that the interrupt is not mapped appropriately from the capture unit, but rather to some sort of gpio mapping, although I do not know what the third and the fourth column in /proc/interrupts show.

An attempt to probe for the interrupt using this code also fails with no detected interrupts:

    do {
        iowrite16(0x0000, &ecap_data.pecap[ECAP_ECEINT]);   // Disable all interrupts
        iowrite16(0x00ff, &ecap_data.pecap[ECAP_ECCLR]);    // And clear status
        mask = probe_irq_on();
        iowrite16(0x0010, &ecap_data.pecap[ECAP_ECEINT]);   // Re-enable CEVT4 interrupt
        iowrite16(0x0010, &ecap_data.pecap[ECAP_ECFRC]);    // And force-trigger it
        udelay(5);
        istatus = probe_irq_off(mask);
        if (istatus == 0) {
            printk(KERN_INFO "No interrupt reported\n");
        }
    } while (istatus <= 0 && count++ < 5);

It sure looks to me that there is some sort of interrupt mapping/enabling that is new with the 4.x kernels which I am missing.

Any help and explanation would be greatly appreciated!
Reply all
Reply to author
Forward
0 new messages