Spidev1.0 and spidev2.0 initialisations are swapped on some device starts

Verdin iMX8MP 2GB WB IT V1.1A
Image: torizon-core-docker-verdin-imx8mp-Tezi_6.6.1+build.12
Custom carrier board;

For our project we have two differen SPI busses, which are accessed via SPIDEV driver.
Most of the time everything works as expected, expect with some minor (most likely unrelated) errors.
But sometimes the hardware-pins associated with /dev/spidev1.0 and /dev/spidev2.0 are swapped. Which means after a restart, its possible that /dev/spidev1.0 is associated with ecspi2 and /dev/spidev2.0 is associated with ecspi1.
Restarting the device, fixes this problem. spidev1.0 - ecspi1, spidev2.0 - ecspi2.

Is there a way to make sure spidev1.0 is allways assicated with ecspi1, and the same for spidev2.0?
Or is this a part of the startup process that can’t be fixed?

DeviceTree for the SPIDEV:

Pin-Definitions:

/* Verdin SPI_1 */
&ecspi1 {
    #address-cells = <1>;
    #size-cells = <0>;
    cs-gpios = <&gpio5 9 GPIO_ACTIVE_LOW>;
    pinctrl-names = "default";
    pinctrl-0 = <&pinctrl_ecspi1>;
};

/* Verdin SPI_2 */
&ecspi2 {
    #address-cells = <1>;
    #size-cells = <0>;
    cs-gpios = <&gpio5 21 GPIO_ACTIVE_LOW>;
    pinctrl-names = "default";
    pinctrl-0 = <&pinctrl_ecspi2>;
};

pinctrl_ecspi1: ecspi1grp {
	fsl,pins =
		<MX8MP_IOMUXC_ECSPI1_MISO__ECSPI1_MISO		0x1c4>,	/* SODIMM 198 */
		<MX8MP_IOMUXC_ECSPI1_MOSI__ECSPI1_MOSI		0x4>,	/* SODIMM 200 */
		<MX8MP_IOMUXC_ECSPI1_SCLK__ECSPI1_SCLK		0x4>,	/* SODIMM 196 */
		<MX8MP_IOMUXC_ECSPI1_SS0__GPIO5_IO09		0x1c4>;	/* SODIMM 202 */
};

pinctrl_ecspi2: ecspi2grp {
	fsl,pins =
		<MX8MP_IOMUXC_I2C4_SCL__ECSPI2_MISO		    0x1c4>,	/* SODIMM 14 */
		<MX8MP_IOMUXC_I2C3_SDA__ECSPI2_MOSI		    0x4>,	/* SODIMM 93 */
		<MX8MP_IOMUXC_I2C3_SCL__ECSPI2_SCLK		    0x4>,	/* SODIMM 95 */
		<MX8MP_IOMUXC_I2C4_SDA__GPIO5_IO21		    0x1c4>;	/* SODIMM 12 */
};

Activation of the spidev-driver:

/* Verdin SPI_1 */
&ecspi1 {
	#address-cells = <1>;
	#size-cells = <0>;
	status = "okay";

	spidev@0 {
		/* Use compatible "rohm,dh2228fv" to bind spidev driver */
		compatible = "rohm,dh2228fv";
		reg = <0>;
		spi-max-frequency = <10000000>;
	};
};

/* Verdin SPI_2 */
&ecspi2 {
	#address-cells = <1>;
	#size-cells = <0>;
	status = "okay";

	spidev@0 {
		/* Use compatible "rohm,dh2228fv" to bind spidev driver */
		compatible = "rohm,dh2228fv";
		reg = <0>;
		spi-max-frequency = <10000000>;
	};
};

gpioinfo output in case of swapped SPIs:

gpiochip4 - 32 lines:
        line   0:  "SODIMM_42"       unused   input  active-high 
        line   1:  "SODIMM_46"       unused   input  active-high 
        line   2: "SODIMM_187"       unused   input  active-high 
        line   3:  "SODIMM_20"       unused   input  active-high 
        line   4:  "SODIMM_22"       unused   input  active-high 
        line   5:  "SODIMM_15"       "KEY0"   input  active-high [used]
        line   6: "SODIMM_196"       unused   input  active-high 
        line   7: "SODIMM_200"       unused   input  active-high 
        line   8: "SODIMM_198"       unused   input  active-high 
        line   9: "SODIMM_202"   "spi2 CS0"  output   active-low [used]
        line  10:      unnamed       unused   input  active-high 
        line  11:      unnamed       unused   input  active-high 
        line  12:      unnamed       unused   input  active-high 
        line  13:      unnamed       unused   input  active-high 
        line  14:      unnamed        "scl"  output  active-high [used open-drain]
        line  15:      unnamed        "sda"   input  active-high [used open-drain]
        line  16:  "SODIMM_55"       "KEY4"   input  active-high [used]
        line  17:  "SODIMM_53"       "KEY3"   input  active-high [used]
        line  18:  "SODIMM_95"       unused   input  active-high 
        line  19:  "SODIMM_93"       unused   input  active-high 
        line  20:  "SODIMM_14"       unused  output  active-high 
        line  21:  "SODIMM_12"   "spi1 CS0"  output   active-low [used]
        line  22: "SODIMM_129"       unused   input  active-high 
        line  23: "SODIMM_131"       unused   input  active-high 
        line  24: "SODIMM_137"       unused   input  active-high 
        line  25: "SODIMM_139"       unused   input  active-high 
        line  26: "SODIMM_147"       unused   input  active-high 
        line  27: "SODIMM_149"       unused   input  active-high 
        line  28: "SODIMM_151"       unused   input  active-high 
        line  29: "SODIMM_153"       unused   input  active-high 
        line  30:      unnamed       unused   input  active-high 
        line  31:      unnamed       unused   input  active-high 

gpioinfo while the SPIs are initalised as expected:

gpiochip4 - 32 lines:
        line   0:  "SODIMM_42"       unused   input  active-high 
        line   1:  "SODIMM_46"       unused   input  active-high 
        line   2: "SODIMM_187"       unused   input  active-high 
        line   3:  "SODIMM_20"       unused   input  active-high 
        line   4:  "SODIMM_22"       unused   input  active-high 
        line   5:  "SODIMM_15"       unused   input  active-high 
        line   6: "SODIMM_196"       unused   input  active-high 
        line   7: "SODIMM_200"       unused   input  active-high 
        line   8: "SODIMM_198"       unused   input  active-high 
        line   9: "SODIMM_202"   "spi1 CS0"  output   active-low [used]
        line  10:      unnamed       unused   input  active-high 
        line  11:      unnamed       unused   input  active-high 
        line  12:      unnamed       unused   input  active-high 
        line  13:      unnamed       unused   input  active-high 
        line  14:      unnamed        "scl"  output  active-high [used open-drain]
        line  15:      unnamed        "sda"   input  active-high [used open-drain]
        line  16:  "SODIMM_55"       unused   input  active-high 
        line  17:  "SODIMM_53"       unused   input  active-high 
        line  18:  "SODIMM_95"       unused   input  active-high 
        line  19:  "SODIMM_93"       unused   input  active-high 
        line  20:  "SODIMM_14"       unused  output  active-high 
        line  21:  "SODIMM_12"   "spi2 CS0"  output   active-low [used]
        line  22: "SODIMM_129"       unused   input  active-high 
        line  23: "SODIMM_131"       unused   input  active-high 
        line  24: "SODIMM_137"       unused   input  active-high 
        line  25: "SODIMM_139"       unused   input  active-high 
        line  26: "SODIMM_147"       unused   input  active-high 
        line  27: "SODIMM_149"       unused   input  active-high 
        line  28: "SODIMM_151"       unused   input  active-high 
        line  29: "SODIMM_153"       unused   input  active-high 
        line  30:      unnamed       unused   input  active-high 
        line  31:      unnamed       unused   input  active-high

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:


To address the issue of SPI device assignments being swapped between /dev/spidev1.0 and /dev/spidev2.0 on your Verdin iMX8MP 2GB WB IT V1.1A, it’s essential to ensure deterministic SPI device naming across reboots. This swapping issue can occur due to the asynchronous nature of device initialization in the Linux kernel, which might not always guarantee the order in which SPI devices are enumerated and assigned their respective /dev/spidevX.Y device files.

One approach to mitigate this issue is to use udev rules to create symbolic links for the SPI devices based on attributes that uniquely identify each SPI bus, such as the kernel device path or properties specific to each SPI controller. This method allows for consistent device naming, independent of the order in which they are initialized.

Here’s a general outline of steps to create persistent symbolic links for your SPI devices:

  1. Identify Unique Attributes: Use udevadm info to identify unique attributes for each SPI bus. You might want to look for attributes like the kernel device path (DEVPATH), driver name, or physical location on the bus.

    udevadm info -a -p /sys/bus/spi/devices/spi1
    
  2. Create Udev Rule: Based on the unique attributes identified, create a udev rule file in /etc/udev/rules.d/, for example, 99-spi-devices.rules. In this file, you can write rules to match each SPI bus and create a symbolic link with a consistent name.

    Example udev rule:

    ACTION=="add", KERNEL=="spi1.0", ATTRS{some_attribute}=="value", SYMLINK+="myspidev1"
    ACTION=="add", KERNEL=="spi2.0", ATTRS{another_attribute}=="value", SYMLINK+="myspidev2"
    

    Replace ATTRS{some_attribute}=="value" with the actual attribute and value that uniquely identifies each SPI bus.

  3. Reload Udev Rules: After creating the rule, reload the udev rules and trigger them to apply the changes.

    sudo udevadm control --reload-rules
    sudo udevadm trigger
    
  4. Access SPI Devices by Symbolic Links: Instead of using /dev/spidev1.0 or /dev/spidev2.0, use

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

CAN (Linux) | Toradex Developer Center.

Hello @aigF,

I hope the answer from @ToradexAI solved your issue. As it suggested, this could be solved by simply setting a udev rule.

Hello,

yes the udev rules seem to have fixed the problem.
Best regards