3.4. Interrupt Handling

Our example handler is for an ISA bus device. If it was PCI you would be able to share the interrupt and would have set SA_SHIRQ to indicate a shared IRQ. We pass the device pointer as the interrupt routine argument. We don't need to since we only support one card but doing this will make it easier to upgrade the driver for multiple devices in the future.

Our interrupt routine needs to do little if we assume the card can simply queue one frame to be read after it captures it.


static struct wait_queue *capture_wait;
static int capture_ready = 0;

static void camera_irq(int irq, void *dev_id, 
                          struct pt_regs *regs)
{
        capture_ready=1;
        wake_up_interruptible(&capture_wait);
}
  

The interrupt handler is nice and simple for this card as we are assuming the card is buffering the frame for us. This means we have little to do but wake up anybody interested. We also set a capture_ready flag, as we may capture a frame before an application needs it. In this case we need to know that a frame is ready. If we had to collect the frame on the interrupt life would be more complex.

The two new routines we need to supply are camera_read which returns a frame, and camera_poll which waits for a frame to become ready.


static int camera_poll(struct video_device *dev, 
	struct file *file, struct poll_table *wait)
{
        poll_wait(file, &capture_wait, wait);
        if(capture_read)
                return POLLIN|POLLRDNORM;
        return 0;
}

  

Our wait queue for polling is the capture_wait queue. This will cause the task to be woken up by our camera_irq routine. We check capture_read to see if there is an image present and if so report that it is readable.