This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

GPIO Interrupt not working in Keystone 2 (TCI6638K2K )

Part Number: TCI6638K2K

Hi,

One of my projects uses TCI6638K2K , the ARM core runs "Processor SDK Linux (version:3.10.10-rt7) " . My goal is to upgrade the linux from version "3.10.10-rt7" to "4.14.79-rt47" ( obtained from ti.com)

I was able to successfully upgrade the linux on the SoC. 

root ~# uname -a
Linux soc3.dsm 4.14.79-rt47-g28d73230da #7 SMP PREEMPT RT Fri Dec 27 16:32:22 EST 2019 armv7l GNU/Linux

After updating to the new linux, I noticed that the GPIO interrupt which was working in the older version, stopped working in 4.14 version.

---

Output of "cat /proc/interrupts"

 44:          0          0          0          0  GPIO-AINTC 161 Edge      gpio9_handler
 45:          0          0          0          0  GPIO-AINTC 162 Edge      gpio10_handler

As you can see from this , the handler is attached but the interrupt is not invoked.  I am having issues for GPIO #9 and GPIO #10, below is the code snippet for GPIO #9 and the interrupt should be triggered on the rising edge. The code snippet is given below, 

/************************************************************/
static unsigned int gpio9 = 9;      /* GPIO 9 */


static int __init _gpio9_init(void)
{
    int result = 0;

    if (!gpio_is_valid(gpio9))
    {
        printk(KERN_INFO "Invalid GPIO \n");
        return -ENODEV;
    }
    gpio_request(gpio9, "sysfs");      // Set up the gpio
    gpio_direction_input(gpio9);       // Set the button GPIO to be an input
    gpio_export(gpio9, false);         // Causes gpio to appear in /sys/class/gpio
    

    irqNumber = gpio_to_irq(gpio9);
    printk(KERN_INFO "GPIO9 is mapped to IRQ: %d\n", irqNumber);

    memset(&info, 0, sizeof(struct siginfo));
    info.si_signo = SIGUSR1;
    info.si_code = SI_QUEUE;
    info.si_errno = 0;
    result = register_chrdev( major, "gpio9_drv", &gpio9_fops );
    if ( result < 0 )
    {
        printk( "gpio9_drv: can't get major number\n" );
        major = -1;
        return 0;
    }
    if ( major == 0 ) major = result;
    printk(KERN_ALERT "register_chrdev  success\n");

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

    printk(KERN_INFO "GPIO9: The interrupt request result is: %d\n", result);
    return result;
}

static void __exit gpio9_exit(void)
{
    free_irq(irqNumber, NULL);               // Free the IRQ number, no *dev_id required in this case
    gpio_unexport(gpio9);               // Unexport the Button GPIO
    gpio_free(gpio9);                   // Free the Button GPIO
    printk(KERN_INFO "gpio9 exit\n");
}

static irq_handler_t gpio9f_irq_handler(unsigned int irq, void *dev_id, struct pt_regs *regs)
{
    if (!gpio9handler)
    {
        return (irq_handler_t) IRQ_HANDLED;      // Announce that the IRQ has been handled correctly
    }
    else
    {
        //Send signal to the user task
        udelay(100);
        send_sig(SIGUSR1, gpio9handler, 0);
        send_sig_count++;
        return (irq_handler_t) IRQ_HANDLED;      // Announce that the IRQ has been handled correctly
    }
}

/// This next calls are  mandatory -- they identify the initialization function
/// and the cleanup function (as above).
module_init(_gpio9_init);
module_exit(gpio9_exit);
/************************************************************/

The above module used to work in linux 3.10.10, But in the newer version of linux (4.14) I do not see the IRQ handler is invoked.

I would like to know the following

1. Has anyone encountered issue by using GPIO as interrupts in Linux version 4.14?

 2. Is there any additional changes in the above driver code are required for the newer version  of linux?

 3. I noticed that for the GPIO driver support for keystone, gpio-davinci is used, so In the devicetree,  do I have to include/remove any parameters for the GPIO? ( below is the devicetree snippet for the GPIO)

/***********************************/

  gpio0: gpio@260bf00 {
                        compatible = "ti,keystone-gpio";
                        reg = <0x0260bf00 0x38>;
                        gpio-controller;
                        #gpio-cells = <2>;
                        /* HW Interrupts mapped to GPIO pins */
                        interrupts = <GIC_SPI 120 IRQ_TYPE_EDGE_RISING>,
                                        <GIC_SPI 121 IRQ_TYPE_EDGE_RISING>,
                                        <GIC_SPI 122 IRQ_TYPE_EDGE_RISING>,
                                        <GIC_SPI 123 IRQ_TYPE_EDGE_RISING>,
                                        <GIC_SPI 124 IRQ_TYPE_EDGE_RISING>,
                                        <GIC_SPI 125 IRQ_TYPE_EDGE_RISING>,
                                        <GIC_SPI 126 IRQ_TYPE_EDGE_RISING>,
                                        <GIC_SPI 127 IRQ_TYPE_EDGE_RISING>,
                                        <GIC_SPI 128 IRQ_TYPE_EDGE_RISING>,
                                        <GIC_SPI 129 IRQ_TYPE_EDGE_RISING>,
                                        <GIC_SPI 130 IRQ_TYPE_EDGE_RISING>,
                                        <GIC_SPI 131 IRQ_TYPE_EDGE_RISING>,
                                        <GIC_SPI 132 IRQ_TYPE_EDGE_RISING>,
                                        <GIC_SPI 133 IRQ_TYPE_EDGE_RISING>,
                                        <GIC_SPI 134 IRQ_TYPE_EDGE_RISING>,
                                        <GIC_SPI 135 IRQ_TYPE_EDGE_RISING>,
                                        <GIC_SPI 136 IRQ_TYPE_EDGE_RISING>,
                                        <GIC_SPI 137 IRQ_TYPE_EDGE_RISING>,
                                        <GIC_SPI 138 IRQ_TYPE_EDGE_RISING>,
                                        <GIC_SPI 139 IRQ_TYPE_EDGE_RISING>,
                                        <GIC_SPI 140 IRQ_TYPE_EDGE_RISING>,
                                        <GIC_SPI 141 IRQ_TYPE_EDGE_RISING>,
                                        <GIC_SPI 142 IRQ_TYPE_EDGE_RISING>,
                                        <GIC_SPI 143 IRQ_TYPE_EDGE_RISING>,
                                        <GIC_SPI 144 IRQ_TYPE_EDGE_RISING>,
                                        <GIC_SPI 145 IRQ_TYPE_EDGE_RISING>,
                                        <GIC_SPI 146 IRQ_TYPE_EDGE_RISING>,
                                        <GIC_SPI 147 IRQ_TYPE_EDGE_RISING>,
                                        <GIC_SPI 148 IRQ_TYPE_EDGE_RISING>,
                                        <GIC_SPI 149 IRQ_TYPE_EDGE_RISING>,
                                        <GIC_SPI 150 IRQ_TYPE_EDGE_RISING>,
                                        <GIC_SPI 151 IRQ_TYPE_EDGE_RISING>;

                        clocks = <&clkgpio>;
                        clock-names = "gpio";
                        ti,ngpio = <32>;
                        ti,davinci-gpio-unbanked = <32>;
                };
/************************************/

4. I am also wondering if any changes are required in the GIC-400 ( Global Interrupt Controller).

Any pointers to in the issue would be appreciated. Please let me know if you need any additional information.

Thanks,

Ruban

  • Hi,

    I'll take a look at this and update the thread.

    Best Regards,
    Yordan

  • Could you also share how did you configure the dts file?

    Best Regards,
    Yordan

  • Hi Yordan,

    Thanks for looking into this issue.

    The configuration of the GPIO in the device tree is provided in the case description. And below is the Interrupt controller configuration in the devicetree

    /*********************/
        gic: interrupt-controller {
            compatible = "arm,gic-400", "arm,cortex-a15-gic";
            #interrupt-cells = <3>;
            interrupt-controller;
            reg = <0x0 0x02561000 0x0 0x1000>,
                  <0x0 0x02562000 0x0 0x2000>,
                  <0x0 0x02564000 0x0 0x2000>,
                  <0x0 0x02566000 0x0 0x2000>;
            interrupts = <GIC_PPI 9 (GIC_CPU_MASK_SIMPLE(4) |
                    IRQ_TYPE_LEVEL_HIGH)>;
        };

    /**********************/

    I have attached the all DTS files for your reference.  Please let me know if you need any additional information.


    keystone_devicetree_files.zip

    Best Regards,

    Ruban

  • Having exactly same issue with Keystone 2 just upgraded Kernel from 4.1 to 4.19 using TI Yocto Redistribution.

    4.1: GPIO interrupts register and work.

    4.19: Interrupts register, and can be seen so in kernel, I can see the kernel can read GPIO level changes, but no interrupts actually triggered. Almost seems like interrupt controller isn't configured correctly or the link between GPIO and INTC is broken.

  • Yordan,

    Can you update us on the status of the investigation? 

    As I mentioned in the thread I appear to have the same issue after upgrading kernel from 4.1 to 4.19. My dts config is fairly similar to what is already posted in the thread. I did a little bit of digging to see what was done for GPIO and IRQ drivers between 4.1 and 4.19. I noticed GPIO driver is heavily modified. Interrupt controller is less so. 

    Unfortunately for us returning to 4.1 is not acceptable, as we have discovered issues with CIFS that affected our use cases that were fixed in the later kernels.