All,

I am having some troubles getting interrupts to fire from my kernel module.  I 
have connected the ISR with a call to request_irq() and have configured my 
device to generate interrupts.   However, my ISR is called once when I connect 
the interrupt for the first time.  After that it never is called again.  It 
seems like that interrupt is getting stuck disabled, but that does not make 
sense as to why.

The device is on the PCIE0 bus and works just fine in another OS (namely 
Vxworks - that is the driver I am working on porting to Linux).

Here is how I am connecting the ISR and the ISR itself.  Am I doing something 
stupid?

Thanks for the help!

Jonathan

PS - Our hardware is a custom spun PPC405EX board based on the AMCC Kilauea 
board and uses the kilauea.dts with no modifications.

A quick note - I realize that I am not checking if I was the one to interrupt 
the CPU.  I am not worried about that right now - especially since I know there 
is nothing else that will interrupt the CPU on this IRQ right now anyway - it 
never fires.


int fpga_open(struct inode *inode, struct file *filp)
{
        int err = 0;

        /* Make sure we have successfully probed the device */
        if (NULL == fpga_drv.pcidev)
        {
                return -ENODEV;
        }

        /* Only one process at a time can have access to the FPGA */
        if (0 != atomic_read(&fpga_drv.openCount))
        {
                atomic_inc(&fpga_drv.openCount);
                printk(KERN_WARNING "FPGA: Could not open device: already open. 
\n");
                return -EBUSY;
        }

        /* If not already in use, state that we are */
        atomic_inc(&fpga_drv.openCount);

        /* Store a pointer to the PCI device structure */
        filp->private_data = fpga_drv.pcidev;

        /* Attach ISR to IRQ */
        if (request_irq(fpga_drv.pcidev->irq, &fpga_isr, IRQF_SHARED,
                        FPGA_MODULE_NAME, fpga_drv.pcidev))
        {
                printk( KERN_ERR "FPGA: Unable to connect FPGA ISR (%d)!\n",
                                fpga_drv.pcidev->irq);
                return -EPERM;
        }

        return 0;
}

/* Interrupt Service Routine */
irqreturn_t fpga_isr(int irq, void *dev_id)
{
        uint32_t status = 0;

        status = fpga_drv.cfg_ptr[FPGA_INTER_STATUS];
        printk(KERN_NOTICE "FPGA: Interrupt fired! (%#08x)\n", status);
        if (status & FPGA_INTERRUPT_SPI)
        {
                rt_sem_v(&fpga_drv.sarSem);
        }

        /* Return HANDLED */
        return (IRQ_HANDLED);}
_______________________________________________
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev

Reply via email to