I am upgrading from Toradex BSP 5.6.0 to 6.5.0 and the behaviour of the sc16is7xx
module is now different (and maybe broken). It appears as though the driver is in an infinite loop of querying for the interrupt status of the SPI attached device. There are 4 processes running which sum to almost 100% of one core
- irq/143-spi1.0 (first device IRQ)
- irq/149-spi1.1 (second device IRQ)
- spi1 (the driver)
- irq/40-3083000 (SPI1’s IRQ)
I think this is consistent with the idea that the IRQ is never being cleared. The SPI transactions look good and well formed, and the devices always return no IRQ outstanding. However, the next sets of transactions are a repeat of the previous interrupt query.
To verify my hardware is fine, I went back to BSP5.6 and everything works fine.
When looking at the output of /proc/interrupts
, the two IRQ lines are now Level triggered, instead of Edge triggered. Looking through the changes to the driver since then, this does make sense. However, how does the interrupt configuration get used then? I have tried all 4 different variants of high/low and edge/level, and there is no change in behaviour.
The current device tree used int he BPS6.5 version is as follows:
Device tree, both devices in IRQ loops
/dts-v1/;
#include "imx8mm-verdin.dtsi"
#include "imx8mm-verdin-wifi.dtsi"
#include "imx8mm-verdin-dahlia.dtsi"
#include "imx8mm-pinfunc.h"
#include <dt-bindings/gpio/gpio.h>
#include <dt-bindings/interrupt-controller/arm-gic.h>
/ {
compatible = "toradex,verdin-imx8mm-wifi-dahlia",
"toradex,verdin-imx8mm-wifi",
"toradex,verdin-imx8mm",
"fsl,imx8mm";
/* fixed clock dedicated to the first DUART controller */
clk25m0: clk25m0 {
compatible = "fixed-clock";
#clock-cells = <0>;
clock-frequency = <25000000>;
};
/* fixed clock dedicated to the second DUART controller */
clk25m1: clk25m1 {
compatible = "fixed-clock";
#clock-cells = <0>;
clock-frequency = <25000000>;
};
};
&flexspi {
status = "disabled";
};
&pinctrl_gpio3 {
/delete-property/ fsl,pins;
};
&iomuxc {
pinctrl_duart1_irq: duart1irqgrp {
fsl,pins =
<MX8MM_IOMUXC_NAND_DATA02_QSPI_A_DATA2 0x146>; /* SODIMM 60 */
};
pinctrl_duart2_irq: duart2irqgrp {
fsl,pins =
<MX8MM_IOMUXC_NAND_DQS_QSPI_A_DQS 0x106>; /* SODIMM 66 */
};
pinctrl_duart2_cs: duart2csgrp {
fsl,pins =
<MX8MM_IOMUXC_UART3_RXD_GPIO5_IO26 0x6>; /* SODIMM 210 */
};
};
/* Verdin SPI_1 */
&ecspi2 {
pinctrl-0 = <&pinctrl_ecspi2>, <&pinctrl_duart2_cs>;
cs-gpios = <&gpio5 13 GPIO_ACTIVE_LOW>,
<&gpio5 26 GPIO_ACTIVE_LOW>;
fsl,spi-num-chipselects = <2>;
status = "okay";
spidev0: spidev@0
{
status = "disabled";
};
duart1: sc16is752@0 {
compatible = "nxp,sc16is752";
spi-max-frequency = <400000>;
reg = <0>;
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_duart1_irq>;
clocks = <&clk25m0>;
interrupt-parent = <&gpio3>;
interrupts = <8 IRQ_TYPE_EDGE_FALLING>;
status = "okay";
};
duart2: sc16is752@1 {
compatible = "nxp,sc16is752";
spi-max-frequency = <400000>;
reg = <1>;
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_duart2_irq>;
clocks = <&clk25m1>;
interrupt-parent = <&gpio3>;
interrupts = <14 IRQ_TYPE_EDGE_RISING>; /* Yes, this line is inverted. */
status = "okay";
};
};
If I then remove the pinctrl
entries within each of the two duart entries, then only the second device seems to be in an IRQ loop. (I had originally put in the pinctrl
entries when migrating to BSP6.5 as this is what the Mallow device tree used for its TPM device on the SPI bus.) Seeing how the first device worked, and the second didn’t, I tried swapping some things around and it seems like it does not matter which IRQ level type I use, it will always be used by the driver to be IRQ_TYPE_LEVEL_LOW
. This is different from BSP5.6 version of the sc16is7xx driver where the interrupts
property seems to be used.
I was able to get a partially functional system by deleting the second duart with the inverted IRQ line. My final device tree that partially works looks like this:
Device tree, only one device, no IRQ loop
/dts-v1/;
#include "imx8mm-verdin.dtsi"
#include "imx8mm-verdin-wifi.dtsi"
#include "imx8mm-verdin-dahlia.dtsi"
#include "imx8mm-pinfunc.h"
#include <dt-bindings/gpio/gpio.h>
#include <dt-bindings/interrupt-controller/arm-gic.h>
/ {
compatible = "toradex,verdin-imx8mm-wifi-dahlia",
"toradex,verdin-imx8mm-wifi",
"toradex,verdin-imx8mm",
"fsl,imx8mm";
/* fixed clock dedicated to the first DUART controller */
clk25m0: clk25m0 {
compatible = "fixed-clock";
#clock-cells = <0>;
clock-frequency = <25000000>;
};
/* fixed clock dedicated to the second DUART controller */
clk25m1: clk25m1 {
compatible = "fixed-clock";
#clock-cells = <0>;
clock-frequency = <25000000>;
};
};
&flexspi {
status = "disabled";
};
&pinctrl_gpio3 {
/delete-property/ fsl,pins;
};
&iomuxc {
pinctrl_duart1_irq: duart1irqgrp {
fsl,pins =
<MX8MM_IOMUXC_NAND_DATA02_QSPI_A_DATA2 0x146>; /* SODIMM 60 - active low IRQ line, now unreferenced*/
};
pinctrl_duart2_irq: duart2irqgrp {
fsl,pins =
<MX8MM_IOMUXC_NAND_DQS_QSPI_A_DQS 0x106>; /* SODIMM 66 - active high IRQ line, now unreferenced*/
};
pinctrl_duart2_cs: duart2csgrp {
fsl,pins =
<MX8MM_IOMUXC_UART3_RXD_GPIO5_IO26 0x6>; /* SODIMM 210 */
};
};
/* Verdin SPI_1 */
&ecspi2 {
pinctrl-0 = <&pinctrl_ecspi2>, <&pinctrl_duart2_cs>;
cs-gpios = <&gpio5 13 GPIO_ACTIVE_LOW>,
<&gpio5 26 GPIO_ACTIVE_LOW>;
fsl,spi-num-chipselects = <2>;
status = "okay";
spidev0: spidev@0
{
status = "disabled";
};
duart1: sc16is752@0 {
compatible = "nxp,sc16is752";
spi-max-frequency = <4000000>;
reg = <0>;
clocks = <&clk25m0>;
interrupt-parent = <&gpio3>;
interrupts = <8 IRQ_TYPE_EDGE_FALLING>;
status = "okay";
};
};
What I’m not sure about is if my conclusions are correct
- Does the sc16is7xx driver only support
IRQ_TYPE_LEVEL_LOW
? It seems like from the driver source that this would be the case. - Where is the proper location to specify
pinctrl-0 = <&pinctrl_duart1_irq>;
? - why do I need to disable
spidev@0
? This is a change in needed to make to mydts
file between the two BSP versions and I have no idea which device tree file it comes from, or if it even comes from a device tree anywhere.
If it helps, here’s my tdx-info from the device running BSP6.5.0:
tdx-info
Software summary
------------------------------------------------------------
Bootloader: U-Boot
Kernel version: 5.15.129-rt67-6.5.0-devel+git.6f8fd49366db #1 SMP PREEMPT_RT Fri Dec 22 11:15:52 UTC 2023
Kernel command line: root=PARTUUID=a17d4c3c-02 ro rootwait console=tty1 console=ttymxc0,115200 consoleblank=0 earlycon
Distro name: NAME="TDX Wayland with XWayland RT"
Distro version: VERSION_ID=6.5.0-devel-20240209163348-build.0
Distro variant: -
Hostname: verdin-imx8mm-06902104
------------------------------------------------------------
Hardware info
------------------------------------------------------------
HW model: custom
Toradex version: 0055 V1.1B
Serial number: 06902104
Processor arch: aarch64
------------------------------------------------------------