[PATCH v3 2/8] board: ten64: add fdt fixup to hide usb hub topology
Mathew McBride
matt at traverse.com.au
Fri May 1 03:36:03 CEST 2026
The USB Hub (microchip,usb5744) can enter a dis-/reconnect loop
if a driver tries to re-initialise the hub over I2C.
On the Ten64 board, this process only needs to be run once
per system reset cycle, which is carried out by U-Boot.
As there are distributions shipping with the affected
driver by default, the best solution is to remove
the USB hub topology information from the FDT passed
to the operating system, so the OS won't attempt
to re-initialise the USB hub under any circumstance.
Signed-off-by: Mathew McBride <matt at traverse.com.au>
---
board/traverse/ten64/ten64.c | 57 ++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 57 insertions(+)
diff --git a/board/traverse/ten64/ten64.c b/board/traverse/ten64/ten64.c
index d41bd2e9dee..c5fbf4b4a04 100644
--- a/board/traverse/ten64/ten64.c
+++ b/board/traverse/ten64/ten64.c
@@ -186,6 +186,58 @@ void fdt_fixup_board_enet(void *fdt)
fdt_status_fail(fdt, offset);
}
+/* The onboard USB hub driver (microchip,usb5744)
+ * can cause a disconnect-reconnect loop if the operating system
+ * attempts to re-initialise the hub after U-Boot has already done it.
+ * (This process only needs to be done once per system RESET cycle)
+ *
+ * To avoid this condition, make the hub topology invisible
+ * to the operating system.
+ * It is also required to remove the hub on boards
+ * without it (RevD).
+ *
+ * The USB hub fixup may fail for legitimate reasons:
+ * 1. FDT has already been fixed. For example, the control
+ * FDT previously modified by board_fix_fdt is
+ * re-used for bootflow.
+ * 2. The FDT blob is based on an older version
+ * without the hub topology, such as older OpenWrt
+ * FIT images with their own device tree.
+ */
+int fdt_fixup_usb_hub(void *fdt)
+{
+ int usb1_hub2744_offset, usb1_hub5744_offset;
+ int i2c_usb5744_offset;
+ int err;
+
+ usb1_hub2744_offset = fdt_path_offset(fdt, "/soc/usb at 3110000/hub at 1");
+
+ if (usb1_hub2744_offset < 0)
+ return usb1_hub2744_offset;
+
+ err = fdt_del_node(fdt, usb1_hub2744_offset);
+ if (err)
+ return err;
+
+ usb1_hub5744_offset = fdt_path_offset(fdt, "/soc/usb at 3110000/hub at 2");
+ if (usb1_hub5744_offset < 0)
+ return usb1_hub5744_offset;
+
+ err = fdt_del_node(fdt, usb1_hub5744_offset);
+ if (err)
+ return err;
+
+ i2c_usb5744_offset = fdt_path_offset(fdt, "/soc/i2c at 2000000/usb-hub at 2d");
+ if (i2c_usb5744_offset < 0)
+ return i2c_usb5744_offset;
+
+ err = fdt_setprop_string(fdt, i2c_usb5744_offset, "status", "disabled");
+ if (err)
+ return err;
+
+ return 0;
+}
+
/* Called after SoC board_late_init in fsl-layerscape/soc.c */
int fsl_board_late_init(void)
{
@@ -251,6 +303,11 @@ int ft_board_setup(void *blob, struct bd_info *bd)
fdt_fixup_icid(blob);
+ /* This fixup may fail for legitimate
+ * reasons (see comments for fdt_fixup_usb_hub).
+ * Hence, errors with it are silently ignored.
+ */
+ fdt_fixup_usb_hub(blob);
return 0;
}
--
2.52.0
More information about the U-Boot
mailing list