4
votes

I have a GPIO peripheral, defined in Device Tree as that:

gpio0: gpio@2300000 
{
    compatible = "fsl,qoriq-gpio";
    reg = <0x0 0x2300000 0x0 0x10000>;
    interrupts = <GIC_SPI 66 IRQ_TYPE_LEVEL_HIGH>;
    gpio-controller;
    #gpio-cells = <2>;
    interrupt-controller;
    #interrupt-cells = <2>;
};

I want to write an interrupt handler for this (as a kernel module). But this IRQ number (66) is a hardware one and I need a virtual, Linux IRQ number to pass it to request_irq.

How can I get this number? There is only one interrupt controller (GIC).

Is there a way to do this without writing a platform device driver (as there is probably already one working in the system and I think I cannot register another one).

1
What end are you trying to achieve here ? Are you trying to convert a GPIO into interrupt or what ?yashC
The author is asking how to get linux virtual irq from hw irqAlex Hoppus
Yes, I am basically trying to register (request) an Interrupt handler when GPIO pins chang state.zupazt3

1 Answers

1
votes

As per you comment you want to register a GPIO as an interrupt. The node of device tree that you have posted is the interrupt controller node, which wont concern us for the task we have at hand.

To register a gpio as an interrupt, you first need to find a GPIO which can be configured as an interrupt (in most modern processors all GPIOs support it) and then you have to make sure it is not used by some other device by multiplexing it (if it is used by some one like SPI or UART etc , you can disable them from device tree if you are not using that entity).

now that you have a GPIO pin that you can use. Find the GPIO number on kernel that pin corresponds to (it depends on the architecture of your processor and its carrier board).

When you have that you can just write a simple module that will export your GPIO and use it as interrupt.

Below is a snippet from http://derekmolloy.ie

gpio_request(gpioButton, "sysfs");       // Set up the gpioButton
gpio_direction_input(gpioButton);        // Set the button GPIO to be an input
gpio_set_debounce(gpioButton, 200);      // Debounce the button with a delay of 200ms
gpio_export(gpioButton, false);          // Causes gpio115 to appear in /sys/class/gpio
                  // the bool argument prevents the direction from being changed
// Perform a quick test to see that the button is working as expected on LKM load
printk(KERN_INFO "GPIO_TEST: The button state is currently: %d\n", gpio_get_value(gpioButton));

// GPIO numbers and IRQ numbers are not the same! This function performs the mapping for us
irqNumber = gpio_to_irq(gpioButton);
printk(KERN_INFO "GPIO_TEST: The button is mapped to IRQ: %d\n", irqNumber);

// This next call requests an interrupt line
result = request_irq(irqNumber,             // The interrupt number requested
                    (irq_handler_t) ebbgpio_irq_handler, // The pointer to the handler function below
                    IRQF_TRIGGER_RISING,   // Interrupt on rising edge (button press, not release)
                    "ebb_gpio_handler",    // Used in /proc/interrupts to identify the owner
                    NULL);                 // The *dev_id for shared interrupt lines, NULL is okay

Link to the complete code.