summaryrefslogtreecommitdiffstats
path: root/drivers/usb/dwc3
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/usb/dwc3')
-rw-r--r--drivers/usb/dwc3/Kconfig4
-rw-r--r--drivers/usb/dwc3/core.c23
-rw-r--r--drivers/usb/dwc3/dwc3-pci.c2
-rw-r--r--drivers/usb/dwc3/dwc3-qcom.c13
-rw-r--r--drivers/usb/dwc3/gadget.c14
5 files changed, 41 insertions, 15 deletions
diff --git a/drivers/usb/dwc3/Kconfig b/drivers/usb/dwc3/Kconfig
index 03ededa86da1..b2f72b0e75c6 100644
--- a/drivers/usb/dwc3/Kconfig
+++ b/drivers/usb/dwc3/Kconfig
@@ -152,11 +152,11 @@ config USB_DWC3_IMX8MP
config USB_DWC3_XILINX
tristate "Xilinx Platforms"
- depends on (ARCH_ZYNQMP || ARCH_VERSAL) && OF
+ depends on (ARCH_ZYNQMP || COMPILE_TEST) && OF
default USB_DWC3
help
Support Xilinx SoCs with DesignWare Core USB3 IP.
- This driver handles both ZynqMP and Versal SoC operations.
+ This driver handles ZynqMP SoC operations.
Say 'Y' or 'M' if you have one such device.
config USB_DWC3_AM62
diff --git a/drivers/usb/dwc3/core.c b/drivers/usb/dwc3/core.c
index 1f348bc867c2..476b63618511 100644
--- a/drivers/usb/dwc3/core.c
+++ b/drivers/usb/dwc3/core.c
@@ -122,21 +122,25 @@ static void __dwc3_set_mode(struct work_struct *work)
unsigned long flags;
int ret;
u32 reg;
+ u32 desired_dr_role;
mutex_lock(&dwc->mutex);
+ spin_lock_irqsave(&dwc->lock, flags);
+ desired_dr_role = dwc->desired_dr_role;
+ spin_unlock_irqrestore(&dwc->lock, flags);
pm_runtime_get_sync(dwc->dev);
if (dwc->current_dr_role == DWC3_GCTL_PRTCAP_OTG)
dwc3_otg_update(dwc, 0);
- if (!dwc->desired_dr_role)
+ if (!desired_dr_role)
goto out;
- if (dwc->desired_dr_role == dwc->current_dr_role)
+ if (desired_dr_role == dwc->current_dr_role)
goto out;
- if (dwc->desired_dr_role == DWC3_GCTL_PRTCAP_OTG && dwc->edev)
+ if (desired_dr_role == DWC3_GCTL_PRTCAP_OTG && dwc->edev)
goto out;
switch (dwc->current_dr_role) {
@@ -164,7 +168,7 @@ static void __dwc3_set_mode(struct work_struct *work)
*/
if (dwc->current_dr_role && ((DWC3_IP_IS(DWC3) ||
DWC3_VER_IS_PRIOR(DWC31, 190A)) &&
- dwc->desired_dr_role != DWC3_GCTL_PRTCAP_OTG)) {
+ desired_dr_role != DWC3_GCTL_PRTCAP_OTG)) {
reg = dwc3_readl(dwc->regs, DWC3_GCTL);
reg |= DWC3_GCTL_CORESOFTRESET;
dwc3_writel(dwc->regs, DWC3_GCTL, reg);
@@ -184,11 +188,11 @@ static void __dwc3_set_mode(struct work_struct *work)
spin_lock_irqsave(&dwc->lock, flags);
- dwc3_set_prtcap(dwc, dwc->desired_dr_role);
+ dwc3_set_prtcap(dwc, desired_dr_role);
spin_unlock_irqrestore(&dwc->lock, flags);
- switch (dwc->desired_dr_role) {
+ switch (desired_dr_role) {
case DWC3_GCTL_PRTCAP_HOST:
ret = dwc3_host_init(dwc);
if (ret) {
@@ -1096,8 +1100,13 @@ static int dwc3_core_init(struct dwc3 *dwc)
if (!dwc->ulpi_ready) {
ret = dwc3_core_ulpi_init(dwc);
- if (ret)
+ if (ret) {
+ if (ret == -ETIMEDOUT) {
+ dwc3_core_soft_reset(dwc);
+ ret = -EPROBE_DEFER;
+ }
goto err0;
+ }
dwc->ulpi_ready = true;
}
diff --git a/drivers/usb/dwc3/dwc3-pci.c b/drivers/usb/dwc3/dwc3-pci.c
index fb14511b1e10..89c9ab2b19f8 100644
--- a/drivers/usb/dwc3/dwc3-pci.c
+++ b/drivers/usb/dwc3/dwc3-pci.c
@@ -45,7 +45,7 @@
#define PCI_DEVICE_ID_INTEL_ADLN 0x465e
#define PCI_DEVICE_ID_INTEL_ADLN_PCH 0x54ee
#define PCI_DEVICE_ID_INTEL_ADLS 0x7ae1
-#define PCI_DEVICE_ID_INTEL_RPL 0x460e
+#define PCI_DEVICE_ID_INTEL_RPL 0xa70e
#define PCI_DEVICE_ID_INTEL_RPLS 0x7a61
#define PCI_DEVICE_ID_INTEL_MTLP 0x7ec1
#define PCI_DEVICE_ID_INTEL_MTL 0x7e7e
diff --git a/drivers/usb/dwc3/dwc3-qcom.c b/drivers/usb/dwc3/dwc3-qcom.c
index 7c40f3ffc054..b0a0351d2d8b 100644
--- a/drivers/usb/dwc3/dwc3-qcom.c
+++ b/drivers/usb/dwc3/dwc3-qcom.c
@@ -261,7 +261,8 @@ static int dwc3_qcom_interconnect_init(struct dwc3_qcom *qcom)
if (IS_ERR(qcom->icc_path_apps)) {
dev_err(dev, "failed to get apps-usb path: %ld\n",
PTR_ERR(qcom->icc_path_apps));
- return PTR_ERR(qcom->icc_path_apps);
+ ret = PTR_ERR(qcom->icc_path_apps);
+ goto put_path_ddr;
}
max_speed = usb_get_maximum_speed(&qcom->dwc3->dev);
@@ -274,16 +275,22 @@ static int dwc3_qcom_interconnect_init(struct dwc3_qcom *qcom)
}
if (ret) {
dev_err(dev, "failed to set bandwidth for usb-ddr path: %d\n", ret);
- return ret;
+ goto put_path_apps;
}
ret = icc_set_bw(qcom->icc_path_apps, APPS_USB_AVG_BW, APPS_USB_PEAK_BW);
if (ret) {
dev_err(dev, "failed to set bandwidth for apps-usb path: %d\n", ret);
- return ret;
+ goto put_path_apps;
}
return 0;
+
+put_path_apps:
+ icc_put(qcom->icc_path_apps);
+put_path_ddr:
+ icc_put(qcom->icc_path_ddr);
+ return ret;
}
/**
diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c
index 6d524fa76443..789976567f9f 100644
--- a/drivers/usb/dwc3/gadget.c
+++ b/drivers/usb/dwc3/gadget.c
@@ -1464,8 +1464,18 @@ static int dwc3_prepare_trbs_sg(struct dwc3_ep *dep,
*/
if (num_trbs_left == 1 || (needs_extra_trb &&
num_trbs_left <= 2 &&
- sg_dma_len(sg_next(s)) >= length))
- must_interrupt = true;
+ sg_dma_len(sg_next(s)) >= length)) {
+ struct dwc3_request *r;
+
+ /* Check if previous requests already set IOC */
+ list_for_each_entry(r, &dep->started_list, list) {
+ if (r != req && !r->request.no_interrupt)
+ break;
+
+ if (r == req)
+ must_interrupt = true;
+ }
+ }
dwc3_prepare_one_trb(dep, req, trb_length, 1, i, false,
must_interrupt);