Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Linux Device Tree Help (GPIO controller/interrupts)

I've been learning about linux device trees and we've been trying to start porting some of our older code to use them. I'm having a little bit of trouble with the gpio controller node:

gpio1: gpio-controller@c00 {
    #gpio-cells = <2>;
    compatible = "cavium,octeon-3860-gpio";
    reg = <0xc00 0x100>;
    gpio-controller;
    /* Interrupts are specified by two parts:
     * 1) GPIO pin number (0..15)
     * 2) Triggering (1 - edge rising
     *                2 - edge falling
     *                4 - level active high
     *                8 - level active low)
     */
    interrupt-controller;
    interrupt-cells = <2>;
    interrupts = <0 24>, <1 25>, <2 26>, <3 27>;

};

I'm trying to map certain IRQs to GPIO pins, however, it looks like its only ever mapping the first one <0 24> IRQ 24 to gpio pin 0. I looked at the source code and it doesnt seem like it will ever interate of 'interrupts', though the device tree bindings text file seems to hint that it will (devicetree/bindings/gpio/cavium-octeon-gpio.txt). Does anyone know how i can map a handful of interupts to different gpio pins?

like image 505
nigp4w rudy Avatar asked May 06 '14 12:05

nigp4w rudy


People also ask

What are GPIO interrupts?

GPIO interrupt handling is inherently a two-stage process. The interrupt from the general-purpose I/O (GPIO) controller, which causes the GPIO framework extension (GpioClx) interrupt service routine (ISR) to run, is called the primary interrupt.

What is interrupt parent?

The interrupt-parent property is a property of a device node containing a phandle to the interrupt controller to which it is attached. Nodes without an interrupt-parent property can inherit the property from their parent node.


2 Answers

gpio handling is still not 100% the same between platforms, so I'll give you the gist of it, and you may need to adapt to your platform (find a dts that uses the same or similar SoC). My platform is Freescale imx.6 Here this is the gist of it:

First: Leave gpio1 node alone. (It is probably set up correctly in the dtsi you got from your upstream vendor)

Second: If you want .e.g. gpio 1 15 to be an interrupt, active high in the device node you want to consume the gpio interrupt, add

interrupt-parent = <&gpio1>;
interrupts = <15 IRQ_TYPE_LEVEL_HIGH>;

for example: from arch/arm/boot/dts/imx6qdl-gw52xx.dtsi

touchscreen: egalax_ts@04 {
        compatible = "eeti,egalax_ts";
        reg = <0x04>;
        interrupt-parent = <&gpio7>;
        interrupts = <12 2>;
        wakeup-gpios = <&gpio7 12 GPIO_ACTIVE_LOW>;
};
like image 119
Joshua Clayton Avatar answered Nov 20 '22 09:11

Joshua Clayton


I'm not familiar with your machine, but if you look here:

https://elinux.org/Device_Tree_Usage#How_Interrupts_Work

you will see that the interrupt specifiers are for the interrupt controller of the node in which they are defined (i.e. parent interrupt controller), and not for the node itself.

Since you aren't even showing where and if you actually enable the interrupt (pin, trigger), I assume you did not know this.

So what does the interrupt controller node of gpio1 look like?

Does it really expect to receive multiple interrupts from the same source in the form (pin, irq)?

For example, on am335x, all interrupts on gpio1 are mapped to a specific index on the OMAP35 INTC controller, meaning that only 1 interrupt is defined in the gpio1 node, signaling to INTC whether or not an interrupt occurred on gpio1.

like image 42
user3760778 Avatar answered Nov 20 '22 09:11

user3760778