MCP2515 with Orin Nano: problems with interrupts?

Hi,

I am trying to connect an MCP2515 using SPI1 on the 40-pin hdr of dev kit, using L4T 36.4.3.

Here’s my pinmux config:

#include <dt-bindings/pinctrl/pinctrl-tegra.h>

#include "./devsense-gpio-default.dtsi"

/ {
    bus@0 {
	pinmux@2430000 {
		pinctrl-names = "default", "drive", "unused";
		pinctrl-0 = <&pinmux_default>;
		pinctrl-1 = <&drive_default>;
		//pinctrl-2 = <&pinmux_unused_lowpower>;

		pinmux_default: common {

			soc_gpio33_pq6 {
				nvidia,pins = "soc_gpio33_pq6";
				nvidia,function = "rsvd0";
				nvidia,pull = <TEGRA_PIN_PULL_UP>;
				nvidia,tristate = <TEGRA_PIN_DISABLE>;
				nvidia,enable-input = <TEGRA_PIN_ENABLE>;
				nvidia,io-high-voltage = <TEGRA_PIN_DISABLE>;
				nvidia,lpdr = <TEGRA_PIN_DISABLE>;
			};

			spi1_sck_pz3 {
				nvidia,pins = "spi1_sck_pz3";
				nvidia,function = "spi1";
				nvidia,pull = <TEGRA_PIN_PULL_NONE>;
				nvidia,tristate = <TEGRA_PIN_DISABLE>;
				nvidia,enable-input = <TEGRA_PIN_DISABLE>;
				nvidia,io-high-voltage = <TEGRA_PIN_DISABLE>;
				nvidia,lpdr = <TEGRA_PIN_DISABLE>;
			};

			spi1_miso_pz4 {
				nvidia,pins = "spi1_miso_pz4";
				nvidia,function = "spi1";
				nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
				nvidia,tristate = <TEGRA_PIN_ENABLE>;
				nvidia,enable-input = <TEGRA_PIN_ENABLE>;
				nvidia,io-high-voltage = <TEGRA_PIN_DISABLE>;
				nvidia,lpdr = <TEGRA_PIN_DISABLE>;
			};

			spi1_mosi_pz5 {
				nvidia,pins = "spi1_mosi_pz5";
				nvidia,function = "spi1";
				nvidia,pull = <TEGRA_PIN_PULL_NONE>;
				nvidia,tristate = <TEGRA_PIN_DISABLE>;
				nvidia,enable-input = <TEGRA_PIN_DISABLE>;
				nvidia,io-high-voltage = <TEGRA_PIN_DISABLE>;
				nvidia,lpdr = <TEGRA_PIN_DISABLE>;
			};

			spi1_cs0_pz6 {
				nvidia,pins = "spi1_cs0_pz6";
				nvidia,function = "spi1";
				nvidia,pull = <TEGRA_PIN_PULL_NONE>;
				nvidia,tristate = <TEGRA_PIN_DISABLE>;
				nvidia,enable-input = <TEGRA_PIN_DISABLE>;
				nvidia,io-high-voltage = <TEGRA_PIN_DISABLE>;
				nvidia,lpdr = <TEGRA_PIN_DISABLE>;
			};

			spi1_cs1_pz7 {
				nvidia,pins = "spi1_cs1_pz7";
				nvidia,function = "spi1";
				nvidia,pull = <TEGRA_PIN_PULL_NONE>;
				nvidia,tristate = <TEGRA_PIN_DISABLE>;
				nvidia,enable-input = <TEGRA_PIN_DISABLE>;
				nvidia,io-high-voltage = <TEGRA_PIN_DISABLE>;
				nvidia,lpdr = <TEGRA_PIN_DISABLE>;
			};

		};

		drive_default: drive {
                };
	};
    };
};

Here’s my SPI config:

/dts-v1/;

#include "tegra234-p3768-0000+p3767-0005-nv.dts"

#include "./devsense-pinmux.dtsi"
#include "../include/kernel/dt-bindings/interrupt-controller/irq.h"
#include <dt-bindings/pinctrl/pinctrl-tegra.h>
#include <dt-bindings/tegra234-p3767-0000-common.h>
/ {
    compatible = "nvidia,p3768-0000+p3767-0005-super", "nvidia,p3767-0005", "nvidia,tegra234";
    model = "NVIDIA Jetson Orin Nano Developer Kit with MCP2515";

    clocks {
	can_clock: can_clock {
	       compatible = "fixed-clock";
               #clock-cells = <0>;
	       clock-frequency = <16000000>;
	       clock-accuracy = <100>;
	   };
    };
    bus@0 {
	spi@3210000 {
	    spi@0 {
		status = "disabled";
	    };
	    can@0 {
		status = "okay";
		compatible = "microchip,mcp2515";
		reg = <0x0>;
		spi-max-frequency = <2000000>;
		clocks = <&can_clock>;
		interrupt-parent = <&gpio>;
		interrupts = <TEGRA234_MAIN_GPIO(Q, 6) IRQ_TYPE_LEVEL_LOW>;
		//interrupts = <TEGRA234_MAIN_GPIO(Q, 6) IRQ_TYPE_EDGE_FALLING>;
		nvidia,enable-hw-based-cs;
		gpio-controller;
		#gpio-cells = <2>;
		controller-data {
		    nvidia,enable-hw-based-cs;
		    nvidia,rx-clk-tap-delay = <0x10>;
		    nvidia,tx-clk-tap-delay = <0x0>;
		    nvidia,cs-setup-clk-count = <0x1e>;
		    nvidia,cs-hold-clk-count = <0x1e>;
		};
	    };

	};

    };
};

I am facing the following issue: when using IRQ_TYPE_LEVEL_LOW above:

  • the command ip link set can1 up hangs. Strace
  • I see no kernel message in console/dmesg
  • I can’t kill the ip command with ctrl-C or kill -9
  • with the link up command hanging, I can do grep "gpio 106" /proc/interrupts:
237:          1          0          0          0          0          0  2200000.gpio 106 Level     spi0.0

it shows that the interrupt has been called.

  • gpioinfo 0 | grep 106 returns: line 106: "PQ.06" "interrupt" input active-high [used]

When I try to strace the ip link up command above, I get:

...
bind(3, {sa_family=AF_NETLINK, nl_pid=0, nl_groups=00000000}, 12) = 0
getsockname(3, {sa_family=AF_NETLINK, nl_pid=2319, nl_groups=00000000}, [12]) = 0
setsockopt(3, SOL_NETLINK, NETLINK_GET_STRICT_CHK, [1], 4) = 0
sendto(3, [{nlmsg_len=32, nlmsg_type=0x10 /* NLMSG_??? */, nlmsg_flags=NLM_F_REQUEST|NLM_F_ACK, nlmsg_seq=0, nlmsg_pid=0}, "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"], 32, 0, NULL, 0) = 32
recvmsg(3, {msg_name={sa_family=AF_NETLINK, nl_pid=0, nl_groups=00000000}, msg_namelen=12, msg_iov=[{iov_base=[{nlmsg_len=52, nlmsg_type=NLMSG_ERROR, nlmsg_flags=0, nlmsg_seq=0, nlmsg_pid=2319}, {error=-ENODEV, msg=[{nlmsg_len=32, nlmsg_type=0x10 /* NLMSG_??? */, nlmsg_flags=NLM_F_REQUEST|NLM_F_ACK, nlmsg_seq=0, nlmsg_pid=0}, "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"]}], iov_len=16384}], msg_iovlen=1, msg_controllen=0, msg_flags=0}, 0) = 52
socket(AF_NETLINK, SOCK_RAW|SOCK_CLOEXEC, NETLINK_ROUTE) = 4
setsockopt(4, SOL_SOCKET, SO_SNDBUF, [32768], 4) = 0
setsockopt(4, SOL_SOCKET, SO_RCVBUF, [1048576], 4) = 0
setsockopt(4, SOL_NETLINK, NETLINK_EXT_ACK, [1], 4) = 0
bind(4, {sa_family=AF_NETLINK, nl_pid=0, nl_groups=00000000}, 12) = 0
getsockname(4, {sa_family=AF_NETLINK, nl_pid=-46257228, nl_groups=00000000}, [12]) = 0
sendmsg(4, {msg_name={sa_family=AF_NETLINK, nl_pid=0, nl_groups=00000000}, msg_namelen=12, msg_iov=[{iov_base=[{nlmsg_len=52, nlmsg_type=0x12 /* NLMSG_??? */, nlmsg_flags=NLM_F_REQUEST, nlmsg_seq=1742293406, nlmsg_pid=0}, "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x08\x00\x1d\x00\x09\x00\x00\x00\x0c\x00\x03\x00\x63\x61\x6e\x2d"...], iov_len=52}], msg_iovlen=1, msg_controllen=0, msg_flags=0}, 0) = 52
recvmsg(4, {msg_name={sa_family=AF_NETLINK, nl_pid=0, nl_groups=00000000}, msg_namelen=12, msg_iov=[{iov_base=NULL, iov_len=0}], msg_iovlen=1, msg_controllen=0, msg_flags=MSG_TRUNC}, MSG_PEEK|MSG_TRUNC) = 880
getrandom("\x2c\xb0\xf7\x87\x5c\xea\xf7\xbe", 8, GRND_NONBLOCK) = 8
brk(NULL)                               = 0xaaaaf4db3000
brk(0xaaaaf4dd4000)                     = 0xaaaaf4dd4000
recvmsg(4, {msg_name={sa_family=AF_NETLINK, nl_pid=0, nl_groups=00000000}, msg_namelen=12, msg_iov=[{iov_base=[{nlmsg_len=880, nlmsg_type=0x10 /* NLMSG_??? */, nlmsg_flags=0, nlmsg_seq=1742293406, nlmsg_pid=-46257228}, "\x00\x00\x18\x01\x04\x00\x00\x00\x80\x00\x04\x00\x00\x00\x00\x00\x0c\x00\x03\x00\x63\x61\x6e\x2d\x6d\x63\x70\x00\x08\x00\x0d\x00"...], iov_len=32768}], msg_iovlen=1, msg_controllen=0, msg_flags=0}, 0) = 880
close(4)                                = 0
sendmsg(3, {msg_name={sa_family=AF_NETLINK, nl_pid=0, nl_groups=00000000}, msg_namelen=12, msg_iov=[{iov_base=[{nlmsg_len=32, nlmsg_type=0x10 /* NLMSG_??? */, nlmsg_flags=NLM_F_REQUEST|NLM_F_ACK, nlmsg_seq=1742293406, nlmsg_pid=0}, "\x00\x00\x00\x00\x04\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00"], iov_len=32}], msg_iovlen=1, msg_controllen=0, msg_flags=0}, 0

so sendmsg is not returning. Maybe because of an interrupt problem?

When using IRQ_TYPE_EDGE_FALLING:

  • the interface comes up with ip link set can1 up
  • but I can’t send or receive packet. Presumably the driver is not receiving interrupts.
  • gpioinfo 0 | grep 106 returns: line 106: "PQ.06" "interrupt" input active-high [used] , but maybe it should be active_low?
  • grep "gpio 106" /proc/interrupts show that interrupt is not happening:
269:          0          0          0          0          0          0  2200000.gpio 106 Edge      spi0.0
  • gpioget 0 106 says 0: the mcp2515 chip did set the interrupt line to 0, which should trigger the interrupt. But it does not.

This problem seems very similar to this post: MCP2515 - Interrupts Disabled
. Also, I did read
MCP2515 verification.

Is there anything wrong in my configuration? What can I do to diagnose the hanging of ip link up ?

Thank you.

Hi julien.pilet,

How about your gpio dtsi(devsense-gpio-default.dtsi)?
Have you removed the GPIO usage for those SPI pins?

Please remove these lines in device tree.

Could you connect and configure the exact same as this example which has been verified working with MCP2515 on Orin Nano?

Thank you for your help.

How about your gpio dtsi(devsense-gpio-default.dtsi)?

Here’s the file:

#include <dt-bindings/gpio/tegra234-gpio.h>


/ {
	gpio@2200000 {
		gpio-init-names = "default";
		gpio-init-0 = <&gpio_main_default>;

		gpio_main_default: default {
			gpio-input = <
				TEGRA234_MAIN_GPIO(B, 0)
				TEGRA234_MAIN_GPIO(Y, 0)
				TEGRA234_MAIN_GPIO(Y, 1)
				TEGRA234_MAIN_GPIO(Y, 2)
				TEGRA234_MAIN_GPIO(Y, 3)
				TEGRA234_MAIN_GPIO(Y, 4)
				TEGRA234_MAIN_GPIO(Z, 1)
				TEGRA234_MAIN_GPIO(P, 6)
				TEGRA234_MAIN_GPIO(Q, 5)
				TEGRA234_MAIN_GPIO(Q, 6)
				TEGRA234_MAIN_GPIO(R, 4)
				TEGRA234_MAIN_GPIO(R, 5)
				TEGRA234_MAIN_GPIO(N, 1)
				TEGRA234_MAIN_GPIO(G, 0)
				TEGRA234_MAIN_GPIO(G, 6)
				TEGRA234_MAIN_GPIO(G, 7)
				TEGRA234_MAIN_GPIO(H, 0)
				TEGRA234_MAIN_GPIO(H, 7)
				TEGRA234_MAIN_GPIO(I, 0)
				TEGRA234_MAIN_GPIO(I, 1)
				TEGRA234_MAIN_GPIO(I, 2)
				TEGRA234_MAIN_GPIO(AC, 6)
				TEGRA234_MAIN_GPIO(L, 2)
				>;
			gpio-output-low = <
				TEGRA234_MAIN_GPIO(H, 6)
				TEGRA234_MAIN_GPIO(I, 5)
				TEGRA234_MAIN_GPIO(AC, 0)
				TEGRA234_MAIN_GPIO(K, 4)
				TEGRA234_MAIN_GPIO(K, 5)
				>;
			gpio-output-high = <
				TEGRA234_MAIN_GPIO(Q, 3)
				TEGRA234_MAIN_GPIO(A, 0)
				>;
		};
	};
	gpio@c2f0000 {
		gpio-init-names = "default";
		gpio-init-0 = <&gpio_aon_default>;

		gpio_aon_default: default {
			gpio-input = <
				TEGRA234_AON_GPIO(EE, 2)
				TEGRA234_AON_GPIO(EE, 4)
				>;
			gpio-output-low = <
				TEGRA234_AON_GPIO(CC, 0)
				TEGRA234_AON_GPIO(CC, 2)
				TEGRA234_AON_GPIO(CC, 3)
				TEGRA234_AON_GPIO(AA, 4)
				>;
			gpio-output-high = <
				TEGRA234_AON_GPIO(CC, 1)
				TEGRA234_AON_GPIO(AA, 5)
				TEGRA234_AON_GPIO(BB, 3)
				>;
		};
	};
	gpio@9250000 {
		gpio-init-names = "default";
		gpio-init-0 = <&gpio_fsi_default>;

		gpio_fsi_default: default {
			gpio-input = <
				>;
			gpio-output-low = <
				>;
			gpio-output-high = <
				>;
		};
	};
};

It has been generated by the excel spreadsheet.

Please remove these lines in device tree.

I replaced that with:

            /delete-node/ spi@0;
            /delete-node/ spi@1;

this way, the “tegra-spidev” definitions of tegra234-p3768-0000+p3767-xxxx-nv-common.dtsi are removed.
After that, I get only can@0 and prod-settings as subfolder of /sys/firmware/devicetree/base/bus@0/spi@3210000.

Could you connect and configure the exact same as this example which has been verified working with MCP2515 on Orin Nano?

According to the document, this has been verified on Orin NX, not Orin Nano.
My assembly is a bit different, since I only have 1 MCP2515. It is connected to the Nano mttcan port.
Here’s a simplified schema.
The MCP2515 is connected the same way as in the verification document, except that the interrupt line goes to pin 33 (which is used by the 2nd mcp2515 in the verification).

Note that the spi bus seems to be working, since dmesg tells me:

[   11.464849] mcp251x spi0.0: CANCTRL 0x87
[   11.465559] mcp251x spi0.0 can0: MCP2515 successfully initialized.

Orin NX and Orin Nano should have similar design and setup to use MCP2515.

Which pin you used as interrupt for MCP2515?
PQ.06 (PIN31 of 40-pins header)!?

I’ve checked this. Why do you need MCP2551(CAN transceiver) for MCP2515?
I remember that CAN transceiver is included for MCP2515.
(i.e. MCP2515 module would transform SPI interface to CAN-H/CAN-L).

It seems CAN from MCP2515 module is enumerated as can0 rather than can1.
How do you setup this CAN interface?

Which pin you used as interrupt for MCP2515?
PQ.06 (PIN31 of 40-pins header)!?

Correct, PIN 31.

Why do you need MCP2551(CAN transceiver) for MCP2515?

The MCP2515 CAN controller chip requires an external CAN transceiver to function properly. The MCP2515 itself is only a controller that handles the data link layer protocol of CAN communication, but it cannot directly connect to the physical CAN bus. To create a complete CAN node, it is necessary to pair the MCP2515 with a CAN transceiver chip.

It seems CAN from MCP2515 module is enumerated as can0 rather than can1

Actually, it is random and it changes at each boot. mcp251x and mttcan initialize in parallel, and the one finishing first is not deterministic. So I created files in /etc/udev/rules.d so that they get renamed to can-mcp and can-mtt.
This way, dmesg tells me:

mttcan c310000.mttcan can-mtt: renamed from can0
mcp251x spi0.0 can-mcp: renamed from can0

and I get deterministic interface names. I did not include this in my original post to keep it focused.

Note that we used a scope to check the electric signal when can-mtt is sending data. We see the bits when they pass on the bus.

How do you setup this CAN interface?

Here’s my init script

#!/bin/bash
set -e

ip link set can-mtt type can bitrate 250000
ip link set can-mtt txqueuelen 1000 
while ! ip link set can-mtt up; do sleep 1; done

ip link set can-mcp type can bitrate 250000 triple-sampling on restart-ms 100
ip link set can-mcp txqueuelen 1000 
while ! ip link set can-mcp up; do sleep 1; done

With IRQ_TYPE_EDGE_FALLING in the device tree, the script completes properly.
With IRQ_TYPE_LEVEL_LOW, the command ip link set can-mcp up never returns.
Once this ip command is hanging, it is interesting to note that I can’t sudo -s anymore. If I try, it hangs also, never returning. So something goes wrong in the kernel. Looks like a dead lock. The only way to recover is to reboot.

Do you mean that it works as expected if you configure it as IRQ_TYPE_EDGE_FALLING ?
Do you have any requirement to configure it as IRQ_TYPE_LEVEL_LOW?
Could you also measure the state of your interrupt(PIN31 of 40-pins header) to see if it keeps at low and causes hang issue?

Please also share the full dmesg for further check.

Do you mean that it works as expected if you configure it as IRQ_TYPE_EDGE_FALLING ?

As mentioned in my original post, with IRQ_TYPE_EDGE_FALLING, the ip link up command succeeds, but after, I can’t receive any packet on the interface. I can send 1 message, the next ones won’t get send.
I think there’s an interrupt issue when using IRQ_TYPE_EDGE_FALLING.

Do you have any requirement to configure it as IRQ_TYPE_LEVEL_LOW?

not really, but since this is what worked in MCP2515 verification, I assume it is the correct way to go.
But maybe there’s a way to make it work with IRQ_TYPE_EDGE_FALLING. I do not know.

Could you also measure the state of your interrupt(PIN31 of 40-pins header) to see if it keeps at low and causes hang issue?

Here’s an experiment with configuration IRQ_TYPE_LEVEL_LOW.
Right after boot, before trying to bring the can interface up:

$ gpioinfo 0 | grep 106
        line 106:      "PQ.06"       unused   input  active-high
$ gpioget 0 106
1

So after boot, the interrupt line is not active.
The I configure the interface:

# ip link set can-mcp type can bitrate 250000 triple-sampling on restart-ms 100
# ip link set can-mcp up

this last command never returns.
In another terminal, I do:

# gpioget 0 106
1

so the interrupt line is not active.
Let’s send a packet through the other interface:

$ cansend  can-mtt 09F80101#7D0BAA1838854D01

The command hangs. In another terminal:

# gpioget 0 106
1

So it seems that something is blocking in the kernel before cansend can send the packet.
Here’s the full dmesg at this stage.

Now let’s try the same experiment with IRQ_TYPE_EDGE_FALLING.

$ ip link set can-mtt type can bitrate 250000
$ ip link set can-mtt up
$ ip link set can-mcp type can bitrate 250000 triple-sampling on restart-ms 100
$ ip link set can-mcp up

Both interfaces come up. dmesg says:

[  242.605172] mttcan c310000.mttcan can-mtt: Bitrate set
[  247.303707] mttcan_controller_config: ctrlmode 0
[  247.303758] mttcan c310000.mttcan can-mtt: Bitrate set
[  247.303989] IPv6: ADDRCONF(NETDEV_CHANGE): can-mtt: link becomes ready
[  261.208418] mcp251x spi0.0: CNF: 0x01 0xf5 0x01
[  261.209222] IPv6: ADDRCONF(NETDEV_CHANGE): can-mcp: link becomes ready

All good.

$ gpioget 0 106
1

No interrupt yet. Let’s send a packet.

$ cansend  can-mtt 09F80101#7D0BAA1838854D01
$ gpioget 0 106
0

Now the interrupt line is active. It remains active. Let’s reset the mcp2515 chip:

$ ip link set can-mcp down
$ ip link set can-mcp up
$ gpioget 0 106
1

interrupt line is inactive.
I can send a single packet with:

# cansend can-mcp 09F80101#7D0BAA1838854D01

And it is received on the other side:

$ candump can-mtt
  can-mtt  09F80101   [8]  7D 0B AA 18 38 85 4D 01

However, the interrupt line stay at 0, so sending another packet does not work:

$ gpioget 0 106
0
$ cansend can-mcp 09F80101#7D0BAA1838854D02

this time candump can-mtt does not show anything. Here’s the full dmesg at this stage.

Could you also measure the state of your interrupt(PIN31 of 40-pins header) to see if it keeps at low and causes hang issue?
As I explained above, I used gpioget 0 106 to read this line. It is consistent with what we observe using a scope.

Please also share the full dmesg for further check.
Sure, here you go: edge falling config and level low config.

There’s no error in the both dmesg you shared.

It seems your board is still alive since you can run command in another terminal.
Could you add some debug logs in mttcan driver to clarify the exact line it gets hang?

Is your issue about interrupt staying 0 which causing the 2nd packet can not be sent?
If so, have you tried to reload mcp driver to check if it could recover?

$ sudo rmmod mcp251x
$ sudo modprobe mcp251x

Could you add some debug logs in mttcan driver to clarify the exact line it gets hang?

Instead, I re-compiled a kernel with function_graph tracer.

Is your issue about interrupt staying 0 which causing the 2nd packet can not be sent?
If so, have you tried to reload mcp driver to check if it could recover?

I can recover with:

ifconfig can-mcp down
ifconfig can-mcp up

No need to rmmod/modprobe.
Then I can again send 1 packet. This is in EDGE_FALLING mode. I tried with IRQ_TYPE_EDGE_BOTH, but even then, it seems the driver receives the IRQ only when the gpio line goes from 0 to 1.

I think the problem is there:

$ grep PQ.06 /sys/kernel/debug/gpio
gpio-454 (PQ.06               )
$ grep LOW /sys/kernel/debug/gpio 
 gpio-343 (PEE.04              |Power               ) in  hi IRQ ACTIVE LOW
 gpio-383 (PG.00               |Force Recovery      ) in  hi IRQ ACTIVE LOW
 gpio-390 (PG.07               |cd                  ) in  lo IRQ ACTIVE LOW

something is wrong when configuring the gpio IRQ, because PQ.06 should end with IRQ ACTIVE LOW, but it does not.

So for some reason, both IRQ_TYPE_EDGE_FALLING and IRQ_TYPE_EDGE_BOTH trigger the interrupt when the line is raising instead of falling.

When using IRQ_TYPE_LEVEL_LOW, tracing the mcp251x driver gives, when bringing up the interface:

1)               |  mcp251x_open [mcp251x]() {
 ------------------------------------------
 1)    ip-2468     =>  irq/236-2469 
 ------------------------------------------

 1)               |  mcp251x_can_ist [mcp251x]() {
 1)               |  /* received interrupt from mcp2515 */
 ------------------------------------------
 0)  gsd-pow-2135  =>    ip-2468    
 ------------------------------------------

 0)               |    mcp251x_hw_wake [mcp251x]() {

so it seams the driver deadlocks itself or something… because none of mcp251x_open, mcp251x_can_ist or mcp251x_hw_wake return.
I added a trace_printk in mcp251x_can_ist right after getting the lock, and this message is not printed.
It means the interrupt handler waits for the lock.

I’ll continue investigating, but if you could help me setup the interrupt line so that it triggers at falling edge, that would be great.

I have found something new.

If I replace mutex_lock with mutex_trylock in the interrupt handler in mcp251x.c like this:

        trace_printk("received interrupt from mcp2515");
        if (mutex_trylock(&priv->mcp_lock) == 0) {
                trace_printk("mcp2515: interrupt mutex busy, skipping");
                return IRQ_NONE;
        }

I can send and receive messages with IRQ_TYPE_LEVEL_LOW, but the interrupt handler keeps being called, even when there’s nothing to do. With my workaround, I get a loadavg of 3.1 when doing nothing. Not great.
This will drain our batteries, so I have to fix it, possibly by making the system work with IRQ_TYPE_EDGE_FALLING.

From your current investigation in mcp251x driver, it seems there’s the bug.
Have you also checked with your vendor for driver issue?

Could you also try using PQ.05 instead(since we’ve verified it working on the devkit with IRQ_TYPE_LEVEL_LOW)?

From your current investigation in mcp251x driver, it seems there’s the bug.

The bug is in the interrupt line setup, which, I think, is covered by the tegra234-gpio driver.
Isn’t it that one that uses the IRQ_TYPE_EDGE_FALLING constant to configure the hardware?

Could you also try using PQ.05 instead(since we’ve verified it working on the devkit with IRQ_TYPE_LEVEL_LOW)?

I can try that, but since PQ.05 is handled by the same gpio driver, I would be surprised if I get another result. I’ll try it soon.

I did try using PQ.05. With this GPIO, it works both with IRQ_TYPE_LEVEL_LOW and IRQ_TYPE_EDGE_FALLING.

No idea why PQ.05 and PQ.06 behave differently. Well, problem solved for now. Thank you.

OK, I understand now.

If I remove soc_gpio33_pq6 block from pinmux_default: common {, it works with PQ.06.
So something was wrong there.

1 Like

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.