summaryrefslogtreecommitdiffstats
path: root/sys/dev/usb/controller/dwc_otg.c
diff options
context:
space:
mode:
authorhselasky <hselasky@FreeBSD.org>2015-11-06 13:34:55 +0000
committerhselasky <hselasky@FreeBSD.org>2015-11-06 13:34:55 +0000
commitdb79c0ea60938d1fbeb64dbd3b3150c257cc0067 (patch)
tree8fb8892e5dd59992b32a7ae7cb97958ca2b32664 /sys/dev/usb/controller/dwc_otg.c
parent35ef2880578082538f62f53ea7940b4e76e659bc (diff)
downloadFreeBSD-src-db79c0ea60938d1fbeb64dbd3b3150c257cc0067.zip
FreeBSD-src-db79c0ea60938d1fbeb64dbd3b3150c257cc0067.tar.gz
MFC r290195:
Reduce the DWC OTG interrupt load by not reading all the host channel status registers for every interrupt. Check a common host channel status interrupt register first, then conditionally read the individual host channel status registers.
Diffstat (limited to 'sys/dev/usb/controller/dwc_otg.c')
-rw-r--r--sys/dev/usb/controller/dwc_otg.c17
1 files changed, 11 insertions, 6 deletions
diff --git a/sys/dev/usb/controller/dwc_otg.c b/sys/dev/usb/controller/dwc_otg.c
index 744321b..14cf5ce 100644
--- a/sys/dev/usb/controller/dwc_otg.c
+++ b/sys/dev/usb/controller/dwc_otg.c
@@ -2559,6 +2559,7 @@ dwc_otg_interrupt_poll_locked(struct dwc_otg_softc *sc)
struct usb_xfer *xfer;
uint32_t count;
uint32_t temp;
+ uint32_t haint;
uint8_t got_rx_status;
uint8_t x;
@@ -2576,14 +2577,18 @@ repeat:
DPRINTF("Yield\n");
return;
}
+
/* get all host channel interrupts */
- for (x = 0; x != sc->sc_host_ch_max; x++) {
+ haint = DWC_OTG_READ_4(sc, DOTG_HAINT);
+ while (1) {
+ x = ffs(haint) - 1;
+ if (x >= sc->sc_host_ch_max)
+ break;
temp = DWC_OTG_READ_4(sc, DOTG_HCINT(x));
- if (temp != 0) {
- DWC_OTG_WRITE_4(sc, DOTG_HCINT(x), temp);
- temp &= ~HCINT_SOFTWARE_ONLY;
- sc->sc_chan_state[x].hcint |= temp;
- }
+ DWC_OTG_WRITE_4(sc, DOTG_HCINT(x), temp);
+ temp &= ~HCINT_SOFTWARE_ONLY;
+ sc->sc_chan_state[x].hcint |= temp;
+ haint &= ~(1U << x);
}
if (sc->sc_last_rx_status == 0) {
OpenPOWER on IntegriCloud