Unable to configure GPIO from devicetree

Hello,

Because we need to use the LAN9303 eth switch we upgraded torizon from 5.7.6 to 6.7.0. We built a custom version with yocto because we needed to add another driver.

Using the custom 6.7.0 Yocto build i run torizoncore-builder with a custom device-tree, as i have done with 5.7.6. Here GPIO3_IO11 (SOM pin 196) from the “pinctrl_dap1_gpios” is used as an input with interrupt by the software in the operating system. It is one of 4 pins that need to be configured like this.
The issue is that this pin is not configured as it should be after flashing torizon to the SOM. The other 3 are correct.

I am configuring SOM pins
196 gpio3.io12
200 gpio3.io06
202 gpio3.io14
204 gpio3.io11
as input with interrupt low

running cat /sys/kernel/debug/gpio i get this

gpio-396 (MXM3_281            |sysfs               ) in  hi IRQ
gpio-390 (MXM3_87             |sysfs               ) in  hi IRQ
gpio-398 (MXM3_126            |sysfs               ) in  lo IRQ
gpio-395 (                    |PHY reset           ) out hi ACTIVE LOW

My issue is with gpio-395, it should be the same as the other ones.

I am not sure who is configuring this gpio. If i use the base dts(imx8qm-apalis-eval.dts) from which i started the modifications it still gets set up as PHY reset.

INFO:


Software summary
------------------------------------------------------------
Bootloader:               U-Boot
Kernel version:           5.15.148-6.7.0-devel+git.94979392529c #1-TorizonCore SMP PREEMPT Fri Apr 26 07:54:49 UTC 2024
Kernel command line:      root=LABEL=otaroot rootfstype=ext4 quiet logo.nologo vt.global_cursor_default=0 plymouth.ignore-serial-consoles splash fbcon=map:3 ostree=/ostree/boot.1/torizon/4a006e4ec68acad2789f78fb09a282f512c6ee6f55a7d1d9a1f4bb14fcef70c4/0
Distro name:              NAME="TorizonCore"
Distro version:           VERSION_ID=6.7.0-devel-20240523073626-build.0
Distro variant:           VARIANT="Docker"
Hostname:                 apalis-imx8-06875151
------------------------------------------------------------

Hardware info
------------------------------------------------------------
HW model:                 Toradex Apalis iMX8QM V1.1
Toradex version:          0037 V1.1C
Serial number:            06875151
Processor arch:           aarch64
------------------------------------------------------------

What can i do to find the one that is configuring the pin?

Hi, I’m the Toradex AI Assistant. I’m in early beta, and I would appreciate your feedback.
The Toradex Support team will follow up with you shortly!

Did you like my answer?

:+1: :-1:


Hello,

To address the issue of GPIO3_IO11 (SOM pin 196) not being configured as expected in your custom TorizonCore 6.7.0 build, you should follow a systematic approach to identify and correct the configuration. Given that the other pins are correctly configured, the focus should be on what differentiates the configuration of GPIO3_IO11 from the others.

  1. Review Device Tree Overlays: Start by closely examining the device tree overlay (DTO) you’ve created for your custom configuration. Ensure that the pin definition for GPIO3_IO11 is correctly specified, matching the configuration of the other GPIOs that are working as intended. The pin should be defined within a pin control group (pinctrl) in your device tree source (DTS) file, with the correct settings for input with an interrupt on a low level.

  2. Check for Conflicting Configurations: It’s possible that GPIO3_IO11 is being configured elsewhere in the device tree sources (DTS or DTSI files) or in another overlay that gets applied at boot time. Use grep or a similar tool to search through the device tree sources for any instance of GPIO3_IO11 or its corresponding pin name as defined in the SoC’s documentation to ensure there’s no conflicting configuration.

  3. Verify Pin Muxing: Ensure that the pin muxing for GPIO3_IO11 is set correctly to function as a GPIO. The pin might be multiplexed for a different function by default, and you need to explicitly configure it as a GPIO in your device tree overlay.

  4. Inspect U-Boot Configuration: Since the bootloader (U-Boot) can also configure pins, verify that U-Boot is not setting up GPIO3_IO11 in a way that conflicts with your desired configuration. Look into the U-Boot environment variables and the board-specific U-Boot configuration files for any pin setup related to GPIO3_IO11.

  5. Runtime Configuration Check: After booting, check the pin configuration at runtime using the Linux sysfs interface or tools like devmem2 to directly read the hardware registers related to pin configuration. This can help confirm if the pin is being set up as expected after boot and might help identify when the configuration changes if it does.

  6. Kernel Log Analysis: Review the kernel boot log (dmesg) for any messages related to GPIO or pin configuration that might indicate why GPIO3_IO11 is being configured differently. Look for any errors or warnings that might suggest

Please, also check if these links can help you solve your problem:

Pinmuxing i.MX 8M Mini/Plus Based Modules | Toradex Developer Center.

Still no solution.

I also have problems with other pins dunning under 6.7.0 that work fine under 5.7.6.

What changes are made in the gpio driver here?

Greetings @c.gantner,

I think I know what happened here.

Let’s focus on just pin 204/gpio3.io11. Here you believe that this pin corresponds to gpio-395 in the kernel. This is true back in the kernel used in our 5.X versions:

 gpio-393 (MXM3_229            )
 gpio-394 (MXM3_233            |fsl_lpspi           ) in  lo
 gpio-395 (MXM3_204            )
 gpio-396 (MXM3_196            )

Notice here that gpio-395 has the label MXM3_204. These labels come from the device tree. Now in our 6.X OS version notice how gpio-395 no longer as the same label:

gpio-395 (                    |PHY reset           ) out hi ACTIVE LOW

But if you look at the output of cat /sys/kernel/debug/gpio in 6.X you’ll notice the label of MXM3_204 is instead here:

 gpio-329 (MXM3_229            )
 gpio-330 (MXM3_233            |spi1 CS0            ) out hi ACTIVE LOW
 gpio-331 (MXM3_204            )
 gpio-332 (MXM3_196            )

In the new kernel it seems the numbering has shifted for all the pins and pin 204 is now instead gpio-331. It is due to this numbering change that you’re seeing issues since now the GPIO numbers you used in 5.X are not the same as 6.X. Therefore, you’re confusing which pin you’re manipulating now.

As a side-note the sysfs interface for GPIO has long since been deprecated: https://www.kernel.org/doc/Documentation/gpio/sysfs.txt

Cause of this changes and instabilities like what you witnessed here with the numbering changing can happen. This is why typically we advise to not use sysfs for GPIO manipulation these days. Instead we recommend libgpiod: How to Use GPIO on Torizon OS | Toradex Developer Center

This method does not rely on these kernel gpio numberings and instead rely on the actual gpio enumerations (gpio3.11 for example). Making them more consistent across kernel versions.

Best Regards,
Jeremias

Thank you for the explanation. GPIOs can now be configured and used as expected in docker.

The last problem that appeared when we switched to 6.7.0 is that our configured and functional gpio-poweroff node is not working anymore.

The pin should be pulled low on shut down to stop the dcdc converter. on 5.7.6 it works but on 6.7.0 it remains at 2V and above the 0.6V threshold.

Do you have any idea about this?

Thanks.

The last problem that appeared when we switched to 6.7.0 is that our configured and functional gpio-poweroff node is not working anymore.

I think I know what this issue is. The way the gpio-poweroff driver works has slightly changed in our 6.X BSP. In the device tree node there is now a priority field that is needed: linux-toradex.git - Linux kernel for Apalis, Colibri and Verdin modules

So for example your your device tree node sohuld look something like this:

gpio_poweroff: gpio-poweroff {
            compatible = "gpio-poweroff";
            gpios = <&lsio_gpio4 4 GPIO_ACTIVE_LOW>;
            active-delay-ms = <100>;
            inactive-delay-ms = <100>;
            timeout-ms = <100>;
            status = "okay";
            priority = <100>;
        };

The only thing new here is the priority field as a I said. Everything else existed back in 5.X.

Best Regards,
Jeremias

1 Like

It worked with the new field.

Thank you.

Perfect glad that was the issue.