Introduction

The Xilinx® LogiCORE™ IP AXI General Purpose Input/Output (GPIO) core provides a general purpose input/output interface to the AXI interface.
This 32-bit soft Intellectual Property (IP) core is designed to interface with the AXI4-Lite interface.The AXI GPIO design provides a general purpose
input/output interface to an AXI4-Lite interface. The AXI GPIO can be configured as either a single or a dual-channel device.
The width of each channel is independently configurable.

HW IP Features

  • Supports the AXI4-Lite interface specification
  • Supports configurable single or dual GPIO channel(s)
  • Supports configurable channel width for GPIO pins from 1 to 32 bits
  • Supports dynamic programming of each GPIO bit as input or output
  • Supports individual configuration of each channel
  • Supports independent reset values for each bit of all registers
  • Supports optional interrupt request generation

Features supported in driver

  • Supports the AXI4-Lite interface specification
  • Supports configurable single or dual GPIO channel(s)
  • Supports configurable channel width for GPIO pins from 1 to 32 bits
  • Supports dynamic programming of each GPIO bit as input or output
  • Supports individual configuration of each channel
  • Supports independent reset values for each bit of all registers
  • Supports optional interrupt request generation

Missing Features, Known Issues and Limitations

  • None

Kernel Configuration Options for Driver

To enable GPIO in the kernel, the following configuration options need to be enabled:
CONFIG_GPIO_SYSFS=y
CONFIG_SYSFS=y
CONFIG_GPIO_XILINX=y (for axi_gpio)

Devicetree

axi_gpio_0: gpio@40000000 {
        #gpio-cells = <2>;
        compatible = "xlnx,xps-gpio-1.00.a";
        gpio-controller ;
        interrupt-parent = <&microblaze_0_intc>;
        interrupts = < 6 2 >;
        reg = < 0x40000000 0x10000 >;
        xlnx,all-inputs = <0x0>;
        xlnx,all-inputs-2 = <0x0>;
        xlnx,dout-default = <0x0>;
        xlnx,dout-default-2 = <0x0>;
        xlnx,gpio-width = <0x2>;
        xlnx,gpio2-width = <0x2>;
        xlnx,interrupt-present = <0x1>;
        xlnx,is-dual = <0x1>;
        xlnx,tri-default = <0xffffffff>;
        xlnx,tri-default-2 = <0xffffffff>;
} ;
 

Test procedure on ZCU102 eval board

Using GPIO with SysFs:
The GPIO driver fits in the Linux GPIO framework. It does provide access to the GPIO by user space through the sysfs filesystem. For details please refer to - the above-mentioned - documentation. The following text is aimed to augment, not replace the existing documentation.

For the examples below, there are some important points with sysfs.
  1. The GPIO controllers are visible in /sys/class/gpio. Each controller controls a number of GPIO signals.
  2. The GPIO signals must be exported into the sysfs before they can be manipulated. The number of the GPIO signal must be written to the GPIO export file to cause this to happen.
  3. After exporting the GPIO signal a new directory based on the GPIO signal number will appear in /sys/class/gpio. Under that directory are direction and value files that can be read and written.
Mounting Sysfs:
The root file system being used may not have sysfs mounted and it cannot be used if it's not mounted. The directory /sys is also needed to mount the sysfs on. The root file system must be writable to do the following steps.
> mkdir /sys
> mount -t sysfs sysfs /sys

Expected Output

Note from the boot log what the mappings of the 2 AXI GPIO units are :
[    1.354448] XGpio: /amba_pl@0/gpio@80000000: registered, base is 504
[    1.354761] XGpio: /amba_pl@0/gpio@80010000: registered, base is 496
The AXI GPIO driving the LEDs is at 0x80000000 so its base is 504.
The AXI GPIO reading the DIP switches is at 0x80010000 so its base is 496.
Note the nodes in place :
root@plnx_aarch64:/sys/class/gpio# ls /sys/class/gpio
export       gpiochip306  gpiochip496  unexport
gpiochip290  gpiochip322  gpiochip504
Activate LEDs using sysfs
Each created node controls a single bit of GPIO
root@plnx_aarch64:~# echo 504 > /sys/class/gpio/export
root@plnx_aarch64:/sys/class/gpio# ls /sys/class/gpio
export       gpiochip290  gpiochip322  gpiochip504
gpio504      gpiochip306  gpiochip496  unexport
root@plnx_aarch64:~# echo out > /sys/class/gpio/gpio504/direction
root@plnx_aarch64:~# echo 1 > /sys/class/gpio/gpio504/value – note the respective LED lights
root@plnx_aarch64:~# echo 505 > /sys/class/gpio/export
root@plnx_aarch64:~# echo out > /sys/class/gpio/gpio505/direction
root@plnx_aarch64:~# echo 1 > /sys/class/gpio/gpio505/value – note the respective LED lights
Repeat for 506 - 511
Read DIP Switches using sysfs
Each created node controls a single bit of GPIO
root@plnx_aarch64:~# echo 496 > /sys/class/gpio/export
root@plnx_aarch64:~# echo in > /sys/class/gpio/gpio496/direction
root@plnx_aarch64:~# cat /sys/class/gpio/gpio496/value – try each switch position
root@plnx_aarch64:~# echo 497 > /sys/class/gpio/export
root@plnx_aarch64:~# echo in > /sys/class/gpio/gpio497/direction
root@plnx_aarch64:~# cat /sys/class/gpio/gpio497/value – try each switch position
Repeat for 498 - 503
 

Addition of Dip Switches and Push Buttons to the node to generate interrupts on ZCU102 eval boards

This section covers process of modifying the device tree (DTS) by adding dip switches and push buttons subnodes to generate interrupts.
These are suitable for more complex applications involving handling interrupts.

Kernel Configuration for dip switches and push buttons

In order to use, the kernel must be configured correctly. Configure the kernel as described in Build Kernel, and then make sure the following options are enabled in menuconfig:
  • Device Drivers
    • GPIO Support
      • Memory Mapped GPIO Drivers
        • Xilinx GPIO support
        • Xilinx Zynq GPIO support
    • Input device support
      • Keyboards
        • GPIO Buttons
        • Polled GPIO buttons

Enable below kernel configuration options:
CONFIG_KEYBOARD_GPIO=y
CONFIG_KEYBOARD_GPIO_POLLED=y
 
Dip Switches to the device tree
Dip Switches are available only for Input GPIO application. Each created subnode controls a single bit of GPIO.
Under "gpio-keys" node in the dts file, create subnodes for dip switches as per design with names shown below:
    gpio-keys {
        compatible = "gpio-keys";
        #address-cells = <1>;
        #size-cells = <0>;
        autorepeat;
        sw19 {
            label = "sw19";
            gpios = <&gpio 22 0>;
            linux,code = <108>; /* down */
            gpio-key,wakeup;
            autorepeat;
        };
        GPIO_DIP_SW0 {
            label = "GPIO_DIP_SW0";
            gpios = <&axi_gpio_0 0x0 0x0>;
            linux,code = <108>;
            gpio-key,wakeup;
            autorepeat;
        };
        GPIO_DIP_SW1 {
            label = "GPIO_DIP_SW1";
            gpios = <&axi_gpio_0 0x1 0x0>;
            linux,code = <108>;
            gpio-key,wakeup;
            autorepeat;
        };
        GPIO_DIP_SW2 {
            label = "GPIO_DIP_SW2";
            gpios = <&axi_gpio_0 0x2 0x0>;
            linux,code = <108>;
            gpio-key,wakeup;
            autorepeat;
        };
        GPIO_DIP_SW3 {
            label = "GPIO_DIP_SW3";
            gpios = <&axi_gpio_0 0x3 0x0>;
            linux,code = <108>;
            gpio-key,wakeup;
            autorepeat;
        };
        GPIO_DIP_SW4 {
            label = "GPIO_DIP_SW4";
            gpios = <&axi_gpio_0 0x4 0x0>;
            linux,code = <108>;
            gpio-key,wakeup;
            autorepeat;
        };
        GPIO_DIP_SW5 {
            label = "GPIO_DIP_SW5";
            gpios = <&axi_gpio_0 0x5 0x0>;
            linux,code = <108>;
            gpio-key,wakeup;
            autorepeat;
        };
        GPIO_DIP_SW6 {
            label = "GPIO_DIP_SW6";
            gpios = <&axi_gpio_0 0x6 0x0>;
            linux,code = <108>;
            gpio-key,wakeup;
            autorepeat;
        };
        GPIO_DIP_SW7 {
            label = "GPIO_DIP_SW7";
            gpios = <&axi_gpio_0 0x7 0x0>;
            linux,code = <108>;
            gpio-key,wakeup;
            autorepeat;
        };
     };
 
  • The Label refers to the descriptive name of the dip switch.
  • The string <&axi_gpio_0 0x0 0x0> references the AXI GPIO 0 controller and states that GPIO_DIP_SW0 is on pin 0, GPIO_DIP_SW1 is on pin 1 and same for remaining dip switches; the 0 states that the device is active high.
  • The linux,code property determines which key will show up in the event.
  • gpio-key,wakeup will enable the GPIO to wake the system from suspend.
  • The autorepeat property allows holding the key to continuously generate events.
Full documentation can be found here Documentation/devicetree/bindings/input/gpio-keys.txt.

After this, boot the linux. We should able to see the label names of dip switches in cat /proc/interrupts. On and off any of the dip switches and view the trigger count of that dip switch using "cat /proc/interrupts".

Expected Output

root@xilinx-zcu102-zu9-es2-rev1_0-2017:/sys/class/gpio# dmesg | grep gpio
[    1.337411] XGpio: /amba_pl@0/gpio@a0010000: registered, base is 504
[    4.127198] input: gpio-keys as /devices/platform/gpio-keys/input/input0
It means AXI GPIO reading the DIP Switches at 0xa0010000 and ist base is 504.
root@xilinx-zcu102-zu9-es2-rev1_0-2017:~# cd /sysc /class/gpio/
root@xilinx-zcu102-zu9-es2-rev1_0-2017:/sys/class/gpio# ls
export       gpiochip298  gpiochip314  gpiochip330  gpiochip504  unexport
root@xilinx-zcu102-zu9-es2-rev1_0-2017:~# cat /proc/interrupts
           CPU0       CPU1       CPU2       CPU3
  3:          0          0          0          0     GICv2  29 Level     arch_timer
  4:       1115       1701       1909       1106     GICv2  30 Level     arch_timer
  7:          0          0          0          0     GICv2 187 Level     arm-smmu global fault, arm-smmu-context-fault, arm-smmu-context-fault, arm-smmu-context-fault, arm-smmu-context-fault, arm-smmu-context-fault, arm-smmu-context-fault, arm-smmu-context-fault, arm-smmu-context-fault, arm-smmu-context-fault, arm-smmu-context-fault, arm-smmu-context-fault, arm-smmu-context-fault, arm-smmu-context-fault
 12:          0          0          0          0     GICv2  67 Level     zynqmp_pm
 15:          0          0          0          0     GICv2 156 Level     zynqmp-dma
 16:          0          0          0          0     GICv2 157 Level     zynqmp-dma
 17:          0          0          0          0     GICv2 158 Level     zynqmp-dma
 18:          0          0          0          0     GICv2 159 Level     zynqmp-dma
 19:          0          0          0          0     GICv2 160 Level     zynqmp-dma
 20:          0          0          0          0     GICv2 161 Level     zynqmp-dma
 21:          0          0          0          0     GICv2 162 Level     zynqmp-dma
 22:          0          0          0          0     GICv2 163 Level     zynqmp-dma
 24:          0          0          0          0     GICv2 109 Level     zynqmp-dma
 25:          0          0          0          0     GICv2 110 Level     zynqmp-dma
 26:          0          0          0          0     GICv2 111 Level     zynqmp-dma
 27:          0          0          0          0     GICv2 112 Level     zynqmp-dma
 28:          0          0          0          0     GICv2 113 Level     zynqmp-dma
 29:          0          0          0          0     GICv2 114 Level     zynqmp-dma
 30:          0          0          0          0     GICv2 115 Level     zynqmp-dma
 31:          0          0          0          0     GICv2 116 Level     zynqmp-dma
 33:          0          0          0          0     GICv2  95 Level     eth0, eth0
 35:        302          0          0          0     GICv2  49 Level     cdns-i2c
 36:         43          0          0          0     GICv2  50 Level     cdns-i2c
 37:          0          0          0          0     GICv2  42 Level     ff960000.memory-controller
 38:          0          0          0          0     GICv2 150 Level     nwl_pcie:misc
 43:         14          0          0          0     GICv2  47 Level     ff0f0000.spi
 44:          0          0          0          0     GICv2  58 Level     ffa60000.rtc
 45:          0          0          0          0     GICv2  59 Level     ffa60000.rtc
 46:          0          0          0          0     GICv2 165 Level     ahci-ceva[fd0c0000.ahci]
 47:        192          0          0          0     GICv2  81 Level     mmc0
 48:         62          0          0          0     GICv2  53 Level     xuartps
 50:          0          0          0          0     GICv2 145 Edge      fd4d0000.watchdog
 51:          0          0          0          0     GICv2  88 Level     ams-irq
 52:          0          0          0          0     GICv2 151 Level     fd4a0000.dp
 53:          0          0          0          0     GICv2 154 Level     fd4c0000.dma
 55:          0          0          0          0  Xilinx INTC   1 Level   -level     a0000000.i2c
 **57:          0          0          0          0     xgpio   0 Edge      GPIO_DIP_SW0**
 **58:          0          0          0          0     xgpio   1 Edge      GPIO_DIP_SW1**
 **59:          0          0          0          0     xgpio   2 Edge      GPIO_DIP_SW2**
 **60:          0          0          0          0     xgpio   3 Edge      GPIO_DIP_SW3**
 **61:          0          0          0          0     xgpio   4 Edge      GPIO_DIP_SW4**
 87:          0          0          0          0  zynq-gpio  22 Edge      sw19
239:          0          0          0          0     GICv2  97 Level     xhci-hcd:usb1
IPI0:      2073        972       1065       2191       Rescheduling interrupts
IPI1:        69         49         54         43       Function call interrupts
IPI2:         0          0          0          0       CPU stop interrupts
IPI3:       156        154         29        142       Timer broadcast interrupts
IPI4:         0          0          0          0       IRQ work interrupts
IPI5:         0          0          0          0       CPU wake-up interrupts
After switching on and off any of the dip switches, the trigger count of that dip switch increases as shown below
root@xilinx-zcu102-zu9-es2-rev1_0-2017:/sys/class/gpio# cat /proc/interrupts
           CPU0       CPU1       CPU2       CPU3
  3:          0          0          0          0     GICv2  29 Level     arch_timer
  4:       3061       2185      10195       1814     GICv2  30 Level     arch_timer
  7:          0          0          0          0     GICv2 187 Level     arm-smmu global fault, arm-smmu-context-fault, arm-smmu-context-fault, arm-smmu-context-fault, arm-smmu-context-fault, arm-smmu-context-fault, arm-smmu-context-fault, arm-smmu-context-fault, arm-smmu-context-fault, arm-smmu-context-fault, arm-smmu-context-fault, arm-smmu-context-fault, arm-smmu-context-fault, arm-smmu-context-fault
 12:          0          0          0          0     GICv2  67 Level     zynqmp_pm
 15:          0          0          0          0     GICv2 156 Level     zynqmp-dma
 16:          0          0          0          0     GICv2 157 Level     zynqmp-dma
 17:          0          0          0          0     GICv2 158 Level     zynqmp-dma
 18:          0          0          0          0     GICv2 159 Level     zynqmp-dma
 19:          0          0          0          0     GICv2 160 Level     zynqmp-dma
 20:          0          0          0          0     GICv2 161 Level     zynqmp-dma
 21:          0          0          0          0     GICv2 162 Level     zynqmp-dma
 22:          0          0          0          0     GICv2 163 Level     zynqmp-dma
 24:          0          0          0          0     GICv2 109 Level     zynqmp-dma
 25:          0          0          0          0     GICv2 110 Level     zynqmp-dma
 26:          0          0          0          0     GICv2 111 Level     zynqmp-dma
 27:          0          0          0          0     GICv2 112 Level     zynqmp-dma
 28:          0          0          0          0     GICv2 113 Level     zynqmp-dma
 29:          0          0          0          0     GICv2 114 Level     zynqmp-dma
 30:          0          0          0          0     GICv2 115 Level     zynqmp-dma
 31:          0          0          0          0     GICv2 116 Level     zynqmp-dma
 33:          0          0          0          0     GICv2  95 Level     eth0, eth0
 35:        302          0          0          0     GICv2  49 Level     cdns-i2c
 36:         43          0          0          0     GICv2  50 Level     cdns-i2c
 37:          0          0          0          0     GICv2  42 Level     ff960000.memory-controller
 38:          0          0          0          0     GICv2 150 Level     nwl_pcie:misc
 43:         14          0          0          0     GICv2  47 Level     ff0f0000.spi
 44:          0          0          0          0     GICv2  58 Level     ffa60000.rtc
 45:          0          0          0          0     GICv2  59 Level     ffa60000.rtc
 46:          0          0          0          0     GICv2 165 Level     ahci-ceva[fd0c0000.ahci]
 47:        192          0          0          0     GICv2  81 Level     mmc0
 48:        733          0          0          0     GICv2  53 Level     xuartps
 50:          0          0          0          0     GICv2 145 Edge      fd4d0000.watchdog
 51:          0          0          0          0     GICv2  88 Level     ams-irq
 52:          0          0          0          0     GICv2 151 Level     fd4a0000.dp
 53:          0          0          0          0     GICv2 154 Level     fd4c0000.dma
 55:          0          0          0          0  Xilinx INTC   1 Level   -level     a0000000.i2c
 **57:         18          0          0          0     xgpio   0 Edge      GPIO_DIO_SW0**
 **58:         19          0          0          0     xgpio   1 Edge      GPIO_DIP_SW1**
 **59:         16          0          0          0     xgpio   2 Edge      GPIO_DIP_SW2**
 **60:         10          0          0          0     xgpio   3 Edge      GPIO_DIP_SW3**
 **61:          6          0          0          0     xgpio   4 Edge      GPIO_DIP_SW4**
 87:          0          0          0          0  zynq-gpio  22 Edge      sw19
239:          0          0          0          0     GICv2  97 Level     xhci-hcd:usb1
IPI0:      2106        996       1183       2261       Rescheduling interrupts
IPI1:        69         49         54         43       Function call interrupts
IPI2:         0          0          0          0       CPU stop interrupts
IPI3:      1457       1541        536       1442       Timer broadcast interrupts
IPI4:         0          0          0          0       IRQ work interrupts
IPI5:         0          0          0          0       CPU wake-up interrupts
 

Push buttons to the device tree

Push buttons are available only for Input GPIO application.
Each created subnode controls a single bit of GPIO. Under "gpio-keys" node in the dts file, create subnodes for Push buttons as per design with names shown below:
    gpio-keys {
        compatible = "gpio-keys";
        #address-cells = <1>;
        #size-cells = <0>;
        autorepeat;
        sw19 {
            label = "sw19";
            gpios = <&gpio 22 0>;
            linux,code = <108>; /* down */
            gpio-key,wakeup;
            autorepeat;
        };
        SW15 {
            label = "SW15";
            gpios = <&axi_gpio_1 0x0 0x0>;
                        linux,code = <108>;
            gpio-key,wakeup;
            autorepeat;
        };
        SW14 {
            label = "SW14";
            gpios = <&axi_gpio_1 0x1 0x0>;
                        linux,code = <108>;
            gpio-key,wakeup;
            autorepeat;
        };
        SW16 {
            label = "SW16";
            gpios = <&axi_gpio_1 0x2 0x0>;
                        linux,code = <108>;
            gpio-key,wakeup;
            autorepeat;
        };
        SW17 {
            label = "SW17";
            gpios = <&axi_gpio_1 0x3 0x0>;
                        linux,code = <108>;
            gpio-key,wakeup;
            autorepeat;
        };
        SW18 {
            label = "SW18";
            gpios = <&axi_gpio_1 0x4 0x0>;
                        linux,code = <108>;
            gpio-key,wakeup;
            autorepeat;
        };
    };
 
  • The Label refers to the descriptive name of the Push button.
  • The string <&axi_gpio_1 0x0 0x0> references the AXI GPIO 1 controller and states that SW15 is on pin 0, SW14 is on pin 1 and same for remaining Push buttons; the 0 states that the device is active high.
  • The linux,code property determines which key will show up in the event.
  • gpio-key,wakeup will enable the GPIO to wake the system from suspend.
  • The autorepeat property allows holding the key to continuously generate events.
Full documentation can be found here Documentation/devicetree/bindings/input/gpio-keys.txt.

After this, boot the linux. We should able to see the label names of push buttons in cat /proc/interrupts. Press any of the push buttons and view the trigger count of those push buttons in cat /proc/interrupts.

Expected Output

root@plnx_aarch64:~# c dmesg | grep gpio
[    1.329832] XGpio: /amba_pl@0/gpio@b0002000: registered, base is 491
It means AXI GPIO reading the push buttons at b0002000 and its base starts from 491 to 495.
[    4.680308] input: gpio-keys as /devices/platform/gpio-keys/input/input0
root@plnx_aarch64:~# cat /proc/interrupts
           CPU0       CPU1       CPU2       CPU3
  2:          0          0          0          0     GICv2  29 Level     arch_timer
  3:       1765       2701       1206       1053     GICv2  30 Level     arch_timer
 10:          0          0          0          0     GICv2  67 Level     zynqmp_pm
 13:          0          0          0          0     GICv2 156 Level     zynqmp-dma
 14:          0          0          0          0     GICv2 157 Level     zynqmp-dma
 15:          0          0          0          0     GICv2 158 Level     zynqmp-dma
 16:          0          0          0          0     GICv2 159 Level     zynqmp-dma
 17:          0          0          0          0     GICv2 160 Level     zynqmp-dma
 18:          0          0          0          0     GICv2 161 Level     zynqmp-dma
 19:          0          0          0          0     GICv2 162 Level     zynqmp-dma
 20:          0          0          0          0     GICv2 163 Level     zynqmp-dma
 22:          0          0          0          0     GICv2 109 Level     zynqmp-dma
 23:          0          0          0          0     GICv2 110 Level     zynqmp-dma
 24:          0          0          0          0     GICv2 111 Level     zynqmp-dma
 25:          0          0          0          0     GICv2 112 Level     zynqmp-dma
 26:          0          0          0          0     GICv2 113 Level     zynqmp-dma
 27:          0          0          0          0     GICv2 114 Level     zynqmp-dma
 28:          0          0          0          0     GICv2 115 Level     zynqmp-dma
 29:          0          0          0          0     GICv2 116 Level     zynqmp-dma
 31:          0          0          0          0     GICv2  95 Level     eth0, eth0
 33:        302          0          0          0     GICv2  49 Level     cdns-i2c
 34:         43          0          0          0     GICv2  50 Level     cdns-i2c
 35:          0          0          0          0     GICv2  42 Level     ff960000.memory-controller
 36:          0          0          0          0     GICv2 150 Level     nwl_pcie:misc
 41:         14          0          0          0     GICv2  47 Level     ff0f0000.spi
 42:          0          0          0          0     GICv2  58 Level     ffa60000.rtc
 43:          0          0          0          0     GICv2  59 Level     ffa60000.rtc
 44:          0          0          0          0     GICv2 165 Level     ahci-ceva[fd0c0000.ahci]
 45:        174          0          0          0     GICv2  81 Level     mmc0
 46:         82          0          0          0     GICv2  53 Level     xuartps
 48:          0          0          0          0     GICv2 145 Edge      fd4d0000.watchdog
 49:          0          0          0          0     GICv2  88 Level     ams-irq
 50:          0          0          0          0     GICv2 151 Level     fd4a0000.dp
 51:          0          0          0          0     GICv2 154 Level     fd4c0000.dma
 **53:          0          0          0          0     xgpio   0 Edge      SW15**
 **54:          0          0          0          0     xgpio   1 Edge      SW14**
 **55:          0          0          0          0     xgpio   2 Edge      SW16**
 **56:          0          0          0          0     xgpio   3 Edge      SW17**
 **57:          0          0          0          0     xgpio   4 Edge      SW18**
 **80:          0          0          0          0  zynq-gpio  22 Edge     sw19**
232:          0          0          0          0     GICv2  97 Level     xhci-hcd:usb1
IPI0:      1691       1101       1537       1320       Rescheduling interrupts
IPI1:        57         47         64         39       Function call interrupts
IPI2:         0          0          0          0       CPU stop interrupts
IPI3:        93        157        200        215       Timer broadcast interrupts
IPI4:         0          0          0          0       IRQ work interrupts
IPI5:         0          0          0          0       CPU wake-up interrupts
root@plnx_aarch64:/sys/class/gpio#
root@plnx_aarch64:/sys/class/gpio# echo 491 > export
-sh: echo: write error: Device or resource busy
root@plnx_aarch64:/sys/class/gpio# echo 492 > export
-sh: echo: write error: Device or resource busy
root@plnx_aarch64:/sys/class/gpio# echo 493 > export
-sh: echo: write error: Device or resource busy
root@plnx_aarch64:/sys/class/gpio# echo 494 > export
-sh: echo: write error: Device or resource busy
root@plnx_aarch64:/sys/class/gpio# echo 495 > export
-sh: echo: write error: Device or resource busy
root@plnx_aarch64:/sys/class/gpio#
After pressing any of the push buttons, count of that push button increases as shown below.
root@plnx_aarch64:/sys/class/gpio# cat /proc/interrupts
           CPU0       CPU1       CPU2       CPU3
  2:          0          0          0          0     GICv2  29 Level     arch_timer
  3:       6915      12365       1875       1126     GICv2  30 Level     arch_timer
 10:          0          0          0          0     GICv2  67 Level     zynqmp_pm
 13:          0          0          0          0     GICv2 156 Level     zynqmp-dma
 14:          0          0          0          0     GICv2 157 Level     zynqmp-dma
 15:          0          0          0          0     GICv2 158 Level     zynqmp-dma
 16:          0          0          0          0     GICv2 159 Level     zynqmp-dma
 17:          0          0          0          0     GICv2 160 Level     zynqmp-dma
 18:          0          0          0          0     GICv2 161 Level     zynqmp-dma
 19:          0          0          0          0     GICv2 162 Level     zynqmp-dma
 20:          0          0          0          0     GICv2 163 Level     zynqmp-dma
 22:          0          0          0          0     GICv2 109 Level     zynqmp-dma
 23:          0          0          0          0     GICv2 110 Level     zynqmp-dma
 24:          0          0          0          0     GICv2 111 Level     zynqmp-dma
 25:          0          0          0          0     GICv2 112 Level     zynqmp-dma
 26:          0          0          0          0     GICv2 113 Level     zynqmp-dma
 27:          0          0          0          0     GICv2 114 Level     zynqmp-dma
 28:          0          0          0          0     GICv2 115 Level     zynqmp-dma
 29:          0          0          0          0     GICv2 116 Level     zynqmp-dma
 31:          0          0          0          0     GICv2  95 Level     eth0, eth0
 33:        302          0          0          0     GICv2  49 Level     cdns-i2c
 34:         43          0          0          0     GICv2  50 Level     cdns-i2c
 35:          0          0          0          0     GICv2  42 Level     ff960000.memory-controller
 36:          0          0          0          0     GICv2 150 Level     nwl_pcie:misc
 41:         14          0          0          0     GICv2  47 Level     ff0f0000.spi
 42:          0          0          0          0     GICv2  58 Level     ffa60000.rtc
 43:          0          0          0          0     GICv2  59 Level     ffa60000.rtc
 44:          0          0          0          0     GICv2 165 Level     ahci-ceva[fd0c0000.ahci]
 45:        174          0          0          0     GICv2  81 Level     mmc0
 46:       1111          0          0          0     GICv2  53 Level     xuartps
 48:          0          0          0          0     GICv2 145 Edge      fd4d0000.watchdog
 49:          0          0          0          0     GICv2  88 Level     ams-irq
 50:          0          0          0          0     GICv2 151 Level     fd4a0000.dp
 51:          0          0          0          0     GICv2 154 Level     fd4c0000.dma
 **53:         12          0          0          0     xgpio   0 Edge      SW15**
 **54:          9          0          0          0     xgpio   1 Edge      SW14**
 **55:          9          0          0          0     xgpio   2 Edge      SW16**
 **56:          6          0          0          0     xgpio   3 Edge      SW17**
 **57:          8          0          0          0     xgpio   4 Edge      SW18**
 80:          0          0          0          0  zynq-gpio  22 Edge     sw19
232:          0          0          0          0     GICv2  97 Level     xhci-hcd:usb1
IPI0:      1733       1223       1649       1340       Rescheduling interrupts
IPI1:        57         47         64         39       Function call interrupts
IPI2:         0          0          0          0       CPU stop interrupts
IPI3:      1720       1344       2083       2149       Timer broadcast interrupts
IPI4:         0          0          0          0       IRQ work interrupts
IPI5:         0          0          0          0       CPU wake-up interrupts
Err:          0
root@plnx_aarch64:/sys/class/gpio#

Mainline Status

This driver is currently in sync with mainline kernel except for the following:
  • gpio: xilinx: Use read/writel for ARM64
  • gpio: xilinx: Add clock adaptation support
  • gpio: Add simple remove and exit functions
  • gpio: xilinx: Fix the NULL pointer access
  • gpio: gpio-xilinx.c: Fix kernel doc warnings
  • gpio: gpio-xilinx: Fix warnings in the driver

Change Log

2016.3
Summary:
  • gpio: xilinx: Use read/writel for ARM64.
Commits:
  • c8105d8 gpio: xilinx: Use read/writel for ARM64.

2016.4
None

2017.1
Summary:
  • Merge tag 'v4.8' into master
  • gpio: xilinx: Add clock adaptation support
  • gpio: Add simple remove and exit functions
  • gpio: xilinx: Fix the NULL pointer access
Commits:
  • 15add85 Merge tag 'v4.8' into master
  • 34b6b71 gpio: xilinx: Add clock adaptation support
  • e469c51 gpio: Add simple remove and exit functions
  • 30b6bc6 gpio: xilinx: Fix the NULL pointer access

2017.2
None

2017.3
Summary:
  • gpio: gpio-xilinx.c: Fix kernel doc warnings
  • gpio: gpio-xilinx: Fix warnings in the driver
Commits:
  • 24132f8 gpio: gpio-xilinx.c: Fix kernel doc warnings
  • 3da7287 gpio: gpio-xilinx: Fix warnings in the driver

2017.4
  • None

2018.1

Summary:

  • gpio: xilinx: Add reset support
  • gpio:xilinx: defer probe if clock is not found

Commits:

  • 7ed822egpio: xilinx: Add reset support
  • 3bbc2fdgpio:xilinx: defer probe if clock is not found

2018.2
  • None

Related Links

https://github.com/Xilinx/linux-xlnx/blob/master/drivers/gpio/gpio-xilinx.c