1

I have a custom ZYNQ7000-based board. I want to insert an AXI GPIO that directly generate an interrupt. I want to handle the interrupt in a kernel module. All things sound to be correct but it does not work. My Toolset:

Petalinux 2021.2 installed on Ubuntu 20.04.03 Vivado 2021.2

  1. I have only one interrupt that I connect it to the processor interrupt input.
  2. I connect a push button to AXI GPIO 1 and configure it to generate interrupt.
  3. Based on my pl-DTS file
/ {
amba_pl: amba_pl {
  #address-cells = <1>;
  #size-cells = <1>;
  compatible = "simple-bus";
  ranges ;
  axi_gpio_0: gpio@41200000 {
    #gpio-cells = <3>;
    clock-names = "s_axi_aclk";
    clocks = <&clkc 15>;
    compatible = "xlnx,axi-gpio-2.0", "xlnx,xps-gpio-1.00.a";
    gpio-controller ;
    reg = <0x41200000 0x10000>;
    xlnx,all-inputs = <0x0>;
    xlnx,all-inputs-2 = <0x0>;
    xlnx,all-outputs = <0x1>;
    xlnx,all-outputs-2 = <0x0>;
    xlnx,dout-default = <0x00000000>;
    xlnx,dout-default-2 = <0x00000000>;
    xlnx,gpio-width = <0x4>;
    xlnx,gpio2-width = <0x20>;
    xlnx,interrupt-present = <0x0>;
    xlnx,is-dual = <0x0>;
    xlnx,tri-default = <0xFFFFFFFF>;
    xlnx,tri-default-2 = <0xFFFFFFFF>;
  };
  axi_gpio_1: gpio@41210000 {
    #gpio-cells = <3>;
    #interrupt-cells = <2>;
    clock-names = "s_axi_aclk";
    clocks = <&clkc 15>;
    compatible = "xlnx,axi-gpio-2.0", "xlnx,xps-gpio-1.00.a";
    gpio-controller;
    interrupt-controller;
    interrupt-names = "ip2intc_irpt";
    interrupt-parent = <&intc>;
    interrupts = <0 29 4>;
    reg = <0x41210000 0x10000>;
    xlnx,all-inputs = <0x1>;
    xlnx,all-inputs-2 = <0x0>;
    xlnx,all-outputs = <0x0>;
    xlnx,all-outputs-2 = <0x0>;
    xlnx,dout-default = <0x00000000>;
    xlnx,dout-default-2 = <0x00000000>;
    xlnx,gpio-width = <0x1>;
    xlnx,gpio2-width = <0x20>;
    xlnx,interrupt-present = <0x1>;
    xlnx,is-dual = <0x0>;
    xlnx,tri-default = <0xFFFFFFFF>;
    xlnx,tri-default-2 = <0xFFFFFFFF>;
  };
  };
};

The interrupt should be at 61 (29 + 32 = 61): interrupts = <0 29 4>;.

  1. I enable the interrupt enable register and global interrupt register.
  2. I want to write a kernel module and register the axi-gpio interrupt in that and register a ISR to handle it. the main part of my code is as follows:
if (request_irq(IRQ_NUM, isr, 0, DEVICE_NAME, NULL)) {
  printk(KERN_ERR "my_init: Cannot register IRQ %d\n", IRQ_NUM);
  return -EIO;
 } else {
  printk(KERN_INFO "my_init: Registered IRQ %d\n", IRQ_NUM);
 }

 printk(KERN_INFO "my_init: Initialize Module \"%s\"\n", DEVICE_NAME);  
 pdev = platform_device_register_simple(DEVICE_NAME, 0, NULL, 0);        
 if (pdev == NULL) {                           
  printk(KERN_WARNING "my_init: Adding platform device \"%s\" failed\n", DEVICE_NAME);
  kfree(pdev);                               
  return -ENODEV;                              
 }

PROBLEMS:

  1. Interrupt 61 could not be registered.
  2. In fact, I found "all free interrupts" and tried "all" with my axi-gpio. None of them works correctly.
  3. I do not want to use GPIO-keys or UIO because they need a blocking read BUT I want to write a kernel module and register the axi-gpio interrupt in that by interrupt request function (request_irq()) and register a ISR for it.
  4. I searched and read all previous problems in the Xilinx and other venders. I tried all solutions but I cannot find anything.

BTW: The connection between push button and processor is okay because I could activate it by the GPIO-keys. GPIO-keys interrupt catches the push button actions.

0andriy
  • 4,183
  • 1
  • 24
  • 37

0 Answers0