UIO to handle GPIO interrupts?

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

UIO to handle GPIO interrupts?

3,077 Views
surrealist14
Contributor III

I am hoping that you can provide advice on using UIO to handle an interrupt from user space.  I found an excellent summary at https://yurovsky.github.io/2014/10/10/linux-uio-gpio-interrupt.html and have tried to follow it as well as I can, being a newcomer to Yocto and embedded Linux.

We are using a Variscite DART-MX8M-MINI development kit.  I have enabled spidev, which I am using to communicate with an ADS1299 EEG analog front end from TI.  It generates a “data ready” interrupt DRDY# (active low).  I’d like to be able to handle this falling-edge interrupt by connecting it to a GPIO (GPIO1_0) and either read() or poll() to wait for an interrupt, and can then read the acquired data using /dev/spidev0.0.

In my device tree, I have added the following under my &ecspi1 node.  I am not certain this is the correct place to add this information, or if I can simply add it within the device tree “root” node “/ {“.  I would appreciate your advice on the best place add this information.

       // Added for DRDY# interrupt on GPIO1_0 from user space

       user_io@0 {

              compatible = "mydevice,generic-uio,ui_pdrv";

              status = "okay";

              interrupt-parent = <&gpio1>;

              interrupts = <0 IRQ_TYPE_EDGE_FALLING>;

              pinctrl-names = "default";

              pinctrl-0 = <&pinctrl_user_io>;

       };

Under my dts &iomuxc node, the various pinctrl groups are defined.  I added the following for GPIO1_0:

              // Added for DRDY# interrupt on GPIO1_0 from user space

              pinctrl_user_io: user_io-0 {

                     fsl,pins = <

                           MX8MM_IOMUXC_GPIO1_IO00_GPIO1_IO0           0x1c0

                     >;

              };

This _should_ configure the pin to enable a pull-up.  Can you confirm this?

I have modified my kernel .config file via menuconfig, and it contains the following entries:

CONFIG_UIO=y

CONFIG_UIO_PDRV_GENIRQ=m

 

The “y” setting for CONFIG_UIO was evidently due to other dependencies in the provided configuration.

However, when I boot the board up, I cannot see /dev/uio0 or run the modprobe command as specified in the description at the link provided:

root@imx8mm-var-dart:~# ls /dev/u*

/dev/ubi_ctrl  /dev/udev_network_queue  /dev/uhid  /dev/uinput  /dev/urandom

root@imx8mm-var-dart:~# modprobe uio_pdrv_genirq of_id="mydevice,generic-uio,ui_pdrv"

modprobe: FATAL: Module uio_pdrv_genirq not found in directory /lib/modules/4.19.35-imx8mm+ge6d3e3fefe4e

I used grep to look for “uio” in the /lib/modules directory, and only found the following:

root@imx8mm-var-dart:/lib/modules/4.19.35-imx8mm+ge6d3e3fefe4e# grep -RnI uio .

./modules.builtin:270:kernel/drivers/uio/uio.ko

I am stumped, and think I must have something wrong in my .dts file, my .config file, or in the packages/libraries added to the Yocto image.  Do you have any suggestions for how to diagnose/fix this problem. My .dts file and .config file is attached.

Thanks for your help.  UIO apparently is a "preferred" way to handle writing simple device drivers from user space.  Do I need to add something to Yocto to enable UIO and UIO_PDRV_GENIRQ?

Best regards,

Scott

0 Kudos
3 Replies

1,244 Views
superyyf
Contributor II
Hi, I'm doing the same work on S32G, trying to communicate to a linux slave with spi. May I ask you that is the uio method feasible? I will be very grateful if I can get your answer.
0 Kudos

2,962 Views
jamesbone
NXP TechSupport
NXP TechSupport

Hello,

You can see if the Interrupt it is already set, by  using CAT like this :

cat /proc/interrupts

              CPU0       CPU1      CPU2       CPU3      

16:        2313         1658       2361         878        GIC      29  twd

17:           0               0            0               0          GIC      87  i.MX Timer Tick

18:          35              0            0               0          GIC      45  mxs-dma

19:           5               0            0               0          GIC      47  bch

22:           2               0            0               0          GIC      65  2010000.ecspi

23:           0               0            0               0          GIC      79  202c000.ssi

38:           0               0            0               0      gpio-mxc   6  2198000.usdhc cd

75:          69              0            0               0      gpio-mxc   9  da9063-irq

147:          6               0            0               0      gpio-mxc  13  PS_irq_handler

150:        193             0            0               0      gpio-mxc  16  CLK_irq_handler

0 Kudos

2,962 Views
surrealist14
Contributor III

Thanks for your reply.  My gpio1_0 line does not seem to appear in cat /proc/interrupts:

root@imx8mm-var-dart:~# cat /proc/interrupts
CPU0 CPU1 CPU2 CPU3
3: 6583 6523 6361 6633 GICv3 30 Level arch_timer
6: 40 81 99 39 GICv3 79 Level iMX system counter timer
7: 0 0 0 0 GICv3 23 Level arm-pmu
8: 0 0 0 0 GICv3 106 Level ddrc
9: 0 0 0 0 GICv3 107 Level ddrc
10: 0 0 0 0 GICv3 108 Level ddrc
11: 0 0 0 0 GICv3 109 Level ddrc
12: 0 0 0 0 GICv3 130 Edge ddr_perf
13: 0 0 0 0 GICv3 48 Level csi
14: 0 0 0 0 GICv3 49 Level 32e30000.mipi_csi
25: 0 0 0 0 GICv3 36 Level 30370000.snvs:snvs-powerkey
28: 563 0 0 0 GICv3 58 Level 30860000.serial
29: 0 0 0 0 GICv3 60 Level 30880000.serial
30: 0 0 0 0 GICv3 59 Level 30890000.serial
31: 541 0 0 0 GICv3 67 Level 30a20000.i2c
32: 148 0 0 0 GICv3 68 Level 30a30000.i2c
33: 62 0 0 0 GICv3 69 Level 30a40000.i2c
34: 0 0 0 0 GICv3 70 Level 30a50000.i2c
35: 5 0 0 0 GICv3 61 Level 30a60000.serial
37: 0 0 0 0 GICv3 72 Level 32e40000.usb
38: 79 0 0 0 GICv3 73 Level 32e50000.usb
39: 11021 0 0 0 GICv3 54 Level mmc0
40: 4439 0 0 0 GICv3 55 Level mmc1
41: 536 0 0 0 GICv3 56 Level mmc2
42: 0 0 0 0 GICv3 82 Level sai
43: 768 0 0 0 GICv3 34 Level sdma
44: 0 0 0 0 GICv3 135 Level sdma
45: 0 0 0 0 GICv3 66 Level sdma
46: 0 0 0 0 GICv3 110 Level 30280000.wdog
47: 0 0 0 0 GICv3 63 Level 30820000.ecspi
48: 1 0 0 0 GICv3 150 Level 30be0000.ethernet
49: 0 0 0 0 GICv3 151 Level 30be0000.ethernet
50: 196 0 0 0 GICv3 152 Level 30be0000.ethernet
51: 839 0 0 0 GICv3 37 Level imx-lcdif-crtc.0
52: 1 0 0 0 GICv3 50 Level 32e10000.mipi_dsi
56: 0 0 0 0 GICv3 62 Level hx280enc
57: 0 0 0 0 GICv3 39 Level hantrodec
58: 0 0 0 0 GICv3 40 Level hantrodec
59: 127 0 0 0 GICv3 35 Level galcore:0
60: 66 0 0 0 GICv3 57 Level galcore:2d
62: 0 0 0 0 GICv3 52 Level caam-snvs
78: 0 0 0 0 gpio-mxc 14 Edge edt-ft5x06
79: 0 0 0 0 gpio-mxc 15 Edge ds1337
104: 0 0 0 0 gpio-mxc 8 Edge bd718xx-irq
108: 0 0 0 0 gpio-mxc 12 Edge 30b50000.mmc cd
166: 0 0 0 0 gpio-mxc 6 Edge Back
173: 0 0 0 0 gpio-mxc 13 Edge Home
175: 0 0 0 0 gpio-mxc 15 Edge Down
178: 0 0 0 0 gpio-mxc 18 Edge Up
224: 0 0 0 0 bd718xx-irq 5 Edge gpio_keys
225: 2 0 0 0 GICv3 137 Level 30901000.jr0
226: 4 0 0 0 GICv3 138 Level 30902000.jr1
227: 0 0 0 0 GICv3 146 Level 30903000.jr2
IPI0: 1470 13013 2654 2594 Rescheduling interrupts
IPI1: 74 165 163 164 Function call interrupts
IPI2: 0 0 0 0 CPU stop interrupts
IPI3: 0 0 0 0 CPU stop (for crash dump) interrupts
IPI4: 3 14 28 27 Timer broadcast interrupts
IPI5: 1040 276 307 383 IRQ work interrupts
IPI6: 0 0 0 0 CPU wake-up interrupts
Err: 0
root@imx8mm-var-dart:~#

The first link you provided brought me to  a generic page on makelinux.net.  Perhaps it was incorrect?

The second link brought me to a general description of Linux interrupt handlers, but I'm trying to use UIO so that I can handle a GPIO interrupt from user space, not write a Linux kernel module.

Can you provide any help regarding enabling UIO and the UIO interrupt handling?

Many thanks!

Scott

0 Kudos