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