git: 4c57e83e7b6b - stable/13 - usb: dwc3: implement hw.usb.xhci.use_polling

From: Hans Petter Selasky <hselasky_at_FreeBSD.org>
Date: Sun, 30 Apr 2023 06:57:54 UTC
The branch stable/13 has been updated by hselasky:

URL: https://cgit.FreeBSD.org/src/commit/?id=4c57e83e7b6b4027546844daa3d81484f2b603a6

commit 4c57e83e7b6b4027546844daa3d81484f2b603a6
Author:     Kyle Evans <kevans@FreeBSD.org>
AuthorDate: 2023-02-28 01:59:43 +0000
Commit:     Hans Petter Selasky <hselasky@FreeBSD.org>
CommitDate: 2023-04-30 06:56:17 +0000

    usb: dwc3: implement hw.usb.xhci.use_polling
    
    Polling is currently only implemented in the xhci pci attachment.
    Adding it to dwc3 doesn't make it much uglier, and supporting it can be
    useful for confirming that hardware's otherwise functional when
    interrupts are apparently not firing.
    
    Reviewed by:    manu
    Differential Revision:  https://reviews.freebsd.org/D38816
    
    (cherry picked from commit 5e54bb1ea9e904075225dc96641c2ede3fc3273c)
---
 sys/dev/usb/controller/dwc3.c | 34 ++++++++++++++++++++++++++++------
 1 file changed, 28 insertions(+), 6 deletions(-)

diff --git a/sys/dev/usb/controller/dwc3.c b/sys/dev/usb/controller/dwc3.c
index d5e3b3f50a9d..b99d74625022 100644
--- a/sys/dev/usb/controller/dwc3.c
+++ b/sys/dev/usb/controller/dwc3.c
@@ -103,6 +103,17 @@ struct snps_dwc3_softc {
 
 #define	IS_DMA_32B	1
 
+static void
+xhci_interrupt_poll(void *_sc)
+{
+	struct xhci_softc *sc = _sc;
+
+	USB_BUS_UNLOCK(&sc->sc_bus);
+	xhci_interrupt(sc);
+	USB_BUS_LOCK(&sc->sc_bus);
+	usb_callout_reset(&sc->sc_callout, 1, (void *)&xhci_interrupt_poll, sc);
+}
+
 static int
 snps_dwc3_attach_xhci(device_t dev)
 {
@@ -133,12 +144,14 @@ snps_dwc3_attach_xhci(device_t dev)
 	sprintf(sc->sc_vendor, "Synopsys");
 	device_set_desc(sc->sc_bus.bdev, "Synopsys");
 
-	err = bus_setup_intr(dev, sc->sc_irq_res, INTR_TYPE_BIO | INTR_MPSAFE,
-	    NULL, (driver_intr_t *)xhci_interrupt, sc, &sc->sc_intr_hdl);
-	if (err != 0) {
-		device_printf(dev, "Failed to setup IRQ, %d\n", err);
-		sc->sc_intr_hdl = NULL;
-		return (err);
+	if (xhci_use_polling() == 0) {
+		err = bus_setup_intr(dev, sc->sc_irq_res, INTR_TYPE_BIO | INTR_MPSAFE,
+		    NULL, (driver_intr_t *)xhci_interrupt, sc, &sc->sc_intr_hdl);
+		if (err != 0) {
+			device_printf(dev, "Failed to setup IRQ, %d\n", err);
+			sc->sc_intr_hdl = NULL;
+			return (err);
+		}
 	}
 
 	err = xhci_init(sc, dev, IS_DMA_32B);
@@ -147,6 +160,15 @@ snps_dwc3_attach_xhci(device_t dev)
 		return (ENXIO);
 	}
 
+	usb_callout_init_mtx(&sc->sc_callout, &sc->sc_bus.bus_mtx, 0);
+
+	if (xhci_use_polling() != 0) {
+		device_printf(dev, "Interrupt polling at %dHz\n", hz);
+		USB_BUS_LOCK(&sc->sc_bus);
+		xhci_interrupt_poll(sc);
+		USB_BUS_UNLOCK(&sc->sc_bus);
+	}
+
 	err = xhci_start_controller(sc);
 	if (err != 0) {
 		device_printf(dev, "Failed to start XHCI controller, with error %d\n", err);