aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKyle Evans <kevans@FreeBSD.org>2023-02-28 01:59:43 +0000
committerKyle Evans <kevans@FreeBSD.org>2023-02-28 22:16:14 +0000
commit5e54bb1ea9e904075225dc96641c2ede3fc3273c (patch)
tree4c5ffecd885bc00f9829625c951ffc030deffaa5
parentdc8616edc580806afb1efaec1cdc3cc9a1b3804e (diff)
downloadsrc-5e54bb1ea9e904075225dc96641c2ede3fc3273c.tar.gz
src-5e54bb1ea9e904075225dc96641c2ede3fc3273c.zip
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
-rw-r--r--sys/dev/usb/controller/dwc3.c34
1 files changed, 28 insertions, 6 deletions
diff --git a/sys/dev/usb/controller/dwc3.c b/sys/dev/usb/controller/dwc3.c
index 361db0f5e835..dc5c90df0d72 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);