summaryrefslogtreecommitdiffstats
path: root/drivers/usb/dwc3
diff options
context:
space:
mode:
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>2014-05-23 11:28:21 +0900
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2014-05-23 11:28:21 +0900
commitf8712528ae0bfef50f30b1da3d58e22f4f007889 (patch)
tree77dffd5ac91fd75f5e87595adb31176fd2bf3f11 /drivers/usb/dwc3
parentc311e391a7efd101250c0e123286709b7e736249 (diff)
parent7751b6fb05869bcb318e74420148c06577adf894 (diff)
downloadop-kernel-dev-f8712528ae0bfef50f30b1da3d58e22f4f007889.zip
op-kernel-dev-f8712528ae0bfef50f30b1da3d58e22f4f007889.tar.gz
Merge tag 'usb-for-v3.16' of git://git.kernel.org/pub/scm/linux/kernel/git/balbi/usb into usb-next
Felipe writes: usb: patches for v3.16 merge window Not a lot here during this merge window. Mostly we just have the usual miscellaneous patches (removal of unnecessary prints, proper dependencies being added to Kconfig, build warning fixes, new device ID, etc. Other than those, the only important new features are the new support for OS Strings which should help Linux Gadget Drivers behave better under MS Windows. Also Babble Recovery implementation for MUSB on AM335x. Lastly, we also have ARCH_QCOM PHY support though phy-msm. Signed-of-by: Felipe Balbi <balbi@ti.com> Conflicts: drivers/usb/phy/phy-mv-u3d-usb.c
Diffstat (limited to 'drivers/usb/dwc3')
-rw-r--r--drivers/usb/dwc3/Kconfig4
-rw-r--r--drivers/usb/dwc3/core.c253
-rw-r--r--drivers/usb/dwc3/dwc3-exynos.c71
-rw-r--r--drivers/usb/dwc3/dwc3-omap.c2
-rw-r--r--drivers/usb/dwc3/dwc3-pci.c21
-rw-r--r--drivers/usb/dwc3/gadget.c83
6 files changed, 280 insertions, 154 deletions
diff --git a/drivers/usb/dwc3/Kconfig b/drivers/usb/dwc3/Kconfig
index e2c730f..8eb996e 100644
--- a/drivers/usb/dwc3/Kconfig
+++ b/drivers/usb/dwc3/Kconfig
@@ -44,7 +44,7 @@ comment "Platform Glue Driver Support"
config USB_DWC3_OMAP
tristate "Texas Instruments OMAP5 and similar Platforms"
- depends on EXTCON
+ depends on EXTCON && (ARCH_OMAP2PLUS || COMPILE_TEST)
default USB_DWC3
help
Some platforms from Texas Instruments like OMAP5, DRA7xxx and
@@ -54,6 +54,7 @@ config USB_DWC3_OMAP
config USB_DWC3_EXYNOS
tristate "Samsung Exynos Platform"
+ depends on ARCH_EXYNOS || COMPILE_TEST
default USB_DWC3
help
Recent Exynos5 SoCs ship with one DesignWare Core USB3 IP inside,
@@ -72,6 +73,7 @@ config USB_DWC3_PCI
config USB_DWC3_KEYSTONE
tristate "Texas Instruments Keystone2 Platforms"
+ depends on ARCH_KEYSTONE || COMPILE_TEST
default USB_DWC3
help
Support of USB2/3 functionality in TI Keystone2 platforms.
diff --git a/drivers/usb/dwc3/core.c b/drivers/usb/dwc3/core.c
index 10aaaae..eb69eb9 100644
--- a/drivers/usb/dwc3/core.c
+++ b/drivers/usb/dwc3/core.c
@@ -486,70 +486,20 @@ static void dwc3_core_exit(struct dwc3 *dwc)
phy_exit(dwc->usb3_generic_phy);
}
-#define DWC3_ALIGN_MASK (16 - 1)
-
-static int dwc3_probe(struct platform_device *pdev)
+static int dwc3_core_get_phy(struct dwc3 *dwc)
{
- struct device *dev = &pdev->dev;
- struct dwc3_platform_data *pdata = dev_get_platdata(dev);
+ struct device *dev = dwc->dev;
struct device_node *node = dev->of_node;
- struct resource *res;
- struct dwc3 *dwc;
-
- int ret = -ENOMEM;
-
- void __iomem *regs;
- void *mem;
-
- mem = devm_kzalloc(dev, sizeof(*dwc) + DWC3_ALIGN_MASK, GFP_KERNEL);
- if (!mem) {
- dev_err(dev, "not enough memory\n");
- return -ENOMEM;
- }
- dwc = PTR_ALIGN(mem, DWC3_ALIGN_MASK + 1);
- dwc->mem = mem;
-
- res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
- if (!res) {
- dev_err(dev, "missing IRQ\n");
- return -ENODEV;
- }
- dwc->xhci_resources[1].start = res->start;
- dwc->xhci_resources[1].end = res->end;
- dwc->xhci_resources[1].flags = res->flags;
- dwc->xhci_resources[1].name = res->name;
-
- res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
- if (!res) {
- dev_err(dev, "missing memory resource\n");
- return -ENODEV;
- }
+ int ret;
if (node) {
- dwc->maximum_speed = of_usb_get_maximum_speed(node);
-
dwc->usb2_phy = devm_usb_get_phy_by_phandle(dev, "usb-phy", 0);
dwc->usb3_phy = devm_usb_get_phy_by_phandle(dev, "usb-phy", 1);
-
- dwc->needs_fifo_resize = of_property_read_bool(node, "tx-fifo-resize");
- dwc->dr_mode = of_usb_get_dr_mode(node);
- } else if (pdata) {
- dwc->maximum_speed = pdata->maximum_speed;
-
- dwc->usb2_phy = devm_usb_get_phy(dev, USB_PHY_TYPE_USB2);
- dwc->usb3_phy = devm_usb_get_phy(dev, USB_PHY_TYPE_USB3);
-
- dwc->needs_fifo_resize = pdata->tx_fifo_resize;
- dwc->dr_mode = pdata->dr_mode;
} else {
dwc->usb2_phy = devm_usb_get_phy(dev, USB_PHY_TYPE_USB2);
dwc->usb3_phy = devm_usb_get_phy(dev, USB_PHY_TYPE_USB3);
}
- /* default to superspeed if no maximum_speed passed */
- if (dwc->maximum_speed == USB_SPEED_UNKNOWN)
- dwc->maximum_speed = USB_SPEED_SUPER;
-
if (IS_ERR(dwc->usb2_phy)) {
ret = PTR_ERR(dwc->usb2_phy);
if (ret == -ENXIO || ret == -ENODEV) {
@@ -600,6 +550,132 @@ static int dwc3_probe(struct platform_device *pdev)
}
}
+ return 0;
+}
+
+static int dwc3_core_init_mode(struct dwc3 *dwc)
+{
+ struct device *dev = dwc->dev;
+ int ret;
+
+ switch (dwc->dr_mode) {
+ case USB_DR_MODE_PERIPHERAL:
+ dwc3_set_mode(dwc, DWC3_GCTL_PRTCAP_DEVICE);
+ ret = dwc3_gadget_init(dwc);
+ if (ret) {
+ dev_err(dev, "failed to initialize gadget\n");
+ return ret;
+ }
+ break;
+ case USB_DR_MODE_HOST:
+ dwc3_set_mode(dwc, DWC3_GCTL_PRTCAP_HOST);
+ ret = dwc3_host_init(dwc);
+ if (ret) {
+ dev_err(dev, "failed to initialize host\n");
+ return ret;
+ }
+ break;
+ case USB_DR_MODE_OTG:
+ dwc3_set_mode(dwc, DWC3_GCTL_PRTCAP_OTG);
+ ret = dwc3_host_init(dwc);
+ if (ret) {
+ dev_err(dev, "failed to initialize host\n");
+ return ret;
+ }
+
+ ret = dwc3_gadget_init(dwc);
+ if (ret) {
+ dev_err(dev, "failed to initialize gadget\n");
+ return ret;
+ }
+ break;
+ default:
+ dev_err(dev, "Unsupported mode of operation %d\n", dwc->dr_mode);
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+static void dwc3_core_exit_mode(struct dwc3 *dwc)
+{
+ switch (dwc->dr_mode) {
+ case USB_DR_MODE_PERIPHERAL:
+ dwc3_gadget_exit(dwc);
+ break;
+ case USB_DR_MODE_HOST:
+ dwc3_host_exit(dwc);
+ break;
+ case USB_DR_MODE_OTG:
+ dwc3_host_exit(dwc);
+ dwc3_gadget_exit(dwc);
+ break;
+ default:
+ /* do nothing */
+ break;
+ }
+}
+
+#define DWC3_ALIGN_MASK (16 - 1)
+
+static int dwc3_probe(struct platform_device *pdev)
+{
+ struct device *dev = &pdev->dev;
+ struct dwc3_platform_data *pdata = dev_get_platdata(dev);
+ struct device_node *node = dev->of_node;
+ struct resource *res;
+ struct dwc3 *dwc;
+
+ int ret;
+
+ void __iomem *regs;
+ void *mem;
+
+ mem = devm_kzalloc(dev, sizeof(*dwc) + DWC3_ALIGN_MASK, GFP_KERNEL);
+ if (!mem) {
+ dev_err(dev, "not enough memory\n");
+ return -ENOMEM;
+ }
+ dwc = PTR_ALIGN(mem, DWC3_ALIGN_MASK + 1);
+ dwc->mem = mem;
+ dwc->dev = dev;
+
+ res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
+ if (!res) {
+ dev_err(dev, "missing IRQ\n");
+ return -ENODEV;
+ }
+ dwc->xhci_resources[1].start = res->start;
+ dwc->xhci_resources[1].end = res->end;
+ dwc->xhci_resources[1].flags = res->flags;
+ dwc->xhci_resources[1].name = res->name;
+
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ if (!res) {
+ dev_err(dev, "missing memory resource\n");
+ return -ENODEV;
+ }
+
+ if (node) {
+ dwc->maximum_speed = of_usb_get_maximum_speed(node);
+
+ dwc->needs_fifo_resize = of_property_read_bool(node, "tx-fifo-resize");
+ dwc->dr_mode = of_usb_get_dr_mode(node);
+ } else if (pdata) {
+ dwc->maximum_speed = pdata->maximum_speed;
+
+ dwc->needs_fifo_resize = pdata->tx_fifo_resize;
+ dwc->dr_mode = pdata->dr_mode;
+ }
+
+ /* default to superspeed if no maximum_speed passed */
+ if (dwc->maximum_speed == USB_SPEED_UNKNOWN)
+ dwc->maximum_speed = USB_SPEED_SUPER;
+
+ ret = dwc3_core_get_phy(dwc);
+ if (ret)
+ return ret;
+
dwc->xhci_resources[0].start = res->start;
dwc->xhci_resources[0].end = dwc->xhci_resources[0].start +
DWC3_XHCI_REGS_END;
@@ -621,7 +697,6 @@ static int dwc3_probe(struct platform_device *pdev)
dwc->regs = regs;
dwc->regs_size = resource_size(res);
- dwc->dev = dev;
dev->dma_mask = dev->parent->dma_mask;
dev->dma_parms = dev->parent->dma_parms;
@@ -670,41 +745,9 @@ static int dwc3_probe(struct platform_device *pdev)
goto err_usb3phy_power;
}
- switch (dwc->dr_mode) {
- case USB_DR_MODE_PERIPHERAL:
- dwc3_set_mode(dwc, DWC3_GCTL_PRTCAP_DEVICE);
- ret = dwc3_gadget_init(dwc);
- if (ret) {
- dev_err(dev, "failed to initialize gadget\n");
- goto err2;
- }
- break;
- case USB_DR_MODE_HOST:
- dwc3_set_mode(dwc, DWC3_GCTL_PRTCAP_HOST);
- ret = dwc3_host_init(dwc);
- if (ret) {
- dev_err(dev, "failed to initialize host\n");
- goto err2;
- }
- break;
- case USB_DR_MODE_OTG:
- dwc3_set_mode(dwc, DWC3_GCTL_PRTCAP_OTG);
- ret = dwc3_host_init(dwc);
- if (ret) {
- dev_err(dev, "failed to initialize host\n");
- goto err2;
- }
-
- ret = dwc3_gadget_init(dwc);
- if (ret) {
- dev_err(dev, "failed to initialize gadget\n");
- goto err2;
- }
- break;
- default:
- dev_err(dev, "Unsupported mode of operation %d\n", dwc->dr_mode);
+ ret = dwc3_core_init_mode(dwc);
+ if (ret)
goto err2;
- }
ret = dwc3_debugfs_init(dwc);
if (ret) {
@@ -717,21 +760,7 @@ static int dwc3_probe(struct platform_device *pdev)
return 0;
err3:
- switch (dwc->dr_mode) {
- case USB_DR_MODE_PERIPHERAL:
- dwc3_gadget_exit(dwc);
- break;
- case USB_DR_MODE_HOST:
- dwc3_host_exit(dwc);
- break;
- case USB_DR_MODE_OTG:
- dwc3_host_exit(dwc);
- dwc3_gadget_exit(dwc);
- break;
- default:
- /* do nothing */
- break;
- }
+ dwc3_core_exit_mode(dwc);
err2:
dwc3_event_buffers_cleanup(dwc);
@@ -766,23 +795,7 @@ static int dwc3_remove(struct platform_device *pdev)
pm_runtime_disable(&pdev->dev);
dwc3_debugfs_exit(dwc);
-
- switch (dwc->dr_mode) {
- case USB_DR_MODE_PERIPHERAL:
- dwc3_gadget_exit(dwc);
- break;
- case USB_DR_MODE_HOST:
- dwc3_host_exit(dwc);
- break;
- case USB_DR_MODE_OTG:
- dwc3_host_exit(dwc);
- dwc3_gadget_exit(dwc);
- break;
- default:
- /* do nothing */
- break;
- }
-
+ dwc3_core_exit_mode(dwc);
dwc3_event_buffers_cleanup(dwc);
dwc3_free_event_buffers(dwc);
dwc3_core_exit(dwc);
diff --git a/drivers/usb/dwc3/dwc3-exynos.c b/drivers/usb/dwc3/dwc3-exynos.c
index 28c8ad7..f9fb8ad 100644
--- a/drivers/usb/dwc3/dwc3-exynos.c
+++ b/drivers/usb/dwc3/dwc3-exynos.c
@@ -24,9 +24,10 @@
#include <linux/dma-mapping.h>
#include <linux/clk.h>
#include <linux/usb/otg.h>
-#include <linux/usb/usb_phy_gen_xceiv.h>
+#include <linux/usb/usb_phy_generic.h>
#include <linux/of.h>
#include <linux/of_platform.h>
+#include <linux/regulator/consumer.h>
struct dwc3_exynos {
struct platform_device *usb2_phy;
@@ -34,17 +35,19 @@ struct dwc3_exynos {
struct device *dev;
struct clk *clk;
+ struct regulator *vdd33;
+ struct regulator *vdd10;
};
static int dwc3_exynos_register_phys(struct dwc3_exynos *exynos)
{
- struct usb_phy_gen_xceiv_platform_data pdata;
+ struct usb_phy_generic_platform_data pdata;
struct platform_device *pdev;
int ret;
memset(&pdata, 0x00, sizeof(pdata));
- pdev = platform_device_alloc("usb_phy_gen_xceiv", PLATFORM_DEVID_AUTO);
+ pdev = platform_device_alloc("usb_phy_generic", PLATFORM_DEVID_AUTO);
if (!pdev)
return -ENOMEM;
@@ -56,7 +59,7 @@ static int dwc3_exynos_register_phys(struct dwc3_exynos *exynos)
if (ret)
goto err1;
- pdev = platform_device_alloc("usb_phy_gen_xceiv", PLATFORM_DEVID_AUTO);
+ pdev = platform_device_alloc("usb_phy_generic", PLATFORM_DEVID_AUTO);
if (!pdev) {
ret = -ENOMEM;
goto err1;
@@ -107,12 +110,12 @@ static int dwc3_exynos_probe(struct platform_device *pdev)
struct device *dev = &pdev->dev;
struct device_node *node = dev->of_node;
- int ret = -ENOMEM;
+ int ret;
exynos = devm_kzalloc(dev, sizeof(*exynos), GFP_KERNEL);
if (!exynos) {
dev_err(dev, "not enough memory\n");
- goto err1;
+ return -ENOMEM;
}
/*
@@ -122,21 +125,20 @@ static int dwc3_exynos_probe(struct platform_device *pdev)
*/
ret = dma_coerce_mask_and_coherent(dev, DMA_BIT_MASK(32));
if (ret)
- goto err1;
+ return ret;
platform_set_drvdata(pdev, exynos);
ret = dwc3_exynos_register_phys(exynos);
if (ret) {
dev_err(dev, "couldn't register PHYs\n");
- goto err1;
+ return ret;
}
clk = devm_clk_get(dev, "usbdrd30");
if (IS_ERR(clk)) {
dev_err(dev, "couldn't get clock\n");
- ret = -EINVAL;
- goto err1;
+ return -EINVAL;
}
exynos->dev = dev;
@@ -144,23 +146,48 @@ static int dwc3_exynos_probe(struct platform_device *pdev)
clk_prepare_enable(exynos->clk);
+ exynos->vdd33 = devm_regulator_get(dev, "vdd33");
+ if (IS_ERR(exynos->vdd33)) {
+ ret = PTR_ERR(exynos->vdd33);
+ goto err2;
+ }
+ ret = regulator_enable(exynos->vdd33);
+ if (ret) {
+ dev_err(dev, "Failed to enable VDD33 supply\n");
+ goto err2;
+ }
+
+ exynos->vdd10 = devm_regulator_get(dev, "vdd10");
+ if (IS_ERR(exynos->vdd10)) {
+ ret = PTR_ERR(exynos->vdd10);
+ goto err3;
+ }
+ ret = regulator_enable(exynos->vdd10);
+ if (ret) {
+ dev_err(dev, "Failed to enable VDD10 supply\n");
+ goto err3;
+ }
+
if (node) {
ret = of_platform_populate(node, NULL, NULL, dev);
if (ret) {
dev_err(dev, "failed to add dwc3 core\n");
- goto err2;
+ goto err4;
}
} else {
dev_err(dev, "no device node, failed to add dwc3 core\n");
ret = -ENODEV;
- goto err2;
+ goto err4;
}
return 0;
+err4:
+ regulator_disable(exynos->vdd10);
+err3:
+ regulator_disable(exynos->vdd33);
err2:
clk_disable_unprepare(clk);
-err1:
return ret;
}
@@ -174,6 +201,9 @@ static int dwc3_exynos_remove(struct platform_device *pdev)
clk_disable_unprepare(exynos->clk);
+ regulator_disable(exynos->vdd33);
+ regulator_disable(exynos->vdd10);
+
return 0;
}
@@ -192,12 +222,27 @@ static int dwc3_exynos_suspend(struct device *dev)
clk_disable(exynos->clk);
+ regulator_disable(exynos->vdd33);
+ regulator_disable(exynos->vdd10);
+
return 0;
}
static int dwc3_exynos_resume(struct device *dev)
{
struct dwc3_exynos *exynos = dev_get_drvdata(dev);
+ int ret;
+
+ ret = regulator_enable(exynos->vdd33);
+ if (ret) {
+ dev_err(dev, "Failed to enable VDD33 supply\n");
+ return ret;
+ }
+ ret = regulator_enable(exynos->vdd10);
+ if (ret) {
+ dev_err(dev, "Failed to enable VDD10 supply\n");
+ return ret;
+ }
clk_enable(exynos->clk);
diff --git a/drivers/usb/dwc3/dwc3-omap.c b/drivers/usb/dwc3/dwc3-omap.c
index 1160ff4..4af4c35 100644
--- a/drivers/usb/dwc3/dwc3-omap.c
+++ b/drivers/usb/dwc3/dwc3-omap.c
@@ -393,7 +393,7 @@ static int dwc3_omap_probe(struct platform_device *pdev)
struct extcon_dev *edev;
struct regulator *vbus_reg = NULL;
- int ret = -ENOMEM;
+ int ret;
int irq;
int utmi_mode = 0;
diff --git a/drivers/usb/dwc3/dwc3-pci.c b/drivers/usb/dwc3/dwc3-pci.c
index f393c18..a60bab7 100644
--- a/drivers/usb/dwc3/dwc3-pci.c
+++ b/drivers/usb/dwc3/dwc3-pci.c
@@ -23,7 +23,7 @@
#include <linux/platform_device.h>
#include <linux/usb/otg.h>
-#include <linux/usb/usb_phy_gen_xceiv.h>
+#include <linux/usb/usb_phy_generic.h>
/* FIXME define these in <linux/pci_ids.h> */
#define PCI_VENDOR_ID_SYNOPSYS 0x16c3
@@ -40,13 +40,13 @@ struct dwc3_pci {
static int dwc3_pci_register_phys(struct dwc3_pci *glue)
{
- struct usb_phy_gen_xceiv_platform_data pdata;
+ struct usb_phy_generic_platform_data pdata;
struct platform_device *pdev;
int ret;
memset(&pdata, 0x00, sizeof(pdata));
- pdev = platform_device_alloc("usb_phy_gen_xceiv", 0);
+ pdev = platform_device_alloc("usb_phy_generic", 0);
if (!pdev)
return -ENOMEM;
@@ -58,7 +58,7 @@ static int dwc3_pci_register_phys(struct dwc3_pci *glue)
if (ret)
goto err1;
- pdev = platform_device_alloc("usb_phy_gen_xceiv", 1);
+ pdev = platform_device_alloc("usb_phy_generic", 1);
if (!pdev) {
ret = -ENOMEM;
goto err1;
@@ -99,7 +99,7 @@ static int dwc3_pci_probe(struct pci_dev *pci,
struct resource res[2];
struct platform_device *dwc3;
struct dwc3_pci *glue;
- int ret = -ENOMEM;
+ int ret;
struct device *dev = &pci->dev;
glue = devm_kzalloc(dev, sizeof(*glue), GFP_KERNEL);
@@ -110,7 +110,7 @@ static int dwc3_pci_probe(struct pci_dev *pci,
glue->dev = dev;
- ret = pci_enable_device(pci);
+ ret = pcim_enable_device(pci);
if (ret) {
dev_err(dev, "failed to enable pci device\n");
return -ENODEV;
@@ -127,8 +127,7 @@ static int dwc3_pci_probe(struct pci_dev *pci,
dwc3 = platform_device_alloc("dwc3", PLATFORM_DEVID_AUTO);
if (!dwc3) {
dev_err(dev, "couldn't allocate dwc3 device\n");
- ret = -ENOMEM;
- goto err1;
+ return -ENOMEM;
}
memset(res, 0x00, sizeof(struct resource) * ARRAY_SIZE(res));
@@ -145,7 +144,7 @@ static int dwc3_pci_probe(struct pci_dev *pci,
ret = platform_device_add_resources(dwc3, res, ARRAY_SIZE(res));
if (ret) {
dev_err(dev, "couldn't add resources to dwc3 device\n");
- goto err1;
+ return ret;
}
pci_set_drvdata(pci, glue);
@@ -167,9 +166,6 @@ static int dwc3_pci_probe(struct pci_dev *pci,
err3:
platform_device_put(dwc3);
-err1:
- pci_disable_device(pci);
-
return ret;
}
@@ -180,7 +176,6 @@ static void dwc3_pci_remove(struct pci_dev *pci)
platform_device_unregister(glue->dwc3);
platform_device_unregister(glue->usb2_phy);
platform_device_unregister(glue->usb3_phy);
- pci_disable_device(pci);
}
static const struct pci_device_id dwc3_pci_id_table[] = {
diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c
index 70715ee..9d64dd0 100644
--- a/drivers/usb/dwc3/gadget.c
+++ b/drivers/usb/dwc3/gadget.c
@@ -298,11 +298,76 @@ static const char *dwc3_gadget_ep_cmd_string(u8 cmd)
}
}
+static const char *dwc3_gadget_generic_cmd_string(u8 cmd)
+{
+ switch (cmd) {
+ case DWC3_DGCMD_SET_LMP:
+ return "Set LMP";
+ case DWC3_DGCMD_SET_PERIODIC_PAR:
+ return "Set Periodic Parameters";
+ case DWC3_DGCMD_XMIT_FUNCTION:
+ return "Transmit Function Wake Device Notification";
+ case DWC3_DGCMD_SET_SCRATCHPAD_ADDR_LO:
+ return "Set Scratchpad Buffer Array Address Lo";
+ case DWC3_DGCMD_SET_SCRATCHPAD_ADDR_HI:
+ return "Set Scratchpad Buffer Array Address Hi";
+ case DWC3_DGCMD_SELECTED_FIFO_FLUSH:
+ return "Selected FIFO Flush";
+ case DWC3_DGCMD_ALL_FIFO_FLUSH:
+ return "All FIFO Flush";
+ case DWC3_DGCMD_SET_ENDPOINT_NRDY:
+ return "Set Endpoint NRDY";
+ case DWC3_DGCMD_RUN_SOC_BUS_LOOPBACK:
+ return "Run SoC Bus Loopback Test";
+ default:
+ return "UNKNOWN";
+ }
+}
+
+static const char *dwc3_gadget_link_string(enum dwc3_link_state link_state)
+{
+ switch (link_state) {
+ case DWC3_LINK_STATE_U0:
+ return "U0";
+ case DWC3_LINK_STATE_U1:
+ return "U1";
+ case DWC3_LINK_STATE_U2:
+ return "U2";
+ case DWC3_LINK_STATE_U3:
+ return "U3";
+ case DWC3_LINK_STATE_SS_DIS:
+ return "SS.Disabled";
+ case DWC3_LINK_STATE_RX_DET:
+ return "RX.Detect";
+ case DWC3_LINK_STATE_SS_INACT:
+ return "SS.Inactive";
+ case DWC3_LINK_STATE_POLL:
+ return "Polling";
+ case DWC3_LINK_STATE_RECOV:
+ return "Recovery";
+ case DWC3_LINK_STATE_HRESET:
+ return "Hot Reset";
+ case DWC3_LINK_STATE_CMPLY:
+ return "Compliance";
+ case DWC3_LINK_STATE_LPBK:
+ return "Loopback";
+ case DWC3_LINK_STATE_RESET:
+ return "Reset";
+ case DWC3_LINK_STATE_RESUME:
+ return "Resume";
+ default:
+ return "UNKNOWN link state\n";
+ }
+}
+
int dwc3_send_gadget_generic_command(struct dwc3 *dwc, int cmd, u32 param)
{
u32 timeout = 500;
u32 reg;
+ dev_vdbg(dwc->dev, "generic cmd '%s' [%d] param %08x\n",
+ dwc3_gadget_generic_cmd_string(cmd), cmd, param);
+
dwc3_writel(dwc->regs, DWC3_DGCMDPAR, param);
dwc3_writel(dwc->regs, DWC3_DGCMD, cmd | DWC3_DGCMD_CMDACT);
@@ -332,9 +397,9 @@ int dwc3_send_gadget_ep_cmd(struct dwc3 *dwc, unsigned ep,
u32 timeout = 500;
u32 reg;
- dev_vdbg(dwc->dev, "%s: cmd '%s' params %08x %08x %08x\n",
+ dev_vdbg(dwc->dev, "%s: cmd '%s' [%d] params %08x %08x %08x\n",
dep->name,
- dwc3_gadget_ep_cmd_string(cmd), params->param0,
+ dwc3_gadget_ep_cmd_string(cmd), cmd, params->param0,
params->param1, params->param2);
dwc3_writel(dwc->regs, DWC3_DEPCMDPAR0(ep), params->param0);
@@ -515,7 +580,7 @@ static int __dwc3_gadget_ep_enable(struct dwc3_ep *dep,
{
struct dwc3 *dwc = dep->dwc;
u32 reg;
- int ret = -ENOMEM;
+ int ret;
dev_vdbg(dwc->dev, "Enabling %s\n", dep->name);
@@ -604,6 +669,10 @@ static int __dwc3_gadget_ep_disable(struct dwc3_ep *dep)
dwc3_remove_requests(dwc, dep);
+ /* make sure HW endpoint isn't stalled */
+ if (dep->flags & DWC3_EP_STALL)
+ __dwc3_gadget_ep_set_halt(dep, 0);
+
reg = dwc3_readl(dwc->regs, DWC3_DALEPENA);
reg &= ~DWC3_DALEPENA_EP(dep->number);
dwc3_writel(dwc->regs, DWC3_DALEPENA, reg);
@@ -2441,8 +2510,6 @@ static void dwc3_gadget_linksts_change_interrupt(struct dwc3 *dwc,
}
}
- dwc->link_state = next;
-
switch (next) {
case DWC3_LINK_STATE_U1:
if (dwc->speed == USB_SPEED_SUPER)
@@ -2460,7 +2527,11 @@ static void dwc3_gadget_linksts_change_interrupt(struct dwc3 *dwc,
break;
}
- dev_vdbg(dwc->dev, "%s link %d\n", __func__, dwc->link_state);
+ dev_vdbg(dwc->dev, "link change: %s [%d] -> %s [%d]\n",
+ dwc3_gadget_link_string(dwc->link_state),
+ dwc->link_state, dwc3_gadget_link_string(next), next);
+
+ dwc->link_state = next;
}
static void dwc3_gadget_hibernation_interrupt(struct dwc3 *dwc,
OpenPOWER on IntegriCloud