LinuxQuestions.org

LinuxQuestions.org (/questions/)
-   Linux - Embedded & Single-board computer (https://www.linuxquestions.org/questions/linux-embedded-and-single-board-computer-78/)
-   -   What's wrong with the interrupt? (https://www.linuxquestions.org/questions/linux-embedded-and-single-board-computer-78/whats-wrong-with-the-interrupt-814176/)

ligang 06-14-2010 11:41 PM

What's wrong with the interrupt?
 
I am debugging an Linux device driver which contains an external interrupt. The driver can receive this interrupt but shows a strange response.

CPU is S3C2410 (ARM9).

1.Add driver module to kernal:
Code:

insmod cc2420_driver.ko
2.Interrupt response:
Code:

scl_CC2420 interrupt, at pin 67
irq event 67: bogus return value 17
[<c0027dfc>] (dump_stack+0x0/0x14) from [<c00614ac>] (__report_bad_irq+0x38/0x9)[<c0061474>] (__report_bad_irq+0x0/0x94) from [<c0061580>] (note_interrupt+0x78) r4:c02efb94
[<c0061508>] (note_interrupt+0x0/0x26c) from [<c00622b4>] (handle_edge_irq+0x12)[<c0062194>] (handle_edge_irq+0x0/0x144) from [<c0038ab0>] (s3c_irq_demux_extin) r6:c0315a98 r5:00000015 r4:00000000
[<c0038a20>] (s3c_irq_demux_extint8+0x0/0xa4) from [<c0023044>] (asm_do_IRQ+0x4) r4:c02ef184
[<c0023000>] (asm_do_IRQ+0x0/0x5c) from [<c0023a44>] (__irq_svc+0x24/0xa0)
Exception stack(0xc02e5f54 to 0xc02e5f9c)
5f40:                                              c306ee20 ffffffff f410000c
5f60: 80000013 c00249cc c02e4000 c001ff28 c02e7c78 3001e64c 41129200 3001e618
5f80: c02e5fa8 c02e5f9c c02e5f9c c0024a2c c0024a38 80000013 ffffffff
 r7:c02e7c78 r6:00000020 r5:f4000000 r4:ffffffff
[<c00249cc>] (default_idle+0x0/0x78) from [<c0024a8c>] (cpu_idle+0x48/0x64)
[<c0024a44>] (cpu_idle+0x0/0x64) from [<c023501c>] (rest_init+0x50/0x60)
 r5:c02ffda8 r4:c0313fdc
[<c0234fcc>] (rest_init+0x0/0x60) from [<c0008930>] (start_kernel+0x27c/0x2e4)
[<c00086b4>] (start_kernel+0x0/0x2e4) from [<30008034>] (0x30008034)
handlers:
[<bf00822c>] (basicRfRecvPacket+0x0/0x840 [cc2420_send])

3.Relatd source code:
3.1 extern interrupt initialization
Code:

gpiovalue = (~(EINT8_23)) & ioread32(S3C2410_INTMOD);^M
        iowrite32(gpiovalue, S3C2410_INTMOD);  // IRQ^M
        ^M
        // Enable EINT8_23 interrupt^M
        gpiovalue = ioread32(S3C2410_INTMSK);^M
#ifdef _DEBUG^M
        printk("S3C2410_INTMSK(before) = %X\n", gpiovalue);^M
#endif^M
        gpiovalue &= (~(EINT8_23));            ^M
        iowrite32(gpiovalue, S3C2410_INTMSK);  ^M
#ifdef _DEBUG^M
        printk("S3C2410_INTMSK(after) = %X\n",ioread32(S3C2410_INTMSK));^M
#endif^M
^M
        // enable FIFOP interrupt^M
        gpiovalue = ioread32(S3C2410_EINTMASK);^M
        gpiovalue &= (~(1<<23));^M
        iowrite32(gpiovalue, S3C2410_EINTMASK);          ^M
#ifdef _DEBUG^M
        printk("S3C2410_EINTMASK = %X\n",ioread32(S3C2410_EINTMASK));^M
#endif^M
^M
        // setting the external interrupt triggered format^M
        //gpiovalue = ioread32(rEXINT2)&(~(0xFF00F000));^M
#ifdef _DEBUG^M
        printk("rEXINT2(before) = 0X%X\n",gpiovalue);^M
#endif^M
        //gpiovalue |= INTTRI_FIFOP; // | INTTRI_FIFO | INTTRI_EINT11;^M
        gpiovalue=0x40000000;^M
        iowrite32(gpiovalue,rEXINT2);^M
#ifdef _DEBUG^M
        printk("rEXINT2 = 0X%X\n",ioread32(rEXINT2));^M
#endif
        DISABLE_FIFOP_INT();

3.2 register the interrupt
Code:

reval = request_irq(IRQ_EINT23, basicRfRecvPacket, SA_INTERRUPT, SPI_NAME, NULL);^M
        if (reval)^M
        {^M
#ifdef  _DEBUG ^M
        printk(KERN_ALERT "request_irq IRQ_EINT23 failed\n");^M
#endif          ^M
          }

3.3 interrupt service handler
Code:

static irqreturn_t basicRfRecvPacket(int irq, void * dev_id)^M
{^M
        u8 length;^M
        u16 fcf, sequence, PanId, destAddr, srcAddr, rssi;^M
//#ifdef  _DEBUG ^M
    printk(KERN_ALERT "\nmscl_CC2420 interrupt, at pin %d\n", irq);^M
//#endif    ^M
        DISABLE_FIFOP_INT();^M
^M
        // check if RXFIFO is overflow^M
        if (FIFOP_IS_1 && FIFO_IS_1)^M
        {^M
                FASTSPI_STROBE(CC2420_SFLUSHRX);^M
                DELAY(100);^M
                FASTSPI_STROBE(CC2420_SFLUSHRX);^M
                DELAY(100);^M
                ENABLE_FIFOP_INT();^M
                return;^M
        }^M
        FASTSPI_READ_FIFO_BYTE(length); ^M
        FASTSPI_READ_FIFO_NO_WAIT(&fcf, 2);^M
        FASTSPI_READ_FIFO_NO_WAIT(&sequence, 2);^M
        FASTSPI_READ_FIFO_NO_WAIT(&PanId, 2);^M
        FASTSPI_READ_FIFO_NO_WAIT(&destAddr, 2);^M
        FASTSPI_READ_FIFO_NO_WAIT(&srcAddr, 2);^M
        FASTSPI_READ_FIFO_NO_WAIT(pRxBuffer, 4);^M
        FASTSPI_READ_FIFO_NO_WAIT(&rssi, 2);^M
        //#ifdef _DEBUG^M
        printk("-- Length = 0x%X\n", length);^M
        printk("-- fcf = 0x%X\n", fcf);^M
        printk("-- sequence = 0x%X\n", sequence);^M
        printk("-- PanId = 0x%X\n", PanId);^M
        printk("-- destAddr = 0x%X\n", destAddr);^M
        printk("-- srcAddr = 0x%X\n", srcAddr);^M
        printk("-- pRxBuffer = %s\n", pRxBuffer);^M
        printk("-- rssi = %d\n", rssi);^M
//#endif^M
        // for test, these two pins will immediately go low when all datas have been received ^M
        while (FIFO_IS_1||SFD_IS_1) ;^M
        if (FIFOP_IS_1 && FIFO_IS_1)^M
        {^M
                FASTSPI_STROBE(CC2420_SFLUSHRX);^M
                DELAY(1);^M
                FASTSPI_STROBE(CC2420_SFLUSHRX);^M
                DELAY(1);^M
                ENABLE_FIFOP_INT();^M
                return;        ^M
        }^M
        ENABLE_FIFOP_INT();^M
}^M


ligang 06-18-2010 08:09 AM

For 2.6 kernel, all the interrupt service handler needs return value. Thus in basicRfRecvPacket() I should change all the "return" to "return IRQ_HANDLED" which is defined as 1 in ./include/linux/irqreturn.h


All times are GMT -5. The time now is 04:38 AM.