diff options
author | Manu Gautam <mgautam@codeaurora.org> | 2016-06-24 12:30:37 +0530 |
---|---|---|
committer | Vamsi Krishna Samavedam <vskrishn@codeaurora.org> | 2017-02-02 14:20:44 -0800 |
commit | a4f63f1693dd85a9e597cdb8466c78fe658db14b (patch) | |
tree | a1ff2ff2dd4bba4797c911908eb19d8844c32e89 | |
parent | af883d4db0b398542bb561808a11019f0998d129 (diff) |
usb: xhci-plat: Add DT parameter to program xhci imod_interval
XHCI allows interrupt moderation using imod_interval at 250ns
increments. Add DT parameter to specify this imod_value for
targets mainly with single CPU to reduce CPU interrupt loads.
This allows better balance between CPU usage and performance.
CRs-fixed: 1019219
Change-Id: Id479c162da6492caff4dd83de4054fee63b6abc5
Signed-off-by: Manu Gautam <mgautam@codeaurora.org>
-rw-r--r-- | Documentation/devicetree/bindings/usb/dwc3.txt | 2 | ||||
-rw-r--r-- | drivers/usb/dwc3/host.c | 6 | ||||
-rw-r--r-- | drivers/usb/host/xhci-plat.c | 14 | ||||
-rw-r--r-- | include/linux/usb/xhci_pdriver.h | 4 |
4 files changed, 26 insertions, 0 deletions
diff --git a/Documentation/devicetree/bindings/usb/dwc3.txt b/Documentation/devicetree/bindings/usb/dwc3.txt index 3136687adb57..ddca4c39e2de 100644 --- a/Documentation/devicetree/bindings/usb/dwc3.txt +++ b/Documentation/devicetree/bindings/usb/dwc3.txt @@ -60,6 +60,7 @@ Optional properties: - snps,num-normal-evt-buffs: If present, specifies number of normal event buffers. Default is 1. - snps,num-gsi-evt-buffs: If present, specifies number of GSI based hardware accelerated event buffers. 1 event buffer is needed per h/w accelerated endpoint. + - xhci-imod-value: Interrupt moderation interval for host mode (in increments of 250nsec). This is usually a subnode to DWC3 glue to which it is connected. @@ -74,4 +75,5 @@ dwc3@4a030000 { tx-fifo-resize; snps,usb3-u1u2-disable; snps,num-gsi-evt-buffs = <0x2>; + xhci-imod-value = <4000>; }; diff --git a/drivers/usb/dwc3/host.c b/drivers/usb/dwc3/host.c index d03678a02185..7f1ae5cf9909 100644 --- a/drivers/usb/dwc3/host.c +++ b/drivers/usb/dwc3/host.c @@ -25,6 +25,7 @@ int dwc3_host_init(struct dwc3 *dwc) struct platform_device *xhci; struct usb_xhci_pdata pdata; int ret; + struct device_node *node = dwc->dev->of_node; xhci = platform_device_alloc("xhci-hcd", PLATFORM_DEVID_AUTO); if (!xhci) { @@ -52,6 +53,11 @@ int dwc3_host_init(struct dwc3 *dwc) pdata.usb3_lpm_capable = dwc->usb3_lpm_capable; + ret = of_property_read_u32(node, "xhci-imod-value", + &pdata.imod_interval); + if (ret) + pdata.imod_interval = 0; /* use default xhci.c value */ + ret = platform_device_add_data(xhci, &pdata, sizeof(pdata)); if (ret) { dev_err(dwc->dev, "couldn't add platform data to xHCI device\n"); diff --git a/drivers/usb/host/xhci-plat.c b/drivers/usb/host/xhci-plat.c index 1221a80e0bdc..05d96fd8c07c 100644 --- a/drivers/usb/host/xhci-plat.c +++ b/drivers/usb/host/xhci-plat.c @@ -138,6 +138,8 @@ static int xhci_plat_probe(struct platform_device *pdev) struct clk *clk; int ret; int irq; + u32 temp, imod; + unsigned long flags; if (usb_disabled()) return -ENODEV; @@ -256,6 +258,18 @@ static int xhci_plat_probe(struct platform_device *pdev) device_wakeup_enable(&xhci->shared_hcd->self.root_hub->dev); + /* override imod interval if specified */ + if (pdata && pdata->imod_interval) { + imod = pdata->imod_interval & ER_IRQ_INTERVAL_MASK; + spin_lock_irqsave(&xhci->lock, flags); + temp = readl_relaxed(&xhci->ir_set->irq_control); + temp &= ~ER_IRQ_INTERVAL_MASK; + temp |= imod; + writel_relaxed(temp, &xhci->ir_set->irq_control); + spin_unlock_irqrestore(&xhci->lock, flags); + dev_dbg(&pdev->dev, "%s: imod set to %u\n", __func__, imod); + } + ret = device_create_file(&pdev->dev, &dev_attr_config_imod); if (ret) dev_err(&pdev->dev, "%s: unable to create imod sysfs entry\n", diff --git a/include/linux/usb/xhci_pdriver.h b/include/linux/usb/xhci_pdriver.h index 376654b5b0f7..a44b53c33e75 100644 --- a/include/linux/usb/xhci_pdriver.h +++ b/include/linux/usb/xhci_pdriver.h @@ -19,9 +19,13 @@ * @usb3_lpm_capable: determines if this xhci platform supports USB3 * LPM capability * + * @imod_interval: minimum inter-interrupt interval. Specified in + * 250nsec increments. + * */ struct usb_xhci_pdata { unsigned usb3_lpm_capable:1; + unsigned imod_interval; }; #endif /* __USB_CORE_XHCI_PDRIVER_H */ |