Delay for /sys/class/gpio/gpioX/direction becoming available to write to

I am using a C program to set up my GPIO.

I am finding that a 20ms delay is necessary between writing the GPIO pin number to /sys/class/gpio/export and writing “out” to /sys/class/gpio/gpioX/direction.

The strange thing is, although /sys/class/gpio/gpioX/direction appears immediately after writing to /sys/class/gpio/export, it is not actually accessible until 20ms later.

Is Nvidia aware of this problem? It’s not nice to hard code delays into programs…

hello jetsonnvidia,

may I know which JetPack release version you’re working with.
also, please share how you monitor GPIO status to get 20ms delay results, had you also probe the signaling to narrow down the issue.
thanks

Jetpack 4.4.

This is what I do (in C):

// echo $gpioNumStr > /sys/class/gpio/export
char gpioNumStr[] = "216";
WriteSysfs("/sys/class/gpio/export", gpioNumStr);

// echo out > /sys/class/gpio/gpio$gpioNumStr/direction
char buf[64];
sprintf(buf, "/sys/class/gpio/gpio%s/direction", gpioNumStr);
usleep(20000);	// Test different values of this until it works.
WriteSysfs(buf, "out");

So I simply increased the delay until it worked. I used “access()” command to check that the file exists, although this is not in the code above.

hello jetsonnvidia,

there’s gpiochip_setup_dev to register GPIOs during kernel initialization stage.
you may search kernel messages about the details.
for example,

$ dmesg | grep "registered GPIOs"
[    0.558047] gpiochip_setup_dev: registered GPIOs 0 to 255 on device: gpiochip0 (tegra-gpio)
[    0.615717] gpiochip_setup_dev: registered GPIOs 504 to 511 on device: gpiochip1 (max77620-gpio)

instead of using hard-code delay.
you may enable APIs to access GPIO pin via device tree. static inline int of_get_named_gpio(struct device_node *np, const char *propname, int index){...}
please also check below as an example,

there’s IMX274 sensor driver to define GPIO as reset pin in the device tree.
$L4T_Sources/r32.4.2/Linux_for_Tegra/source/public/hardware/nvidia/platform/t18x/common/kernel-dts/t18x-common-platforms/tegra186-quill-camera-imx274-a00.dts

reset-gpios = <&tegra_main_gpio CAM0_RST_L GPIO_ACTIVE_HIGH>;

and…
there’s kernel driver to use the APIs to parse the pin, and have control from driver side.
$L4T_Sources/r32.4.2/Linux_for_Tegra/source/public/kernel/nvidia/drivers/media/i2c/imx274.c

static struct camera_common_pdata *imx274_parse_dt(struct tegracam_device *tc_dev)
{
...
        board_priv_pdata->reset_gpio = of_get_named_gpio(node, "reset-gpios", 0);

I have the Tegra kernel source and tegra_main_gpio is not mentioned anywhere. Are you sure about that? I do see this line:

reset-gpios = <0x56 0x97 0x0>;

Also, while it is interesting to know that GPIO pins can be set in the device tree, it is another step of complexity and I’d prefer to set things up in userspace. Thanks for your reply all the same.

hello jetsonnvidia,

please check device tree for node definitions, for example, t210 were define this pin as group of &gpio
$L4T_Sources/r32.4.2/Linux_for_Tegra/source/public/hardware/nvidia/platform/t210/jetson/kernel-dts/jetson-platforms/tegra210-jetson-cv-camera-imx274-a00.dtsi

reset-gpios = <&gpio CAM0_RST_L GPIO_ACTIVE_HIGH>;

you’ll found some default gpio definitions as following,
$L4T_Sources/r32.4.2/Linux_for_Tegra/source/public/hardware/nvidia/platform/t210/porg/kernel-dts/porg-platforms/tegra210-porg-gpio-p3448-0000-a02.dtsi

       gpio: gpio@6000d000 {...}

Okay, thanks.

All things considered, it looks like if I want to do this in userspace I will need the delay.