Take the 2-minute tour ×

I am writing a kernel v4l2 driver for an ov7670 CMOS element attached to GPIO pins on a Raspberry Pi. I set up three IRQ lines (Pixel, Href, and Vsync)

Here is how I am requesting them:

ret = request_irq(  PX_IRQ, 

ret = request_irq(  HREF_IRQ, 

ret = request_irq(  VSYNC_IRQ,

Now that goes fine:

#cat /proc/interrupts
3:       4168   ARMCTRL  BCM2708 Timer Tick
9:          0   ARMCTRL  ov7670rpipx
10:          0   ARMCTRL  ov7670rpihref
11:          0   ARMCTRL  ov7670rpivsync
32:      68523   ARMCTRL  dwc_otg, dwc_otg_pcd, dwc_otg_hcd:usb1
52:          0   ARMCTRL  BCM2708 GPIO catchall handler
65:        543   ARMCTRL  ARM Mailbox IRQ
66:          2   ARMCTRL  VCHIQ doorbell
75:          1   ARMCTRL
77:       3439   ARMCTRL  bcm2708_sdhci (dma)
79:          0   ARMCTRL  bcm2708_i2c.0, bcm2708_i2c.1
80:          0   ARMCTRL  bcm2708_spi.0
83:         21   ARMCTRL  uart-pl011
84:       7436   ARMCTRL  mmc0
FIQ:              usb_fiq
Err:          0

Looks good.

This is how I disable the IRQs:

/* Disable Interrupts */
free_irq(PX_IRQ, ov7670rpi_pixel_interrupt);
free_irq(HREF_IRQ, ov7670rpi_href_interrupt);
free_irq(VSYNC_IRQ, ov7670rpi_vsync_interrupt);

I have also tried:

/* Disable Interrupts */
free_irq(PX_IRQ, NULL);
free_irq(HREF_IRQ, NULL);
free_irq(VSYNC_IRQ, NULL);

Both ways make it so that once the module is unloaded, I can not access /proc/interrupts. When I try to cat /proc/interrupts, they system locks.

share|improve this question
See free_irq doc. Have you made sure the irq is disabled before free_irq? The NULL will not work. You need the same dev_id parameter as request_irq. Also, the kernel version may help people answer. Knowing about how GPIOs and interrupts work, I think you have the wrong numbers. Did you define PX_IRQ, etc? –  artless noise Apr 21 '13 at 0:14
Ah the numbers could be the issue then. To be honest, I was using those as placeholder numbers until I figured out the proper ones. I suppose that could easily wreak havoc on the system if I just choose arbitrary ones? Yes, I defined PX_IRQ, etc... Where does one usually find the proper available lines for GPIO? In this case, BCM2708 Thanks –  push.pop Apr 21 '13 at 0:19
Ah, it looks like bcm2708_gpio.c Provides a helper function to do just that. actually, maybe not. I think that just initializes the catchall... –  push.pop Apr 21 '13 at 0:36

1 Answer 1

up vote 1 down vote accepted

The correct way to do this is to use gpio_request() with your GPIO numbers.

 #define PX_GPIO 9
 #define HREF_GPIO 10
 #define VSYNC_GPIO 11

 gpio_request(PX_GPIO, "v4l_rpi_px");
 gpio_request(HREF_GPIO, "v4l_rpi_href");
 gpio_request(VSYNC_GPIO, "v4l_rpi_vsync");

 /* Now, gpio_to_irq() can be used. */
 ret = request_irq(gpio_to_irq(PX_GPIO), 
 /* etc. */

bcm2708_gpio.c provides a GPIO interrupt controller as detailed in this question. See also the GPIO documentation.

Your primary interrupt controller ARMCTRL has interrupt 52 as BCM2708 GPIO catchall handler. This IRQ is chained and supports IRQ on each gpio line. The controller for the GPIO's will be listed differently in /proc/interrupts as GPIO.

share|improve this answer
Awesome, thank you! I just found some fragments with this info, and I am working on getting it written. Do you know if I need to call gpio_request(...) before free_irq(gpio_to_irq(...))? –  push.pop Apr 21 '13 at 1:22
gpio_request() is to get the gpio resource. It is possible that multiple drivers may wish to use this pin. This should always come first. It is somewhat unrelated to the irqs. Read the GPIO documentation for more info. –  artless noise Apr 21 '13 at 15:53

Your Answer


