I am trying to correctly register interrupt in kernel for user interface.
Surprisingly, I did not find many examples in kernel for that.
irq handler
static irqreturn_t irq_handler(int irq, void *dev_id)
{
struct el_irq_dev *el_irq = &el_irq_devices[0];
printk("irq in\n");
spin_lock(&el->my_lock,flags);
clear_interrupt()
some_buffer[buf_wr] = ch;
el_irq->buf_wr++;
if (el_irqbuf_wr >= 16)
el_irqbuf_wr = 0;
spin_unlock(&el->my_lock,flags);
wake_up_interruptible(&el->pollw);
return IRQ_HANDLED;
}
ioctl for waiting on interrupts
static long el_device_ioctl( struct file *filp,
unsigned int ioctl_num,
unsigned long ioctl_param)
{
struct el_irq_dev *el_irq = &el_irq_devices[0];
switch (ioctl_num) {
case IOCTL_WAIT_IRQ: <<<---- using ioctl (no poll) to wait on interrupt
wait_event_interruptible(el_irq->pollw, &el_irq->buf_wr != &el_irq->buf_rd) ;
spin_lock(&el_irq->my_lock);
if (el_irq->buf_wr != &el_irq->buf_rd)
{
my_value=some_buffer[el_irq->buf_rd];
el_irq->buf_rd++;
if (el_irq->buf_rd >= 16)
el_irq->buf_rd = 0;
}
spin_unlock(&el_irq->my_lock);
copy_to_user(ioctl_param,&my_value,sizeof(my_value));
default:
break;
}
return 0;
}
My question is:
- Should we put the clear of interrupts (clear_interrupt() ) in fpga in the interrupt before or after the wake_up ? Can we event put the clearing interrupt in the userspace handler (IOCTL_WAIT_IRQ) instead of clearing the interrupt in the interrupt handler ?
- As you can see in the code, I am using cyclic buffer in order to handle cases where the userspace handler is missing interrupts. Is that really required or can we assume that there are no misses ? In other words, Is it reasnoble to assume that there should never be missed interrupts ? so that the ioctl call should never see more than 1 waiting interrupt ? If yes - maybe I don't need buffer mechanism between the interrupt handler and the ioctl handler.
Thank you, Ran