summaryrefslogtreecommitdiffstats
path: root/drivers/usb/dwc3/gadget.c
diff options
context:
space:
mode:
authorJohn Youn <johnyoun@synopsys.com>2016-11-14 21:32:43 +0100
committerFelipe Balbi <felipe.balbi@linux.intel.com>2016-11-18 12:54:51 +0100
commitcf40b86b6ef6df5262ef5a8463b42524e6aa5590 (patch)
tree6b41f22b027882f680188af07bf8d2d736cca3fc /drivers/usb/dwc3/gadget.c
parentusb: dwc2: add amcc,dwc-otg support (diff)
downloadlinux-cf40b86b6ef6df5262ef5a8463b42524e6aa5590.tar.xz
linux-cf40b86b6ef6df5262ef5a8463b42524e6aa5590.zip
usb: dwc3: Implement interrupt moderation
Implement interrupt moderation which allows the interrupt rate to be throttled. To enable this feature the dwc->imod_interval must be set to 1 or greater. This value specifies the minimum inter-interrupt interval, in 250 ns increments. A value of 0 disables interrupt moderation. This applies for DWC_usb3 version 3.00a and higher and for DWC_usb31 version 1.20a and higher. Signed-off-by: John Youn <johnyoun@synopsys.com> Signed-off-by: Felipe Balbi <felipe.balbi@linux.intel.com>
Diffstat (limited to 'drivers/usb/dwc3/gadget.c')
-rw-r--r--drivers/usb/dwc3/gadget.c16
1 files changed, 16 insertions, 0 deletions
diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c
index 3d5ba4106979..e2416de36bb0 100644
--- a/drivers/usb/dwc3/gadget.c
+++ b/drivers/usb/dwc3/gadget.c
@@ -1685,6 +1685,17 @@ static int __dwc3_gadget_start(struct dwc3 *dwc)
int ret = 0;
u32 reg;
+ /*
+ * Use IMOD if enabled via dwc->imod_interval. Otherwise, if
+ * the core supports IMOD, disable it.
+ */
+ if (dwc->imod_interval) {
+ dwc3_writel(dwc->regs, DWC3_DEV_IMOD(0), dwc->imod_interval);
+ dwc3_writel(dwc->regs, DWC3_GEVNTCOUNT(0), DWC3_GEVNTCOUNT_EHB);
+ } else if (dwc3_has_imod(dwc)) {
+ dwc3_writel(dwc->regs, DWC3_DEV_IMOD(0), 0);
+ }
+
reg = dwc3_readl(dwc->regs, DWC3_DCFG);
reg &= ~(DWC3_DCFG_SPEED_MASK);
@@ -2847,6 +2858,11 @@ static irqreturn_t dwc3_process_event_buf(struct dwc3_event_buffer *evt)
reg &= ~DWC3_GEVNTSIZ_INTMASK;
dwc3_writel(dwc->regs, DWC3_GEVNTSIZ(0), reg);
+ if (dwc->imod_interval) {
+ dwc3_writel(dwc->regs, DWC3_GEVNTCOUNT(0), DWC3_GEVNTCOUNT_EHB);
+ dwc3_writel(dwc->regs, DWC3_DEV_IMOD(0), dwc->imod_interval);
+ }
+
return ret;
}