summaryrefslogtreecommitdiff
path: root/drivers/usb
diff options
context:
space:
mode:
authorManu Gautam <mgautam@codeaurora.org>2016-06-24 12:30:37 +0530
committerVamsi Krishna Samavedam <vskrishn@codeaurora.org>2017-02-02 14:20:44 -0800
commita4f63f1693dd85a9e597cdb8466c78fe658db14b (patch)
treea1ff2ff2dd4bba4797c911908eb19d8844c32e89 /drivers/usb
parentaf883d4db0b398542bb561808a11019f0998d129 (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>
Diffstat (limited to 'drivers/usb')
-rw-r--r--drivers/usb/dwc3/host.c6
-rw-r--r--drivers/usb/host/xhci-plat.c14
2 files changed, 20 insertions, 0 deletions
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",