This is an automated email from the ASF dual-hosted git repository.

xiaoxiang pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/nuttx.git

commit 0547aa5c6c639e2a5403ac0d54d96dc2ed0353d3
Author: Alan Carvalho de Assis <acas...@gmail.com>
AuthorDate: Sat Aug 30 17:47:08 2025 -0300

    arch/arm/imxrt: Modify USB EHCI driver to support two USBs
    
    Some iMXRT chips like iMXRT-1050 has two USB controllers, but until
    now only USB1 was supported. This patch modify the driver to support
    both USBs.
    
    Signed-off-by: Alan C. Assis <acas...@gmail.com>
---
 arch/arm/src/imxrt/hardware/imxrt_usbotg.h | 143 +++--
 arch/arm/src/imxrt/hardware/imxrt_usbphy.h | 106 ++--
 arch/arm/src/imxrt/imxrt_ehci.c            | 916 ++++++++++++++++++++---------
 arch/arm/src/imxrt/imxrt_ehci.h            |   2 +-
 arch/arm/src/imxrt/imxrt_usbdev.c          | 142 ++---
 5 files changed, 855 insertions(+), 454 deletions(-)

diff --git a/arch/arm/src/imxrt/hardware/imxrt_usbotg.h 
b/arch/arm/src/imxrt/hardware/imxrt_usbotg.h
index d65e94363c..34f4dcf856 100644
--- a/arch/arm/src/imxrt/hardware/imxrt_usbotg.h
+++ b/arch/arm/src/imxrt/hardware/imxrt_usbotg.h
@@ -121,82 +121,85 @@
 #define IMXRT_USBNC_USB_OTG1_CTRL_OFFSET        0x0800 /* OTG1 Control 
Register */
 #define IMXRT_USBNC_USB_OTG1_PHY_CTRL_0_OFFSET  0x0818 /* OTG1 Phy Control 
Register */
 
+#define IMXRT_USBNC_USB_OTG2_CTRL_OFFSET        0x0804 /* OTG1 Control 
Register */
+#define IMXRT_USBNC_USB_OTG2_PHY_CTRL_0_OFFSET  0x081c /* OTG1 Phy Control 
Register */
+
 /* USBOTG register (virtual) addresses **************************************/
 
 /* Device/host capability registers */
 
-#define IMXRT_USBOTG_HCCR_BASE             (IMXRT_USB_BASE + 
IMXRT_USBOTG_HCCR_OFFSET)
-#define IMXRT_USBOTG_CAPLENGTH             (IMXRT_USB_BASE + 
IMXRT_USBOTG_CAPLENGTH_OFFSET)
-#define IMXRT_USBHOST_HCIVERSION           (IMXRT_USB_BASE + 
IMXRT_USBHOST_HCIVERSION_OFFSET)
-#define IMXRT_USBHOST_HCSPARAMS            (IMXRT_USB_BASE + 
IMXRT_USBHOST_HCSPARAMS_OFFSET)
-#define IMXRT_USBHOST_HCCPARAMS            (IMXRT_USB_BASE + 
IMXRT_USBHOST_HCCPARAMS_OFFSET)
-#define IMXRT_USBDEV_DCIVERSION            (IMXRT_USB_BASE + 
IMXRT_USBDEV_DCIVERSION_OFFSET)
-#define IMXRT_USBDEV_DCCPARAMS             (IMXRT_USB_BASE + 
IMXRT_USBDEV_DCCPARAMS_OFFSET)
+#define IMXRT_USBOTG_HCCR_BASE(n)             (IMXRT_USB_BASE + (0x200 * (n)) 
+ IMXRT_USBOTG_HCCR_OFFSET)
+#define IMXRT_USBOTG_CAPLENGTH(n)             (IMXRT_USB_BASE + (0x200 * (n)) 
+ IMXRT_USBOTG_CAPLENGTH_OFFSET)
+#define IMXRT_USBHOST_HCIVERSION(n)           (IMXRT_USB_BASE + (0x200 * (n)) 
+ IMXRT_USBHOST_HCIVERSION_OFFSET)
+#define IMXRT_USBHOST_HCSPARAMS(n)            (IMXRT_USB_BASE + (0x200 * (n)) 
+ IMXRT_USBHOST_HCSPARAMS_OFFSET)
+#define IMXRT_USBHOST_HCCPARAMS(n)            (IMXRT_USB_BASE + (0x200 * (n)) 
+ IMXRT_USBHOST_HCCPARAMS_OFFSET)
+#define IMXRT_USBDEV_DCIVERSION(n)            (IMXRT_USB_BASE + (0x200 * (n)) 
+ IMXRT_USBDEV_DCIVERSION_OFFSET)
+#define IMXRT_USBDEV_DCCPARAMS(n)             (IMXRT_USB_BASE + (0x200 * (n)) 
+ IMXRT_USBDEV_DCCPARAMS_OFFSET)
 
 /* Device/host operational registers */
 
-#define IMXRT_USBOTG_HCOR_BASE             (IMXRT_USB_BASE + 
IMXRT_USBOTG_HCOR_OFFSET)
-#define IMXRT_USBOTG_USBCMD                (IMXRT_USB_BASE + 
IMXRT_USBOTG_USBCMD_OFFSET)
-#define IMXRT_USBOTG_USBSTS                (IMXRT_USB_BASE + 
IMXRT_USBOTG_USBSTS_OFFSET)
-#define IMXRT_USBOTG_USBINTR               (IMXRT_USB_BASE + 
IMXRT_USBOTG_USBINTR_OFFSET)
-#define IMXRT_USBOTG_FRINDEX               (IMXRT_USB_BASE + 
IMXRT_USBOTG_FRINDEX_OFFSET)
-#define IMXRT_USBOTG_PERIODICLIST          (IMXRT_USB_BASE + 
IMXRT_USBOTG_PERIODICLIST_OFFSET)
-#define IMXRT_USBOTG_DEVICEADDR            (IMXRT_USB_BASE + 
IMXRT_USBOTG_DEVICEADDR_OFFSET)
-#define IMXRT_USBOTG_ASYNCLISTADDR         (IMXRT_USB_BASE + 
IMXRT_USBOTG_ASYNCLISTADDR_OFFSET)
-#define IMXRT_USBOTG_ENDPOINTLIST          (IMXRT_USB_BASE + 
IMXRT_USBOTG_ENDPOINTLIST_OFFSET)
-#define IMXRT_USBOTG_TTCTRL                (IMXRT_USB_BASE + 
IMXRT_USBOTG_TTCTRL_OFFSET)
-#define IMXRT_USBOTG_BURSTSIZE             (IMXRT_USB_BASE + 
IMXRT_USBOTG_BURSTSIZE_OFFSET)
-#define IMXRT_USBOTG_TXFILLTUNING          (IMXRT_USB_BASE + 
IMXRT_USBOTG_TXFILLTUNING_OFFSET)
-#define IMXRT_USBOTG_BINTERVAL             (IMXRT_USB_BASE + 
IMXRT_USBOTG_BINTERVAL_OFFSET)
-#define IMXRT_USBOTG_ENDPTNAK              (IMXRT_USB_BASE + 
IMXRT_USBOTG_ENDPTNAK_OFFSET)
-#define IMXRT_USBOTG_ENDPTNAKEN            (IMXRT_USB_BASE + 
IMXRT_USBOTG_ENDPTNAKEN_OFFSET)
-#define IMXRT_USBOTG_PORTSC1               (IMXRT_USB_BASE + 
IMXRT_USBOTG_PORTSC1_OFFSET)
-#define IMXRT_USBOTG_OTGSC                 (IMXRT_USB_BASE + 
IMXRT_USBOTG_OTGSC_OFFSET)
-#define IMXRT_USBOTG_USBMODE               (IMXRT_USB_BASE + 
IMXRT_USBOTG_USBMODE_OFFSET)
-
-#define IMXRT_USBDEV_USBCMD                (IMXRT_USB_BASE + 
IMXRT_USBDEV_USBCMD_OFFSET)
-#define IMXRT_USBDEV_USBSTS                (IMXRT_USB_BASE + 
IMXRT_USBDEV_USBSTS_OFFSET)
-#define IMXRT_USBDEV_USBINTR               (IMXRT_USB_BASE + 
IMXRT_USBDEV_USBINTR_OFFSET)
-#define IMXRT_USBDEV_FRINDEX               (IMXRT_USB_BASE + 
IMXRT_USBDEV_FRINDEX_OFFSET)
-#define IMXRT_USBDEV_DEVICEADDR            (IMXRT_USB_BASE + 
IMXRT_USBDEV_DEVICEADDR_OFFSET)
-#define IMXRT_USBDEV_ENDPOINTLIST          (IMXRT_USB_BASE + 
IMXRT_USBDEV_ENDPOINTLIST_OFFSET)
-#define IMXRT_USBDEV_BURSTSIZE             (IMXRT_USB_BASE + 
IMXRT_USBDEV_BURSTSIZE_OFFSET)
-#define IMXRT_USBDEV_BINTERVAL             (IMXRT_USB_BASE + 
IMXRT_USBDEV_BINTERVAL_OFFSET)
-#define IMXRT_USBDEV_ENDPTNAK              (IMXRT_USB_BASE + 
IMXRT_USBDEV_ENDPTNAK_OFFSET)
-#define IMXRT_USBDEV_ENDPTNAKEN            (IMXRT_USB_BASE + 
IMXRT_USBDEV_ENDPTNAKEN_OFFSET)
-#define IMXRT_USBDEV_PORTSC1               (IMXRT_USB_BASE + 
IMXRT_USBDEV_PORTSC1_OFFSET)
-#define IMXRT_USBDEV_USBMODE               (IMXRT_USB_BASE + 
IMXRT_USBDEV_USBMODE_OFFSET)
-
-#define IMXRT_USBHOST_USBCMD               (IMXRT_USB_BASE + 
IMXRT_USBHOST_USBCMD_OFFSET)
-#define IMXRT_USBHOST_USBSTS               (IMXRT_USB_BASE + 
IMXRT_USBHOST_USBSTS_OFFSET)
-#define IMXRT_USBHOST_USBINTR              (IMXRT_USB_BASE + 
IMXRT_USBHOST_USBINTR_OFFSET)
-#define IMXRT_USBHOST_FRINDEX              (IMXRT_USB_BASE + 
IMXRT_USBHOST_FRINDEX_OFFSET)
-#define IMXRT_USBHOST_PERIODICLIST         (IMXRT_USB_BASE + 
IMXRT_USBHOST_PERIODICLIST_OFFSET)
-#define IMXRT_USBHOST_ASYNCLISTADDR        (IMXRT_USB_BASE + 
IMXRT_USBHOST_ASYNCLISTADDR_OFFSET)
-#define IMXRT_USBHOST_TTCTRL               (IMXRT_USB_BASE + 
IMXRT_USBHOST_TTCTRL_OFFSET)
-#define IMXRT_USBHOST_BURSTSIZE            (IMXRT_USB_BASE + 
IMXRT_USBHOST_BURSTSIZE_OFFSET)
-#define IMXRT_USBHOST_TXFILLTUNING         (IMXRT_USB_BASE + 
IMXRT_USBHOST_TXFILLTUNING_OFFSET)
-#define IMXRT_USBHOST_BINTERVAL            (IMXRT_USB_BASE + 
IMXRT_USBHOST_BINTERVAL_OFFSET)
-#define IMXRT_USBHOST_PORTSC1              (IMXRT_USB_BASE + 
IMXRT_USBHOST_PORTSC1_OFFSET)
-#define IMXRT_USBHOST_USBMODE              (IMXRT_USB_BASE + 
IMXRT_USBHOST_USBMODE_OFFSET)
+#define IMXRT_USBOTG_HCOR_BASE(n)             (IMXRT_USB_BASE + (0x200 * (n)) 
+ IMXRT_USBOTG_HCOR_OFFSET)
+#define IMXRT_USBOTG_USBCMD(n)                (IMXRT_USB_BASE + (0x200 * (n)) 
+ IMXRT_USBOTG_USBCMD_OFFSET)
+#define IMXRT_USBOTG_USBSTS(n)                (IMXRT_USB_BASE + (0x200 * (n)) 
+ IMXRT_USBOTG_USBSTS_OFFSET)
+#define IMXRT_USBOTG_USBINTR(n)               (IMXRT_USB_BASE + (0x200 * (n)) 
+ IMXRT_USBOTG_USBINTR_OFFSET)
+#define IMXRT_USBOTG_FRINDEX(n)               (IMXRT_USB_BASE + (0x200 * (n)) 
+ IMXRT_USBOTG_FRINDEX_OFFSET)
+#define IMXRT_USBOTG_PERIODICLIST(n)          (IMXRT_USB_BASE + (0x200 * (n)) 
+ IMXRT_USBOTG_PERIODICLIST_OFFSET)
+#define IMXRT_USBOTG_DEVICEADDR(n)            (IMXRT_USB_BASE + (0x200 * (n)) 
+ IMXRT_USBOTG_DEVICEADDR_OFFSET)
+#define IMXRT_USBOTG_ASYNCLISTADDR(n)         (IMXRT_USB_BASE + (0x200 * (n)) 
+ IMXRT_USBOTG_ASYNCLISTADDR_OFFSET)
+#define IMXRT_USBOTG_ENDPOINTLIST(n)          (IMXRT_USB_BASE + (0x200 * (n)) 
+ IMXRT_USBOTG_ENDPOINTLIST_OFFSET)
+#define IMXRT_USBOTG_TTCTRL(n)                (IMXRT_USB_BASE + (0x200 * (n)) 
+ IMXRT_USBOTG_TTCTRL_OFFSET)
+#define IMXRT_USBOTG_BURSTSIZE(n)             (IMXRT_USB_BASE + (0x200 * (n)) 
+ IMXRT_USBOTG_BURSTSIZE_OFFSET)
+#define IMXRT_USBOTG_TXFILLTUNING(n)          (IMXRT_USB_BASE + (0x200 * (n)) 
+ IMXRT_USBOTG_TXFILLTUNING_OFFSET)
+#define IMXRT_USBOTG_BINTERVAL(n)             (IMXRT_USB_BASE + (0x200 * (n)) 
+ IMXRT_USBOTG_BINTERVAL_OFFSET)
+#define IMXRT_USBOTG_ENDPTNAK(n)              (IMXRT_USB_BASE + (0x200 * (n)) 
+ IMXRT_USBOTG_ENDPTNAK_OFFSET)
+#define IMXRT_USBOTG_ENDPTNAKEN(n)            (IMXRT_USB_BASE + (0x200 * (n)) 
+ IMXRT_USBOTG_ENDPTNAKEN_OFFSET)
+#define IMXRT_USBOTG_PORTSC1(n)               (IMXRT_USB_BASE + (0x200 * (n)) 
+ IMXRT_USBOTG_PORTSC1_OFFSET)
+#define IMXRT_USBOTG_OTGSC(n)                 (IMXRT_USB_BASE + (0x200 * (n)) 
+ IMXRT_USBOTG_OTGSC_OFFSET)
+#define IMXRT_USBOTG_USBMODE(n)               (IMXRT_USB_BASE + (0x200 * (n)) 
+ IMXRT_USBOTG_USBMODE_OFFSET)
+
+#define IMXRT_USBDEV_USBCMD(n)                (IMXRT_USB_BASE + (0x200 * (n)) 
+ IMXRT_USBDEV_USBCMD_OFFSET)
+#define IMXRT_USBDEV_USBSTS(n)                (IMXRT_USB_BASE + (0x200 * (n)) 
+ IMXRT_USBDEV_USBSTS_OFFSET)
+#define IMXRT_USBDEV_USBINTR(n)               (IMXRT_USB_BASE + (0x200 * (n)) 
+ IMXRT_USBDEV_USBINTR_OFFSET)
+#define IMXRT_USBDEV_FRINDEX(n)               (IMXRT_USB_BASE + (0x200 * (n)) 
+ IMXRT_USBDEV_FRINDEX_OFFSET)
+#define IMXRT_USBDEV_DEVICEADDR(n)            (IMXRT_USB_BASE + (0x200 * (n)) 
+ IMXRT_USBDEV_DEVICEADDR_OFFSET)
+#define IMXRT_USBDEV_ENDPOINTLIST(n)          (IMXRT_USB_BASE + (0x200 * (n)) 
+ IMXRT_USBDEV_ENDPOINTLIST_OFFSET)
+#define IMXRT_USBDEV_BURSTSIZE(n)             (IMXRT_USB_BASE + (0x200 * (n)) 
+ IMXRT_USBDEV_BURSTSIZE_OFFSET)
+#define IMXRT_USBDEV_BINTERVAL(n)             (IMXRT_USB_BASE + (0x200 * (n)) 
+ IMXRT_USBDEV_BINTERVAL_OFFSET)
+#define IMXRT_USBDEV_ENDPTNAK(n)              (IMXRT_USB_BASE + (0x200 * (n)) 
+ IMXRT_USBDEV_ENDPTNAK_OFFSET)
+#define IMXRT_USBDEV_ENDPTNAKEN(n)            (IMXRT_USB_BASE + (0x200 * (n)) 
+ IMXRT_USBDEV_ENDPTNAKEN_OFFSET)
+#define IMXRT_USBDEV_PORTSC1(n)               (IMXRT_USB_BASE + (0x200 * (n)) 
+ IMXRT_USBDEV_PORTSC1_OFFSET)
+#define IMXRT_USBDEV_USBMODE(n)               (IMXRT_USB_BASE + (0x200 * (n)) 
+ IMXRT_USBDEV_USBMODE_OFFSET)
+
+#define IMXRT_USBHOST_USBCMD(n)               (IMXRT_USB_BASE + (0x200 * (n)) 
+ IMXRT_USBHOST_USBCMD_OFFSET)
+#define IMXRT_USBHOST_USBSTS(n)               (IMXRT_USB_BASE + (0x200 * (n)) 
+ IMXRT_USBHOST_USBSTS_OFFSET)
+#define IMXRT_USBHOST_USBINTR(n)              (IMXRT_USB_BASE + (0x200 * (n)) 
+ IMXRT_USBHOST_USBINTR_OFFSET)
+#define IMXRT_USBHOST_FRINDEX(n)              (IMXRT_USB_BASE + (0x200 * (n)) 
+ IMXRT_USBHOST_FRINDEX_OFFSET)
+#define IMXRT_USBHOST_PERIODICLIST(n)         (IMXRT_USB_BASE + (0x200 * (n)) 
+ IMXRT_USBHOST_PERIODICLIST_OFFSET)
+#define IMXRT_USBHOST_ASYNCLISTADDR(n)        (IMXRT_USB_BASE + (0x200 * (n)) 
+ IMXRT_USBHOST_ASYNCLISTADDR_OFFSET)
+#define IMXRT_USBHOST_TTCTRL(n)               (IMXRT_USB_BASE + (0x200 * (n)) 
+ IMXRT_USBHOST_TTCTRL_OFFSET)
+#define IMXRT_USBHOST_BURSTSIZE(n)            (IMXRT_USB_BASE + (0x200 * (n)) 
+ IMXRT_USBHOST_BURSTSIZE_OFFSET)
+#define IMXRT_USBHOST_TXFILLTUNING(n)         (IMXRT_USB_BASE + (0x200 * (n)) 
+ IMXRT_USBHOST_TXFILLTUNING_OFFSET)
+#define IMXRT_USBHOST_BINTERVAL(n)            (IMXRT_USB_BASE + (0x200 * (n)) 
+ IMXRT_USBHOST_BINTERVAL_OFFSET)
+#define IMXRT_USBHOST_PORTSC1(n)              (IMXRT_USB_BASE + (0x200 * (n)) 
+ IMXRT_USBHOST_PORTSC1_OFFSET)
+#define IMXRT_USBHOST_USBMODE(n)              (IMXRT_USB_BASE + (0x200 * (n)) 
+ IMXRT_USBHOST_USBMODE_OFFSET)
 
 /* Device endpoint registers */
 
-#define IMXRT_USBDEV_ENDPTSETUPSTAT        (IMXRT_USB_BASE + 
IMXRT_USBDEV_ENDPTSETUPSTAT_OFFSET)
-#define IMXRT_USBDEV_ENDPTPRIME            (IMXRT_USB_BASE + 
IMXRT_USBDEV_ENDPTPRIME_OFFSET)
-#define IMXRT_USBDEV_ENDPTFLUSH            (IMXRT_USB_BASE + 
IMXRT_USBDEV_ENDPTFLUSH_OFFSET)
-#define IMXRT_USBDEV_ENDPTSTATUS           (IMXRT_USB_BASE + 
IMXRT_USBDEV_ENDPTSTATUS_OFFSET)
-#define IMXRT_USBDEV_ENDPTCOMPLETE         (IMXRT_USB_BASE + 
IMXRT_USBDEV_ENDPTCOMPLETE_OFFSET)
+#define IMXRT_USBDEV_ENDPTSETUPSTAT(n)     (IMXRT_USB_BASE + (0x200 * (n)) + 
IMXRT_USBDEV_ENDPTSETUPSTAT_OFFSET)
+#define IMXRT_USBDEV_ENDPTPRIME(n)         (IMXRT_USB_BASE + (0x200 * (n)) + 
IMXRT_USBDEV_ENDPTPRIME_OFFSET)
+#define IMXRT_USBDEV_ENDPTFLUSH(n)         (IMXRT_USB_BASE + (0x200 * (n)) + 
IMXRT_USBDEV_ENDPTFLUSH_OFFSET)
+#define IMXRT_USBDEV_ENDPTSTATUS(n)        (IMXRT_USB_BASE + (0x200 * (n)) + 
IMXRT_USBDEV_ENDPTSTATUS_OFFSET)
+#define IMXRT_USBDEV_ENDPTCOMPLETE(n)      (IMXRT_USB_BASE + (0x200 * (n)) + 
IMXRT_USBDEV_ENDPTCOMPLETE_OFFSET)
 
 #define IMXRT_USBDEV_ENDPTCTRL(n)          (IMXRT_USB_BASE + 
IMXRT_USBDEV_ENDPTCTRL_OFFSET(n))
-#define IMXRT_USBDEV_ENDPTCTRL0            (IMXRT_USB_BASE + 
IMXRT_USBDEV_ENDPTCTRL0_OFFSET)
-#define IMXRT_USBDEV_ENDPTCTRL1            (IMXRT_USB_BASE + 
IMXRT_USBDEV_ENDPTCTRL1_OFFSET)
-#define IMXRT_USBDEV_ENDPTCTRL2            (IMXRT_USB_BASE + 
IMXRT_USBDEV_ENDPTCTRL2_OFFSET)
-#define IMXRT_USBDEV_ENDPTCTRL3            (IMXRT_USB_BASE + 
IMXRT_USBDEV_ENDPTCTRL3_OFFSET)
-#define IMXRT_USBDEV_ENDPTCTRL4            (IMXRT_USB_BASE + 
IMXRT_USBDEV_ENDPTCTRL4_OFFSET)
-#define IMXRT_USBDEV_ENDPTCTRL5            (IMXRT_USB_BASE + 
IMXRT_USBDEV_ENDPTCTRL5_OFFSET)
-#define IMXRT_USBDEV_ENDPTCTRL6            (IMXRT_USB_BASE + 
IMXRT_USBDEV_ENDPTCTRL6_OFFSET)
-#define IMXRT_USBDEV_ENDPTCTRL7            (IMXRT_USB_BASE + 
IMXRT_USBDEV_ENDPTCTRL7_OFFSET)
+#define IMXRT_USBDEV_ENDPTCTRL0(n)         (IMXRT_USB_BASE + (0x200 * (n)) + 
IMXRT_USBDEV_ENDPTCTRL0_OFFSET)
+#define IMXRT_USBDEV_ENDPTCTRL1(n)         (IMXRT_USB_BASE + (0x200 * (n)) + 
IMXRT_USBDEV_ENDPTCTRL1_OFFSET)
+#define IMXRT_USBDEV_ENDPTCTRL2(n)         (IMXRT_USB_BASE + (0x200 * (n)) + 
IMXRT_USBDEV_ENDPTCTRL2_OFFSET)
+#define IMXRT_USBDEV_ENDPTCTRL3(n)         (IMXRT_USB_BASE + (0x200 * (n)) + 
IMXRT_USBDEV_ENDPTCTRL3_OFFSET)
+#define IMXRT_USBDEV_ENDPTCTRL4(n)         (IMXRT_USB_BASE + (0x200 * (n)) + 
IMXRT_USBDEV_ENDPTCTRL4_OFFSET)
+#define IMXRT_USBDEV_ENDPTCTRL5(n)         (IMXRT_USB_BASE + (0x200 * (n)) + 
IMXRT_USBDEV_ENDPTCTRL5_OFFSET)
+#define IMXRT_USBDEV_ENDPTCTRL6(n)         (IMXRT_USB_BASE + (0x200 * (n)) + 
IMXRT_USBDEV_ENDPTCTRL6_OFFSET)
+#define IMXRT_USBDEV_ENDPTCTRL7(n)         (IMXRT_USB_BASE + (0x200 * (n)) + 
IMXRT_USBDEV_ENDPTCTRL7_OFFSET)
 
 /* Device non-core registers */
 
@@ -733,4 +736,16 @@
                                                        /* Bit 30: Reserved */
 #define USBNC_WIR                            (1 << 31) /* Bit 31: Wake up 
interrupt request */
 
+/* USB VBUS 3.0 Regulator */
+
+#define IMXRT_PMU_REG_3P0                    0x120
+
+#define PMU_REG_3P0_OUTPUT_TRG_SHIFT         (8)
+#define PMU_REG_3P0_OUTPUT_TRG_MASK          (0x1f << 
PMU_REG_3P0_OUTPUT_TRG_SHIFT)
+#define PMU_REG_3P0_OUTPUT_TRG(x)            (x << 
PMU_REG_3P0_OUTPUT_TRG_SHIFT)
+
+#define PMU_REG_3P0_ENABLE_LINREG            (1 << 0)
+
+#define IMXRT_USBVBUS_REG_3P0                (IMXRT_ANATOP_BASE + 
IMXRT_PMU_REG_3P0)
+
 #endif /* __ARCH_ARM_SRC_IMXRT_HARDWARE_IMXRT_USBOTG_H */
diff --git a/arch/arm/src/imxrt/hardware/imxrt_usbphy.h 
b/arch/arm/src/imxrt/hardware/imxrt_usbphy.h
index d2f1cb61d0..0e703a5ac8 100644
--- a/arch/arm/src/imxrt/hardware/imxrt_usbphy.h
+++ b/arch/arm/src/imxrt/hardware/imxrt_usbphy.h
@@ -34,30 +34,41 @@
  * Pre-processor Definitions
  ****************************************************************************/
 
-#define IMXRT_USBPHY_BASE                   (IMXRT_USBPHY1_BASE)  /* USB PHY 
Base */
+#define IMXRT_USBPHY_BASE_OFFSET            0x1000  /* USB1 PHY Base */
+
+/* Simple hack to get iMXRT117x working with same macro */
+
+#ifdef CONFIG_ARCH_FAMILY_IMXRT117x
+#  define IMXRT_ANATOP_BASE                 0x40433000 /* ANATOP doesn't exist 
on rt117x, it is used this way here only to make the code compatible */
+#  define IMXRT_USBPHY_SHIFT                0x4000
+#else
+#  define IMXRT_USBPHY_SHIFT                0x1000
+#endif
+
+#define IMXRT_USBPHY_BASE(n)                (IMXRT_ANATOP_BASE + 
IMXRT_USBPHY_BASE_OFFSET + (IMXRT_USBPHY_SHIFT * (n)))  /* USB PHY Base */
 
 /* Register Offsets *********************************************************/
 
-#define IMXRT_USBPHY1_PWD_OFFSET            0x0000  /* USBPHY1 USB PHY 
Power-Down Register */
-#define IMXRT_USBPHY1_PWD_CLR_OFFSET        0x0008  /* USBPHY1 USB PHY 
Power-Down Register Clear */
-#define IMXRT_USBPHY1_CTRL_OFFSET           0x0030  /* USBPHY1 USB PHY General 
Control Register */
-#define IMXRT_USBPHY1_CTRL_CLR_OFFSET       0x0038  /* USBPHY1 USB PHY General 
Control Register Clear */
+#define IMXRT_USBPHY_PWD_OFFSET             0x0000  /* USBPHY1/2 USB PHY 
Power-Down Register */
+#define IMXRT_USBPHY_PWD_CLR_OFFSET         0x0008  /* USBPHY1/2 USB PHY 
Power-Down Register Clear */
+#define IMXRT_USBPHY_CTRL_OFFSET            0x0030  /* USBPHY1/2 USB PHY 
General Control Register */
+#define IMXRT_USBPHY_CTRL_CLR_OFFSET        0x0038  /* USBPHY1/2 USB PHY 
General Control Register Clear */
 
-#define IMXRT_USBPHY1_PLL_SIC_OFFSET        0x00a0
-#define IMXRT_USBPHY1_PLL_SIC_SET_OFFSET    0x00a4
-#define IMXRT_USBPHY1_PLL_SIC_CLR_OFFSET    0x00a8
-#define IMXRT_USBPHY1_PLL_SIC_TOG_OFFSET    0x00ac
+#define IMXRT_USBPHY_PLL_SIC_OFFSET         0x00a0
+#define IMXRT_USBPHY_PLL_SIC_SET_OFFSET     0x00a4
+#define IMXRT_USBPHY_PLL_SIC_CLR_OFFSET     0x00a8
+#define IMXRT_USBPHY_PLL_SIC_TOG_OFFSET     0x00ac
 
 /* Register addresses *******************************************************/
 
-#define IMXRT_USBPHY1_PWD                   (IMXRT_USBPHY_BASE + 
IMXRT_USBPHY1_PWD_OFFSET)      /* USBPHY1 USB PHY Power-Down Register */
-#define IMXRT_USBPHY1_PWD_CLR               (IMXRT_USBPHY_BASE + 
IMXRT_USBPHY1_PWD_CLR_OFFSET)  /* USBPHY1 USB PHY Power-Down Register Clear */
-#define IMXRT_USBPHY1_CTRL                  (IMXRT_USBPHY_BASE + 
IMXRT_USBPHY1_CTRL_OFFSET)     /* USBPHY1 USB PHY General Control Register */
-#define IMXRT_USBPHY1_CTRL_CLR              (IMXRT_USBPHY_BASE + 
IMXRT_USBPHY1_CTRL_CLR_OFFSET) /* USBPHY1 USB PHY General Control Register 
Clear */
-#define IMXRT_USBPHY1_PLL_SIC               (IMXRT_USBPHY_BASE + 
IMXRT_USBPHY1_PLL_SIC_OFFSET)
-#define IMXRT_USBPHY1_PLL_SIC_SET           (IMXRT_USBPHY_BASE + 
IMXRT_USBPHY1_PLL_SIC_SET_OFFSET)
-#define IMXRT_USBPHY1_PLL_SIC_CLR           (IMXRT_USBPHY_BASE + 
IMXRT_USBPHY1_PLL_SIC_CLR_OFFSET)
-#define IMXRT_USBPHY1_PLL_SIC_TOG           (IMXRT_USBPHY_BASE + 
IMXRT_USBPHY1_PLL_SIC_TOG_OFFSET)
+#define IMXRT_USBPHY_PWD(n)                   (IMXRT_USBPHY_BASE(n) + 
IMXRT_USBPHY_PWD_OFFSET)      /* USBPHY1 USB PHY Power-Down Register */
+#define IMXRT_USBPHY_PWD_CLR(n)               (IMXRT_USBPHY_BASE(n) + 
IMXRT_USBPHY_PWD_CLR_OFFSET)  /* USBPHY1 USB PHY Power-Down Register Clear */
+#define IMXRT_USBPHY_CTRL(n)                  (IMXRT_USBPHY_BASE(n) + 
IMXRT_USBPHY_CTRL_OFFSET)     /* USBPHY1 USB PHY General Control Register */
+#define IMXRT_USBPHY_CTRL_CLR(n)              (IMXRT_USBPHY_BASE(n) + 
IMXRT_USBPHY_CTRL_CLR_OFFSET) /* USBPHY1 USB PHY General Control Register Clear 
*/
+#define IMXRT_USBPHY_PLL_SIC(n)               (IMXRT_USBPHY_BASE(n) + 
IMXRT_USBPHY_PLL_SIC_OFFSET)
+#define IMXRT_USBPHY_PLL_SIC_SET(n)           (IMXRT_USBPHY_BASE(n) + 
IMXRT_USBPHY_PLL_SIC_SET_OFFSET)
+#define IMXRT_USBPHY_PLL_SIC_CLR(n)           (IMXRT_USBPHY_BASE(n) + 
IMXRT_USBPHY_PLL_SIC_CLR_OFFSET)
+#define IMXRT_USBPHY_PLL_SIC_TOG(n)           (IMXRT_USBPHY_BASE(n) + 
IMXRT_USBPHY_PLL_SIC_TOG_OFFSET)
 
 /* Register Bit Definitions *************************************************/
 
@@ -73,23 +84,52 @@
 
 /* USB PHY General Control Register  */
 
-#define USBPHY_CTRL_SFTRST          (1 << 31)  /* Bit 31: Soft-reset */
-#define USBPHY_CTRL_CLKGATE         (1 << 30)  /* Bit 30: Gate UTMI clocks */
+#define USBPHY_CTRL_SFTRST            (1 << 31)  /* Bit 31: Soft-reset */
+#define USBPHY_CTRL_CLKGATE           (1 << 30)  /* Bit 30: Gate UTMI clocks */
+#define USBPHY_CTRL_UTMI_SUSPENDM     (1 << 29)  /* Bit 29: UTMI suspend DM */
+#define USBPHY_CTRL_HOST_FORCE_LS_SE0 (1 << 28)  /* Bit 28: Host force 
low-speed */
+#define USBPHY_CTRL_OTG_ID_VALUE      (1 << 27)  /* Bit 27: Filter glitches ID 
pad */
+                                                 /* Bits 26-25: Reserved */
+#define USBPHY_CTRL_FSDLL_RST_EN      (1 << 24)  /* Bit 24: Enable FSDLL logic 
*/
+#define USBPHY_CTRL_ENVBUSCHG_WKUP    (1 << 23)  /* Bit 23: Wakeup if VBUS 
change when USB is suspended */
+#define USBPHY_CTRL_ENIDCHG_WKUP      (1 << 22)  /* Bit 22: Wakeup if ID 
change when USB is suspended */
+#define USBPHY_CTRL_ENDPDMCHG_WKUP    (1 << 21)  /* Bit 21: Wakeup if DP/DM 
change when USB is suspended */
+#define USBPHY_CTRL_ENAUTOCLR_PHY_PWD (1 << 20)  /* Bit 20: Autoclear PWD bit 
if there wakeup event when USB is suspended */
+#define USBPHY_CTRL_ENAUTOCLR_CLKGATE (1 << 19)  /* Bit 19: Autoclear CLKGATE 
bit if there wakeup event when USB is suspended */
+#define USBPHY_CTRL_ENAUTO_PWRON_PLL  (1 << 18)  /* Bit 18: Autoclear POWER 
bit if there wakeup event when USB is suspended */
+#define USBPHY_CTRL_WAKEUP_IRQ        (1 << 17)  /* Bit 17: Indicates there is 
a wakeup event, reset this bit writing 1 to it */
+#define USBPHY_CTRL_ENIRQWAKEUP       (1 << 16)  /* Bit 16: Enable interrupt 
for  wakeup event */
+#define USBPHY_CTRL_ENUTMILEVEL3      (1 << 15)  /* Bit 15: Enable UTMI+ 
Level3 */
+#define USBPHY_CTRL_ENUTMILEVEL2      (1 << 14)  /* Bit 14: Enable UTMI+ 
Level2 */
+#define USBPHY_CTRL_DATA_ON_LRADC     (1 << 13)  /* Bit 13: Enable LRADC to 
monitor DP/DM, non-USB modes only */
+#define USBPHY_CTRL_DEVPLUGIN_IRQ     (1 << 12)  /* Bit 12: Enable interrupt 
for detection activity to the USB line */
+#define USBPHY_CTRL_ENIRQDEVPLUGIN    (1 << 11)  /* Bit 11: Enable interrupt 
for detection activity to the USB line */
+#define USBPHY_CTRL_RESUME_IRQ        (1 << 10)  /* Bit 10: Indicates to host 
is sending a wake-up after suspend, write 1 to clear this interrupt */
+#define USBPHY_CTRL_ENIRQRESUMEDET    (1 << 9)   /* Bit 9:  Enable the resume 
IRQ */
+#define USBPHY_CTRL_RESUMEIRQSTICKY   (1 << 8)   /* Bit 8:  Set 1 to make 
RESUME IRQ Sticky */
+#define USBPHY_CTRL_ENOTGIDDETECT     (1 << 7)   /* Bit 7:  Enable circuit to 
detect ID pin */
+#define USBPHY_CTRL_OTG_ID_CHG_IRG    (1 << 6)   /* Bit 6:  OTG ID IRQ, 
indicates value of ID pin changed */
+#define USBPHY_CTRL_DEVPLUGIN_POL     (1 << 5)   /* Bit 5:  If 0 IRQ when 
plugged in, if 1 IRQ when plugged out */
+#define USBPHY_CTRL_ENDEVPLUGINDETECT (1 << 4)   /* Bit 4:  Enables 220K ohm 
pullup to detect host connectivity */
+#define USBPHY_CTRL_HOSTDISCONDET_IRQ (1 << 3)   /* Bit 3:  Indicates the 
device was disconnected in high-speed mode, write 1 to clear IRQ */
+#define USBPHY_CTRL_ENIRQHOSTDISCON   (1 << 2)   /* Bit 2:  Enable device 
disconnected IRQ */
+#define USBPHY_CTRL_ENHOSTDISCONDET   (1 << 1)   /* Bit 1:  Enable HighSpeed 
disconnect detector */
+#define USBPHY_CTRL_ENOTG_ID_CHG_IRQ  (1 << 0)   /* Bit 0:  Enable 
OTG_ID_CHG_IRQ */
 
 /* USB PHY PLL Control/Status Register (PLL_SIC, only in IMXRT117X) */
-#define USBPHY1_PLL_SIC_PLL_POSTDIV_SHIFT  (2)        /* Bits 2-5: PLL_POSTDIV 
*/
-#define USBPHY1_PLL_SIC_PLL_POSTDIV_MASK   (0x7 << 
USBPHY1_PLL_SIC_PLL_POSTDIV_SHIFT)
-#define USBPHY1_PLL_SIC_PLL_POSTDIV(n)     (((n) << 
USBPHY1_PLL_SIC_PLL_POSTDIV_SHIFT) & USBPHY1_PLL_SIC_PLL_POSTDIV_MASK)
-#define USBPHY1_PLL_SIC_PLL_EN_USB_CLKS    (1 << 6)   /* Bit 6: 
PLL_EN_USB_CLKS */
-#define USBPHY1_PLL_SIC_PLL_POWER          (1 << 12)  /* Bit 12: PLL_POWER */
-#define USBPHY1_PLL_SIC_PLL_ENABLE         (1 << 13)  /* Bit 13: PLL_ENABLE */
-#define USBPHY1_PLL_SIC_PLL_BYPASS         (1 << 16)  /* Bit 16: PLL_BYPASS */
-#define USBPHY1_PLL_SIC_REFBIAS_PWD_SEL    (1 << 19)  /* Bit 19: 
REFBIAS_PWD_SEL */
-#define USBPHY1_PLL_SIC_REFBIAS_PWD        (1 << 20)  /* Bit 20: Power down 
the reference bias */
-#define USBPHY1_PLL_SIC_PLL_REG_ENABLE     (1 << 21)  /* Bit 21: 
PLL_REG_ENABLE */
-#define USBPHY1_PLL_SIC_PLL_DIV_SEL_SHIFT  (22)       /* Bits 22-25: 
PLL_DIV_SEL */
-#define USBPHY1_PLL_SIC_PLL_DIV_SEL_MASK   (0x7 << 
USBPHY1_PLL_SIC_PLL_DIV_SEL_SHIFT)
-#define USBPHY1_PLL_SIC_PLL_DIV_SEL(n)     (((n) << 
USBPHY1_PLL_SIC_PLL_DIV_SEL_SHIFT) & USBPHY1_PLL_SIC_PLL_DIV_SEL_MASK)
-#define USBPHY1_PLL_SIC_PLL_LOCK           (1 << 31)  /* Bit 31: PLL_LOCK */
+#define USBPHY_PLL_SIC_PLL_POSTDIV_SHIFT   (2)        /* Bits 2-5: PLL_POSTDIV 
*/
+#define USBPHY_PLL_SIC_PLL_POSTDIV_MASK    (0x7 << 
USBPHY_PLL_SIC_PLL_POSTDIV_SHIFT)
+#define USBPHY_PLL_SIC_PLL_POSTDIV(n)      (((n) << 
USBPHY_PLL_SIC_PLL_POSTDIV_SHIFT) & USBPHY_PLL_SIC_PLL_POSTDIV_MASK)
+#define USBPHY_PLL_SIC_PLL_EN_USB_CLKS     (1 << 6)   /* Bit 6: 
PLL_EN_USB_CLKS */
+#define USBPHY_PLL_SIC_PLL_POWER           (1 << 12)  /* Bit 12: PLL_POWER */
+#define USBPHY_PLL_SIC_PLL_ENABLE          (1 << 13)  /* Bit 13: PLL_ENABLE */
+#define USBPHY_PLL_SIC_PLL_BYPASS          (1 << 16)  /* Bit 16: PLL_BYPASS */
+#define USBPHY_PLL_SIC_REFBIAS_PWD_SEL     (1 << 19)  /* Bit 19: 
REFBIAS_PWD_SEL */
+#define USBPHY_PLL_SIC_REFBIAS_PWD         (1 << 20)  /* Bit 20: Power down 
the reference bias */
+#define USBPHY_PLL_SIC_PLL_REG_ENABLE      (1 << 21)  /* Bit 21: 
PLL_REG_ENABLE */
+#define USBPHY_PLL_SIC_PLL_DIV_SEL_SHIFT   (22)       /* Bits 22-25: 
PLL_DIV_SEL */
+#define USBPHY_PLL_SIC_PLL_DIV_SEL_MASK    (0x7 << 
USBPHY_PLL_SIC_PLL_DIV_SEL_SHIFT)
+#define USBPHY_PLL_SIC_PLL_DIV_SEL(n)      (((n) << 
USBPHY_PLL_SIC_PLL_DIV_SEL_SHIFT) & USBPHY_PLL_SIC_PLL_DIV_SEL_MASK)
+#define USBPHY_PLL_SIC_PLL_LOCK            (1 << 31)  /* Bit 31: PLL_LOCK */
 
 #endif /* __ARCH_ARM_SRC_IMXRT_HARDWARE_IMXRT_USBPHY_H */
diff --git a/arch/arm/src/imxrt/imxrt_ehci.c b/arch/arm/src/imxrt/imxrt_ehci.c
index fce6678547..62c639ff08 100644
--- a/arch/arm/src/imxrt/imxrt_ehci.c
+++ b/arch/arm/src/imxrt/imxrt_ehci.c
@@ -122,11 +122,11 @@
 
 /* Host Controller Capability Registers */
 
-#define HCCR ((struct ehci_hccr_s *)IMXRT_USBOTG_HCCR_BASE)
+#define HCCR(n) ((struct ehci_hccr_s *)IMXRT_USBOTG_HCCR_BASE(n))
 
 /* Host Controller Operational Registers */
 
-#define HCOR ((volatile struct ehci_hcor_s *)IMXRT_USBOTG_HCOR_BASE)
+#define HCOR(n) ((volatile struct ehci_hcor_s *)IMXRT_USBOTG_HCOR_BASE(n))
 
 /* Interrupts ***************************************************************
  * This is the set of interrupts handled by this driver.
@@ -219,12 +219,16 @@ struct imxrt_list_s
                                   */
 };
 
+/* Needed by following typedefs */
+
+struct imxrt_ehci_dev_s;
+
 /* List traversal call-out functions */
 
 typedef int (*foreach_qh_t)(struct imxrt_qh_s *qh, uint32_t **bp,
-                            void *arg);
+                            void *arg, struct imxrt_ehci_dev_s *ehci_dev);
 typedef int (*foreach_qtd_t)(struct imxrt_qtd_s *qtd, uint32_t **bp,
-                             void *arg);
+                             void *arg, struct imxrt_ehci_dev_s *ehci_dev);
 
 /* This structure describes one endpoint. */
 
@@ -251,6 +255,26 @@ struct imxrt_epinfo_s
 #endif
 };
 
+/* This structure will be used to access EHCI over functions and isr */
+
+struct imxrt_ehci_dev_s
+{
+  int                  ctrid;     /* USB Controller (USB1 = 0, USB2 = 1) */
+  struct imxrt_ehci_s *ehci;      /* Pointer to current EHCI device */
+  struct imxrt_qh_s   *asynchead;
+  struct imxrt_qh_s   *qhpool;
+  struct imxrt_qtd_s  *qtdpool;
+  struct imxrt_qh_s   *intrhead;
+  uint32_t            *framelist;
+  uint32_t             pending;   /* Pending interrupts */
+};
+
+struct imxrt_usbhost_conn_s
+{
+  struct usbhost_connection_s ehci_conn;
+  struct imxrt_ehci_dev_s *ehci_dev;
+};
+
 /* This structure retains the state of one root hub port */
 
 struct imxrt_rhport_s
@@ -271,6 +295,10 @@ struct imxrt_rhport_s
   /* This is the hub port description understood by class drivers */
 
   struct usbhost_roothubport_s hport;
+
+  /* This is the USB Controller ID: USB1 (0) or USB2 (1) */
+
+  struct imxrt_ehci_dev_s *ehci_dev;
 };
 
 /* This structure retains the overall state of the USB host controller */
@@ -419,25 +447,31 @@ static void imxrt_putreg(uint32_t regval, volatile 
uint32_t *regaddr);
 static inline uint32_t imxrt_getreg(volatile uint32_t *regaddr);
 static inline void imxrt_putreg(uint32_t regval, volatile uint32_t *regaddr);
 #endif
-static int ehci_wait_usbsts(uint32_t maskbits, uint32_t donebits,
+static int ehci_wait_usbsts(int controller, uint32_t maskbits,
+         uint32_t donebits,
          unsigned int delay);
 
 /* Allocators ***************************************************************/
 
-static struct imxrt_qh_s *imxrt_qh_alloc(void);
-static void imxrt_qh_free(struct imxrt_qh_s *qh);
-static struct imxrt_qtd_s *imxrt_qtd_alloc(void);
-static void imxrt_qtd_free(struct imxrt_qtd_s *qtd);
+static struct imxrt_qh_s *imxrt_qh_alloc(struct imxrt_ehci_dev_s *ehci_dev);
+static void imxrt_qh_free(struct imxrt_qh_s *qh,
+                          struct imxrt_ehci_dev_s *ehci_dev);
+static struct imxrt_qtd_s *imxrt_qtd_alloc(struct imxrt_ehci_dev_s
+                                           *ehci_dev);
+static void imxrt_qtd_free(struct imxrt_qtd_s *qtd,
+                           struct imxrt_ehci_dev_s *ehci_dev);
 
 /* List Management **********************************************************/
 
 static int imxrt_qh_foreach(struct imxrt_qh_s *qh, uint32_t **bp,
-         foreach_qh_t handler, void *arg);
-static int imxrt_qtd_foreach(struct imxrt_qh_s *qh, foreach_qtd_t handler,
-         void *arg);
-static int imxrt_qtd_discard(struct imxrt_qtd_s *qtd, uint32_t **bp,
-         void *arg);
-static int imxrt_qh_discard(struct imxrt_qh_s *qh);
+         foreach_qh_t handler, void *arg, struct imxrt_ehci_dev_s *ehci_dev);
+static int imxrt_qtd_foreach(struct imxrt_qh_s *qh,
+         foreach_qtd_t handler, void *arg,
+         struct imxrt_ehci_dev_s *ehci_dev);
+static int imxrt_qtd_discard(struct imxrt_qtd_s *qtd,
+         uint32_t **bp, void *arg, struct imxrt_ehci_dev_s *ehci_dev);
+static int imxrt_qh_discard(struct imxrt_qh_s *qh,
+                            struct imxrt_ehci_dev_s *ehci_dev);
 
 /* Cache Operations *********************************************************/
 
@@ -447,21 +481,24 @@ static int imxrt_qtd_invalidate(struct imxrt_qtd_s *qtd, 
uint32_t **bp,
 static int imxrt_qh_invalidate(struct imxrt_qh_s *qh);
 #endif
 static int imxrt_qtd_flush(struct imxrt_qtd_s *qtd, uint32_t **bp,
-                           void *arg);
-static int imxrt_qh_flush(struct imxrt_qh_s *qh);
+                           void *arg, struct imxrt_ehci_dev_s *ehci_dev);
+static int imxrt_qh_flush(struct imxrt_qh_s *qh,
+                          struct imxrt_ehci_dev_s *ehci_dev);
 
 /* Endpoint Transfer Handling ***********************************************/
 
 #ifdef CONFIG_IMXRT_EHCI_USB1_REGDEBUG
 static void imxrt_qtd_print(struct imxrt_qtd_s *qtd);
 static void imxrt_qh_print(struct imxrt_qh_s *qh);
-static int imxrt_qtd_dump(struct imxrt_qtd_s *qtd, uint32_t **bp, void *arg);
-static int imxrt_qh_dump(struct imxrt_qh_s *qh, uint32_t **bp, void *arg);
+static int imxrt_qtd_dump(struct imxrt_qtd_s *qtd, uint32_t **bp, void *arg,
+                          struct imxrt_ehci_dev_s *ehci_dev);
+static int imxrt_qh_dump(struct imxrt_qh_s *qh, uint32_t **bp, void *arg,
+                         struct imxrt_ehci_dev_s *ehci_dev);
 #else
 #  define imxrt_qtd_print(qtd)
 #  define imxrt_qh_print(qh)
-#  define imxrt_qtd_dump(qtd, bp, arg) ((void)OK)
-#  define imxrt_qh_dump(qh, bp, arg)   ((void)OK)
+#  define imxrt_qtd_dump(qtd, bp, arg, ehci_dev) ((void)OK)
+#  define imxrt_qh_dump(qh, bp, arg, ehci_dev)   ((void)OK)
 #endif
 
 static inline uint8_t imxrt_ehci_speed(uint8_t usbspeed);
@@ -469,21 +506,25 @@ static int imxrt_ioc_setup(struct imxrt_rhport_s *rhport,
          struct imxrt_epinfo_s *epinfo);
 static int imxrt_ioc_wait(struct imxrt_epinfo_s *epinfo);
 static void imxrt_qh_enqueue(struct imxrt_qh_s *qhead,
-         struct imxrt_qh_s *qh);
+         struct imxrt_qh_s *qh, struct imxrt_ehci_dev_s *ehci_dev);
 static struct imxrt_qh_s *imxrt_qh_create(struct imxrt_rhport_s *rhport,
-         struct imxrt_epinfo_s *epinfo);
+         struct imxrt_epinfo_s *epinfo, struct imxrt_ehci_dev_s *ehci_dev);
 static int imxrt_qtd_addbpl(struct imxrt_qtd_s *qtd, const void *buffer,
-         size_t buflen);
+         size_t buflen, struct imxrt_ehci_dev_s *ehci_dev);
 static struct imxrt_qtd_s *imxrt_qtd_setupphase(
-         struct imxrt_epinfo_s *epinfo, const struct usb_ctrlreq_s *req);
+         struct imxrt_epinfo_s *epinfo, const struct usb_ctrlreq_s *req,
+         struct imxrt_ehci_dev_s *ehci_dev);
 static struct imxrt_qtd_s *imxrt_qtd_dataphase(struct imxrt_epinfo_s *epinfo,
-         void *buffer, int buflen, uint32_t tokenbits);
-static struct imxrt_qtd_s *imxrt_qtd_statusphase(uint32_t tokenbits);
+         void *buffer, int buflen, uint32_t tokenbits,
+         struct imxrt_ehci_dev_s *ehci_dev);
+static struct imxrt_qtd_s *imxrt_qtd_statusphase(uint32_t tokenbits,
+         struct imxrt_ehci_dev_s *ehci_dev);
 #ifndef CONFIG_USBHOST_INT_DISABLE
 static int imxrt_intr_setup(struct imxrt_rhport_s *rhport,
          struct imxrt_epinfo_s *epinfo, uint8_t *buffer, size_t buflen);
 #endif
-static ssize_t imxrt_transfer_wait(struct imxrt_epinfo_s *epinfo);
+static ssize_t imxrt_transfer_wait(struct imxrt_rhport_s *rhport,
+                                   struct imxrt_epinfo_s *epinfo);
 #ifdef CONFIG_USBHOST_ASYNCH
 static inline int imxrt_ioc_async_setup(struct imxrt_rhport_s *rhport,
          struct imxrt_epinfo_s *epinfo, usbhost_asynch_t callback,
@@ -494,16 +535,18 @@ static void imxrt_asynch_completion(struct imxrt_epinfo_s 
*epinfo);
 /* Interrupt Handling *******************************************************/
 
 static int imxrt_qtd_ioccheck(struct imxrt_qtd_s *qtd, uint32_t **bp,
-         void *arg);
+         void *arg, struct imxrt_ehci_dev_s *ehci_dev);
 static int imxrt_qh_ioccheck(struct imxrt_qh_s *qh, uint32_t **bp,
-         void *arg);
+         void *arg, struct imxrt_ehci_dev_s *ehci_dev);
 #ifdef CONFIG_USBHOST_ASYNCH
 static int imxrt_qtd_cancel(struct imxrt_qtd_s *qtd, uint32_t **bp,
-         void *arg);
-static int imxrt_qh_cancel(struct imxrt_qh_s *qh, uint32_t **bp, void *arg);
+         void *arg, struct imxrt_ehci_dev_s *ehci_dev);
+static int imxrt_qh_cancel(struct imxrt_qh_s *qh, uint32_t **bp, void *arg,
+         struct imxrt_ehci_dev_s *ehci_dev);
 #endif
-static inline void imxrt_ioc_bottomhalf(void);
-static inline void imxrt_portsc_bottomhalf(void);
+static inline void imxrt_ioc_bottomhalf(struct imxrt_ehci_dev_s *ehci_dev);
+static inline void imxrt_portsc_bottomhalf(struct imxrt_ehci_dev_s
+                                           *ehci_dev);
 static inline void imxrt_syserr_bottomhalf(void);
 static inline void imxrt_async_advance_bottomhalf(void);
 static void imxrt_ehci_bottomhalf(void *arg);
@@ -558,7 +601,7 @@ static void imxrt_disconnect(struct usbhost_driver_s *drvr,
 
 /* Initialization ***********************************************************/
 
-static int imxrt_reset(void);
+static int imxrt_reset(int ctrid);
 
 /****************************************************************************
  * Private Data
@@ -569,20 +612,21 @@ static int imxrt_reset(void);
  * single global instance.
  */
 
-static struct imxrt_ehci_s g_ehci =
+static struct imxrt_ehci_s g_ehci_usb1 =
 {
   .lock = NXMUTEX_INITIALIZER,
   .pscsem = SEM_INITIALIZER(0),
   .ep0.iocsem = SEM_INITIALIZER(1),
 };
 
-/* This is the connection/enumeration interface */
-
-static struct usbhost_connection_s g_ehciconn =
+#if defined(CONFIG_IMXRT_USBOTG2)
+static struct imxrt_ehci_s g_ehci_usb2 =
 {
-  .wait = imxrt_wait,
-  .enumerate = imxrt_enumerate,
+  .lock = NXMUTEX_INITIALIZER,
+  .pscsem = SEM_INITIALIZER(0),
+  .ep0.iocsem = SEM_INITIALIZER(1),
 };
+#endif
 
 /* Maps USB chapter 9 speed to EHCI speed */
 
@@ -593,50 +637,155 @@ static const uint8_t g_ehci_speed[4] =
 
 /* The head of the asynchronous queue */
 
-static struct imxrt_qh_s g_asynchead aligned_data(32);
+static struct imxrt_qh_s g_asynchead_usb1 aligned_data(32);
+
+#if defined(CONFIG_IMXRT_USBOTG2)
+static struct imxrt_qh_s g_asynchead_usb2 aligned_data(32);
+#endif
 
 #ifndef CONFIG_USBHOST_INT_DISABLE
 /* The head of the periodic queue */
 
-static struct imxrt_qh_s g_intrhead aligned_data(32);
+static struct imxrt_qh_s g_intrhead_usb1   aligned_data(32);
+
+#if defined(CONFIG_IMXRT_USBOTG2)
+static struct imxrt_qh_s g_intrhead_usb2   aligned_data(32);
+#endif
 
 /* The frame list */
 
 #ifdef CONFIG_IMXRT_EHCI_USB1_PREALLOCATE
-static uint32_t g_framelist[FRAME_LIST_SIZE] aligned_data(4096);
+static uint32_t g_framelist_usb1[FRAME_LIST_SIZE] aligned_data(4096);
 #else
-static uint32_t *g_framelist;
+static uint32_t *g_framelist_usb1;
 #endif
+
+#if defined(CONFIG_IMXRT_USBOTG2)
+#ifdef CONFIG_IMXRT_EHCI_USB2_PREALLOCATE
+static uint32_t g_framelist_usb2[FRAME_LIST_SIZE] aligned_data(4096);
+#else
+static uint32_t *g_framelist_usb2;
+#endif
+#endif /* CONFIG_IMXRT_USBOTG2 */
+
 #endif /* CONFIG_USBHOST_INT_DISABLE */
 
-#ifdef CONFIG_IMXRT_EHCI_USB1_PREALLOCATE
+#ifdef CONFIG_IMXRT_USBOTG1
+#  ifdef CONFIG_IMXRT_EHCI_USB1_PREALLOCATE
 /* Pools of pre-allocated data structures.  These will all be linked into the
  * free lists within g_ehci.  These must all be aligned to 32-byte boundaries
  */
 
 /* Queue Head (QH) pool */
 
-static struct imxrt_qh_s g_qhpool[CONFIG_IMXRT_EHCI_USB1_NQHS]
+static struct imxrt_qh_s g_qhpool_usb1[CONFIG_IMXRT_EHCI_USB1_NQHS]
                        aligned_data(32);
 
 /* Queue Element Transfer Descriptor (qTD) pool */
 
-static struct imxrt_qtd_s g_qtdpool[CONFIG_IMXRT_EHCI_USB1_NQTDS]
+static struct imxrt_qtd_s g_qtdpool_usb1[CONFIG_IMXRT_EHCI_USB1_NQTDS]
                         aligned_data(32);
 
-#else
+#  else
 /* Pools of dynamically data structures.  These will all be linked into the
  * free lists within g_ehci.  These must all be aligned to 32-byte boundaries
  */
 
 /* Queue Head (QH) pool */
 
-static struct imxrt_qh_s *g_qhpool;
+static struct imxrt_qh_s *g_qhpool_usb1;
 
 /* Queue Element Transfer Descriptor (qTD) pool */
 
-static struct imxrt_qtd_s *g_qtdpool;
+static struct imxrt_qtd_s *g_qtdpool_usb1;
+
+#  endif
+#endif /* CONFIG_IMXRT_USBOTG1 */
+
+#ifdef CONFIG_IMXRT_USBOTG2
+#  ifdef CONFIG_IMXRT_EHCI_USB2_PREALLOCATE
+/* Pools of pre-allocated data structures.  These will all be linked into the
+ * free lists within g_ehci.  These must all be aligned to 32-byte boundaries
+ */
+
+/* Queue Head (QH) pool */
+
+static struct imxrt_qh_s g_qhpool_usb2[CONFIG_IMXRT_EHCI_USB2_NQHS]
+                       aligned_data(32);
+
+/* Queue Element Transfer Descriptor (qTD) pool */
+
+static struct imxrt_qtd_s g_qtdpool_usb2[CONFIG_IMXRT_EHCI_USB2_NQTDS]
+                        aligned_data(32);
+
+#  else
+/* Pools of dynamically data structures.  These will all be linked into the
+ * free lists within g_ehci.  These must all be aligned to 32-byte boundaries
+ */
+
+/* Queue Head (QH) pool */
+
+static struct imxrt_qh_s *g_qhpool_usb2;
+
+/* Queue Element Transfer Descriptor (qTD) pool */
+
+static struct imxrt_qtd_s *g_qtdpool_usb2;
+
+#  endif
+#endif /* CONFIG_IMXRT_USBOTG2 */
+
+/* EHCI Device instance to be passed to share as private between functions */
+
+#if defined(CONFIG_IMXRT_USBOTG1)
+static struct imxrt_ehci_dev_s g_ehci_dev_usb1 =
+{
+  .ehci      = &g_ehci_usb1,
+  .asynchead = &g_asynchead_usb1,
+  .qhpool    = &g_qhpool_usb1[0],
+  .qtdpool   = &g_qtdpool_usb1[0],
+  .framelist = &g_framelist_usb1[0],
+  .intrhead  = &g_intrhead_usb1,
+  .pending   = 0,
+};
+#endif
+
+#if defined(CONFIG_IMXRT_USBOTG2)
+static struct imxrt_ehci_dev_s g_ehci_dev_usb2 =
+{
+  .ehci      = &g_ehci_usb2,
+  .asynchead = &g_asynchead_usb2,
+  .qhpool    = &g_qhpool_usb2[0],
+  .qtdpool   = &g_qtdpool_usb2[0],
+  .framelist = &g_framelist_usb2[0],
+  .intrhead  = &g_intrhead_usb2,
+  .pending   = 0,
+};
+#endif
+
+/* This is the connection/enumeration interface */
+
+#if defined(CONFIG_IMXRT_USBOTG1)
+static struct imxrt_usbhost_conn_s g_ehci_usb1_conn =
+{
+  .ehci_conn =
+  {
+    .wait = imxrt_wait,
+    .enumerate = imxrt_enumerate,
+  },
+  .ehci_dev = &g_ehci_dev_usb1,
+};
+#endif
 
+#if defined(CONFIG_IMXRT_USBOTG2)
+static struct imxrt_usbhost_conn_s g_ehci_usb2_conn =
+{
+  .ehci_conn =
+  {
+    .wait = imxrt_wait,
+    .enumerate = imxrt_enumerate,
+  },
+  .ehci_dev = &g_ehci_dev_usb2,
+};
 #endif
 
 #ifdef HAVE_USBHOST_TRACE
@@ -1019,8 +1168,8 @@ static inline void imxrt_putreg(uint32_t regval, volatile 
uint32_t *regaddr)
  *
  ****************************************************************************/
 
-static int ehci_wait_usbsts(uint32_t maskbits, uint32_t donebits,
-                            unsigned int delay)
+static int ehci_wait_usbsts(int controller, uint32_t maskbits,
+                            uint32_t donebits, unsigned int delay)
 {
   uint32_t regval;
   unsigned int timeout;
@@ -1035,7 +1184,7 @@ static int ehci_wait_usbsts(uint32_t maskbits, uint32_t 
donebits,
 
       /* Read the USBSTS register and check for a system error */
 
-      regval = imxrt_getreg(&HCOR->usbsts);
+      regval = imxrt_getreg(&HCOR(controller)->usbsts);
       if ((regval & EHCI_INT_SYSERROR) != 0)
         {
           usbhost_trace1(EHCI_TRACE1_SYSTEMERROR, regval);
@@ -1069,16 +1218,16 @@ static int ehci_wait_usbsts(uint32_t maskbits, uint32_t 
donebits,
  *
  ****************************************************************************/
 
-static struct imxrt_qh_s *imxrt_qh_alloc(void)
+static struct imxrt_qh_s *imxrt_qh_alloc(struct imxrt_ehci_dev_s *ehci_dev)
 {
   struct imxrt_qh_s *qh;
 
   /* Remove the QH structure from the freelist */
 
-  qh = (struct imxrt_qh_s *)g_ehci.qhfree;
+  qh = (struct imxrt_qh_s *)ehci_dev->ehci->qhfree;
   if (qh)
     {
-      g_ehci.qhfree = ((struct imxrt_list_s *)qh)->flink;
+      ehci_dev->ehci->qhfree = ((struct imxrt_list_s *)qh)->flink;
       memset(qh, 0, sizeof(struct imxrt_qh_s));
     }
 
@@ -1095,14 +1244,15 @@ static struct imxrt_qh_s *imxrt_qh_alloc(void)
  *
  ****************************************************************************/
 
-static void imxrt_qh_free(struct imxrt_qh_s *qh)
+static void imxrt_qh_free(struct imxrt_qh_s *qh,
+                          struct imxrt_ehci_dev_s *ehci_dev)
 {
   struct imxrt_list_s *entry = (struct imxrt_list_s *)qh;
 
   /* Put the QH structure back into the free list */
 
-  entry->flink  = g_ehci.qhfree;
-  g_ehci.qhfree = entry;
+  entry->flink  = ehci_dev->ehci->qhfree;
+  ehci_dev->ehci->qhfree = entry;
 }
 
 /****************************************************************************
@@ -1116,16 +1266,16 @@ static void imxrt_qh_free(struct imxrt_qh_s *qh)
  *
  ****************************************************************************/
 
-static struct imxrt_qtd_s *imxrt_qtd_alloc(void)
+static struct imxrt_qtd_s *imxrt_qtd_alloc(struct imxrt_ehci_dev_s *ehci_dev)
 {
   struct imxrt_qtd_s *qtd;
 
   /* Remove the qTD from the freelist */
 
-  qtd = (struct imxrt_qtd_s *)g_ehci.qtdfree;
+  qtd = (struct imxrt_qtd_s *)ehci_dev->ehci->qtdfree;
   if (qtd)
     {
-      g_ehci.qtdfree = ((struct imxrt_list_s *)qtd)->flink;
+      ehci_dev->ehci->qtdfree = ((struct imxrt_list_s *)qtd)->flink;
       memset(qtd, 0, sizeof(struct imxrt_qtd_s));
     }
 
@@ -1144,14 +1294,15 @@ static struct imxrt_qtd_s *imxrt_qtd_alloc(void)
  *
  ****************************************************************************/
 
-static void imxrt_qtd_free(struct imxrt_qtd_s *qtd)
+static void imxrt_qtd_free(struct imxrt_qtd_s *qtd,
+                           struct imxrt_ehci_dev_s *ehci_dev)
 {
   struct imxrt_list_s *entry = (struct imxrt_list_s *)qtd;
 
   /* Put the qTD back into the free list */
 
-  entry->flink   = g_ehci.qtdfree;
-  g_ehci.qtdfree = entry;
+  entry->flink   = ehci_dev->ehci->qtdfree;
+  ehci_dev->ehci->qtdfree = entry;
 }
 
 /****************************************************************************
@@ -1165,7 +1316,8 @@ static void imxrt_qtd_free(struct imxrt_qtd_s *qtd)
  ****************************************************************************/
 
 static int imxrt_qh_foreach(struct imxrt_qh_s *qh, uint32_t **bp,
-                            foreach_qh_t handler, void *arg)
+                            foreach_qh_t handler, void *arg,
+                            struct imxrt_ehci_dev_s *ehci_dev)
 {
   struct imxrt_qh_s *next;
   uintptr_t physaddr;
@@ -1192,7 +1344,7 @@ static int imxrt_qh_foreach(struct imxrt_qh_s *qh, 
uint32_t **bp,
        */
 
       else if (imxrt_virtramaddr(physaddr & QH_HLP_MASK) ==
-               (uintptr_t)&g_asynchead)
+               (uintptr_t)ehci_dev->asynchead)
         {
           /* That will also terminate the loop */
 
@@ -1217,7 +1369,7 @@ static int imxrt_qh_foreach(struct imxrt_qh_s *qh, 
uint32_t **bp,
        * out uses it, it must update it as necessary.
        */
 
-      ret = handler(qh, bp, arg);
+      ret = handler(qh, bp, arg, ehci_dev);
 
       /* If the handler returns any non-zero value, then terminate the
        * traversal early.
@@ -1245,8 +1397,9 @@ static int imxrt_qh_foreach(struct imxrt_qh_s *qh, 
uint32_t **bp,
  *
  ****************************************************************************/
 
-static int imxrt_qtd_foreach(struct imxrt_qh_s *qh, foreach_qtd_t handler,
-                             void *arg)
+static int imxrt_qtd_foreach(struct imxrt_qh_s *qh,
+                             foreach_qtd_t handler,
+                             void *arg, struct imxrt_ehci_dev_s *ehci_dev)
 {
   struct imxrt_qtd_s *qtd;
   struct imxrt_qtd_s *next;
@@ -1299,7 +1452,7 @@ static int imxrt_qtd_foreach(struct imxrt_qh_s *qh, 
foreach_qtd_t handler,
        * uses it, it must update it as necessary.
        */
 
-      ret = handler(qtd, &bp, arg);
+      ret = handler(qtd, &bp, arg, ehci_dev);
 
       /* If the handler returns any non-zero value, then terminate the
        * traversal early.
@@ -1327,8 +1480,9 @@ static int imxrt_qtd_foreach(struct imxrt_qh_s *qh, 
foreach_qtd_t handler,
  *
  ****************************************************************************/
 
-static int imxrt_qtd_discard(struct imxrt_qtd_s *qtd, uint32_t **bp,
-                             void *arg)
+static int imxrt_qtd_discard(struct imxrt_qtd_s *qtd,
+                             uint32_t **bp,
+                             void *arg, struct imxrt_ehci_dev_s *ehci_dev)
 {
   DEBUGASSERT(qtd && bp && *bp);
 
@@ -1341,7 +1495,7 @@ static int imxrt_qtd_discard(struct imxrt_qtd_s *qtd, 
uint32_t **bp,
 
   /* Then free the qTD */
 
-  imxrt_qtd_free(qtd);
+  imxrt_qtd_free(qtd, ehci_dev);
   return OK;
 }
 
@@ -1357,7 +1511,8 @@ static int imxrt_qtd_discard(struct imxrt_qtd_s *qtd, 
uint32_t **bp,
  *
  ****************************************************************************/
 
-static int imxrt_qh_discard(struct imxrt_qh_s *qh)
+static int imxrt_qh_discard(struct imxrt_qh_s *qh,
+                            struct imxrt_ehci_dev_s *ehci_dev)
 {
   int ret;
 
@@ -1365,7 +1520,7 @@ static int imxrt_qh_discard(struct imxrt_qh_s *qh)
 
   /* Free all of the qTD's attached to the QH */
 
-  ret = imxrt_qtd_foreach(qh, imxrt_qtd_discard, NULL);
+  ret = imxrt_qtd_foreach(qh, imxrt_qtd_discard, NULL, ehci_dev);
   if (ret < 0)
     {
       usbhost_trace1(EHCI_TRACE1_QTDFOREACH_FAILED, -ret);
@@ -1373,7 +1528,7 @@ static int imxrt_qh_discard(struct imxrt_qh_s *qh)
 
   /* Then free the QH itself */
 
-  imxrt_qh_free(qh);
+  imxrt_qh_free(qh, ehci_dev);
   return ret;
 }
 
@@ -1418,7 +1573,7 @@ static int imxrt_qh_invalidate(struct imxrt_qh_s *qh)
 
   /* Then invalidate all of the qTD entries in the queue */
 
-  return imxrt_qtd_foreach(qh, imxrt_qtd_invalidate, NULL);
+  return imxrt_qtd_foreach(ehci, qh, imxrt_qtd_invalidate, NULL);
 }
 #endif
 
@@ -1431,7 +1586,8 @@ static int imxrt_qh_invalidate(struct imxrt_qh_s *qh)
  *
  ****************************************************************************/
 
-static int imxrt_qtd_flush(struct imxrt_qtd_s *qtd, uint32_t **bp, void *arg)
+static int imxrt_qtd_flush(struct imxrt_qtd_s *qtd, uint32_t **bp, void *arg,
+                           struct imxrt_ehci_dev_s *ehci_dev)
 {
   /* Flush the D-Cache, i.e., make the contents of the memory match the
    * contents of the D-Cache in the specified address range and invalidate
@@ -1452,7 +1608,8 @@ static int imxrt_qtd_flush(struct imxrt_qtd_s *qtd, 
uint32_t **bp, void *arg)
  *
  ****************************************************************************/
 
-static int imxrt_qh_flush(struct imxrt_qh_s *qh)
+static int imxrt_qh_flush(struct imxrt_qh_s *qh,
+                          struct imxrt_ehci_dev_s *ehci_dev)
 {
   /* Flush the QH first.  This will write the contents of the D-cache to RAM
    * and invalidate the contents of the D-cache so that the next access will
@@ -1464,7 +1621,7 @@ static int imxrt_qh_flush(struct imxrt_qh_s *qh)
 
   /* Then flush all of the qTD entries in the queue */
 
-  return imxrt_qtd_foreach(qh, imxrt_qtd_flush, NULL);
+  return imxrt_qtd_foreach(qh, imxrt_qtd_flush, NULL, ehci_dev);
 }
 
 /****************************************************************************
@@ -1540,7 +1697,8 @@ static void imxrt_qh_print(struct imxrt_qh_s *qh)
  ****************************************************************************/
 
 #ifdef CONFIG_IMXRT_EHCI_USB1_REGDEBUG
-static int imxrt_qtd_dump(struct imxrt_qtd_s *qtd, uint32_t **bp, void *arg)
+static int imxrt_qtd_dump(struct imxrt_qtd_s *qtd, uint32_t **bp, void *arg,
+                          struct imxrt_ehci_dev_s *ehci_dev)
 {
   imxrt_qtd_print(qtd);
   return OK;
@@ -1557,10 +1715,11 @@ static int imxrt_qtd_dump(struct imxrt_qtd_s *qtd, 
uint32_t **bp, void *arg)
  ****************************************************************************/
 
 #ifdef CONFIG_IMXRT_EHCI_USB1_REGDEBUG
-static int imxrt_qh_dump(struct imxrt_qh_s *qh, uint32_t **bp, void *arg)
+static int imxrt_qh_dump(struct imxrt_qh_s *qh, uint32_t **bp, void *arg,
+                         struct imxrt_ehci_dev_s *ehci_dev)
 {
   imxrt_qh_print(qh);
-  return imxrt_qtd_foreach(qh, imxrt_qtd_dump, NULL);
+  return imxrt_qtd_foreach(qh, imxrt_qtd_dump, NULL, ehci_dev);
 }
 #endif
 
@@ -1670,7 +1829,8 @@ static int imxrt_ioc_wait(struct imxrt_epinfo_s *epinfo)
  *
  ****************************************************************************/
 
-static void imxrt_qh_enqueue(struct imxrt_qh_s *qhead, struct imxrt_qh_s *qh)
+static void imxrt_qh_enqueue(struct imxrt_qh_s *qhead, struct imxrt_qh_s *qh,
+                             struct imxrt_ehci_dev_s *ehci_dev)
 {
   uintptr_t physaddr;
 
@@ -1680,7 +1840,7 @@ static void imxrt_qh_enqueue(struct imxrt_qh_s *qhead, 
struct imxrt_qh_s *qh)
    */
 
   qh->fqp = qh->hw.overlay.nqp;
-  imxrt_qh_dump(qh, NULL, NULL);
+  imxrt_qh_dump(qh, NULL, NULL, ehci_dev);
 
   /* Add the new QH to the head of the asynchronous queue list.
    *
@@ -1689,7 +1849,7 @@ static void imxrt_qh_enqueue(struct imxrt_qh_s *qhead, 
struct imxrt_qh_s *qh)
    */
 
   qh->hw.hlp = qhead->hw.hlp;
-  imxrt_qh_flush(qh);
+  imxrt_qh_flush(qh, ehci_dev);
 
   /* Then set the new QH as the first QH in the asynchronous queue and flush
    * the modified head to RAM.
@@ -1711,7 +1871,8 @@ static void imxrt_qh_enqueue(struct imxrt_qh_s *qhead, 
struct imxrt_qh_s *qh)
  ****************************************************************************/
 
 static struct imxrt_qh_s *imxrt_qh_create(struct imxrt_rhport_s *rhport,
-                                          struct imxrt_epinfo_s *epinfo)
+                                          struct imxrt_epinfo_s *epinfo,
+                                          struct imxrt_ehci_dev_s *ehci_dev)
 {
   struct imxrt_qh_s *qh;
   uint32_t rhpndx;
@@ -1721,7 +1882,7 @@ static struct imxrt_qh_s *imxrt_qh_create(struct 
imxrt_rhport_s *rhport,
 
   /* Allocate a new queue head structure */
 
-  qh = imxrt_qh_alloc();
+  qh = imxrt_qh_alloc(ehci_dev);
   if (qh == NULL)
     {
       usbhost_trace1(EHCI_TRACE1_QHALLOC_FAILED, 0);
@@ -1849,7 +2010,7 @@ static struct imxrt_qh_s *imxrt_qh_create(struct 
imxrt_rhport_s *rhport,
  ****************************************************************************/
 
 static int imxrt_qtd_addbpl(struct imxrt_qtd_s *qtd, const void *buffer,
-                            size_t buflen)
+                            size_t buflen, struct imxrt_ehci_dev_s *ehci_dev)
 {
   uint32_t physaddr;
   uint32_t nbytes;
@@ -1926,7 +2087,8 @@ static int imxrt_qtd_addbpl(struct imxrt_qtd_s *qtd, 
const void *buffer,
 
 static struct imxrt_qtd_s *
   imxrt_qtd_setupphase(struct imxrt_epinfo_s *epinfo,
-                       const struct usb_ctrlreq_s *req)
+                       const struct usb_ctrlreq_s *req,
+                       struct imxrt_ehci_dev_s *ehci_dev)
 {
   struct imxrt_qtd_s *qtd;
   uint32_t regval;
@@ -1934,7 +2096,7 @@ static struct imxrt_qtd_s *
 
   /* Allocate a new Queue Element Transfer Descriptor (qTD) */
 
-  qtd = imxrt_qtd_alloc();
+  qtd = imxrt_qtd_alloc(ehci_dev);
   if (qtd == NULL)
     {
       usbhost_trace1(EHCI_TRACE1_REQQTDALLOC_FAILED, 0);
@@ -1969,11 +2131,11 @@ static struct imxrt_qtd_s *
 
   /* Add the buffer data */
 
-  ret = imxrt_qtd_addbpl(qtd, req, USB_SIZEOF_CTRLREQ);
+  ret = imxrt_qtd_addbpl(qtd, req, USB_SIZEOF_CTRLREQ, ehci_dev);
   if (ret < 0)
     {
       usbhost_trace1(EHCI_TRACE1_ADDBPL_FAILED, -ret);
-      imxrt_qtd_free(qtd);
+      imxrt_qtd_free(qtd, ehci_dev);
       return NULL;
     }
 
@@ -1992,9 +2154,11 @@ static struct imxrt_qtd_s *
  *
  ****************************************************************************/
 
-static struct imxrt_qtd_s *imxrt_qtd_dataphase(struct imxrt_epinfo_s *epinfo,
-                                               void *buffer, int buflen,
-                                               uint32_t tokenbits)
+static struct imxrt_qtd_s *
+  imxrt_qtd_dataphase(struct imxrt_epinfo_s *epinfo,
+                      void *buffer, int buflen,
+                      uint32_t tokenbits,
+                      struct imxrt_ehci_dev_s *ehci_dev)
 {
   struct imxrt_qtd_s *qtd;
   uint32_t regval;
@@ -2002,7 +2166,7 @@ static struct imxrt_qtd_s *imxrt_qtd_dataphase(struct 
imxrt_epinfo_s *epinfo,
 
   /* Allocate a new Queue Element Transfer Descriptor (qTD) */
 
-  qtd = imxrt_qtd_alloc();
+  qtd = imxrt_qtd_alloc(ehci_dev);
   if (qtd == NULL)
     {
       usbhost_trace1(EHCI_TRACE1_DATAQTDALLOC_FAILED, 0);
@@ -2037,11 +2201,11 @@ static struct imxrt_qtd_s *imxrt_qtd_dataphase(struct 
imxrt_epinfo_s *epinfo,
 
   /* Add the buffer information to the buffer pointer list */
 
-  ret = imxrt_qtd_addbpl(qtd, buffer, buflen);
+  ret = imxrt_qtd_addbpl(qtd, buffer, buflen, ehci_dev);
   if (ret < 0)
     {
       usbhost_trace1(EHCI_TRACE1_ADDBPL_FAILED, -ret);
-      imxrt_qtd_free(qtd);
+      imxrt_qtd_free(qtd, ehci_dev);
       return NULL;
     }
 
@@ -2060,14 +2224,16 @@ static struct imxrt_qtd_s *imxrt_qtd_dataphase(struct 
imxrt_epinfo_s *epinfo,
  *
  ****************************************************************************/
 
-static struct imxrt_qtd_s *imxrt_qtd_statusphase(uint32_t tokenbits)
+static struct imxrt_qtd_s *
+  imxrt_qtd_statusphase(uint32_t tokenbits,
+                        struct imxrt_ehci_dev_s *ehci_dev)
 {
   struct imxrt_qtd_s *qtd;
   uint32_t regval;
 
   /* Allocate a new Queue Element Transfer Descriptor (qTD) */
 
-  qtd = imxrt_qtd_alloc();
+  qtd = imxrt_qtd_alloc(ehci_dev);
   if (qtd == NULL)
     {
       usbhost_trace1(EHCI_TRACE1_REQQTDALLOC_FAILED, 0);
@@ -2154,7 +2320,7 @@ static int imxrt_async_setup(struct imxrt_rhport_s 
*rhport,
 
   /* Create and initialize a Queue Head (QH) structure for this transfer */
 
-  qh = imxrt_qh_create(rhport, epinfo);
+  qh = imxrt_qh_create(rhport, epinfo, rhport->ehci_dev);
   if (qh == NULL)
     {
       usbhost_trace1(EHCI_TRACE1_QHCREATE_FAILED, 0);
@@ -2186,7 +2352,7 @@ static int imxrt_async_setup(struct imxrt_rhport_s 
*rhport,
        * phase of the request sequence.
        */
 
-      qtd = imxrt_qtd_setupphase(epinfo, req);
+      qtd = imxrt_qtd_setupphase(epinfo, req, rhport->ehci_dev);
       if (qtd == NULL)
         {
           usbhost_trace1(EHCI_TRACE1_QTDSETUP_FAILED, 0);
@@ -2261,7 +2427,8 @@ static int imxrt_async_setup(struct imxrt_rhport_s 
*rhport,
        * buffer.
        */
 
-      qtd = imxrt_qtd_dataphase(epinfo, buffer, buflen, tokenbits);
+      qtd = imxrt_qtd_dataphase(epinfo, buffer, buflen, tokenbits,
+                                rhport->ehci_dev);
       if (qtd == NULL)
         {
           usbhost_trace1(EHCI_TRACE1_QTDDATA_FAILED, 0);
@@ -2320,7 +2487,7 @@ static int imxrt_async_setup(struct imxrt_rhport_s 
*rhport,
        * for the status
        */
 
-      qtd = imxrt_qtd_statusphase(tokenbits);
+      qtd = imxrt_qtd_statusphase(tokenbits, rhport->ehci_dev);
       if (qtd == NULL)
         {
           usbhost_trace1(EHCI_TRACE1_QTDSTATUS_FAILED, 0);
@@ -2345,13 +2512,13 @@ static int imxrt_async_setup(struct imxrt_rhport_s 
*rhport,
 
   /* Add the new QH to the head of the asynchronous queue list */
 
-  imxrt_qh_enqueue(&g_asynchead, qh);
+  imxrt_qh_enqueue(rhport->ehci_dev->asynchead, qh, rhport->ehci_dev);
   return OK;
 
   /* Clean-up after an error */
 
 errout_with_qh:
-  imxrt_qh_discard(qh);
+  imxrt_qh_discard(qh, rhport->ehci_dev);
   return ret;
 }
 
@@ -2409,6 +2576,8 @@ static int imxrt_intr_setup(struct imxrt_rhport_s *rhport,
                             struct imxrt_epinfo_s *epinfo,
                             uint8_t *buffer, size_t buflen)
 {
+  struct imxrt_ehci_dev_s *priv = (struct imxrt_ehci_dev_s *)
+                                  rhport->ehci_dev;
   struct imxrt_qh_s *qh;
   struct imxrt_qtd_s *qtd;
   uintptr_t physaddr;
@@ -2429,7 +2598,7 @@ static int imxrt_intr_setup(struct imxrt_rhport_s *rhport,
 
   /* Create and initialize a Queue Head (QH) structure for this transfer */
 
-  qh = imxrt_qh_create(rhport, epinfo);
+  qh = imxrt_qh_create(rhport, epinfo, priv);
   if (qh == NULL)
     {
       usbhost_trace1(EHCI_TRACE1_QHCREATE_FAILED, 0);
@@ -2457,7 +2626,7 @@ static int imxrt_intr_setup(struct imxrt_rhport_s *rhport,
    * buffer.
    */
 
-  qtd = imxrt_qtd_dataphase(epinfo, buffer, buflen, tokenbits);
+  qtd = imxrt_qtd_dataphase(epinfo, buffer, buflen, tokenbits, priv);
   if (qtd == NULL)
     {
       usbhost_trace1(EHCI_TRACE1_QTDDATA_FAILED, 0);
@@ -2472,24 +2641,24 @@ static int imxrt_intr_setup(struct imxrt_rhport_s 
*rhport,
 
   /* Disable the periodic schedule */
 
-  regval  = imxrt_getreg(&HCOR->usbcmd);
+  regval  = imxrt_getreg(&HCOR(priv->ctrid)->usbcmd);
   regval &= ~EHCI_USBCMD_PSEN;
-  imxrt_putreg(regval, &HCOR->usbcmd);
+  imxrt_putreg(regval, &HCOR(priv->ctrid)->usbcmd);
 
   /* Add the new QH to the head of the interrupt transfer list */
 
-  imxrt_qh_enqueue(&g_intrhead, qh);
+  imxrt_qh_enqueue(qh, priv->intrhead, priv);
 
   /* Re-enable the periodic schedule */
 
   regval |= EHCI_USBCMD_PSEN;
-  imxrt_putreg(regval, &HCOR->usbcmd);
+  imxrt_putreg(regval, &HCOR(priv->ctrid)->usbcmd);
   return OK;
 
   /* Clean-up after an error */
 
 errout_with_qh:
-  imxrt_qh_discard(qh);
+  imxrt_qh_discard(qh, rhport->ehci_dev);
   return ret;
 }
 #endif /* CONFIG_USBHOST_INT_DISABLE */
@@ -2514,8 +2683,11 @@ errout_with_qh:
  *
  ****************************************************************************/
 
-static ssize_t imxrt_transfer_wait(struct imxrt_epinfo_s *epinfo)
+static ssize_t imxrt_transfer_wait(struct imxrt_rhport_s *rhport,
+                                   struct imxrt_epinfo_s *epinfo)
 {
+  struct imxrt_ehci_dev_s *priv = (struct imxrt_ehci_dev_s *)
+                                  rhport->ehci_dev;
   int ret;
   int ret2;
 
@@ -2531,7 +2703,7 @@ static ssize_t imxrt_transfer_wait(struct imxrt_epinfo_s 
*epinfo)
 
   /* REVISIT */
 
-  nxmutex_unlock(&g_ehci.lock);
+  nxmutex_unlock(&priv->ehci->lock);
 
   /* Wait for the IOC completion event */
 
@@ -2541,7 +2713,7 @@ static ssize_t imxrt_transfer_wait(struct imxrt_epinfo_s 
*epinfo)
    * this upon return.
    */
 
-  ret2 = nxmutex_lock(&g_ehci.lock);
+  ret2 = nxmutex_lock(&priv->ehci->lock);
   if (ret >= 0 && ret2 < 0)
     {
       ret = ret2;
@@ -2702,7 +2874,7 @@ static void imxrt_asynch_completion(struct imxrt_epinfo_s 
*epinfo)
  ****************************************************************************/
 
 static int imxrt_qtd_ioccheck(struct imxrt_qtd_s *qtd, uint32_t **bp,
-                              void *arg)
+                              void *arg, struct imxrt_ehci_dev_s *ehci_dev)
 {
   struct imxrt_epinfo_s *epinfo = (struct imxrt_epinfo_s *)arg;
   DEBUGASSERT(qtd && epinfo);
@@ -2735,7 +2907,7 @@ static int imxrt_qtd_ioccheck(struct imxrt_qtd_s *qtd, 
uint32_t **bp,
 
   /* Release this QH by returning it to the free list */
 
-  imxrt_qtd_free(qtd);
+  imxrt_qtd_free(qtd, ehci_dev);
   return OK;
 }
 
@@ -2750,7 +2922,8 @@ static int imxrt_qtd_ioccheck(struct imxrt_qtd_s *qtd, 
uint32_t **bp,
  *
  ****************************************************************************/
 
-static int imxrt_qh_ioccheck(struct imxrt_qh_s *qh, uint32_t **bp, void *arg)
+static int imxrt_qh_ioccheck(struct imxrt_qh_s *qh, uint32_t **bp, void *arg,
+                             struct imxrt_ehci_dev_s *ehci_dev)
 {
   struct imxrt_epinfo_s *epinfo;
   uint32_t token;
@@ -2799,7 +2972,8 @@ static int imxrt_qh_ioccheck(struct imxrt_qh_s *qh, 
uint32_t **bp, void *arg)
 
   /* Remove all active, attached qTD structures from the inactive QH */
 
-  ret = imxrt_qtd_foreach(qh, imxrt_qtd_ioccheck, (void *)qh->epinfo);
+  ret = imxrt_qtd_foreach(qh, imxrt_qtd_ioccheck,
+                          (void *)qh->epinfo, ehci_dev);
   if (ret < 0)
     {
       usbhost_trace1(EHCI_TRACE1_QTDFOREACH_FAILED, -ret);
@@ -2889,7 +3063,7 @@ static int imxrt_qh_ioccheck(struct imxrt_qh_s *qh, 
uint32_t **bp, void *arg)
 
       /* Then release this QH by returning it to the free list */
 
-      imxrt_qh_free(qh);
+      imxrt_qh_free(qh, ehci_dev);
     }
   else
     {
@@ -2914,7 +3088,7 @@ static int imxrt_qh_ioccheck(struct imxrt_qh_s *qh, 
uint32_t **bp, void *arg)
 
 #ifdef CONFIG_USBHOST_ASYNCH
 static int imxrt_qtd_cancel(struct imxrt_qtd_s *qtd, uint32_t **bp,
-                            void *arg)
+                            void *arg, struct imxrt_ehci_dev_s *ehci_dev)
 {
   DEBUGASSERT(qtd != NULL && bp != NULL);
 
@@ -2938,7 +3112,7 @@ static int imxrt_qtd_cancel(struct imxrt_qtd_s *qtd, 
uint32_t **bp,
 
   /* Release this QH by returning it to the free list */
 
-  imxrt_qtd_free(qtd);
+  imxrt_qtd_free(qtd, ehci_dev);
   return OK;
 }
 #endif /* CONFIG_USBHOST_ASYNCH */
@@ -2955,7 +3129,8 @@ static int imxrt_qtd_cancel(struct imxrt_qtd_s *qtd, 
uint32_t **bp,
  ****************************************************************************/
 
 #ifdef CONFIG_USBHOST_ASYNCH
-static int imxrt_qh_cancel(struct imxrt_qh_s *qh, uint32_t **bp, void *arg)
+static int imxrt_qh_cancel(struct imxrt_qh_s *qh, uint32_t **bp, void *arg,
+                           struct imxrt_ehci_dev_s *ehci_dev)
 {
   struct imxrt_epinfo_s *epinfo = (struct imxrt_epinfo_s *)arg;
   uint32_t regval;
@@ -2980,9 +3155,9 @@ static int imxrt_qh_cancel(struct imxrt_qh_s *qh, 
uint32_t **bp, void *arg)
 
   /* Disable both the asynchronous and period schedules */
 
-  regval = imxrt_getreg(&HCOR->usbcmd);
+  regval = imxrt_getreg(&HCOR(ehci_dev->ctrid)->usbcmd);
   imxrt_putreg(regval & ~(EHCI_USBCMD_ASEN | EHCI_USBCMD_PSEN),
-               &HCOR->usbcmd);
+               &HCOR(ehci_dev->ctrid)->usbcmd);
 
   /* Remove the QH from the list
    *
@@ -2999,11 +3174,11 @@ static int imxrt_qh_cancel(struct imxrt_qh_s *qh, 
uint32_t **bp, void *arg)
 
   /* Re-enable the schedules (if they were enabled before. */
 
-  imxrt_putreg(regval, &HCOR->usbcmd);
+  imxrt_putreg(regval, &HCOR(ehci_dev->ctrid)->usbcmd);
 
   /* Remove all active, attached qTD structures from the removed QH */
 
-  ret = imxrt_qtd_foreach(qh, imxrt_qtd_cancel, NULL);
+  ret = imxrt_qtd_foreach(qh, imxrt_qtd_cancel, NULL, ehci_dev);
   if (ret < 0)
     {
       usbhost_trace1(EHCI_TRACE1_QTDFOREACH_FAILED, -ret);
@@ -3013,7 +3188,7 @@ static int imxrt_qh_cancel(struct imxrt_qh_s *qh, 
uint32_t **bp, void *arg)
    * to stop the traverse without an error.
    */
 
-  imxrt_qh_free(qh);
+  imxrt_qh_free(qh, ehci_dev);
   return 1;
 }
 #endif /* CONFIG_USBHOST_ASYNCH */
@@ -3036,7 +3211,7 @@ static int imxrt_qh_cancel(struct imxrt_qh_s *qh, 
uint32_t **bp, void *arg)
  *
  ****************************************************************************/
 
-static inline void imxrt_ioc_bottomhalf(void)
+static inline void imxrt_ioc_bottomhalf(struct imxrt_ehci_dev_s *ehci_dev)
 {
   struct imxrt_qh_s *qh;
   uint32_t *bp;
@@ -3046,15 +3221,15 @@ static inline void imxrt_ioc_bottomhalf(void)
    * Make sure that the head of the asynchronous queue is invalidated.
    */
 
-  up_invalidate_dcache((uintptr_t)&g_asynchead.hw,
-                       (uintptr_t)&g_asynchead.hw +
+  up_invalidate_dcache((uintptr_t)&ehci_dev->asynchead->hw,
+                       (uintptr_t)&ehci_dev->asynchead->hw +
                        sizeof(struct ehci_qh_s));
 
   /* Set the back pointer to the forward QH pointer of the asynchronous
    * queue head.
    */
 
-  bp = (uint32_t *)&g_asynchead.hw.hlp;
+  bp = (uint32_t *)&ehci_dev->asynchead->hw.hlp;
   qh = (struct imxrt_qh_s *)
        imxrt_virtramaddr(imxrt_swap32(*bp) & QH_HLP_MASK);
 
@@ -3062,13 +3237,13 @@ static inline void imxrt_ioc_bottomhalf(void)
    * asynchronous queue head will point back to the queue head.
    */
 
-  if (qh && qh != &g_asynchead)
+  if (qh && qh != ehci_dev->asynchead)
     {
       /* Then traverse and operate on every QH and qTD in the asynchronous
        * queue
        */
 
-      ret = imxrt_qh_foreach(qh, &bp, imxrt_qh_ioccheck, NULL);
+      ret = imxrt_qh_foreach(qh, &bp, imxrt_qh_ioccheck, NULL, ehci_dev);
       if (ret < 0)
         {
           usbhost_trace1(EHCI_TRACE1_QHFOREACH_FAILED, -ret);
@@ -3081,14 +3256,15 @@ static inline void imxrt_ioc_bottomhalf(void)
    * Make sure that the head of the interrupt queue is invalidated.
    */
 
-  up_invalidate_dcache((uintptr_t)&g_intrhead.hw,
-                       (uintptr_t)&g_intrhead.hw + sizeof(struct ehci_qh_s));
+  up_invalidate_dcache((uintptr_t)&ehci_dev->intrhead->hw,
+                       (uintptr_t)&ehci_dev->intrhead->hw +
+                       sizeof(struct ehci_qh_s));
 
   /* Set the back pointer to the forward qTD pointer of the asynchronous
    * queue head.
    */
 
-  bp = (uint32_t *)&g_intrhead.hw.hlp;
+  bp = (uint32_t *)&ehci_dev->intrhead->hw.hlp;
   qh = (struct imxrt_qh_s *)
        imxrt_virtramaddr(imxrt_swap32(*bp) & QH_HLP_MASK);
   if (qh)
@@ -3097,7 +3273,7 @@ static inline void imxrt_ioc_bottomhalf(void)
        * queue.
        */
 
-      ret = imxrt_qh_foreach(qh, &bp, imxrt_qh_ioccheck, NULL);
+      ret = imxrt_qh_foreach(qh, &bp, imxrt_qh_ioccheck, NULL, ehci_dev);
       if (ret < 0)
         {
           usbhost_trace1(EHCI_TRACE1_QHFOREACH_FAILED, -ret);
@@ -3128,7 +3304,7 @@ static inline void imxrt_ioc_bottomhalf(void)
  *
  ****************************************************************************/
 
-static inline void imxrt_portsc_bottomhalf(void)
+static inline void imxrt_portsc_bottomhalf(struct imxrt_ehci_dev_s *ehci_dev)
 {
   struct imxrt_rhport_s *rhport;
   struct usbhost_hubport_s *hport;
@@ -3139,8 +3315,8 @@ static inline void imxrt_portsc_bottomhalf(void)
 
   for (rhpndx = 0; rhpndx < IMXRT_EHCI_NRHPORT; rhpndx++)
     {
-      rhport = &g_ehci.rhport[rhpndx];
-      portsc = imxrt_getreg(&HCOR->portsc[rhpndx]);
+      rhport = &ehci_dev->ehci->rhport[rhpndx];
+      portsc = imxrt_getreg(&HCOR(ehci_dev->ctrid)->portsc[rhpndx]);
 
       usbhost_vtrace2(EHCI_VTRACE2_PORTSC, rhpndx + 1, portsc);
 
@@ -3163,14 +3339,14 @@ static inline void imxrt_portsc_bottomhalf(void)
                   rhport->connected = true;
 
                   usbhost_vtrace2(EHCI_VTRACE2_PORTSC_CONNECTED,
-                                  rhpndx + 1, g_ehci.pscwait);
+                                  rhpndx + 1, ehci_dev->ehci->pscwait);
 
                   /* Notify any waiters */
 
-                  if (g_ehci.pscwait)
+                  if (ehci_dev->ehci->pscwait)
                     {
-                      nxsem_post(&g_ehci.pscsem);
-                      g_ehci.pscwait = false;
+                      nxsem_post(&ehci_dev->ehci->pscsem);
+                      ehci_dev->ehci->pscwait = false;
                     }
                 }
               else
@@ -3187,7 +3363,7 @@ static inline void imxrt_portsc_bottomhalf(void)
                   /* Yes.. disconnect the device */
 
                   usbhost_vtrace2(EHCI_VTRACE2_PORTSC_DISCONND,
-                                  rhpndx + 1, g_ehci.pscwait);
+                                  rhpndx + 1, ehci_dev->ehci->pscwait);
 
                   rhport->connected = false;
                   rhport->lowspeed  = false;
@@ -3207,10 +3383,10 @@ static inline void imxrt_portsc_bottomhalf(void)
                    * event.
                    */
 
-                  if (g_ehci.pscwait)
+                  if (ehci_dev->ehci->pscwait)
                     {
-                      nxsem_post(&g_ehci.pscsem);
-                      g_ehci.pscwait = false;
+                      nxsem_post(&ehci_dev->ehci->pscsem);
+                      ehci_dev->ehci->pscwait = false;
                     }
                 }
               else
@@ -3225,7 +3401,7 @@ static inline void imxrt_portsc_bottomhalf(void)
        * to preserve the values of all R/W bits (RO bits don't matter)
        */
 
-      imxrt_putreg(portsc, &HCOR->portsc[rhpndx]);
+      imxrt_putreg(portsc, &HCOR(ehci_dev->ctrid)->portsc[rhpndx]);
     }
 }
 
@@ -3279,14 +3455,15 @@ static inline void imxrt_async_advance_bottomhalf(void)
 
 static void imxrt_ehci_bottomhalf(void *arg)
 {
-  uint32_t pending = (uint32_t)arg;
+  struct imxrt_ehci_dev_s *priv = (struct imxrt_ehci_dev_s *) arg;
+  uint32_t pending = priv->pending;
 
   /* We need to have exclusive access to the EHCI data structures.  Waiting
    * here is not a good thing to do on the worker thread, but there is no
    * real option (other than to reschedule and delay).
    */
 
-  nxmutex_lock(&g_ehci.lock);
+  nxmutex_lock(&priv->ehci->lock);
 
   /* Handle all unmasked interrupt sources
    * USB Interrupt (USBINT)
@@ -3321,7 +3498,7 @@ static void imxrt_ehci_bottomhalf(void *arg)
           usbhost_vtrace1(EHCI_VTRACE1_USBINTR, pending);
         }
 
-      imxrt_ioc_bottomhalf();
+      imxrt_ioc_bottomhalf(priv);
     }
 
   /* Port Change Detect
@@ -3343,7 +3520,7 @@ static void imxrt_ehci_bottomhalf(void *arg)
 
   if ((pending & EHCI_INT_PORTSC) != 0)
     {
-      imxrt_portsc_bottomhalf();
+      imxrt_portsc_bottomhalf(priv);
     }
 
   /* Frame List Rollover
@@ -3397,13 +3574,13 @@ static void imxrt_ehci_bottomhalf(void *arg)
 
   /* We are done with the EHCI structures */
 
-  nxmutex_unlock(&g_ehci.lock);
+  nxmutex_unlock(&priv->ehci->lock);
 
   /* Re-enable relevant EHCI interrupts.  Interrupts should still be enabled
    * at the level of the interrupt controller.
    */
 
-  imxrt_putreg(EHCI_HANDLED_INTS, &HCOR->usbintr);
+  imxrt_putreg(EHCI_HANDLED_INTS, &HCOR(priv->ctrid)->usbintr);
 }
 
 /****************************************************************************
@@ -3416,14 +3593,15 @@ static void imxrt_ehci_bottomhalf(void *arg)
 
 static int imxrt_ehci_interrupt(int irq, void *context, void *arg)
 {
+  struct imxrt_ehci_dev_s *priv = (struct imxrt_ehci_dev_s *)arg;
   uint32_t usbsts;
   uint32_t pending;
   uint32_t regval;
 
   /* Read Interrupt Status and mask out interrupts that are not enabled. */
 
-  usbsts = imxrt_getreg(&HCOR->usbsts);
-  regval = imxrt_getreg(&HCOR->usbintr);
+  usbsts = imxrt_getreg(&HCOR(priv->ctrid)->usbsts);
+  regval = imxrt_getreg(&HCOR(priv->ctrid)->usbintr);
 
 #ifdef CONFIG_USBHOST_TRACE
   usbhost_vtrace1(EHCI_VTRACE1_TOPHALF, usbsts & regval);
@@ -3444,21 +3622,23 @@ static int imxrt_ehci_interrupt(int irq, void *context, 
void *arg)
        * by controlling the EHCI interrupts.
        */
 
-      DEBUGASSERT(work_available(&g_ehci.work));
-      DEBUGVERIFY(work_queue(HPWORK, &g_ehci.work, imxrt_ehci_bottomhalf,
-                            (void *)pending, 0));
+      priv->pending = pending;
+      DEBUGASSERT(work_available(&priv->ehci->work));
+      DEBUGVERIFY(work_queue(HPWORK, &priv->ehci->work,
+                             imxrt_ehci_bottomhalf,
+                             (void *)priv, 0));
 
       /* Disable further EHCI interrupts so that we do not overrun the work
        * queue.
        */
 
-      imxrt_putreg(0, &HCOR->usbintr);
+      imxrt_putreg(0, &HCOR(priv->ctrid)->usbintr);
 
       /* Clear all pending status bits by writing the value of the pending
        * interrupt bits back to the status register.
        */
 
-      imxrt_putreg(usbsts & EHCI_INT_ALLINTS, &HCOR->usbsts);
+      imxrt_putreg(usbsts & EHCI_INT_ALLINTS, &HCOR(priv->ctrid)->usbsts);
     }
 
   return OK;
@@ -3492,6 +3672,10 @@ static int imxrt_ehci_interrupt(int irq, void *context, 
void *arg)
 static int imxrt_wait(struct usbhost_connection_s *conn,
                       struct usbhost_hubport_s **hport)
 {
+  struct imxrt_usbhost_conn_s *imxrt_conn = (struct imxrt_usbhost_conn_s *)
+                                            conn;
+  struct imxrt_ehci_dev_s *priv = (struct imxrt_ehci_dev_s *)
+                                  imxrt_conn->ehci_dev;
   irqstate_t flags;
   int rhpndx;
   int ret;
@@ -3512,7 +3696,7 @@ static int imxrt_wait(struct usbhost_connection_s *conn,
 
           /* Has the connection state changed on the RH port? */
 
-          rhport   = &g_ehci.rhport[rhpndx];
+          rhport   = &priv->ehci->rhport[rhpndx];
           connport = &rhport->hport.hport;
           if (rhport->connected != connport->connected)
             {
@@ -3533,14 +3717,14 @@ static int imxrt_wait(struct usbhost_connection_s *conn,
 #ifdef CONFIG_USBHOST_HUB
       /* Is a device connected to an external hub? */
 
-      if (g_ehci.hport)
+      if (priv->ehci->hport != NULL)
         {
           volatile struct usbhost_hubport_s *connport;
 
           /* Yes.. return the external hub port */
 
-          connport = g_ehci.hport;
-          g_ehci.hport = NULL;
+          connport = priv->ehci->hport;
+          priv->ehci->hport = NULL;
 
           *hport = (struct usbhost_hubport_s *)connport;
           leave_critical_section(flags);
@@ -3555,8 +3739,8 @@ static int imxrt_wait(struct usbhost_connection_s *conn,
        * and check again
        */
 
-      g_ehci.pscwait = true;
-      ret = nxsem_wait_uninterruptible(&g_ehci.pscsem);
+      priv->ehci->pscwait = true;
+      ret = nxsem_wait_uninterruptible(&priv->ehci->pscsem);
       if (ret < 0)
         {
           return ret;
@@ -3595,6 +3779,10 @@ static int imxrt_wait(struct usbhost_connection_s *conn,
 static int imxrt_rh_enumerate(struct usbhost_connection_s *conn,
                               struct usbhost_hubport_s *hport)
 {
+  struct imxrt_usbhost_conn_s *imxrt_conn = (struct imxrt_usbhost_conn_s *)
+                                            conn;
+  struct imxrt_ehci_dev_s *priv = (struct imxrt_ehci_dev_s *)
+                                  imxrt_conn->ehci_dev;
   struct imxrt_rhport_s *rhport;
   volatile uint32_t *regaddr;
   uint32_t regval;
@@ -3604,7 +3792,7 @@ static int imxrt_rh_enumerate(struct usbhost_connection_s 
*conn,
   rhpndx = hport->port;
 
   DEBUGASSERT(rhpndx >= 0 && rhpndx < IMXRT_EHCI_NRHPORT);
-  rhport = &g_ehci.rhport[rhpndx];
+  rhport = &priv->ehci->rhport[rhpndx];
 
   /* Are we connected to a device?  The caller should have called the wait()
    * method first to be assured that a device is connected.
@@ -3644,7 +3832,7 @@ static int imxrt_rh_enumerate(struct usbhost_connection_s 
*conn,
    * however, also appears to work.
    */
 
-  regval = imxrt_getreg(&HCOR->portsc[rhpndx]);
+  regval = imxrt_getreg(&HCOR(priv->ctrid)->portsc[rhpndx]);
   if ((regval & EHCI_PORTSC_LSTATUS_MASK) == EHCI_PORTSC_LSTATUS_KSTATE)
     {
       /* EHCI Paragraph 2.3.9:
@@ -3693,7 +3881,8 @@ static int imxrt_rh_enumerate(struct usbhost_connection_s 
*conn,
    *   may hold Port Reset asserted to a one when the HCHalted bit is a one.
    */
 
-  DEBUGASSERT((imxrt_getreg(&HCOR->usbsts) & EHCI_USBSTS_HALTED) == 0);
+  DEBUGASSERT((imxrt_getreg(&HCOR(priv->ctrid)->usbsts) &
+               EHCI_USBSTS_HALTED) == 0);
 
   /* EHCI paragraph 2.3.9:
    *
@@ -3706,7 +3895,7 @@ static int imxrt_rh_enumerate(struct usbhost_connection_s 
*conn,
    *   one, it must also write a zero to the Port Enable bit."
    */
 
-  regaddr = &HCOR->portsc[RHPNDX(rhport)];
+  regaddr = &HCOR(priv->ctrid)->portsc[RHPNDX(rhport)];
   regval  = imxrt_getreg(regaddr);
   regval &= ~EHCI_PORTSC_PE;
   regval |= EHCI_PORTSC_RESET;
@@ -3769,7 +3958,7 @@ static int imxrt_rh_enumerate(struct usbhost_connection_s 
*conn,
    *   will be indicated by the PSPD field in PORTSC1.
    */
 
-  regval = imxrt_getreg(&HCOR->portsc[rhpndx]);
+  regval = imxrt_getreg(&HCOR(priv->ctrid)->portsc[rhpndx]);
 
   if ((regval & USBDEV_PRTSC1_PSPD_MASK) == USBDEV_PRTSC1_PSPD_HS)
     {
@@ -3884,6 +4073,9 @@ static int imxrt_ep0configure(struct usbhost_driver_s 
*drvr,
                               usbhost_ep_t ep0, uint8_t funcaddr,
                               uint8_t speed, uint16_t maxpacketsize)
 {
+  struct imxrt_rhport_s *rhport = (struct imxrt_rhport_s *)drvr;
+  struct imxrt_ehci_dev_s *priv = (struct imxrt_ehci_dev_s *)
+                                  rhport->ehci_dev;
   struct imxrt_epinfo_s *epinfo = (struct imxrt_epinfo_s *)ep0;
   int ret;
 
@@ -3891,7 +4083,7 @@ static int imxrt_ep0configure(struct usbhost_driver_s 
*drvr,
 
   /* We must have exclusive access to the EHCI data structures. */
 
-  ret = nxmutex_lock(&g_ehci.lock);
+  ret = nxmutex_lock(&priv->ehci->lock);
   if (ret >= 0)
     {
       /* Remember the new device address and max packet size */
@@ -3900,7 +4092,7 @@ static int imxrt_ep0configure(struct usbhost_driver_s 
*drvr,
       epinfo->speed     = speed;
       epinfo->maxpacket = maxpacketsize;
 
-      nxmutex_unlock(&g_ehci.lock);
+      nxmutex_unlock(&priv->ehci->lock);
     }
 
   return ret;
@@ -4232,6 +4424,8 @@ static int imxrt_ctrlin(struct usbhost_driver_s *drvr, 
usbhost_ep_t ep0,
                         uint8_t *buffer)
 {
   struct imxrt_rhport_s *rhport = (struct imxrt_rhport_s *)drvr;
+  struct imxrt_ehci_dev_s *priv = (struct imxrt_ehci_dev_s *)
+                                  rhport->ehci_dev;
   struct imxrt_epinfo_s *ep0info = (struct imxrt_epinfo_s *)ep0;
   uint16_t len;
   ssize_t nbytes;
@@ -4256,7 +4450,7 @@ static int imxrt_ctrlin(struct usbhost_driver_s *drvr, 
usbhost_ep_t ep0,
    * structures.
    */
 
-  ret = nxmutex_lock(&g_ehci.lock);
+  ret = nxmutex_lock(&priv->ehci->lock);
   if (ret < 0)
     {
       return ret;
@@ -4282,14 +4476,14 @@ static int imxrt_ctrlin(struct usbhost_driver_s *drvr, 
usbhost_ep_t ep0,
 
   /* And wait for the transfer to complete */
 
-  nbytes = imxrt_transfer_wait(ep0info);
-  nxmutex_unlock(&g_ehci.lock);
+  nbytes = imxrt_transfer_wait(rhport, ep0info);
+  nxmutex_unlock(&priv->ehci->lock);
   return nbytes >= 0 ? OK : (int)nbytes;
 
 errout_with_iocwait:
   ep0info->iocwait = false;
 errout_with_lock:
-  nxmutex_unlock(&g_ehci.lock);
+  nxmutex_unlock(&priv->ehci->lock);
   return ret;
 }
 
@@ -4348,6 +4542,8 @@ static ssize_t imxrt_transfer(struct usbhost_driver_s 
*drvr,
                               size_t buflen)
 {
   struct imxrt_rhport_s *rhport = (struct imxrt_rhport_s *)drvr;
+  struct imxrt_ehci_dev_s *priv = (struct imxrt_ehci_dev_s *)
+                                  rhport->ehci_dev;
   struct imxrt_epinfo_s *epinfo = (struct imxrt_epinfo_s *)ep;
   ssize_t nbytes;
   int ret;
@@ -4358,7 +4554,7 @@ static ssize_t imxrt_transfer(struct usbhost_driver_s 
*drvr,
    * structures.
    */
 
-  ret = nxmutex_lock(&g_ehci.lock);
+  ret = nxmutex_lock(&priv->ehci->lock);
   if (ret < 0)
     {
       return (ssize_t)ret;
@@ -4409,15 +4605,15 @@ static ssize_t imxrt_transfer(struct usbhost_driver_s 
*drvr,
 
   /* Then wait for the transfer to complete */
 
-  nbytes = imxrt_transfer_wait(epinfo);
-  nxmutex_unlock(&g_ehci.lock);
+  nbytes = imxrt_transfer_wait(rhport, epinfo);
+  nxmutex_unlock(&priv->ehci->lock);
   return nbytes;
 
 errout_with_iocwait:
   epinfo->iocwait = false;
 errout_with_lock:
   uerr("!!!\n");
-  nxmutex_unlock(&g_ehci.lock);
+  nxmutex_unlock(&priv->ehci->lock);
   return (ssize_t)ret;
 }
 
@@ -4463,6 +4659,8 @@ static int imxrt_asynch(struct usbhost_driver_s *drvr, 
usbhost_ep_t ep,
                         usbhost_asynch_t callback, void *arg)
 {
   struct imxrt_rhport_s *rhport = (struct imxrt_rhport_s *)drvr;
+  struct imxrt_ehci_dev_s *priv = (struct imxrt_ehci_dev_s *)
+                                  rhport->ehci_dev;
   struct imxrt_epinfo_s *epinfo = (struct imxrt_epinfo_s *)ep;
   int ret;
 
@@ -4472,7 +4670,7 @@ static int imxrt_asynch(struct usbhost_driver_s *drvr, 
usbhost_ep_t ep,
    * structures.
    */
 
-  ret = nxmutex_lock(&g_ehci.lock);
+  ret = nxmutex_lock(&priv->ehci->lock);
   if (ret < 0)
     {
       return ret;
@@ -4521,14 +4719,14 @@ static int imxrt_asynch(struct usbhost_driver_s *drvr, 
usbhost_ep_t ep,
 
   /* The transfer is in progress */
 
-  nxmutex_unlock(&g_ehci.lock);
+  nxmutex_unlock(&priv->ehci->lock);
   return OK;
 
 errout_with_callback:
   epinfo->callback = NULL;
   epinfo->arg      = NULL;
 errout_with_lock:
-  nxmutex_unlock(&g_ehci.lock);
+  nxmutex_unlock(&priv->ehci->lock);
   return ret;
 }
 #endif /* CONFIG_USBHOST_ASYNCH */
@@ -4554,6 +4752,9 @@ errout_with_lock:
 
 static int imxrt_cancel(struct usbhost_driver_s *drvr, usbhost_ep_t ep)
 {
+  struct imxrt_rhport_s *rhport = (struct imxrt_rhport_s *)drvr;
+  struct imxrt_ehci_dev_s *priv = (struct imxrt_ehci_dev_s *)
+                                  rhport->ehci_dev;
   struct imxrt_epinfo_s *epinfo = (struct imxrt_epinfo_s *)ep;
   struct imxrt_qh_s *qh;
 #ifdef CONFIG_USBHOST_ASYNCH
@@ -4576,7 +4777,7 @@ static int imxrt_cancel(struct usbhost_driver_s *drvr, 
usbhost_ep_t ep)
    * interrupt level.
    */
 
-  ret = nxmutex_lock(&g_ehci.lock);
+  ret = nxmutex_lock(&priv->ehci->lock);
   if (ret < 0)
     {
       return ret;
@@ -4633,7 +4834,7 @@ static int imxrt_cancel(struct usbhost_driver_s *drvr, 
usbhost_ep_t ep)
            * queue.
            */
 
-          bp = (uint32_t *)&g_asynchead.hw.hlp;
+          bp = (uint32_t *)&priv->asynchead->hw.hlp;
           qh = (struct imxrt_qh_s *)
                imxrt_virtramaddr(imxrt_swap32(*bp) & QH_HLP_MASK);
 
@@ -4642,7 +4843,7 @@ static int imxrt_cancel(struct usbhost_driver_s *drvr, 
usbhost_ep_t ep)
            * head.
            */
 
-          if (qh && qh != &g_asynchead)
+          if (qh && qh != priv->asynchead)
             {
               /* Claim that we successfully cancelled the transfer */
 
@@ -4659,7 +4860,7 @@ static int imxrt_cancel(struct usbhost_driver_s *drvr, 
usbhost_ep_t ep)
            * queue.
            */
 
-          bp = (uint32_t *)&g_intrhead.hw.hlp;
+          bp = (uint32_t *)&priv->intrhead->hw.hlp;
           qh = (struct imxrt_qh_s *)
                imxrt_virtramaddr(imxrt_swap32(*bp) & QH_HLP_MASK);
           if (qh)
@@ -4696,7 +4897,7 @@ static int imxrt_cancel(struct usbhost_driver_s *drvr, 
usbhost_ep_t ep)
    * 3)  Some bad happened and sam_hq_foreach returned an error code < 0.
    */
 
-  ret = imxrt_qh_foreach(qh, &bp, imxrt_qh_cancel, epinfo);
+  ret = imxrt_qh_foreach(qh, &bp, imxrt_qh_cancel, epinfo, priv);
   if (ret < 0)
     {
       usbhost_trace1(EHCI_TRACE1_QTDFOREACH_FAILED, -ret);
@@ -4731,7 +4932,7 @@ exit_terminate:
 #endif
 
 errout_with_lock:
-  nxmutex_unlock(&g_ehci.lock);
+  nxmutex_unlock(&priv->ehci->lock);
   return ret;
 }
 
@@ -4761,6 +4962,9 @@ static int imxrt_connect(struct usbhost_driver_s *drvr,
                          struct usbhost_hubport_s *hport,
                          bool connected)
 {
+  struct imxrt_rhport_s *rhport = (struct imxrt_rhport_s *)drvr;
+  struct imxrt_ehci_dev_s *priv = (struct imxrt_ehci_dev_s *)
+                                  rhport->ehci_dev;
   irqstate_t flags;
 
   /* Set the connected/disconnected flag */
@@ -4772,13 +4976,13 @@ static int imxrt_connect(struct usbhost_driver_s *drvr,
   /* Report the connection event */
 
   flags = enter_critical_section();
-  DEBUGASSERT(g_ehci.hport == NULL); /* REVISIT */
+  DEBUGASSERT(priv->ehci->hport == NULL); /* REVISIT */
 
-  g_ehci.hport = hport;
-  if (g_ehci.pscwait)
+  priv->ehci->hport = hport;
+  if (priv->ehci->pscwait)
     {
-      g_ehci.pscwait = false;
-      nxsem_post(&g_ehci.pscsem);
+      priv->ehci->pscwait = false;
+      nxsem_post(&priv->ehci->pscsem);
     }
 
   leave_critical_section(flags);
@@ -4863,7 +5067,7 @@ static void imxrt_disconnect(struct usbhost_driver_s 
*drvr,
  *
  ****************************************************************************/
 
-static int imxrt_reset(void)
+static int imxrt_reset(int ctrid)
 {
   uint32_t regval;
   unsigned int timeout;
@@ -4875,7 +5079,7 @@ static int imxrt_reset(void)
    * stopped state..."
    */
 
-  imxrt_putreg(0, &HCOR->usbcmd);
+  imxrt_putreg(0, &HCOR(ctrid)->usbcmd);
 
   /* "... Software should not set [HCRESET] to a one when the HCHalted bit in
    *  the USBSTS register is a zero. Attempting to reset an actively running
@@ -4895,7 +5099,7 @@ static int imxrt_reset(void)
        * the HCHalted bit is no longer set in the USBSTS register.
        */
 
-      regval = imxrt_getreg(&HCOR->usbsts);
+      regval = imxrt_getreg(&HCOR(ctrid)->usbsts);
     }
   while (((regval & EHCI_USBSTS_HALTED) == 0) && (timeout < 1000));
 
@@ -4911,9 +5115,9 @@ static int imxrt_reset(void)
    * reset
    */
 
-  regval  = imxrt_getreg(&HCOR->usbcmd);
+  regval  = imxrt_getreg(&HCOR(ctrid)->usbcmd);
   regval |= EHCI_USBCMD_HCRESET;
-  imxrt_putreg(regval, &HCOR->usbcmd);
+  imxrt_putreg(regval, &HCOR(ctrid)->usbcmd);
 
   /* Wait for the HCReset bit to become clear */
 
@@ -4929,7 +5133,7 @@ static int imxrt_reset(void)
        * HCReset bit is no longer set in the USBSTS register.
        */
 
-      regval = imxrt_getreg(&HCOR->usbcmd);
+      regval = imxrt_getreg(&HCOR(ctrid)->usbcmd);
     }
   while (((regval & EHCI_USBCMD_HCRESET) != 0) && (timeout < 1000000));
 
@@ -4969,7 +5173,15 @@ static int imxrt_reset(void)
 
 struct usbhost_connection_s *imxrt_ehci_initialize(int controller)
 {
-  struct usbhost_hubport_s *hport;
+  struct usbhost_hubport_s    *hport;
+  struct imxrt_ehci_s         *ehci;
+  struct imxrt_qh_s           *asynchead;
+  struct imxrt_qh_s           *qhpool;
+  struct imxrt_qtd_s          *qtdpool;
+  struct imxrt_qh_s           *intrhead;
+  struct imxrt_ehci_dev_s     *ehci_dev;
+  struct imxrt_usbhost_conn_s *usb_conn;
+  uint32_t *framelist;
   uint32_t regval;
 #  if defined(CONFIG_DEBUG_USB) && defined(CONFIG_DEBUG_INFO)
   uint16_t regval16;
@@ -4977,40 +5189,69 @@ struct usbhost_connection_s *imxrt_ehci_initialize(int 
controller)
 #  endif
   uintptr_t physaddr;
   int ret;
+  int end;
   int i;
 
   /* Sanity checks */
 
-  DEBUGASSERT(controller == 0);
-  DEBUGASSERT(((uintptr_t)&g_asynchead & 0x1f) == 0);
+  DEBUGASSERT(controller == 0 || controller == 1);
+  DEBUGASSERT(((uintptr_t)&g_asynchead_usb1 & 0x1f) == 0);
   DEBUGASSERT((sizeof(struct imxrt_qh_s) & 0x1f) == 0);
   DEBUGASSERT((sizeof(struct imxrt_qtd_s) & 0x1f) == 0);
 
 #  ifdef CONFIG_IMXRT_EHCI_USB1_PREALLOCATE
-  DEBUGASSERT(((uintptr_t)&g_qhpool & 0x1f) == 0);
-  DEBUGASSERT(((uintptr_t)&g_qtdpool & 0x1f) == 0);
+  DEBUGASSERT(((uintptr_t)&g_qhpool_usb1 & 0x1f) == 0);
+  DEBUGASSERT(((uintptr_t)&g_qtdpool_usb1 & 0x1f) == 0);
 #  endif
 
 #  ifndef CONFIG_USBHOST_INT_DISABLE
-  DEBUGASSERT(((uintptr_t)&g_intrhead & 0x1f) == 0);
+  DEBUGASSERT(((uintptr_t)&g_intrhead_usb1 & 0x1f) == 0);
 #    ifdef CONFIG_IMXRT_EHCI_PREALLOCATE
-  DEBUGASSERT(((uintptr_t)g_framelist & 0xfff) == 0);
+  DEBUGASSERT(((uintptr_t)g_framelist_usb1 & 0xfff) == 0);
 #    endif
 #  endif /* CONFIG_USBHOST_INT_DISABLE */
 
+#if defined(CONFIG_IMXRT_USBOTG1)
+  if (controller == 0)
+    {
+      ehci      = &g_ehci_usb1;
+      asynchead = &g_asynchead_usb1;
+      qhpool    = &g_qhpool_usb1[0];
+      qtdpool   = &g_qtdpool_usb1[0];
+      framelist = &g_framelist_usb1[0];
+      intrhead  = &g_intrhead_usb1;
+      ehci_dev  = &g_ehci_dev_usb1;
+      usb_conn  = &g_ehci_usb1_conn;
+    }
+#endif
+
+#if defined(CONFIG_IMXRT_USBOTG2)
+  if (controller == 1)
+    {
+      ehci      = &g_ehci_usb2;
+      asynchead = &g_asynchead_usb2;
+      qhpool    = &g_qhpool_usb2[0];
+      qtdpool   = &g_qtdpool_usb2[0];
+      framelist = &g_framelist_usb2[0];
+      intrhead  = &g_intrhead_usb2;
+      ehci_dev  = &g_ehci_dev_usb2;
+      usb_conn  = &g_ehci_usb2_conn;
+    }
+#endif
+
   /* Software Configuration *************************************************/
 
   usbhost_vtrace1(EHCI_VTRACE1_INITIALIZING, 0);
 
   /* Initialize function address generation logic */
 
-  usbhost_devaddr_initialize(&g_ehci.devgen);
+  usbhost_devaddr_initialize(&ehci->devgen);
 
   /* Initialize the root hub port structures */
 
   for (i = 0; i < IMXRT_EHCI_NRHPORT; i++)
     {
-      struct imxrt_rhport_s *rhport = &g_ehci.rhport[i];
+      struct imxrt_rhport_s *rhport = &ehci->rhport[i];
 
       /* Initialize the device operations */
 
@@ -5032,7 +5273,12 @@ struct usbhost_connection_s *imxrt_ehci_initialize(int 
controller)
       rhport->drvr.connect = imxrt_connect;
 #  endif
       rhport->drvr.disconnect = imxrt_disconnect;
-      rhport->hport.pdevgen   = &g_ehci.devgen;
+      rhport->hport.pdevgen   = &ehci->devgen;
+
+      /* Let's to identify the controller */
+
+      rhport->ehci_dev = ehci_dev;
+      rhport->ehci_dev->ctrid = controller;
 
       /* Initialize EP0 */
 
@@ -5053,12 +5299,26 @@ struct usbhost_connection_s *imxrt_ehci_initialize(int 
controller)
       hport->speed = USB_SPEED_FULL;
     }
 
-#  ifndef CONFIG_IMXRT_EHCI_USB1_PREALLOCATE
+#  if defined(CONFIG_IMXRT_USBOTG1) \
+   && !defined(CONFIG_IMXRT_EHCI_USB1_PREALLOCATE)
   /* Allocate a pool of free Queue Head (QH) structures */
 
-  g_qhpool = kmm_memalign(32, CONFIG_IMXRT_EHCI_USB1_NQHS *
-                              sizeof(struct imxrt_qh_s));
-  if (!g_qhpool)
+  g_qhpool_usb1 = kmm_memalign(32, CONFIG_IMXRT_EHCI_USB1_NQHS *
+                               sizeof(struct imxrt_qh_s));
+  if (!g_qhpool_usb1)
+    {
+      usbhost_trace1(EHCI_TRACE1_QHPOOLALLOC_FAILED, 0);
+      return NULL;
+    }
+#  endif
+
+#  if defined(CONFIG_IMXRT_USBOTG2) \
+   && !defined(CONFIG_IMXRT_EHCI_USB2_PREALLOCATE)
+  /* Allocate a pool of free Queue Head (QH) structures */
+
+  g_qhpool_usb2 = kmm_memalign(32, CONFIG_IMXRT_EHCI_USB2_NQHS *
+                               sizeof(struct imxrt_qh_s));
+  if (!g_qhpool_usb2)
     {
       usbhost_trace1(EHCI_TRACE1_QHPOOLALLOC_FAILED, 0);
       return NULL;
@@ -5067,46 +5327,106 @@ struct usbhost_connection_s *imxrt_ehci_initialize(int 
controller)
 
   /* Initialize the list of free Queue Head (QH) structures */
 
-  for (i = 0; i < CONFIG_IMXRT_EHCI_USB1_NQHS; i++)
+#  if defined(CONFIG_IMXRT_USBOTG1)
+  if (controller == 0)
+    {
+      end = CONFIG_IMXRT_EHCI_USB1_NQHS;
+    }
+#endif
+
+#  if defined(CONFIG_IMXRT_USBOTG2)
+  if (controller == 1)
+    {
+      end = CONFIG_IMXRT_EHCI_USB2_NQHS;
+    }
+#endif
+
+  for (i = 0; i < end; i++)
     {
       /* Put the QH structure in a free list */
 
-      imxrt_qh_free(&g_qhpool[i]);
+      imxrt_qh_free(&qhpool[i], ehci_dev);
     }
 
-#  ifndef CONFIG_IMXRT_EHCI_USB1_PREALLOCATE
+#  if defined(CONFIG_IMXRT_USBOTG1) \
+   && !defined(CONFIG_IMXRT_EHCI_USB1_PREALLOCATE)
   /* Allocate a pool of free Transfer Descriptor (qTD) structures */
 
-  g_qtdpool = kmm_memalign(32, CONFIG_IMXRT_EHCI_USB1_NQTDS *
+  g_qtdpool_usb1 = kmm_memalign(32, CONFIG_IMXRT_EHCI_USB1_NQTDS *
                                sizeof(struct imxrt_qtd_s));
-  if (!g_qtdpool)
+  if (!g_qtdpool_usb1)
     {
       usbhost_trace1(EHCI_TRACE1_QTDPOOLALLOC_FAILED, 0);
-      kmm_free(g_qhpool);
+      kmm_free(g_qhpool_usb1);
       return NULL;
     }
 #  endif
 
-#  if !defined(CONFIG_IMXRT_EHCI_USB1_PREALLOCATE) && 
!defined(CONFIG_USBHOST_INT_DISABLE)
+#  if defined(CONFIG_IMXRT_USBOTG2) \
+   && !defined(CONFIG_IMXRT_EHCI_USB2_PREALLOCATE)
+  /* Allocate a pool of free Transfer Descriptor (qTD) structures */
+
+  g_qtdpool_usb2 = kmm_memalign(32, CONFIG_IMXRT_EHCI_USB2_NQTDS *
+                               sizeof(struct imxrt_qtd_s));
+  if (!g_qtdpool_usb2)
+    {
+      usbhost_trace1(EHCI_TRACE1_QTDPOOLALLOC_FAILED, 0);
+      kmm_free(g_qhpool_usb2);
+      return NULL;
+    }
+#  endif
+
+#  if defined(CONFIG_IMXRT_USBOTG1) && \
+     !defined(CONFIG_IMXRT_EHCI_USB1_PREALLOCATE) && \
+     !defined(CONFIG_USBHOST_INT_DISABLE)
   /* Allocate the periodic framelist */
 
-  g_framelist = kmm_memalign(4096, FRAME_LIST_SIZE * sizeof(uint32_t));
-  if (!g_framelist)
+  g_framelist_usb1 = kmm_memalign(4096, FRAME_LIST_SIZE * sizeof(uint32_t));
+  if (!g_framelist_usb1)
     {
       usbhost_trace1(EHCI_TRACE1_PERFLALLOC_FAILED, 0);
-      kmm_free(g_qhpool);
-      kmm_free(g_qtdpool);
+      kmm_free(g_qhpool_usb1);
+      kmm_free(g_qtdpool_usb1);
       return NULL;
     }
 #  endif
 
+#  if defined(CONFIG_IMXRT_USBOTG2) && \
+     !defined(CONFIG_IMXRT_EHCI_USB2_PREALLOCATE) && \
+     !defined(CONFIG_USBHOST_INT_DISABLE)
+  /* Allocate the periodic framelist */
+
+  g_framelist_usb2 = kmm_memalign(4096, FRAME_LIST_SIZE * sizeof(uint32_t));
+  if (!g_framelist_usb2)
+    {
+      usbhost_trace1(EHCI_TRACE1_PERFLALLOC_FAILED, 0);
+      kmm_free(g_qhpool_usb2);
+      kmm_free(g_qtdpool_usb2);
+      return NULL;
+    }
+#  endif
+
+#  if defined(CONFIG_IMXRT_USBOTG1)
+  if (controller == 0)
+    {
+      end = CONFIG_IMXRT_EHCI_USB1_NQTDS;
+    }
+#endif
+
+#  if defined(CONFIG_IMXRT_USBOTG2)
+  if (controller == 1)
+    {
+      end = CONFIG_IMXRT_EHCI_USB2_NQTDS;
+    }
+#endif
+
   /* Initialize the list of free Transfer Descriptor (qTD) structures */
 
-  for (i = 0; i < CONFIG_IMXRT_EHCI_USB1_NQTDS; i++)
+  for (i = 0; i < end; i++)
     {
       /* Put the TD in a free list */
 
-      imxrt_qtd_free(&g_qtdpool[i]);
+      imxrt_qtd_free(&qtdpool[i], ehci_dev);
     }
 
   /* EHCI Hardware Configuration ********************************************/
@@ -5115,8 +5435,9 @@ struct usbhost_connection_s *imxrt_ehci_initialize(int 
controller)
 
   /* Reset the controller from the OTG peripheral */
 
-  putreg32(USBDEV_USBCMD_RST, IMXRT_USBDEV_USBCMD);
-  while ((getreg32(IMXRT_USBDEV_USBCMD) & USBDEV_USBCMD_RST) != 0);
+  putreg32(USBDEV_USBCMD_RST, IMXRT_USBDEV_USBCMD(controller));
+  while ((getreg32(IMXRT_USBDEV_USBCMD(controller)) &
+          USBDEV_USBCMD_RST) != 0);
 
   /* Program the controller to be the USB host controller Fixed selections:
    * CM = Host mode ES = 0, Little endian mode.  SLOM Not used in host mode.
@@ -5125,17 +5446,17 @@ struct usbhost_connection_s *imxrt_ehci_initialize(int 
controller)
    * some performance.
    */
 
-#  ifdef CONFIG_IMXRT_EHCI_USB1_SDIS
+#  if defined(CONFIG_IMXRT_EHCI_USB1_SDIS) || 
defined(CONFIG_IMXRT_EHCI_USB2_SDIS)
   putreg32(USBHOST_USBMODE_CM_HOST | USBHOST_USBMODE_SDIS |
-           USBHOST_USBMODE_VBPS, IMXRT_USBDEV_USBMODE);
+           USBHOST_USBMODE_VBPS, IMXRT_USBDEV_USBMODE(controller));
 #  else
   putreg32(USBHOST_USBMODE_CM_HOST | USBHOST_USBMODE_VBPS,
-           IMXRT_USBDEV_USBMODE);
+           IMXRT_USBDEV_USBMODE(controller));
 #  endif
 
   /* Reset the EHCI hardware */
 
-  ret = imxrt_reset();
+  ret = imxrt_reset(controller);
   if (ret < 0)
     {
       usbhost_trace1(EHCI_TRACE1_RESET_FAILED, -ret);
@@ -5147,33 +5468,33 @@ struct usbhost_connection_s *imxrt_ehci_initialize(int 
controller)
    * host configuration in the reset.
    */
 
-#  ifdef CONFIG_IMXRT_EHCI_USB1_SDIS
+#  if defined(CONFIG_IMXRT_EHCI_USB1_SDIS) || 
defined(CONFIG_IMXRT_EHCI_USB2_SDIS)
   putreg32(USBHOST_USBMODE_CM_HOST | USBHOST_USBMODE_SDIS |
-           USBHOST_USBMODE_VBPS, IMXRT_USBDEV_USBMODE);
+           USBHOST_USBMODE_VBPS, IMXRT_USBDEV_USBMODE(controller));
 #  else
   putreg32(USBHOST_USBMODE_CM_HOST | USBHOST_USBMODE_VBPS,
-           IMXRT_USBDEV_USBMODE);
+           IMXRT_USBDEV_USBMODE(controller));
 #  endif
 
   /* Disable all interrupts */
 
-  imxrt_putreg(0, &HCOR->usbintr);
+  imxrt_putreg(0, &HCOR(controller)->usbintr);
 
   /* Clear pending interrupts.  Bits in the USBSTS register are cleared by
    * writing a '1' to the corresponding bit.
    */
 
-  imxrt_putreg(EHCI_INT_ALLINTS, &HCOR->usbsts);
+  imxrt_putreg(EHCI_INT_ALLINTS, &HCOR(controller)->usbsts);
 
 #  if defined(CONFIG_DEBUG_USB) && defined(CONFIG_DEBUG_INFO)
   /* Show the EHCI version */
 
-  regval16 = imxrt_swap16(HCCR->hciversion);
+  regval16 = imxrt_swap16(HCCR(controller)->hciversion);
   usbhost_vtrace2(EHCI_VTRACE2_HCIVERSION, regval16 >> 8, regval16 & 0xff);
 
   /* Verify that the correct number of ports is reported */
 
-  regval = imxrt_getreg(&HCCR->hcsparams);
+  regval = imxrt_getreg(&HCCR(controller)->hcsparams);
   nports = (regval & EHCI_HCSPARAMS_NPORTS_MASK) >>
             EHCI_HCSPARAMS_NPORTS_SHIFT;
 
@@ -5182,7 +5503,7 @@ struct usbhost_connection_s *imxrt_ehci_initialize(int 
controller)
 
   /* Show the HCCPARAMS register */
 
-  regval = imxrt_getreg(&HCCR->hccparams);
+  regval = imxrt_getreg(&HCCR(controller)->hccparams);
   usbhost_vtrace1(EHCI_VTRACE1_HCCPARAMS, regval);
 #  endif
 
@@ -5198,21 +5519,21 @@ struct usbhost_connection_s *imxrt_ehci_initialize(int 
controller)
    * port is reset (and enabled)."
    */
 
-  memset(&g_asynchead, 0, sizeof(struct imxrt_qh_s));
-  physaddr = imxrt_physramaddr((uintptr_t)&g_asynchead);
-  g_asynchead.hw.hlp = imxrt_swap32(physaddr | QH_HLP_TYP_QH);
-  g_asynchead.hw.epchar = imxrt_swap32(QH_EPCHAR_H | QH_EPCHAR_EPS_FULL);
-  g_asynchead.hw.overlay.nqp = imxrt_swap32(QH_NQP_T);
-  g_asynchead.hw.overlay.alt = imxrt_swap32(QH_NQP_T);
-  g_asynchead.hw.overlay.token = imxrt_swap32(QH_TOKEN_HALTED);
-  g_asynchead.fqp = imxrt_swap32(QTD_NQP_T);
+  memset(asynchead, 0, sizeof(struct imxrt_qh_s));
+  physaddr = imxrt_physramaddr((uintptr_t)asynchead);
+  asynchead->hw.hlp = imxrt_swap32(physaddr | QH_HLP_TYP_QH);
+  asynchead->hw.epchar = imxrt_swap32(QH_EPCHAR_H | QH_EPCHAR_EPS_FULL);
+  asynchead->hw.overlay.nqp = imxrt_swap32(QH_NQP_T);
+  asynchead->hw.overlay.alt = imxrt_swap32(QH_NQP_T);
+  asynchead->hw.overlay.token = imxrt_swap32(QH_TOKEN_HALTED);
+  asynchead->fqp = imxrt_swap32(QTD_NQP_T);
 
   /* Set the Current Asynchronous List Address. */
 
-  up_flush_dcache((uintptr_t)&g_asynchead.hw,
-    (uintptr_t)&g_asynchead.hw + sizeof(struct ehci_qh_s));
+  up_flush_dcache((uintptr_t)&asynchead->hw,
+    (uintptr_t)&asynchead->hw + sizeof(struct ehci_qh_s));
 
-  imxrt_putreg(imxrt_swap32(physaddr), &HCOR->asynclistaddr);
+  imxrt_putreg(imxrt_swap32(physaddr), &HCOR(controller)->asynclistaddr);
 
 #  ifndef CONFIG_USBHOST_INT_DISABLE
 
@@ -5221,32 +5542,32 @@ struct usbhost_connection_s *imxrt_ehci_initialize(int 
controller)
    * to point to the Interrupt Queue Head (g_intrhead).
    */
 
-  memset(&g_intrhead, 0, sizeof(struct imxrt_qh_s));
-  g_intrhead.hw.hlp = imxrt_swap32(QH_HLP_T);
-  g_intrhead.hw.overlay.nqp = imxrt_swap32(QH_NQP_T);
-  g_intrhead.hw.overlay.alt = imxrt_swap32(QH_NQP_T);
-  g_intrhead.hw.overlay.token = imxrt_swap32(QH_TOKEN_HALTED);
-  g_intrhead.hw.epcaps = imxrt_swap32(QH_EPCAPS_SSMASK(1));
+  memset(intrhead, 0, sizeof(struct imxrt_qh_s));
+  intrhead->hw.hlp = imxrt_swap32(QH_HLP_T);
+  intrhead->hw.overlay.nqp = imxrt_swap32(QH_NQP_T);
+  intrhead->hw.overlay.alt = imxrt_swap32(QH_NQP_T);
+  intrhead->hw.overlay.token = imxrt_swap32(QH_TOKEN_HALTED);
+  intrhead->hw.epcaps = imxrt_swap32(QH_EPCAPS_SSMASK(1));
 
   /* Attach the periodic QH to Period Frame List */
 
-  physaddr = imxrt_physramaddr((uintptr_t)&g_intrhead);
+  physaddr = imxrt_physramaddr((uintptr_t)intrhead);
   for (i = 0; i < FRAME_LIST_SIZE; i++)
     {
-      g_framelist[i] = imxrt_swap32(physaddr) | PFL_TYP_QH;
+      framelist[i] = imxrt_swap32(physaddr) | PFL_TYP_QH;
     }
 
   /* Set the Periodic Frame List Base Address. */
 
-  physaddr = imxrt_physramaddr((uintptr_t) g_framelist);
-  imxrt_putreg(imxrt_swap32(physaddr), &HCOR->periodiclistbase);
+  physaddr = imxrt_physramaddr((uintptr_t) framelist);
+  imxrt_putreg(imxrt_swap32(physaddr), &HCOR(controller)->periodiclistbase);
 #  endif
 
   /* Enable the asynchronous schedule and, possibly enable the periodic
    * schedule and set the frame list size.
    */
 
-  regval = imxrt_getreg(&HCOR->usbcmd);
+  regval = imxrt_getreg(&HCOR(controller)->usbcmd);
   regval &= ~(EHCI_USBCMD_HCRESET | EHCI_USBCMD_FLSIZE_MASK |
               EHCI_USBCMD_FLSIZE_MASK | EHCI_USBCMD_PSEN |
               EHCI_USBCMD_IAADB | EHCI_USBCMD_LRESET);
@@ -5265,45 +5586,65 @@ struct usbhost_connection_s *imxrt_ehci_initialize(int 
controller)
 #    endif
 #  endif
 
-  imxrt_putreg(regval, &HCOR->usbcmd);
+  imxrt_putreg(regval, &HCOR(controller)->usbcmd);
 
   /* Start the host controller by setting the RUN bit in the USBCMD
    * register.
    */
 
-  regval = imxrt_getreg(&HCOR->usbcmd);
+  regval = imxrt_getreg(&HCOR(controller)->usbcmd);
   regval |= EHCI_USBCMD_RUN;
-  imxrt_putreg(regval, &HCOR->usbcmd);
+  imxrt_putreg(regval, &HCOR(controller)->usbcmd);
 
   /* Route all ports to this host controller by setting the CONFIG flag. */
 
-  regval = imxrt_getreg(&HCOR->configflag);
+  regval = imxrt_getreg(&HCOR(controller)->configflag);
   regval |= EHCI_CONFIGFLAG;
-  imxrt_putreg(regval, &HCOR->configflag);
+  imxrt_putreg(regval, &HCOR(controller)->configflag);
 
   /* Wait for the EHCI to run (i.e., no longer report halted) */
 
-  ret = ehci_wait_usbsts(EHCI_USBSTS_HALTED, 0, 100 * 1000);
+  ret = ehci_wait_usbsts(controller, EHCI_USBSTS_HALTED, 0, 100 * 1000);
   if (ret < 0)
     {
-      usbhost_trace1(EHCI_TRACE1_RUN_FAILED, imxrt_getreg(&HCOR->usbsts));
+      usbhost_trace1(EHCI_TRACE1_RUN_FAILED,
+                     imxrt_getreg(&HCOR(controller)->usbsts));
       return NULL;
     }
 
   /* Interrupt Configuration ************************************************/
 
-  ret = irq_attach(IMXRT_IRQ_USBOTG1, imxrt_ehci_interrupt, NULL);
-  if (ret != 0)
+#ifdef CONFIG_IMXRT_USBOTG1
+  if (controller == 0)
     {
-      usbhost_trace1(EHCI_TRACE1_IRQATTACH_FAILED, IMXRT_IRQ_USBOTG1);
-      return NULL;
+      ret = irq_attach(IMXRT_IRQ_USBOTG1, imxrt_ehci_interrupt,
+                       (void *) ehci_dev);
+      if (ret != 0)
+        {
+          usbhost_trace1(EHCI_TRACE1_IRQATTACH_FAILED, IMXRT_IRQ_USBOTG1);
+          return NULL;
+        }
     }
+#endif
+
+#ifdef CONFIG_IMXRT_USBOTG2
+  if (controller == 1)
+    {
+      ret = irq_attach(IMXRT_IRQ_USBOTG1, imxrt_ehci_interrupt,
+                       (void *) ehci_dev);
+      if (ret != 0)
+        {
+          usbhost_trace1(EHCI_TRACE1_IRQATTACH_FAILED, IMXRT_IRQ_USBOTG2);
+          return NULL;
+        }
+    }
+#endif
 
   /* Enable EHCI interrupts.  Interrupts are still disabled at the level of
    * the interrupt controller.
    */
 
-  imxrt_putreg(EHCI_HANDLED_INTS, &HCOR->usbintr);
+  imxrt_putreg(EHCI_HANDLED_INTS, &HCOR(controller)->usbintr);
 
   /* Enable interrupts at the interrupt controller */
 
@@ -5315,7 +5656,7 @@ struct usbhost_connection_s *imxrt_ehci_initialize(int 
controller)
     {
       /* Enable VBUS power for the port */
 
-      imxrt_usbhost_vbusdrive(i, true);
+      imxrt_usbhost_vbusdrive(controller, i, true);
       up_mdelay(25);
     }
 
@@ -5326,13 +5667,14 @@ struct usbhost_connection_s *imxrt_ehci_initialize(int 
controller)
 
   for (i = 0; i < IMXRT_EHCI_NRHPORT; i++)
     {
-      g_ehci.rhport[i].connected =
-        ((imxrt_getreg(&HCOR->portsc[i]) & EHCI_PORTSC_CCS) != 0);
+      ehci->rhport[i].connected =
+        ((imxrt_getreg(&HCOR(controller)->portsc[i]) &
+         EHCI_PORTSC_CCS) != 0);
     }
 
   usbhost_vtrace1(EHCI_VTRACE1_INIITIALIZED, 0);
 
-  return &g_ehciconn;
+  return (struct usbhost_connection_s *) usb_conn;
 }
 
 /****************************************************************************
diff --git a/arch/arm/src/imxrt/imxrt_ehci.h b/arch/arm/src/imxrt/imxrt_ehci.h
index 1be1241129..f97503e22d 100644
--- a/arch/arm/src/imxrt/imxrt_ehci.h
+++ b/arch/arm/src/imxrt/imxrt_ehci.h
@@ -76,7 +76,7 @@ extern "C"
  *
  ****************************************************************************/
 
-extern void imxrt_usbhost_vbusdrive(int rhport, bool enable);
+extern void imxrt_usbhost_vbusdrive(int ctrid, int rhport, bool enable);
 
 /****************************************************************************
  * Name: imxrt_setup_overcurrent
diff --git a/arch/arm/src/imxrt/imxrt_usbdev.c 
b/arch/arm/src/imxrt/imxrt_usbdev.c
index a3eb705bc5..66012b7c76 100644
--- a/arch/arm/src/imxrt/imxrt_usbdev.c
+++ b/arch/arm/src/imxrt/imxrt_usbdev.c
@@ -791,9 +791,9 @@ static void imxrt_queuedtd(uint8_t epphy, struct 
imxrt_dtd_s *dtd)
 
   uint32_t bit = IMXRT_ENDPTMASK(epphy);
 
-  imxrt_setbits(bit, IMXRT_USBDEV_ENDPTPRIME);
+  imxrt_setbits(bit, IMXRT_USBDEV_ENDPTPRIME(0));
 
-  while (imxrt_getreg(IMXRT_USBDEV_ENDPTPRIME) & bit)
+  while (imxrt_getreg(IMXRT_USBDEV_ENDPTPRIME(0)) & bit)
     ;
 }
 
@@ -832,7 +832,7 @@ static void imxrt_readsetup(uint8_t epphy, struct 
usb_ctrlreq_s *ctrl)
     {
       /* Set the trip wire */
 
-      imxrt_setbits(USBDEV_USBCMD_SUTW, IMXRT_USBDEV_USBCMD);
+      imxrt_setbits(USBDEV_USBCMD_SUTW, IMXRT_USBDEV_USBCMD(0));
 
       up_invalidate_dcache((uintptr_t)dqh,
                            (uintptr_t)dqh + sizeof(struct imxrt_dqh_s));
@@ -844,15 +844,16 @@ static void imxrt_readsetup(uint8_t epphy, struct 
usb_ctrlreq_s *ctrl)
           ((uint8_t *) ctrl)[i] = ((uint8_t *) dqh->setup)[i];
         }
     }
-  while (!(imxrt_getreg(IMXRT_USBDEV_USBCMD) & USBDEV_USBCMD_SUTW));
+  while (!(imxrt_getreg(IMXRT_USBDEV_USBCMD(0)) & USBDEV_USBCMD_SUTW));
 
   /* Clear the trip wire */
 
-  imxrt_clrbits(USBDEV_USBCMD_SUTW, IMXRT_USBDEV_USBCMD);
+  imxrt_clrbits(USBDEV_USBCMD_SUTW, IMXRT_USBDEV_USBCMD(0));
 
   /* Clear the Setup Interrupt */
 
-  imxrt_putreg(IMXRT_ENDPTMASK(IMXRT_EP0_OUT), IMXRT_USBDEV_ENDPTSETUPSTAT);
+  imxrt_putreg(IMXRT_ENDPTMASK(IMXRT_EP0_OUT),
+               IMXRT_USBDEV_ENDPTSETUPSTAT(0));
 }
 
 /****************************************************************************
@@ -871,7 +872,7 @@ static inline void imxrt_set_address(struct imxrt_usbdev_s 
*priv,
 
   imxrt_chgbits(USBDEV_DEVICEADDR_MASK,
                 priv->paddr << USBDEV_DEVICEADDR_SHIFT,
-                IMXRT_USBDEV_DEVICEADDR);
+                IMXRT_USBDEV_DEVICEADDR(0));
 }
 
 /****************************************************************************
@@ -887,11 +888,11 @@ static void imxrt_flushep(struct imxrt_ep_s *privep)
   uint32_t mask = IMXRT_ENDPTMASK(privep->epphy);
   do
     {
-      imxrt_putreg(mask, IMXRT_USBDEV_ENDPTFLUSH);
-      while ((imxrt_getreg(IMXRT_USBDEV_ENDPTFLUSH) & mask) != 0)
+      imxrt_putreg(mask, IMXRT_USBDEV_ENDPTFLUSH(0));
+      while ((imxrt_getreg(IMXRT_USBDEV_ENDPTFLUSH(0)) & mask) != 0)
       ;
     }
-  while ((imxrt_getreg(IMXRT_USBDEV_ENDPTSTATUS) & mask) != 0);
+  while ((imxrt_getreg(IMXRT_USBDEV_ENDPTSTATUS(0)) & mask) != 0);
 }
 
 /****************************************************************************
@@ -1138,7 +1139,7 @@ static void imxrt_ep0configure(struct imxrt_usbdev_s 
*priv)
   /* Enable EP0 */
 
   imxrt_setbits(USBDEV_ENDPTCTRL0_RXE | USBDEV_ENDPTCTRL0_TXE,
-                IMXRT_USBDEV_ENDPTCTRL0);
+                IMXRT_USBDEV_ENDPTCTRL0(0));
 }
 
 /****************************************************************************
@@ -1156,33 +1157,33 @@ static void imxrt_usbreset(struct imxrt_usbdev_s *priv)
   /* Disable all endpoints. Control endpoint 0 is always enabled */
 
   imxrt_clrbits(USBDEV_ENDPTCTRL_RXE | USBDEV_ENDPTCTRL_TXE,
-                IMXRT_USBDEV_ENDPTCTRL1);
+                IMXRT_USBDEV_ENDPTCTRL1(0));
   imxrt_clrbits(USBDEV_ENDPTCTRL_RXE | USBDEV_ENDPTCTRL_TXE,
-                IMXRT_USBDEV_ENDPTCTRL2);
+                IMXRT_USBDEV_ENDPTCTRL2(0));
   imxrt_clrbits(USBDEV_ENDPTCTRL_RXE | USBDEV_ENDPTCTRL_TXE,
-                IMXRT_USBDEV_ENDPTCTRL3);
+                IMXRT_USBDEV_ENDPTCTRL3(0));
   imxrt_clrbits(USBDEV_ENDPTCTRL_RXE | USBDEV_ENDPTCTRL_TXE,
-                IMXRT_USBDEV_ENDPTCTRL4);
+                IMXRT_USBDEV_ENDPTCTRL4(0));
   imxrt_clrbits(USBDEV_ENDPTCTRL_RXE | USBDEV_ENDPTCTRL_TXE,
-                IMXRT_USBDEV_ENDPTCTRL5);
+                IMXRT_USBDEV_ENDPTCTRL5(0));
 
   /* Clear all pending interrupts */
 
-  imxrt_putreg(imxrt_getreg(IMXRT_USBDEV_ENDPTNAK),
-               IMXRT_USBDEV_ENDPTNAK);
-  imxrt_putreg(imxrt_getreg(IMXRT_USBDEV_ENDPTSETUPSTAT),
-               IMXRT_USBDEV_ENDPTSETUPSTAT);
-  imxrt_putreg(imxrt_getreg(IMXRT_USBDEV_ENDPTCOMPLETE),
-               IMXRT_USBDEV_ENDPTCOMPLETE);
+  imxrt_putreg(imxrt_getreg(IMXRT_USBDEV_ENDPTNAK(0)),
+               IMXRT_USBDEV_ENDPTNAK(0));
+  imxrt_putreg(imxrt_getreg(IMXRT_USBDEV_ENDPTSETUPSTAT(0)),
+               IMXRT_USBDEV_ENDPTSETUPSTAT(0));
+  imxrt_putreg(imxrt_getreg(IMXRT_USBDEV_ENDPTCOMPLETE(0)),
+               IMXRT_USBDEV_ENDPTCOMPLETE(0));
 
   /* Wait for all prime operations to have completed and then flush all
    * DTDs
    */
 
-  while (imxrt_getreg(IMXRT_USBDEV_ENDPTPRIME) != 0)
+  while (imxrt_getreg(IMXRT_USBDEV_ENDPTPRIME(0)) != 0)
     ;
-  imxrt_putreg(IMXRT_ENDPTMASK_ALL, IMXRT_USBDEV_ENDPTFLUSH);
-  while (imxrt_getreg(IMXRT_USBDEV_ENDPTFLUSH))
+  imxrt_putreg(IMXRT_ENDPTMASK_ALL, IMXRT_USBDEV_ENDPTFLUSH(0));
+  while (imxrt_getreg(IMXRT_USBDEV_ENDPTFLUSH(0)))
     ;
 
   /* Reset endpoints */
@@ -1210,7 +1211,7 @@ static void imxrt_usbreset(struct imxrt_usbdev_s *priv)
   /* Set the interrupt Threshold control interval to 0 */
 
   imxrt_chgbits(USBDEV_USBCMD_ITC_MASK, USBDEV_USBCMD_ITCIMME,
-                IMXRT_USBDEV_USBCMD);
+                IMXRT_USBDEV_USBCMD(0));
 
   /* Zero out the Endpoint queue heads */
 
@@ -1226,7 +1227,7 @@ static void imxrt_usbreset(struct imxrt_usbdev_s *priv)
 
   /* Initialise the Endpoint List Address */
 
-  imxrt_putreg((uint32_t)g_qh, IMXRT_USBDEV_ENDPOINTLIST);
+  imxrt_putreg((uint32_t)g_qh, IMXRT_USBDEV_ENDPOINTLIST(0));
 
   /* EndPoint 0 initialization */
 
@@ -1236,7 +1237,7 @@ static void imxrt_usbreset(struct imxrt_usbdev_s *priv)
 
   imxrt_putreg(USB_FRAME_INT | USB_ERROR_INT | USBDEV_USBINTR_NAKE |
                USBDEV_USBINTR_SLE | USBDEV_USBINTR_URE | USBDEV_USBINTR_PCE |
-               USBDEV_USBINTR_UE, IMXRT_USBDEV_USBINTR);
+               USBDEV_USBINTR_UE, IMXRT_USBDEV_USBINTR(0));
 }
 
 /****************************************************************************
@@ -1255,15 +1256,17 @@ static inline void imxrt_ep0state(struct imxrt_usbdev_s 
*priv,
   switch (state)
     {
     case EP0STATE_WAIT_NAK_IN:
-      imxrt_putreg(IMXRT_ENDPTMASK(IMXRT_EP0_IN), IMXRT_USBDEV_ENDPTNAKEN);
+      imxrt_putreg(IMXRT_ENDPTMASK(IMXRT_EP0_IN),
+                   IMXRT_USBDEV_ENDPTNAKEN(0));
       break;
 
     case EP0STATE_WAIT_NAK_OUT:
-      imxrt_putreg(IMXRT_ENDPTMASK(IMXRT_EP0_OUT), IMXRT_USBDEV_ENDPTNAKEN);
+      imxrt_putreg(IMXRT_ENDPTMASK(IMXRT_EP0_OUT),
+                   IMXRT_USBDEV_ENDPTNAKEN(0));
       break;
 
     default:
-      imxrt_putreg(0, IMXRT_USBDEV_ENDPTNAKEN);
+      imxrt_putreg(0, IMXRT_USBDEV_ENDPTNAKEN(0));
       break;
     }
 }
@@ -1920,8 +1923,8 @@ static int imxrt_usbinterrupt(int irq, void *context, 
void *arg)
 
   /* Read the interrupts and then clear them */
 
-  disr = imxrt_getreg(IMXRT_USBDEV_USBSTS);
-  imxrt_putreg(disr, IMXRT_USBDEV_USBSTS);
+  disr = imxrt_getreg(IMXRT_USBDEV_USBSTS(0));
+  imxrt_putreg(disr, IMXRT_USBDEV_USBSTS(0));
 
   if (disr & USBDEV_USBSTS_URI)
     {
@@ -1973,7 +1976,7 @@ static int imxrt_usbinterrupt(int irq, void *context, 
void *arg)
 
   if (disr & USBDEV_USBSTS_PCI)
     {
-      portsc1 = imxrt_getreg(IMXRT_USBDEV_PORTSC1);
+      portsc1 = imxrt_getreg(IMXRT_USBDEV_PORTSC1(0));
 
       if (portsc1 & USBDEV_PRTSC1_HSP)
         priv->usbdev.speed = USB_SPEED_HIGH;
@@ -1996,7 +1999,7 @@ static int imxrt_usbinterrupt(int irq, void *context, 
void *arg)
     {
       usbtrace(TRACE_INTDECODE(IMXRT_TRACEINTID_FRAME), 0);
 
-      uint32_t frindex = imxrt_getreg(IMXRT_USBDEV_FRINDEX);
+      uint32_t frindex = imxrt_getreg(IMXRT_USBDEV_FRINDEX(0));
       uint16_t frame_num =
           (frindex & USBDEV_FRINDEX_LFN_MASK) >> USBDEV_FRINDEX_LFN_SHIFT;
 
@@ -2016,14 +2019,14 @@ static int imxrt_usbinterrupt(int irq, void *context, 
void *arg)
     {
       /* Handle completion interrupts */
 
-      uint32_t mask = imxrt_getreg(IMXRT_USBDEV_ENDPTCOMPLETE);
+      uint32_t mask = imxrt_getreg(IMXRT_USBDEV_ENDPTCOMPLETE(0));
 
       if (mask)
         {
           /* Clear any NAK interrupt and completion interrupts */
 
-          imxrt_putreg(mask, IMXRT_USBDEV_ENDPTNAK);
-          imxrt_putreg(mask, IMXRT_USBDEV_ENDPTCOMPLETE);
+          imxrt_putreg(mask, IMXRT_USBDEV_ENDPTNAK(0));
+          imxrt_putreg(mask, IMXRT_USBDEV_ENDPTCOMPLETE(0));
 
           if (mask & IMXRT_ENDPTMASK(0))
             {
@@ -2051,7 +2054,7 @@ static int imxrt_usbinterrupt(int irq, void *context, 
void *arg)
 
       /* Handle setup interrupts */
 
-      uint32_t setupstat = imxrt_getreg(IMXRT_USBDEV_ENDPTSETUPSTAT);
+      uint32_t setupstat = imxrt_getreg(IMXRT_USBDEV_ENDPTSETUPSTAT(0));
       if (setupstat)
         {
           /* Clear the endpoint complete CTRL OUT and IN when a Setup is
@@ -2060,7 +2063,7 @@ static int imxrt_usbinterrupt(int irq, void *context, 
void *arg)
 
           imxrt_putreg(IMXRT_ENDPTMASK(IMXRT_EP0_IN) |
                        IMXRT_ENDPTMASK(IMXRT_EP0_OUT),
-                       IMXRT_USBDEV_ENDPTCOMPLETE);
+                       IMXRT_USBDEV_ENDPTCOMPLETE(0));
 
           if (setupstat & IMXRT_ENDPTMASK(IMXRT_EP0_OUT))
             {
@@ -2073,8 +2076,8 @@ static int imxrt_usbinterrupt(int irq, void *context, 
void *arg)
 
   if (disr & USBDEV_USBSTS_NAKI)
     {
-      uint32_t pending = imxrt_getreg(IMXRT_USBDEV_ENDPTNAK) &
-          imxrt_getreg(IMXRT_USBDEV_ENDPTNAKEN);
+      uint32_t pending = imxrt_getreg(IMXRT_USBDEV_ENDPTNAK(0)) &
+          imxrt_getreg(IMXRT_USBDEV_ENDPTNAKEN(0));
       if (pending)
         {
           /* We shouldn't see NAK interrupts except on Endpoint 0 */
@@ -2092,7 +2095,7 @@ static int imxrt_usbinterrupt(int irq, void *context, 
void *arg)
 
       /* Clear the interrupts */
 
-      imxrt_putreg(pending, IMXRT_USBDEV_ENDPTNAK);
+      imxrt_putreg(pending, IMXRT_USBDEV_ENDPTNAK(0));
     }
 
   usbtrace(TRACE_INTEXIT(IMXRT_TRACEINTID_USB), 0);
@@ -2708,7 +2711,7 @@ static int imxrt_getframe(struct usbdev_s *dev)
   usbtrace(TRACE_DEVGETFRAME, (uint16_t)priv->sof);
   return priv->sof;
 #else
-  uint32_t frindex = imxrt_getreg(IMXRT_USBDEV_FRINDEX);
+  uint32_t frindex = imxrt_getreg(IMXRT_USBDEV_FRINDEX(0));
   uint16_t frame_num =
       (frindex & USBDEV_FRINDEX_LFN_MASK) >> USBDEV_FRINDEX_LFN_SHIFT;
 
@@ -2735,7 +2738,7 @@ static int imxrt_wakeup(struct usbdev_s *dev)
   usbtrace(TRACE_DEVWAKEUP, 0);
 
   flags = enter_critical_section();
-  imxrt_setbits(USBDEV_PRTSC1_FPR, IMXRT_USBDEV_PORTSC1);
+  imxrt_setbits(USBDEV_PRTSC1_FPR, IMXRT_USBDEV_PORTSC1(0));
   leave_critical_section(flags);
   return OK;
 }
@@ -2781,7 +2784,7 @@ static int imxrt_pullup(struct usbdev_s *dev, bool enable)
   irqstate_t flags = enter_critical_section();
   if (enable)
     {
-      imxrt_setbits(USBDEV_USBCMD_RS, IMXRT_USBDEV_USBCMD);
+      imxrt_setbits(USBDEV_USBCMD_RS, IMXRT_USBDEV_USBCMD(0));
 
 #ifdef CONFIG_IMXRT_USB0DEV_NOVBUS
       /* Create a 'false' power event on the USB port so the MAC connects */
@@ -2792,7 +2795,7 @@ static int imxrt_pullup(struct usbdev_s *dev, bool enable)
     }
   else
     {
-      imxrt_clrbits(USBDEV_USBCMD_RS, IMXRT_USBDEV_USBCMD);
+      imxrt_clrbits(USBDEV_USBCMD_RS, IMXRT_USBDEV_USBCMD(0));
     }
 
   leave_critical_section(flags);
@@ -2888,36 +2891,37 @@ void arm_usbinitialize(void)
 #ifdef CONFIG_ARCH_FAMILY_IMXRT117x
   up_mdelay(1);
 
-  putreg32(USBPHY1_PLL_SIC_PLL_POWER |
-           USBPHY1_PLL_SIC_PLL_REG_ENABLE,
-           IMXRT_USBPHY1_PLL_SIC_SET);
+  putreg32(USBPHY_PLL_SIC_PLL_POWER |
+           USBPHY_PLL_SIC_PLL_REG_ENABLE,
+           IMXRT_USBPHY_PLL_SIC_SET(0));
 
-  putreg32(USBPHY1_PLL_SIC_PLL_DIV_SEL_MASK,
-           IMXRT_USBPHY1_PLL_SIC_CLR);
+  putreg32(USBPHY_PLL_SIC_PLL_DIV_SEL_MASK,
+           IMXRT_USBPHY_PLL_SIC_CLR(0));
 
-  putreg32(USBPHY1_PLL_SIC_PLL_DIV_SEL(3),
-           IMXRT_USBPHY1_PLL_SIC_SET);
+  putreg32(USBPHY_PLL_SIC_PLL_DIV_SEL(3),
+           IMXRT_USBPHY_PLL_SIC_SET(0));
 
-  putreg32(USBPHY1_PLL_SIC_PLL_BYPASS,
-           IMXRT_USBPHY1_PLL_SIC_CLR);
+  putreg32(USBPHY_PLL_SIC_PLL_BYPASS,
+           IMXRT_USBPHY_PLL_SIC_CLR(0));
 
-  putreg32(USBPHY1_PLL_SIC_PLL_EN_USB_CLKS,
-           IMXRT_USBPHY1_PLL_SIC_SET);
+  putreg32(USBPHY_PLL_SIC_PLL_EN_USB_CLKS,
+           IMXRT_USBPHY_PLL_SIC_SET(0));
 
   putreg32(USBPHY_CTRL_CLKGATE,
-           IMXRT_USBPHY1_CTRL_CLR);
+           IMXRT_USBPHY_CTRL_CLR(0));
 
-  while ((getreg32(IMXRT_USBPHY1_PLL_SIC) & USBPHY1_PLL_SIC_PLL_LOCK) == 0);
+  while ((getreg32(IMXRT_USBPHY_PLL_SIC(0)) & USBPHY_PLL_SIC_PLL_LOCK) == 0);
 
 #endif
 
   /* Disable USB interrupts */
 
-  imxrt_putreg(0, IMXRT_USBDEV_USBINTR);
+  imxrt_putreg(0, IMXRT_USBDEV_USBINTR(0));
 
   /* Soft reset PHY and enable clock */
 
-  putreg32(USBPHY_CTRL_SFTRST | USBPHY_CTRL_CLKGATE, IMXRT_USBPHY1_CTRL_CLR);
+  putreg32(USBPHY_CTRL_SFTRST | USBPHY_CTRL_CLKGATE,
+           IMXRT_USBPHY_CTRL_CLR(0));
 
   /* Disconnect device */
 
@@ -2925,8 +2929,8 @@ void arm_usbinitialize(void)
 
   /* Reset the controller */
 
-  imxrt_setbits(USBDEV_USBCMD_RST, IMXRT_USBDEV_USBCMD);
-  while (imxrt_getreg(IMXRT_USBDEV_USBCMD) & USBDEV_USBCMD_RST)
+  imxrt_setbits(USBDEV_USBCMD_RST, IMXRT_USBDEV_USBCMD(0));
+  while (imxrt_getreg(IMXRT_USBDEV_USBCMD(0)) & USBDEV_USBCMD_RST)
       ;
 
   /* Power up the PHY (turn off power disable) - USBPHYx_PWDn
@@ -2936,12 +2940,12 @@ void arm_usbinitialize(void)
    * CCM_ANALOG_USBPHYx_PLL_480_CTRLn.
    */
 
-  imxrt_putreg(0, IMXRT_USBPHY1_PWD);
+  imxrt_putreg(0, IMXRT_USBPHY_PWD(0));
 
   /* Program the controller to be the USB device controller */
 
   imxrt_putreg(USBDEV_USBMODE_SDIS | USBDEV_USBMODE_SLOM |
-                USBDEV_USBMODE_CM_DEVICE, IMXRT_USBDEV_USBMODE);
+                USBDEV_USBMODE_CM_DEVICE, IMXRT_USBDEV_USBMODE(0));
 
   /* Attach USB controller interrupt handler */
 
@@ -2986,15 +2990,15 @@ void arm_usbuninitialize(void)
 
   /* Reset the controller */
 
-  imxrt_setbits(USBDEV_USBCMD_RST, IMXRT_USBDEV_USBCMD);
-  while (imxrt_getreg(IMXRT_USBDEV_USBCMD) & USBDEV_USBCMD_RST)
+  imxrt_setbits(USBDEV_USBCMD_RST, IMXRT_USBDEV_USBCMD(0));
+  while (imxrt_getreg(IMXRT_USBDEV_USBCMD(0)) & USBDEV_USBCMD_RST)
       ;
 
   /* Turn off USB power and clocking */
 
   /* Power down the PHY */
 
-  imxrt_putreg(0xffffffff, IMXRT_USBPHY1_PWD);
+  imxrt_putreg(0xffffffff, IMXRT_USBPHY_PWD(0));
 
   /* Stop clock
    * NOTE: This will interfere with USB OTG 2 and should probably be removed

Reply via email to