Which system do you use? Android, Ubuntu, OOWOW or others?
Android 11, self-built
Please describe your issue below:
On the VIM4 there are two USB ports, one USB2.0 and one USB3.0.
We are currently evaluating a device that has issues with USB3.0 (SuperSpeed) and would like to turn the USB3.0 port into a regular USB2.0.
We have tried to edit the device-tree but without success.
How would we go about turning off the USB3.0 SuperSpeed functionality for that specific port?
We found a solution to disable USB3 while keeping USB2 function:
Disable the USB3 phy (crg_phy_20) in the Device Tree
Add the following patch to the AMLogic USB drivers
Verify that the USB3 device is enumerated as an USB2 device (check bus index and Spd value, e.g. 480 vs 5000) cat /sys/kernel/debug/usb/devices
diff --git a/drivers/amlogic/usb/crg/crg_drd.c b/drivers/amlogic/usb/crg/crg_drd.c
index 62da05be4a3d..132c6d387cf2 100644
--- a/drivers/amlogic/usb/crg/crg_drd.c
+++ b/drivers/amlogic/usb/crg/crg_drd.c
@@ -123,8 +123,10 @@ static int crg_core_resume(struct crg_drd *crg)
if (ret)
return ret;
- usb_phy_set_suspend(crg->usb2_phy, 0);
- usb_phy_set_suspend(crg->usb3_phy, 0);
+ if (crg->usb2_phy)
+ usb_phy_set_suspend(crg->usb2_phy, 0);
+ if (crg->usb3_phy)
+ usb_phy_set_suspend(crg->usb3_phy, 0);
switch (crg->dr_mode) {
case USB_DR_MODE_PERIPHERAL:
@@ -151,8 +153,12 @@ static int crg_core_get_phy(struct crg_drd *crg)
crg->super_speed_support = 0;
crg->usb2_phy = devm_usb_get_phy_by_phandle(dev, "usb-phy", 0);
+ if (IS_ERR(crg->usb2_phy))
+ crg->usb2_phy = NULL;
crg->usb3_phy = devm_usb_get_phy_by_phandle(dev, "usb-phy", 1);
+ if (IS_ERR(crg->usb3_phy))
+ crg->usb3_phy = NULL;
if (crg->usb3_phy)
if (crg->usb3_phy->flags == AML_USB3_PHY_ENABLE)
Explanation:
The USB3 phy (crg_phy_20) is disabled in the Device Tree
This results in Linux kernel panic due to null pointer dereference at pc : crg_probe+0x160/0x7cc x0 = 0xffffffffffffffed
This is -19 in signed decimal, which corresponds to -ENODEV (No such device) in Linux error codes.
drivers/amlogic/usb/crg/crg_drd.c:crg_probe() calls crg_core_get_phy(), which executes crg->usb3_phy = devm_usb_get_phy_by_phandle(dev, "usb-phy", 1);
devm_usb_get_phy_by_phandle returns ERR_PTR(-ENODEV) when no matching Device Tree node is found, but the code in drivers/amlogic/usb/crg/crg_drd.c assumes NULL is returned when no device is found. So the code will incorrectly dereference the error pointer.