From owner-freebsd-usb@freebsd.org Fri Oct 30 13:47:30 2015 Return-Path: Delivered-To: freebsd-usb@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id 75C48A1E0C9 for ; Fri, 30 Oct 2015 13:47:30 +0000 (UTC) (envelope-from sebastian.huber@embedded-brains.de) Received: from mail.embedded-brains.de (host-82-135-62-35.customer.m-online.net [82.135.62.35]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id 2517E15BF for ; Fri, 30 Oct 2015 13:47:29 +0000 (UTC) (envelope-from sebastian.huber@embedded-brains.de) Received: from localhost (localhost.localhost [127.0.0.1]) by mail.embedded-brains.de (Postfix) with ESMTP id 075102A1939 for ; Fri, 30 Oct 2015 14:39:09 +0100 (CET) Received: from mail.embedded-brains.de ([127.0.0.1]) by localhost (zimbra.eb.localhost [127.0.0.1]) (amavisd-new, port 10032) with ESMTP id lxpVTS_8TlNB; Fri, 30 Oct 2015 14:39:08 +0100 (CET) Received: from localhost (localhost.localhost [127.0.0.1]) by mail.embedded-brains.de (Postfix) with ESMTP id 6020D2A181A; Fri, 30 Oct 2015 14:39:08 +0100 (CET) X-Virus-Scanned: amavisd-new at zimbra.eb.localhost Received: from mail.embedded-brains.de ([127.0.0.1]) by localhost (zimbra.eb.localhost [127.0.0.1]) (amavisd-new, port 10026) with ESMTP id 5Az78EzlbjSd; Fri, 30 Oct 2015 14:39:08 +0100 (CET) Received: from huber-linux.eb.localhost (unknown [192.168.96.129]) by mail.embedded-brains.de (Postfix) with ESMTP id 3D7E72A097C; Fri, 30 Oct 2015 14:39:08 +0100 (CET) From: Sebastian Huber To: freebsd-usb@freebsd.org Subject: [PATCH] dwc_otg: Reduce interrupt load Date: Fri, 30 Oct 2015 14:38:27 +0100 Message-Id: <1446212307-4660-1-git-send-email-sebastian.huber@embedded-brains.de> X-Mailer: git-send-email 1.8.4.5 X-BeenThere: freebsd-usb@freebsd.org X-Mailman-Version: 2.1.20 Precedence: list List-Id: FreeBSD support for USB List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 30 Oct 2015 13:47:30 -0000 Tested on an Altera Cyclone V development kit. Here the controller has 16 host channels. This change significantly reduced the time spent in the dwc_otg_interrupt_poll_locked() function. --- sys/dev/usb/controller/dwc_otg.c | 21 ++++++++++++--------- sys/dev/usb/controller/dwc_otg.h | 1 + 2 files changed, 13 insertions(+), 9 deletions(-) diff --git a/sys/dev/usb/controller/dwc_otg.c b/sys/dev/usb/controller/dwc_otg.c index e018ab5..a57e064 100644 --- a/sys/dev/usb/controller/dwc_otg.c +++ b/sys/dev/usb/controller/dwc_otg.c @@ -270,8 +270,7 @@ dwc_otg_init_fifo(struct dwc_otg_softc *sc, uint8_t mode) memset(sc->sc_chan_state, 0, sizeof(sc->sc_chan_state)); /* enable all host channel interrupts */ - DWC_OTG_WRITE_4(sc, DOTG_HAINTMSK, - (1U << sc->sc_host_ch_max) - 1U); + DWC_OTG_WRITE_4(sc, DOTG_HAINTMSK, sc->sc_host_ch_mask); } if (mode == DWC_MODE_DEVICE) { @@ -2559,7 +2558,8 @@ dwc_otg_interrupt_poll_locked(struct dwc_otg_softc *sc) uint32_t count; uint32_t temp; uint8_t got_rx_status; - uint8_t x; + uint32_t haint; + int x; if (sc->sc_flags.status_device_mode == 0) { /* @@ -2576,13 +2576,14 @@ repeat: return; } /* get all host channel interrupts */ - for (x = 0; x != sc->sc_host_ch_max; x++) { + haint = DWC_OTG_READ_4(sc, DOTG_HAINT) & sc->sc_host_ch_mask; + while (haint != 0) { + x = ffs((int)haint) - 1; 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) { @@ -3845,6 +3846,8 @@ dwc_otg_init(struct dwc_otg_softc *sc) if (sc->sc_host_ch_max > DWC_OTG_MAX_CHANNELS) sc->sc_host_ch_max = DWC_OTG_MAX_CHANNELS; + sc->sc_host_ch_mask = (1U << sc->sc_host_ch_max) - 1U; + temp = DWC_OTG_READ_4(sc, DOTG_GHWCFG4); sc->sc_dev_in_ep_max = GHWCFG4_NUM_IN_EP_GET(temp); diff --git a/sys/dev/usb/controller/dwc_otg.h b/sys/dev/usb/controller/dwc_otg.h index f5e9887..6882e40 100644 --- a/sys/dev/usb/controller/dwc_otg.h +++ b/sys/dev/usb/controller/dwc_otg.h @@ -185,6 +185,7 @@ struct dwc_otg_softc { uint32_t sc_tmr_val; uint32_t sc_hprt_val; uint32_t sc_xfer_complete; + uint32_t sc_host_ch_mask; uint16_t sc_active_rx_ep; uint16_t sc_last_frame_num; -- 1.8.4.5