diff --git a/drivers/usb/musb/musb_host.c b/drivers/usb/musb/musb_host.c index 8efd2fa472f9..31b061248991 100644 --- a/drivers/usb/musb/musb_host.c +++ b/drivers/usb/musb/musb_host.c @@ -1774,7 +1774,8 @@ void musb_host_rx(struct musb *musb, u8 epnum) status = -EPIPE; } else if (rx_csr & MUSB_RXCSR_H_ERROR) { - dev_err(musb->controller, "ep%d RX three-strikes error", epnum); + dev_err_ratelimited(musb->controller, + "ep%d RX three-strikes error\n", epnum); /* * The three-strikes error could only happen when the USB @@ -1788,6 +1789,17 @@ void musb_host_rx(struct musb *musb, u8 epnum) rx_csr &= ~MUSB_RXCSR_H_ERROR; musb_writew(epio, MUSB_RXCSR, rx_csr); + /* + * Unplugging a USB-Ethernet adapter while it is busy can make + * the controller keep re-asserting the three-strikes error for + * this endpoint before the disconnect is processed. That floods + * the log and can wedge the host port until reboot. Drop the + * stale pending RX interrupt on platforms that support it (e.g. + * AM335x/DSPS) to break the storm; the transfer is still + * aborted below via the fault path. + */ + musb_platform_clear_ep_rxintr(musb, epnum); + } else if (rx_csr & MUSB_RXCSR_DATAERROR) { if (USB_ENDPOINT_XFER_ISOC != qh->type) {