diff --git a/drivers/usbhost/usbhost_xhci.c b/drivers/usbhost/usbhost_xhci.c index ed417a92a52..2c3d3ad559a 100644 --- a/drivers/usbhost/usbhost_xhci.c +++ b/drivers/usbhost/usbhost_xhci.c @@ -1141,6 +1141,10 @@ static int xhci_ctrl_start(FAR struct usbhost_xhci_s *priv) xhci_oper_putreg_8b(priv, XHCI_CRCR, up_addrenv_va_to_pa(priv->cmd.ring) | XHCI_CRCR_RCS); + /* Do not sit on completions; see XHCI_IMOD_INTERVAL */ + + xhci_runt_putreg(priv, XHCI_IMOD(0), XHCI_IMOD_DEFAULT); + /* Enable interrupts */ regval = xhci_runt_getreg(priv, XHCI_IMAN(0)); diff --git a/drivers/usbhost/usbhost_xhci.h b/drivers/usbhost/usbhost_xhci.h index 8f940f8a82c..2fc2aa207ad 100644 --- a/drivers/usbhost/usbhost_xhci.h +++ b/drivers/usbhost/usbhost_xhci.h @@ -315,6 +315,17 @@ #define XHCI_IMOD_IMODI_SHIFT (0) /* Bits 0-15: Interrupt Moderation Interval */ #define XHCI_IMOD_IMODC_SHIFT (16) /* Bits 16-31: Interrupt Moderation Counter */ +/* What to set the moderation interval to, in 250ns units. + * + * The reset default is 4000, a millisecond, which is far too long to wait + * to be told a transfer finished. Zero is too short: it puts no bound on + * how often a controller may interrupt, and a polled device such as a + * keyboard on an interrupt endpoint will then occupy a processor. 160 is + * 40us, which is what Linux uses. + */ + +#define XHCI_IMOD_DEFAULT (160) + /* Event Ring Segment Table Size */ #define XHCI_ERSTS_MASK (0xffff) /* Bit 0-15: Event Ring Segment Table Size */