USB Gadget support on kernel > v5.0

Hi *,
recently (~2-3 month ago) there was a patch series on the kernel.org mailinglist [1] to enable XUSB Gadget support on the TX1. I tried this patch series with several upstream kernel versions (e.g. master, or v5.0-rc8), but I can’t get it to work. Can someone help me out, and tell me what might be the problem. I have the following status:
When I plug in a USB cable, I see messages like:

[   64.075634] tegra-xudc 700d0000.xudc: device mode off
[   64.080711] tegra-xudc 700d0000.xudc: entering ELPG
[   64.085620] tegra-xudc 700d0000.xudc: entering ELPG done
[   65.610804] tegra-xudc 700d0000.xudc: exiting ELPG
[   65.615946] tegra-xudc 700d0000.xudc: exiting ELPG done
[   65.621179] tegra-xudc 700d0000.xudc: device mode on

So it seems like the extcon VBUS part seems to work. The number of interrupts for the ‘extcon_vbus’ device seem to increment properly. On every plug-in of a cable the number of interrupts increments.

But the rest doesn’t seem to work. I verified that my kernel config is correct and has all the gadget related config options enabled. I cross checked with the v4.9 config, and enabled the same stuff. I also see that in ‘/sys/kernel/config/usb_gadget/’, there is already a configuration called l4t, which works fine with the v4.9 kernel (it contains the different configurations and modes, for e.g., serial, network and storage).

But I also noticed that the ‘700d0000.xudc’ device doesn’t trigger any interrupts, whereas on the v4.9 kernel when I plug-in the cable I see a lot of interrupts… so it seems there is an issue with the interrupt delivery?!

Thank you in advance!

[1] https://patchwork.kernel.org/cover/10847321/

Is this the dev carrier board? Is everything stock L4T other than the kernel?

FYI, drivers and device tree are more or less bound to each other. Technically they are independent, but drivers have certain key words they can use if seen in device tree for initial setup. If you change the driver, and if that key word is still used in the same way, then the device tree setup will work as advertised. When you go to a different kernel version this will break down if the key word list has changed. This is loosely a kind of an API version.

USB function might apply to more than one controller of the same exact design. Each controller would have a different base address, but register offsets and the rest of the controllers would more or less be clones of each other. Thus you could have a device tree which matches for two different controllers other than base address. In reality you would also have different lane routings because obviously you wouldn’t want two or more controllers going to the same port (unless they serve different modes and there is a way to switch intelligently between modes).

So your 5.0 kernel will fail if the drivers have changed such that they speak a different version of device tree key words. Or this would fail if your carrier board is modified since lane routings and other details would no longer match. You would need to provide a lot more detail on what has changed, which L4T release (see “head -n 1 /etc/nv_tegra_release”), and what modifications are made.

The content in “/opt” is for device mode to the micro-B USB connector. When a type-A micro-USB connector is inserted this is only a regular host. When a type-B micro-USB is inserted, then this code is an example and is how the gadget framework can be used to create either a virtual storage device or a virtual ethernet device. This works only in USB2 mode because the wiring for USB3 does not exist to that connector (I am assuming this is development carrier board).

Hi,
thank you for your response! It’s really appreciated! So I have a Jetson TX1 Developer Kit, so the carrier board is a P2597.

U-Boot spits out:

TEGRA210
Model: NVIDIA P2371-2180
Board: NVIDIA P2371-2180

Regarding the DTB file. I’m using the DTB file that comes with the Linux kernel version I’m using (arch/arm64/boot/dts/xxxx), so there shouldn’t be a conflict between the APIs. The DTB I’m using is called ‘tegra210-p2371-2180.dtb’, which includes the correct DTSI file for my carrier board (‘tegra210-p2597.dtsi’) Also the patch series I linked above contains a new entry to probe the XUDC controller. I see during bootup the device seems to be correctly probed. The drivers “probe” function is being called and not returning an error. So from this side everything seems ok to me.

Regarding your other comment, from the file system side I’m using the latest R28.

head -n 1 /etc/nv_tegra_release
# R28 (release), REVISION: 2.0, GCID: 10567845, BOARD: t210ref, EABI: aarch64, DATE: Fri Mar  2 04:58:16 UTC 2018

I have now checked the code in ‘/opt’. But it seems there is a service file along with the start script called ‘nv-l4t-usb-device-mode.service’, which already invokes the start script. I see in /sys/kernel/configfs/usb_gadget everything is already set up correctly. Except if I do ‘cat /sys/kernel/config/usb_gadget/l4t/UDC’, the file is empty. But it is supposed to be bound to the XUDC controller. So in my opinion it should print ‘700d0000.xudc’. At least according to [1] or [2].
Also when I try to activate the gadget, it only says resource busy…

sudo su
echo "700d0000.xudc" > UDC 
bash: echo: write error: Device or resource busy

Any ideas.

[1] https://www.kernel.org/doc/Documentation/ABI/testing/configfs-usb-gadget
[2] https://elinux.org/images/e/ef/USB_Gadget_Configfs_API_0.pdf

The 2371 says it is a TX1 module. The 2180 says it is the dev carrier board. Thus the combination. Useful to know because you may run into device tree content for just the module, or for the module when it is on that particular carrier board (the device tree changes depending on carrier board).

Do understand that some of the content which NVIDIA provides in the kernel source tree has relative paths to out of tree content (extra directories). I do not know if this upstream kernel relies on any of that (and if it doesn’t, then this might be part of the problem), and I don’t know if the actual content is even compatible with the TX1. Maybe…maybe not. So I can’t say it will work, but if it can work, then consider this…

When a controller won’t do something because device or resource is busy, then you have to remove whatever is using that controller (at least temporarily). An example is that you can’t umount a file system which is already in use until you kill any programs accessing the partition. I don’t know what is using USB for you, but your echo is in conflict with what the driver is already doing.

I couldn’t tell you what it is which is locking that controller. There could be a difference versus the NVIDIA driver provided with the TX1 and the 5.0 kernel which is upstream, or there could be some other software depending on the driver remaining in its current state. There is example gadget mode code for more recent L4T releases in “/opt/nvidia/l4t-usb-device-mode/”, and perhaps it is just a bad message and should have said “already in device mode”. I can only give vague ideas since the upstream kernel was never meant for the TX1.

What is the need driving the attempt to use the 5.0 kernel? Is there one driver or some feature you need? If so, then perhaps the better route would be to back port that one driver into the older kernel.

Hello linuxdev,
thank you for your help.

Yes exactly, I needed some specific functionality, and I thought applying these USB patches would be the smaller evil. ;-)

And in the mean time I also talked to the developer of the patch series, and he helped me to resolve the issue. By disabling the USB host support for now, the gadget support works. Not a great workaround, but he also said that there will be a new patch series soon, which resolves this issue. But for now I will stick with this…

But yes, still, thank you for the help!