···11+22+ TODO33+~~~~~~44+Please pick something while reading :)55+66+- Implement streaming support for BULK endpoints77+ Tatyana's patch "usb: Add streams support to the gadget framework"88+ introduces streaming support for the gadget driver.99+ Every usb_request has new field called stream_id which holds its id.1010+ Every usb_ep has a field num_supported_strms which describes the max1111+ number of streams supported (for this ep).1212+ UAS is AFAIK the only gadget with streaming support.1313+1414+- Convert interrupt handler to per-ep-thread-irq1515+1616+ As it turns out some DWC3-commands ~1ms to complete. Currently we spin1717+ until the command completes which is bad.1818+1919+ Implementation idea:2020+ - dwc core implements a demultiplexing irq chip for interrupts per2121+ endpoint. The interrupt numbers are allocated during probe and belong2222+ to the device. If MSI provides per-endpoint interrupt this dummy2323+ interrupt chip can be replaced with "real" interrupts.2424+ - interrupts are requested / allocated on usb_ep_enable() and removed on2525+ usb_ep_disable(). Worst case are 32 interrupts, the lower limit is two2626+ for ep0/1.2727+ - dwc3_send_gadget_ep_cmd() will sleep in wait_for_completion_timeout()2828+ until the command completes.2929+ - the interrupt handler is split into the following pieces:3030+ - primary handler of the device3131+ goes through every event and calls generic_handle_irq() for event3232+ it. On return from generic_handle_irq() in acknowledges the event3333+ counter so interrupt goes away (eventually).3434+3535+ - threaded handler of the device3636+ none3737+3838+ - primary handler of the EP-interrupt3939+ reads the event and tries to process it. Everything that requries4040+ sleeping is handed over to the Thread. The event is saved in an4141+ per-endpoint data-structure.4242+ We probably have to pay attention not to process events once we4343+ handed something to thread so we don't process event X prio Y4444+ where X > Y.4545+4646+ - threaded handler of the EP-interrupt4747+ handles the remaining EP work which might sleep such as waiting4848+ for command completion.4949+5050+ Latency:5151+ There should be no increase in latency since the interrupt-thread has a5252+ high priority and will be run before an average task in user land5353+ (except the user changed priorities).
+8
MAINTAINERS
···21392139S: Maintained21402140F: drivers/platform/x86/dell-wmi.c2141214121422142+DESIGNWARE USB3 DRD IP DRIVER21432143+M: Felipe Balbi <balbi@ti.com>21442144+L: linux-usb@vger.kernel.org21452145+L: linux-omap@vger.kernel.org21462146+T: git git://git.kernel.org/pub/scm/linux/kernel/git/balbi/usb.git21472147+S: Maintained21482148+F: drivers/usb/dwc3/21492149+21422150DEVICE NUMBER REGISTRY21432151M: Torben Mathiasen <device@lanana.org>21442152W: http://lanana.org/docs/device-list/index.html
+7
arch/arm/mach-mmp/include/mach/pxa168.h
···3535extern struct pxa_device_desc pxa168_device_keypad;3636extern struct pxa_device_desc pxa168_device_eth;37373838+struct pxa168_usb_pdata {3939+ /* If NULL, default phy init routine for PXA168 would be called */4040+ int (*phy_init)(void __iomem *usb_phy_reg_base);4141+};4242+/* pdata can be NULL */4343+int __init pxa168_add_usb_host(struct pxa168_usb_pdata *pdata);4444+3845static inline int pxa168_add_uart(int id)3946{4047 struct pxa_device_desc *d = NULL;
···6969 default y if ARCH_MSM7070 default y if MICROBLAZE7171 default y if SPARC_LEON7272+ default y if ARCH_MMP7273 default PCI73747475# ARM SA1111 chips have a non-PCI based "OHCI-compatible" USB host interface.···110109 module will be called usbcore.111110112111source "drivers/usb/core/Kconfig"112112+113113+source "drivers/usb/dwc3/Kconfig"113114114115source "drivers/usb/mon/Kconfig"115116
···16361636 int i;16371637 struct usb_hcd *hcd = bus_to_hcd(udev->bus);1638163816391639- if (!udev) {16401640- pr_debug ("%s nodev\n", __func__);16411641- return;16421642- }16431643-16441639 /* mark the device as inactive, so any further urb submissions for16451640 * this device (and any of its children) will fail immediately.16461641 * this quiesces everything except pending urbs.···30183023 i = 512;30193024 else30203025 i = udev->descriptor.bMaxPacketSize0;30213021- if (le16_to_cpu(udev->ep0.desc.wMaxPacketSize) != i) {30263026+ if (usb_endpoint_maxp(&udev->ep0.desc) != i) {30223027 if (udev->speed == USB_SPEED_LOW ||30233028 !(i == 8 || i == 16 || i == 32 || i == 64)) {30243029 dev_err(&udev->dev, "Invalid ep0 maxpacket: %d\n", i);
+1-1
drivers/usb/core/urb.c
···350350 dev->state < USB_STATE_CONFIGURED)351351 return -ENODEV;352352353353- max = le16_to_cpu(ep->desc.wMaxPacketSize);353353+ max = usb_endpoint_maxp(&ep->desc);354354 if (max <= 0) {355355 dev_dbg(&dev->dev,356356 "bogus endpoint ep%d%s in %s (bad maxpacket %d)\n",
+25
drivers/usb/dwc3/Kconfig
···11+config USB_DWC322+ tristate "DesignWare USB3 DRD Core Support"33+ depends on (USB || USB_GADGET)44+ select USB_OTG_UTILS55+ help66+ Say Y or M here if your system has a Dual Role SuperSpeed77+ USB controller based on the DesignWare USB3 IP Core.88+99+ If you choose to build this driver is a dynamically linked1010+ module, the module will be called dwc3.ko.1111+1212+if USB_DWC31313+1414+config USB_DWC3_DEBUG1515+ bool "Enable Debugging Messages"1616+ help1717+ Say Y here to enable debugging messages on DWC3 Driver.1818+1919+config USB_DWC3_VERBOSE2020+ bool "Enable Verbose Debugging Messages"2121+ depends on USB_DWC3_DEBUG2222+ help2323+ Say Y here to enable verbose debugging messages on DWC3 Driver.2424+2525+endif
+36
drivers/usb/dwc3/Makefile
···11+ccflags-$(CONFIG_USB_DWC3_DEBUG) := -DDEBUG22+ccflags-$(CONFIG_USB_DWC3_VERBOSE) += -DVERBOSE_DEBUG33+44+obj-$(CONFIG_USB_DWC3) += dwc3.o55+66+dwc3-y := core.o77+88+ifneq ($(CONFIG_USB_GADGET_DWC3),)99+ dwc3-y += gadget.o ep0.o1010+endif1111+1212+ifneq ($(CONFIG_DEBUG_FS),)1313+ dwc3-y += debugfs.o1414+endif1515+1616+##1717+# Platform-specific glue layers go here1818+#1919+# NOTICE: Make sure your glue layer doesn't depend on anything2020+# which is arch-specific and that it compiles on all situations.2121+#2222+# We want to keep this requirement in order to be able to compile2323+# the entire driver (with all its glue layers) on several architectures2424+# and make sure it compiles fine. This will also help with allmodconfig2525+# and allyesconfig builds.2626+#2727+# The only exception is the PCI glue layer, but that's only because2828+# PCI doesn't provide nops if CONFIG_PCI isn't enabled.2929+##3030+3131+obj-$(CONFIG_USB_DWC3) += dwc3-omap.o3232+3333+ifneq ($(CONFIG_PCI),)3434+ obj-$(CONFIG_USB_DWC3) += dwc3-pci.o3535+endif3636+
+467
drivers/usb/dwc3/core.c
···11+/**22+ * core.c - DesignWare USB3 DRD Controller Core file33+ *44+ * Copyright (C) 2010-2011 Texas Instruments Incorporated - http://www.ti.com55+ * All rights reserved.66+ *77+ * Authors: Felipe Balbi <balbi@ti.com>,88+ * Sebastian Andrzej Siewior <bigeasy@linutronix.de>99+ *1010+ * Redistribution and use in source and binary forms, with or without1111+ * modification, are permitted provided that the following conditions1212+ * are met:1313+ * 1. Redistributions of source code must retain the above copyright1414+ * notice, this list of conditions, and the following disclaimer,1515+ * without modification.1616+ * 2. Redistributions in binary form must reproduce the above copyright1717+ * notice, this list of conditions and the following disclaimer in the1818+ * documentation and/or other materials provided with the distribution.1919+ * 3. The names of the above-listed copyright holders may not be used2020+ * to endorse or promote products derived from this software without2121+ * specific prior written permission.2222+ *2323+ * ALTERNATIVELY, this software may be distributed under the terms of the2424+ * GNU General Public License ("GPL") version 2, as published by the Free2525+ * Software Foundation.2626+ *2727+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS2828+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,2929+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR3030+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR3131+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,3232+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,3333+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR3434+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF3535+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING3636+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS3737+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.3838+ */3939+4040+#include <linux/kernel.h>4141+#include <linux/slab.h>4242+#include <linux/spinlock.h>4343+#include <linux/platform_device.h>4444+#include <linux/pm_runtime.h>4545+#include <linux/interrupt.h>4646+#include <linux/ioport.h>4747+#include <linux/io.h>4848+#include <linux/list.h>4949+#include <linux/delay.h>5050+#include <linux/dma-mapping.h>5151+5252+#include <linux/usb/ch9.h>5353+#include <linux/usb/gadget.h>5454+5555+#include "core.h"5656+#include "gadget.h"5757+#include "io.h"5858+5959+#include "debug.h"6060+6161+/**6262+ * dwc3_core_soft_reset - Issues core soft reset and PHY reset6363+ * @dwc: pointer to our context structure6464+ */6565+static void dwc3_core_soft_reset(struct dwc3 *dwc)6666+{6767+ u32 reg;6868+6969+ /* Before Resetting PHY, put Core in Reset */7070+ reg = dwc3_readl(dwc->regs, DWC3_GCTL);7171+ reg |= DWC3_GCTL_CORESOFTRESET;7272+ dwc3_writel(dwc->regs, DWC3_GCTL, reg);7373+7474+ /* Assert USB3 PHY reset */7575+ reg = dwc3_readl(dwc->regs, DWC3_GUSB3PIPECTL(0));7676+ reg |= DWC3_GUSB3PIPECTL_PHYSOFTRST;7777+ dwc3_writel(dwc->regs, DWC3_GUSB3PIPECTL(0), reg);7878+7979+ /* Assert USB2 PHY reset */8080+ reg = dwc3_readl(dwc->regs, DWC3_GUSB2PHYCFG(0));8181+ reg |= DWC3_GUSB2PHYCFG_PHYSOFTRST;8282+ dwc3_writel(dwc->regs, DWC3_GUSB2PHYCFG(0), reg);8383+8484+ mdelay(100);8585+8686+ /* Clear USB3 PHY reset */8787+ reg = dwc3_readl(dwc->regs, DWC3_GUSB3PIPECTL(0));8888+ reg &= ~DWC3_GUSB3PIPECTL_PHYSOFTRST;8989+ dwc3_writel(dwc->regs, DWC3_GUSB3PIPECTL(0), reg);9090+9191+ /* Clear USB2 PHY reset */9292+ reg = dwc3_readl(dwc->regs, DWC3_GUSB2PHYCFG(0));9393+ reg &= ~DWC3_GUSB2PHYCFG_PHYSOFTRST;9494+ dwc3_writel(dwc->regs, DWC3_GUSB2PHYCFG(0), reg);9595+9696+ /* After PHYs are stable we can take Core out of reset state */9797+ reg = dwc3_readl(dwc->regs, DWC3_GCTL);9898+ reg &= ~DWC3_GCTL_CORESOFTRESET;9999+ dwc3_writel(dwc->regs, DWC3_GCTL, reg);100100+}101101+102102+/**103103+ * dwc3_free_one_event_buffer - Frees one event buffer104104+ * @dwc: Pointer to our controller context structure105105+ * @evt: Pointer to event buffer to be freed106106+ */107107+static void dwc3_free_one_event_buffer(struct dwc3 *dwc,108108+ struct dwc3_event_buffer *evt)109109+{110110+ dma_free_coherent(dwc->dev, evt->length, evt->buf, evt->dma);111111+ kfree(evt);112112+}113113+114114+/**115115+ * dwc3_alloc_one_event_buffer - Allocated one event buffer structure116116+ * @dwc: Pointer to our controller context structure117117+ * @length: size of the event buffer118118+ *119119+ * Returns a pointer to the allocated event buffer structure on succes120120+ * otherwise ERR_PTR(errno).121121+ */122122+static struct dwc3_event_buffer *__devinit123123+dwc3_alloc_one_event_buffer(struct dwc3 *dwc, unsigned length)124124+{125125+ struct dwc3_event_buffer *evt;126126+127127+ evt = kzalloc(sizeof(*evt), GFP_KERNEL);128128+ if (!evt)129129+ return ERR_PTR(-ENOMEM);130130+131131+ evt->dwc = dwc;132132+ evt->length = length;133133+ evt->buf = dma_alloc_coherent(dwc->dev, length,134134+ &evt->dma, GFP_KERNEL);135135+ if (!evt->buf) {136136+ kfree(evt);137137+ return ERR_PTR(-ENOMEM);138138+ }139139+140140+ return evt;141141+}142142+143143+/**144144+ * dwc3_free_event_buffers - frees all allocated event buffers145145+ * @dwc: Pointer to our controller context structure146146+ */147147+static void dwc3_free_event_buffers(struct dwc3 *dwc)148148+{149149+ struct dwc3_event_buffer *evt;150150+ int i;151151+152152+ for (i = 0; i < DWC3_EVENT_BUFFERS_NUM; i++) {153153+ evt = dwc->ev_buffs[i];154154+ if (evt) {155155+ dwc3_free_one_event_buffer(dwc, evt);156156+ dwc->ev_buffs[i] = NULL;157157+ }158158+ }159159+}160160+161161+/**162162+ * dwc3_alloc_event_buffers - Allocates @num event buffers of size @length163163+ * @dwc: Pointer to out controller context structure164164+ * @num: number of event buffers to allocate165165+ * @length: size of event buffer166166+ *167167+ * Returns 0 on success otherwise negative errno. In error the case, dwc168168+ * may contain some buffers allocated but not all which were requested.169169+ */170170+static int __devinit dwc3_alloc_event_buffers(struct dwc3 *dwc, unsigned num,171171+ unsigned length)172172+{173173+ int i;174174+175175+ for (i = 0; i < num; i++) {176176+ struct dwc3_event_buffer *evt;177177+178178+ evt = dwc3_alloc_one_event_buffer(dwc, length);179179+ if (IS_ERR(evt)) {180180+ dev_err(dwc->dev, "can't allocate event buffer\n");181181+ return PTR_ERR(evt);182182+ }183183+ dwc->ev_buffs[i] = evt;184184+ }185185+186186+ return 0;187187+}188188+189189+/**190190+ * dwc3_event_buffers_setup - setup our allocated event buffers191191+ * @dwc: Pointer to out controller context structure192192+ *193193+ * Returns 0 on success otherwise negative errno.194194+ */195195+static int __devinit dwc3_event_buffers_setup(struct dwc3 *dwc)196196+{197197+ struct dwc3_event_buffer *evt;198198+ int n;199199+200200+ for (n = 0; n < DWC3_EVENT_BUFFERS_NUM; n++) {201201+ evt = dwc->ev_buffs[n];202202+ dev_dbg(dwc->dev, "Event buf %p dma %08llx length %d\n",203203+ evt->buf, (unsigned long long) evt->dma,204204+ evt->length);205205+206206+ dwc3_writel(dwc->regs, DWC3_GEVNTADRLO(n),207207+ lower_32_bits(evt->dma));208208+ dwc3_writel(dwc->regs, DWC3_GEVNTADRHI(n),209209+ upper_32_bits(evt->dma));210210+ dwc3_writel(dwc->regs, DWC3_GEVNTSIZ(n),211211+ evt->length & 0xffff);212212+ dwc3_writel(dwc->regs, DWC3_GEVNTCOUNT(n), 0);213213+ }214214+215215+ return 0;216216+}217217+218218+static void dwc3_event_buffers_cleanup(struct dwc3 *dwc)219219+{220220+ struct dwc3_event_buffer *evt;221221+ int n;222222+223223+ for (n = 0; n < DWC3_EVENT_BUFFERS_NUM; n++) {224224+ evt = dwc->ev_buffs[n];225225+ dwc3_writel(dwc->regs, DWC3_GEVNTADRLO(n), 0);226226+ dwc3_writel(dwc->regs, DWC3_GEVNTADRHI(n), 0);227227+ dwc3_writel(dwc->regs, DWC3_GEVNTSIZ(n), 0);228228+ dwc3_writel(dwc->regs, DWC3_GEVNTCOUNT(n), 0);229229+ }230230+}231231+232232+/**233233+ * dwc3_core_init - Low-level initialization of DWC3 Core234234+ * @dwc: Pointer to our controller context structure235235+ *236236+ * Returns 0 on success otherwise negative errno.237237+ */238238+static int __devinit dwc3_core_init(struct dwc3 *dwc)239239+{240240+ unsigned long timeout;241241+ u32 reg;242242+ int ret;243243+244244+ dwc3_core_soft_reset(dwc);245245+246246+ /* issue device SoftReset too */247247+ timeout = jiffies + msecs_to_jiffies(500);248248+ dwc3_writel(dwc->regs, DWC3_DCTL, DWC3_DCTL_CSFTRST);249249+ do {250250+ reg = dwc3_readl(dwc->regs, DWC3_DCTL);251251+ if (!(reg & DWC3_DCTL_CSFTRST))252252+ break;253253+254254+ if (time_after(jiffies, timeout)) {255255+ dev_err(dwc->dev, "Reset Timed Out\n");256256+ ret = -ETIMEDOUT;257257+ goto err0;258258+ }259259+260260+ cpu_relax();261261+ } while (true);262262+263263+ reg = dwc3_readl(dwc->regs, DWC3_GSNPSID);264264+ /* This should read as U3 followed by revision number */265265+ if ((reg & DWC3_GSNPSID_MASK) != 0x55330000) {266266+ dev_err(dwc->dev, "this is not a DesignWare USB3 DRD Core\n");267267+ ret = -ENODEV;268268+ goto err0;269269+ }270270+271271+ dwc->revision = reg & DWC3_GSNPSREV_MASK;272272+273273+ ret = dwc3_alloc_event_buffers(dwc, DWC3_EVENT_BUFFERS_NUM,274274+ DWC3_EVENT_BUFFERS_SIZE);275275+ if (ret) {276276+ dev_err(dwc->dev, "failed to allocate event buffers\n");277277+ ret = -ENOMEM;278278+ goto err1;279279+ }280280+281281+ ret = dwc3_event_buffers_setup(dwc);282282+ if (ret) {283283+ dev_err(dwc->dev, "failed to setup event buffers\n");284284+ goto err1;285285+ }286286+287287+ return 0;288288+289289+err1:290290+ dwc3_free_event_buffers(dwc);291291+292292+err0:293293+ return ret;294294+}295295+296296+static void dwc3_core_exit(struct dwc3 *dwc)297297+{298298+ dwc3_event_buffers_cleanup(dwc);299299+ dwc3_free_event_buffers(dwc);300300+}301301+302302+#define DWC3_ALIGN_MASK (16 - 1)303303+304304+static int __devinit dwc3_probe(struct platform_device *pdev)305305+{306306+ const struct platform_device_id *id = platform_get_device_id(pdev);307307+ struct resource *res;308308+ struct dwc3 *dwc;309309+ void __iomem *regs;310310+ unsigned int features = id->driver_data;311311+ int ret = -ENOMEM;312312+ int irq;313313+ void *mem;314314+315315+ mem = kzalloc(sizeof(*dwc) + DWC3_ALIGN_MASK, GFP_KERNEL);316316+ if (!mem) {317317+ dev_err(&pdev->dev, "not enough memory\n");318318+ goto err0;319319+ }320320+ dwc = PTR_ALIGN(mem, DWC3_ALIGN_MASK + 1);321321+ dwc->mem = mem;322322+323323+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);324324+ if (!res) {325325+ dev_err(&pdev->dev, "missing resource\n");326326+ goto err1;327327+ }328328+329329+ res = request_mem_region(res->start, resource_size(res),330330+ dev_name(&pdev->dev));331331+ if (!res) {332332+ dev_err(&pdev->dev, "can't request mem region\n");333333+ goto err1;334334+ }335335+336336+ regs = ioremap(res->start, resource_size(res));337337+ if (!regs) {338338+ dev_err(&pdev->dev, "ioremap failed\n");339339+ goto err2;340340+ }341341+342342+ irq = platform_get_irq(pdev, 0);343343+ if (irq < 0) {344344+ dev_err(&pdev->dev, "missing IRQ\n");345345+ goto err3;346346+ }347347+348348+ spin_lock_init(&dwc->lock);349349+ platform_set_drvdata(pdev, dwc);350350+351351+ dwc->regs = regs;352352+ dwc->regs_size = resource_size(res);353353+ dwc->dev = &pdev->dev;354354+ dwc->irq = irq;355355+356356+ pm_runtime_enable(&pdev->dev);357357+ pm_runtime_get_sync(&pdev->dev);358358+ pm_runtime_forbid(&pdev->dev);359359+360360+ ret = dwc3_core_init(dwc);361361+ if (ret) {362362+ dev_err(&pdev->dev, "failed to initialize core\n");363363+ goto err3;364364+ }365365+366366+ if (features & DWC3_HAS_PERIPHERAL) {367367+ ret = dwc3_gadget_init(dwc);368368+ if (ret) {369369+ dev_err(&pdev->dev, "failed to initialized gadget\n");370370+ goto err4;371371+ }372372+ }373373+374374+ ret = dwc3_debugfs_init(dwc);375375+ if (ret) {376376+ dev_err(&pdev->dev, "failed to initialize debugfs\n");377377+ goto err5;378378+ }379379+380380+ pm_runtime_allow(&pdev->dev);381381+382382+ return 0;383383+384384+err5:385385+ if (features & DWC3_HAS_PERIPHERAL)386386+ dwc3_gadget_exit(dwc);387387+388388+err4:389389+ dwc3_core_exit(dwc);390390+391391+err3:392392+ iounmap(regs);393393+394394+err2:395395+ release_mem_region(res->start, resource_size(res));396396+397397+err1:398398+ kfree(dwc->mem);399399+400400+err0:401401+ return ret;402402+}403403+404404+static int __devexit dwc3_remove(struct platform_device *pdev)405405+{406406+ const struct platform_device_id *id = platform_get_device_id(pdev);407407+ struct dwc3 *dwc = platform_get_drvdata(pdev);408408+ struct resource *res;409409+ unsigned int features = id->driver_data;410410+411411+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);412412+413413+ pm_runtime_put(&pdev->dev);414414+ pm_runtime_disable(&pdev->dev);415415+416416+ dwc3_debugfs_exit(dwc);417417+418418+ if (features & DWC3_HAS_PERIPHERAL)419419+ dwc3_gadget_exit(dwc);420420+421421+ dwc3_core_exit(dwc);422422+ release_mem_region(res->start, resource_size(res));423423+ iounmap(dwc->regs);424424+ kfree(dwc->mem);425425+426426+ return 0;427427+}428428+429429+static const struct platform_device_id dwc3_id_table[] __devinitconst = {430430+ {431431+ .name = "dwc3-omap",432432+ .driver_data = (DWC3_HAS_PERIPHERAL433433+ | DWC3_HAS_XHCI434434+ | DWC3_HAS_OTG),435435+ },436436+ {437437+ .name = "dwc3-pci",438438+ .driver_data = DWC3_HAS_PERIPHERAL,439439+ },440440+ { }, /* Terminating Entry */441441+};442442+MODULE_DEVICE_TABLE(platform, dwc3_id_table);443443+444444+static struct platform_driver dwc3_driver = {445445+ .probe = dwc3_probe,446446+ .remove = __devexit_p(dwc3_remove),447447+ .driver = {448448+ .name = "dwc3",449449+ },450450+ .id_table = dwc3_id_table,451451+};452452+453453+MODULE_AUTHOR("Felipe Balbi <balbi@ti.com>");454454+MODULE_LICENSE("Dual BSD/GPL");455455+MODULE_DESCRIPTION("DesignWare USB3 DRD Controller Driver");456456+457457+static int __devinit dwc3_init(void)458458+{459459+ return platform_driver_register(&dwc3_driver);460460+}461461+module_init(dwc3_init);462462+463463+static void __exit dwc3_exit(void)464464+{465465+ platform_driver_unregister(&dwc3_driver);466466+}467467+module_exit(dwc3_exit);
+709
drivers/usb/dwc3/core.h
···11+/**22+ * core.h - DesignWare USB3 DRD Core Header33+ *44+ * Copyright (C) 2010-2011 Texas Instruments Incorporated - http://www.ti.com55+ * All rights reserved.66+ *77+ * Authors: Felipe Balbi <balbi@ti.com>,88+ * Sebastian Andrzej Siewior <bigeasy@linutronix.de>99+ *1010+ * Redistribution and use in source and binary forms, with or without1111+ * modification, are permitted provided that the following conditions1212+ * are met:1313+ * 1. Redistributions of source code must retain the above copyright1414+ * notice, this list of conditions, and the following disclaimer,1515+ * without modification.1616+ * 2. Redistributions in binary form must reproduce the above copyright1717+ * notice, this list of conditions and the following disclaimer in the1818+ * documentation and/or other materials provided with the distribution.1919+ * 3. The names of the above-listed copyright holders may not be used2020+ * to endorse or promote products derived from this software without2121+ * specific prior written permission.2222+ *2323+ * ALTERNATIVELY, this software may be distributed under the terms of the2424+ * GNU General Public License ("GPL") version 2, as published by the Free2525+ * Software Foundation.2626+ *2727+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS2828+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,2929+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR3030+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR3131+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,3232+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,3333+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR3434+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF3535+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING3636+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS3737+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.3838+ */3939+4040+#ifndef __DRIVERS_USB_DWC3_CORE_H4141+#define __DRIVERS_USB_DWC3_CORE_H4242+4343+#include <linux/device.h>4444+#include <linux/spinlock.h>4545+#include <linux/list.h>4646+#include <linux/dma-mapping.h>4747+#include <linux/mm.h>4848+#include <linux/debugfs.h>4949+5050+#include <linux/usb/ch9.h>5151+#include <linux/usb/gadget.h>5252+5353+/* Global constants */5454+#define DWC3_ENDPOINTS_NUM 325555+5656+#define DWC3_EVENT_BUFFERS_NUM 25757+#define DWC3_EVENT_BUFFERS_SIZE PAGE_SIZE5858+#define DWC3_EVENT_TYPE_MASK 0xfe5959+6060+#define DWC3_EVENT_TYPE_DEV 06161+#define DWC3_EVENT_TYPE_CARKIT 36262+#define DWC3_EVENT_TYPE_I2C 46363+6464+#define DWC3_DEVICE_EVENT_DISCONNECT 06565+#define DWC3_DEVICE_EVENT_RESET 16666+#define DWC3_DEVICE_EVENT_CONNECT_DONE 26767+#define DWC3_DEVICE_EVENT_LINK_STATUS_CHANGE 36868+#define DWC3_DEVICE_EVENT_WAKEUP 46969+#define DWC3_DEVICE_EVENT_EOPF 67070+#define DWC3_DEVICE_EVENT_SOF 77171+#define DWC3_DEVICE_EVENT_ERRATIC_ERROR 97272+#define DWC3_DEVICE_EVENT_CMD_CMPL 107373+#define DWC3_DEVICE_EVENT_OVERFLOW 117474+7575+#define DWC3_GEVNTCOUNT_MASK 0xfffc7676+#define DWC3_GSNPSID_MASK 0xffff00007777+#define DWC3_GSNPSREV_MASK 0xffff7878+7979+/* Global Registers */8080+#define DWC3_GSBUSCFG0 0xc1008181+#define DWC3_GSBUSCFG1 0xc1048282+#define DWC3_GTXTHRCFG 0xc1088383+#define DWC3_GRXTHRCFG 0xc10c8484+#define DWC3_GCTL 0xc1108585+#define DWC3_GEVTEN 0xc1148686+#define DWC3_GSTS 0xc1188787+#define DWC3_GSNPSID 0xc1208888+#define DWC3_GGPIO 0xc1248989+#define DWC3_GUID 0xc1289090+#define DWC3_GUCTL 0xc12c9191+#define DWC3_GBUSERRADDR0 0xc1309292+#define DWC3_GBUSERRADDR1 0xc1349393+#define DWC3_GPRTBIMAP0 0xc1389494+#define DWC3_GPRTBIMAP1 0xc13c9595+#define DWC3_GHWPARAMS0 0xc1409696+#define DWC3_GHWPARAMS1 0xc1449797+#define DWC3_GHWPARAMS2 0xc1489898+#define DWC3_GHWPARAMS3 0xc14c9999+#define DWC3_GHWPARAMS4 0xc150100100+#define DWC3_GHWPARAMS5 0xc154101101+#define DWC3_GHWPARAMS6 0xc158102102+#define DWC3_GHWPARAMS7 0xc15c103103+#define DWC3_GDBGFIFOSPACE 0xc160104104+#define DWC3_GDBGLTSSM 0xc164105105+#define DWC3_GPRTBIMAP_HS0 0xc180106106+#define DWC3_GPRTBIMAP_HS1 0xc184107107+#define DWC3_GPRTBIMAP_FS0 0xc188108108+#define DWC3_GPRTBIMAP_FS1 0xc18c109109+110110+#define DWC3_GUSB2PHYCFG(n) (0xc200 + (n * 0x04))111111+#define DWC3_GUSB2I2CCTL(n) (0xc240 + (n * 0x04))112112+113113+#define DWC3_GUSB2PHYACC(n) (0xc280 + (n * 0x04))114114+115115+#define DWC3_GUSB3PIPECTL(n) (0xc2c0 + (n * 0x04))116116+117117+#define DWC3_GTXFIFOSIZ(n) (0xc300 + (n * 0x04))118118+#define DWC3_GRXFIFOSIZ(n) (0xc380 + (n * 0x04))119119+120120+#define DWC3_GEVNTADRLO(n) (0xc400 + (n * 0x10))121121+#define DWC3_GEVNTADRHI(n) (0xc404 + (n * 0x10))122122+#define DWC3_GEVNTSIZ(n) (0xc408 + (n * 0x10))123123+#define DWC3_GEVNTCOUNT(n) (0xc40c + (n * 0x10))124124+125125+#define DWC3_GHWPARAMS8 0xc600126126+127127+/* Device Registers */128128+#define DWC3_DCFG 0xc700129129+#define DWC3_DCTL 0xc704130130+#define DWC3_DEVTEN 0xc708131131+#define DWC3_DSTS 0xc70c132132+#define DWC3_DGCMDPAR 0xc710133133+#define DWC3_DGCMD 0xc714134134+#define DWC3_DALEPENA 0xc720135135+#define DWC3_DEPCMDPAR2(n) (0xc800 + (n * 0x10))136136+#define DWC3_DEPCMDPAR1(n) (0xc804 + (n * 0x10))137137+#define DWC3_DEPCMDPAR0(n) (0xc808 + (n * 0x10))138138+#define DWC3_DEPCMD(n) (0xc80c + (n * 0x10))139139+140140+/* OTG Registers */141141+#define DWC3_OCFG 0xcc00142142+#define DWC3_OCTL 0xcc04143143+#define DWC3_OEVTEN 0xcc08144144+#define DWC3_OSTS 0xcc0C145145+146146+/* Bit fields */147147+148148+/* Global Configuration Register */149149+#define DWC3_GCTL_PWRDNSCALE(n) (n << 19)150150+#define DWC3_GCTL_U2RSTECN 16151151+#define DWC3_GCTL_RAMCLKSEL(x) ((x & DWC3_GCTL_CLK_MASK) << 6)152152+#define DWC3_GCTL_CLK_BUS (0)153153+#define DWC3_GCTL_CLK_PIPE (1)154154+#define DWC3_GCTL_CLK_PIPEHALF (2)155155+#define DWC3_GCTL_CLK_MASK (3)156156+157157+#define DWC3_GCTL_PRTCAPDIR(n) (n << 12)158158+#define DWC3_GCTL_PRTCAP_HOST 1159159+#define DWC3_GCTL_PRTCAP_DEVICE 2160160+#define DWC3_GCTL_PRTCAP_OTG 3161161+162162+#define DWC3_GCTL_CORESOFTRESET (1 << 11)163163+#define DWC3_GCTL_DISSCRAMBLE (1 << 3)164164+165165+/* Global USB2 PHY Configuration Register */166166+#define DWC3_GUSB2PHYCFG_PHYSOFTRST (1 << 31)167167+#define DWC3_GUSB2PHYCFG_SUSPHY (1 << 6)168168+169169+/* Global USB3 PIPE Control Register */170170+#define DWC3_GUSB3PIPECTL_PHYSOFTRST (1 << 31)171171+#define DWC3_GUSB3PIPECTL_SUSPHY (1 << 17)172172+173173+/* Device Configuration Register */174174+#define DWC3_DCFG_DEVADDR(addr) ((addr) << 3)175175+#define DWC3_DCFG_DEVADDR_MASK DWC3_DCFG_DEVADDR(0x7f)176176+177177+#define DWC3_DCFG_SPEED_MASK (7 << 0)178178+#define DWC3_DCFG_SUPERSPEED (4 << 0)179179+#define DWC3_DCFG_HIGHSPEED (0 << 0)180180+#define DWC3_DCFG_FULLSPEED2 (1 << 0)181181+#define DWC3_DCFG_LOWSPEED (2 << 0)182182+#define DWC3_DCFG_FULLSPEED1 (3 << 0)183183+184184+/* Device Control Register */185185+#define DWC3_DCTL_RUN_STOP (1 << 31)186186+#define DWC3_DCTL_CSFTRST (1 << 30)187187+#define DWC3_DCTL_LSFTRST (1 << 29)188188+189189+#define DWC3_DCTL_HIRD_THRES_MASK (0x1f << 24)190190+#define DWC3_DCTL_HIRD_THRES(n) (((n) & DWC3_DCTL_HIRD_THRES_MASK) >> 24)191191+192192+#define DWC3_DCTL_APPL1RES (1 << 23)193193+194194+#define DWC3_DCTL_INITU2ENA (1 << 12)195195+#define DWC3_DCTL_ACCEPTU2ENA (1 << 11)196196+#define DWC3_DCTL_INITU1ENA (1 << 10)197197+#define DWC3_DCTL_ACCEPTU1ENA (1 << 9)198198+#define DWC3_DCTL_TSTCTRL_MASK (0xf << 1)199199+200200+#define DWC3_DCTL_ULSTCHNGREQ_MASK (0x0f << 5)201201+#define DWC3_DCTL_ULSTCHNGREQ(n) (((n) << 5) & DWC3_DCTL_ULSTCHNGREQ_MASK)202202+203203+#define DWC3_DCTL_ULSTCHNG_NO_ACTION (DWC3_DCTL_ULSTCHNGREQ(0))204204+#define DWC3_DCTL_ULSTCHNG_SS_DISABLED (DWC3_DCTL_ULSTCHNGREQ(4))205205+#define DWC3_DCTL_ULSTCHNG_RX_DETECT (DWC3_DCTL_ULSTCHNGREQ(5))206206+#define DWC3_DCTL_ULSTCHNG_SS_INACTIVE (DWC3_DCTL_ULSTCHNGREQ(6))207207+#define DWC3_DCTL_ULSTCHNG_RECOVERY (DWC3_DCTL_ULSTCHNGREQ(8))208208+#define DWC3_DCTL_ULSTCHNG_COMPLIANCE (DWC3_DCTL_ULSTCHNGREQ(10))209209+#define DWC3_DCTL_ULSTCHNG_LOOPBACK (DWC3_DCTL_ULSTCHNGREQ(11))210210+211211+/* Device Event Enable Register */212212+#define DWC3_DEVTEN_VNDRDEVTSTRCVEDEN (1 << 12)213213+#define DWC3_DEVTEN_EVNTOVERFLOWEN (1 << 11)214214+#define DWC3_DEVTEN_CMDCMPLTEN (1 << 10)215215+#define DWC3_DEVTEN_ERRTICERREN (1 << 9)216216+#define DWC3_DEVTEN_SOFEN (1 << 7)217217+#define DWC3_DEVTEN_EOPFEN (1 << 6)218218+#define DWC3_DEVTEN_WKUPEVTEN (1 << 4)219219+#define DWC3_DEVTEN_ULSTCNGEN (1 << 3)220220+#define DWC3_DEVTEN_CONNECTDONEEN (1 << 2)221221+#define DWC3_DEVTEN_USBRSTEN (1 << 1)222222+#define DWC3_DEVTEN_DISCONNEVTEN (1 << 0)223223+224224+/* Device Status Register */225225+#define DWC3_DSTS_PWRUPREQ (1 << 24)226226+#define DWC3_DSTS_COREIDLE (1 << 23)227227+#define DWC3_DSTS_DEVCTRLHLT (1 << 22)228228+229229+#define DWC3_DSTS_USBLNKST_MASK (0x0f << 18)230230+#define DWC3_DSTS_USBLNKST(n) (((n) & DWC3_DSTS_USBLNKST_MASK) >> 18)231231+232232+#define DWC3_DSTS_RXFIFOEMPTY (1 << 17)233233+234234+#define DWC3_DSTS_SOFFN_MASK (0x3ff << 3)235235+#define DWC3_DSTS_SOFFN(n) (((n) & DWC3_DSTS_SOFFN_MASK) >> 3)236236+237237+#define DWC3_DSTS_CONNECTSPD (7 << 0)238238+239239+#define DWC3_DSTS_SUPERSPEED (4 << 0)240240+#define DWC3_DSTS_HIGHSPEED (0 << 0)241241+#define DWC3_DSTS_FULLSPEED2 (1 << 0)242242+#define DWC3_DSTS_LOWSPEED (2 << 0)243243+#define DWC3_DSTS_FULLSPEED1 (3 << 0)244244+245245+/* Device Generic Command Register */246246+#define DWC3_DGCMD_SET_LMP 0x01247247+#define DWC3_DGCMD_SET_PERIODIC_PAR 0x02248248+#define DWC3_DGCMD_XMIT_FUNCTION 0x03249249+#define DWC3_DGCMD_SELECTED_FIFO_FLUSH 0x09250250+#define DWC3_DGCMD_ALL_FIFO_FLUSH 0x0a251251+#define DWC3_DGCMD_SET_ENDPOINT_NRDY 0x0c252252+#define DWC3_DGCMD_RUN_SOC_BUS_LOOPBACK 0x10253253+254254+/* Device Endpoint Command Register */255255+#define DWC3_DEPCMD_PARAM_SHIFT 16256256+#define DWC3_DEPCMD_PARAM(x) (x << DWC3_DEPCMD_PARAM_SHIFT)257257+#define DWC3_DEPCMD_GET_RSC_IDX(x) ((x >> DWC3_DEPCMD_PARAM_SHIFT) & 0x7f)258258+#define DWC3_DEPCMD_STATUS_MASK (0x0f << 12)259259+#define DWC3_DEPCMD_STATUS(x) ((x & DWC3_DEPCMD_STATUS_MASK) >> 12)260260+#define DWC3_DEPCMD_HIPRI_FORCERM (1 << 11)261261+#define DWC3_DEPCMD_CMDACT (1 << 10)262262+#define DWC3_DEPCMD_CMDIOC (1 << 8)263263+264264+#define DWC3_DEPCMD_DEPSTARTCFG (0x09 << 0)265265+#define DWC3_DEPCMD_ENDTRANSFER (0x08 << 0)266266+#define DWC3_DEPCMD_UPDATETRANSFER (0x07 << 0)267267+#define DWC3_DEPCMD_STARTTRANSFER (0x06 << 0)268268+#define DWC3_DEPCMD_CLEARSTALL (0x05 << 0)269269+#define DWC3_DEPCMD_SETSTALL (0x04 << 0)270270+#define DWC3_DEPCMD_GETSEQNUMBER (0x03 << 0)271271+#define DWC3_DEPCMD_SETTRANSFRESOURCE (0x02 << 0)272272+#define DWC3_DEPCMD_SETEPCONFIG (0x01 << 0)273273+274274+/* The EP number goes 0..31 so ep0 is always out and ep1 is always in */275275+#define DWC3_DALEPENA_EP(n) (1 << n)276276+277277+#define DWC3_DEPCMD_TYPE_CONTROL 0278278+#define DWC3_DEPCMD_TYPE_ISOC 1279279+#define DWC3_DEPCMD_TYPE_BULK 2280280+#define DWC3_DEPCMD_TYPE_INTR 3281281+282282+/* Structures */283283+284284+struct dwc3_trb_hw;285285+286286+/**287287+ * struct dwc3_event_buffer - Software event buffer representation288288+ * @list: a list of event buffers289289+ * @buf: _THE_ buffer290290+ * @length: size of this buffer291291+ * @dma: dma_addr_t292292+ * @dwc: pointer to DWC controller293293+ */294294+struct dwc3_event_buffer {295295+ void *buf;296296+ unsigned length;297297+ unsigned int lpos;298298+299299+ dma_addr_t dma;300300+301301+ struct dwc3 *dwc;302302+};303303+304304+#define DWC3_EP_FLAG_STALLED (1 << 0)305305+#define DWC3_EP_FLAG_WEDGED (1 << 1)306306+307307+#define DWC3_EP_DIRECTION_TX true308308+#define DWC3_EP_DIRECTION_RX false309309+310310+#define DWC3_TRB_NUM 32311311+#define DWC3_TRB_MASK (DWC3_TRB_NUM - 1)312312+313313+/**314314+ * struct dwc3_ep - device side endpoint representation315315+ * @endpoint: usb endpoint316316+ * @request_list: list of requests for this endpoint317317+ * @req_queued: list of requests on this ep which have TRBs setup318318+ * @trb_pool: array of transaction buffers319319+ * @trb_pool_dma: dma address of @trb_pool320320+ * @free_slot: next slot which is going to be used321321+ * @busy_slot: first slot which is owned by HW322322+ * @desc: usb_endpoint_descriptor pointer323323+ * @dwc: pointer to DWC controller324324+ * @flags: endpoint flags (wedged, stalled, ...)325325+ * @current_trb: index of current used trb326326+ * @number: endpoint number (1 - 15)327327+ * @type: set to bmAttributes & USB_ENDPOINT_XFERTYPE_MASK328328+ * @res_trans_idx: Resource transfer index329329+ * @interval: the intervall on which the ISOC transfer is started330330+ * @name: a human readable name e.g. ep1out-bulk331331+ * @direction: true for TX, false for RX332332+ */333333+struct dwc3_ep {334334+ struct usb_ep endpoint;335335+ struct list_head request_list;336336+ struct list_head req_queued;337337+338338+ struct dwc3_trb_hw *trb_pool;339339+ dma_addr_t trb_pool_dma;340340+ u32 free_slot;341341+ u32 busy_slot;342342+ const struct usb_endpoint_descriptor *desc;343343+ struct dwc3 *dwc;344344+345345+ unsigned flags;346346+#define DWC3_EP_ENABLED (1 << 0)347347+#define DWC3_EP_STALL (1 << 1)348348+#define DWC3_EP_WEDGE (1 << 2)349349+#define DWC3_EP_BUSY (1 << 4)350350+#define DWC3_EP_PENDING_REQUEST (1 << 5)351351+#define DWC3_EP_WILL_SHUTDOWN (1 << 6)352352+353353+ unsigned current_trb;354354+355355+ u8 number;356356+ u8 type;357357+ u8 res_trans_idx;358358+ u32 interval;359359+360360+ char name[20];361361+362362+ unsigned direction:1;363363+};364364+365365+enum dwc3_phy {366366+ DWC3_PHY_UNKNOWN = 0,367367+ DWC3_PHY_USB3,368368+ DWC3_PHY_USB2,369369+};370370+371371+enum dwc3_ep0_state {372372+ EP0_UNCONNECTED = 0,373373+ EP0_IDLE,374374+ EP0_IN_DATA_PHASE,375375+ EP0_OUT_DATA_PHASE,376376+ EP0_IN_WAIT_GADGET,377377+ EP0_OUT_WAIT_GADGET,378378+ EP0_IN_WAIT_NRDY,379379+ EP0_OUT_WAIT_NRDY,380380+ EP0_IN_STATUS_PHASE,381381+ EP0_OUT_STATUS_PHASE,382382+ EP0_STALL,383383+};384384+385385+enum dwc3_link_state {386386+ /* In SuperSpeed */387387+ DWC3_LINK_STATE_U0 = 0x00, /* in HS, means ON */388388+ DWC3_LINK_STATE_U1 = 0x01,389389+ DWC3_LINK_STATE_U2 = 0x02, /* in HS, means SLEEP */390390+ DWC3_LINK_STATE_U3 = 0x03, /* in HS, means SUSPEND */391391+ DWC3_LINK_STATE_SS_DIS = 0x04,392392+ DWC3_LINK_STATE_RX_DET = 0x05, /* in HS, means Early Suspend */393393+ DWC3_LINK_STATE_SS_INACT = 0x06,394394+ DWC3_LINK_STATE_POLL = 0x07,395395+ DWC3_LINK_STATE_RECOV = 0x08,396396+ DWC3_LINK_STATE_HRESET = 0x09,397397+ DWC3_LINK_STATE_CMPLY = 0x0a,398398+ DWC3_LINK_STATE_LPBK = 0x0b,399399+ DWC3_LINK_STATE_MASK = 0x0f,400400+};401401+402402+enum dwc3_device_state {403403+ DWC3_DEFAULT_STATE,404404+ DWC3_ADDRESS_STATE,405405+ DWC3_CONFIGURED_STATE,406406+};407407+408408+/**409409+ * struct dwc3_trb - transfer request block410410+ * @bpl: lower 32bit of the buffer411411+ * @bph: higher 32bit of the buffer412412+ * @length: buffer size (up to 16mb - 1)413413+ * @pcm1: packet count m1414414+ * @trbsts: trb status415415+ * 0 = ok416416+ * 1 = missed isoc417417+ * 2 = setup pending418418+ * @hwo: hardware owner of descriptor419419+ * @lst: last trb420420+ * @chn: chain buffers421421+ * @csp: continue on short packets (only supported on isoc eps)422422+ * @trbctl: trb control423423+ * 1 = normal424424+ * 2 = control-setup425425+ * 3 = control-status-2426426+ * 4 = control-status-3427427+ * 5 = control-data (first trb of data stage)428428+ * 6 = isochronous-first (first trb of service interval)429429+ * 7 = isochronous430430+ * 8 = link trb431431+ * others = reserved432432+ * @isp_imi: interrupt on short packet / interrupt on missed isoc433433+ * @ioc: interrupt on complete434434+ * @sid_sofn: Stream ID / SOF Number435435+ */436436+struct dwc3_trb {437437+ u64 bplh;438438+439439+ union {440440+ struct {441441+ u32 length:24;442442+ u32 pcm1:2;443443+ u32 reserved27_26:2;444444+ u32 trbsts:4;445445+#define DWC3_TRB_STS_OKAY 0446446+#define DWC3_TRB_STS_MISSED_ISOC 1447447+#define DWC3_TRB_STS_SETUP_PENDING 2448448+ };449449+ u32 len_pcm;450450+ };451451+452452+ union {453453+ struct {454454+ u32 hwo:1;455455+ u32 lst:1;456456+ u32 chn:1;457457+ u32 csp:1;458458+ u32 trbctl:6;459459+ u32 isp_imi:1;460460+ u32 ioc:1;461461+ u32 reserved13_12:2;462462+ u32 sid_sofn:16;463463+ u32 reserved31_30:2;464464+ };465465+ u32 control;466466+ };467467+} __packed;468468+469469+/**470470+ * struct dwc3_trb_hw - transfer request block (hw format)471471+ * @bpl: DW0-3472472+ * @bph: DW4-7473473+ * @size: DW8-B474474+ * @trl: DWC-F475475+ */476476+struct dwc3_trb_hw {477477+ __le32 bpl;478478+ __le32 bph;479479+ __le32 size;480480+ __le32 ctrl;481481+} __packed;482482+483483+static inline void dwc3_trb_to_hw(struct dwc3_trb *nat, struct dwc3_trb_hw *hw)484484+{485485+ hw->bpl = cpu_to_le32(lower_32_bits(nat->bplh));486486+ hw->bph = cpu_to_le32(upper_32_bits(nat->bplh));487487+ hw->size = cpu_to_le32p(&nat->len_pcm);488488+ /* HWO is written last */489489+ hw->ctrl = cpu_to_le32p(&nat->control);490490+}491491+492492+static inline void dwc3_trb_to_nat(struct dwc3_trb_hw *hw, struct dwc3_trb *nat)493493+{494494+ u64 bplh;495495+496496+ bplh = le32_to_cpup(&hw->bpl);497497+ bplh |= (u64) le32_to_cpup(&hw->bph) << 32;498498+ nat->bplh = bplh;499499+500500+ nat->len_pcm = le32_to_cpup(&hw->size);501501+ nat->control = le32_to_cpup(&hw->ctrl);502502+}503503+504504+/**505505+ * struct dwc3 - representation of our controller506506+ * ctrl_req: usb control request which is used for ep0507507+ * ep0_trb: trb which is used for the ctrl_req508508+ * setup_buf: used while precessing STD USB requests509509+ * ctrl_req_addr: dma address of ctrl_req510510+ * ep0_trb: dma address of ep0_trb511511+ * ep0_usb_req: dummy req used while handling STD USB requests512512+ * setup_buf_addr: dma address of setup_buf513513+ * @lock: for synchronizing514514+ * @dev: pointer to our struct device515515+ * @event_buffer_list: a list of event buffers516516+ * @gadget: device side representation of the peripheral controller517517+ * @gadget_driver: pointer to the gadget driver518518+ * @regs: base address for our registers519519+ * @regs_size: address space size520520+ * @irq: IRQ number521521+ * @revision: revision register contents522522+ * @is_selfpowered: true when we are selfpowered523523+ * @three_stage_setup: set if we perform a three phase setup524524+ * @ep0_status_pending: ep0 status response without a req is pending525525+ * @ep0state: state of endpoint zero526526+ * @link_state: link state527527+ * @speed: device speed (super, high, full, low)528528+ * @mem: points to start of memory which is used for this struct.529529+ * @root: debugfs root folder pointer530530+ */531531+struct dwc3 {532532+ struct usb_ctrlrequest *ctrl_req;533533+ struct dwc3_trb_hw *ep0_trb;534534+ u8 *setup_buf;535535+ dma_addr_t ctrl_req_addr;536536+ dma_addr_t ep0_trb_addr;537537+ dma_addr_t setup_buf_addr;538538+ struct usb_request ep0_usb_req;539539+ /* device lock */540540+ spinlock_t lock;541541+ struct device *dev;542542+543543+ struct dwc3_event_buffer *ev_buffs[DWC3_EVENT_BUFFERS_NUM];544544+ struct dwc3_ep *eps[DWC3_ENDPOINTS_NUM];545545+546546+ struct usb_gadget gadget;547547+ struct usb_gadget_driver *gadget_driver;548548+549549+ void __iomem *regs;550550+ size_t regs_size;551551+552552+ int irq;553553+554554+ u32 revision;555555+556556+#define DWC3_REVISION_173A 0x5533173a557557+#define DWC3_REVISION_175A 0x5533175a558558+#define DWC3_REVISION_180A 0x5533180a559559+#define DWC3_REVISION_183A 0x5533183a560560+#define DWC3_REVISION_185A 0x5533185a561561+#define DWC3_REVISION_188A 0x5533188a562562+#define DWC3_REVISION_190A 0x5533190a563563+564564+ unsigned is_selfpowered:1;565565+ unsigned three_stage_setup:1;566566+ unsigned ep0_status_pending:1;567567+568568+ enum dwc3_ep0_state ep0state;569569+ enum dwc3_link_state link_state;570570+ enum dwc3_device_state dev_state;571571+572572+ u8 speed;573573+ void *mem;574574+575575+ struct dentry *root;576576+};577577+578578+/* -------------------------------------------------------------------------- */579579+580580+#define DWC3_TRBSTS_OK 0581581+#define DWC3_TRBSTS_MISSED_ISOC 1582582+#define DWC3_TRBSTS_SETUP_PENDING 2583583+584584+#define DWC3_TRBCTL_NORMAL 1585585+#define DWC3_TRBCTL_CONTROL_SETUP 2586586+#define DWC3_TRBCTL_CONTROL_STATUS2 3587587+#define DWC3_TRBCTL_CONTROL_STATUS3 4588588+#define DWC3_TRBCTL_CONTROL_DATA 5589589+#define DWC3_TRBCTL_ISOCHRONOUS_FIRST 6590590+#define DWC3_TRBCTL_ISOCHRONOUS 7591591+#define DWC3_TRBCTL_LINK_TRB 8592592+593593+/* -------------------------------------------------------------------------- */594594+595595+struct dwc3_event_type {596596+ u32 is_devspec:1;597597+ u32 type:6;598598+ u32 reserved8_31:25;599599+} __packed;600600+601601+#define DWC3_DEPEVT_XFERCOMPLETE 0x01602602+#define DWC3_DEPEVT_XFERINPROGRESS 0x02603603+#define DWC3_DEPEVT_XFERNOTREADY 0x03604604+#define DWC3_DEPEVT_RXTXFIFOEVT 0x04605605+#define DWC3_DEPEVT_STREAMEVT 0x06606606+#define DWC3_DEPEVT_EPCMDCMPLT 0x07607607+608608+/**609609+ * struct dwc3_event_depvt - Device Endpoint Events610610+ * @one_bit: indicates this is an endpoint event (not used)611611+ * @endpoint_number: number of the endpoint612612+ * @endpoint_event: The event we have:613613+ * 0x00 - Reserved614614+ * 0x01 - XferComplete615615+ * 0x02 - XferInProgress616616+ * 0x03 - XferNotReady617617+ * 0x04 - RxTxFifoEvt (IN->Underrun, OUT->Overrun)618618+ * 0x05 - Reserved619619+ * 0x06 - StreamEvt620620+ * 0x07 - EPCmdCmplt621621+ * @reserved11_10: Reserved, don't use.622622+ * @status: Indicates the status of the event. Refer to databook for623623+ * more information.624624+ * @parameters: Parameters of the current event. Refer to databook for625625+ * more information.626626+ */627627+struct dwc3_event_depevt {628628+ u32 one_bit:1;629629+ u32 endpoint_number:5;630630+ u32 endpoint_event:4;631631+ u32 reserved11_10:2;632632+ u32 status:4;633633+#define DEPEVT_STATUS_BUSERR (1 << 0)634634+#define DEPEVT_STATUS_SHORT (1 << 1)635635+#define DEPEVT_STATUS_IOC (1 << 2)636636+#define DEPEVT_STATUS_LST (1 << 3)637637+ u32 parameters:16;638638+} __packed;639639+640640+/**641641+ * struct dwc3_event_devt - Device Events642642+ * @one_bit: indicates this is a non-endpoint event (not used)643643+ * @device_event: indicates it's a device event. Should read as 0x00644644+ * @type: indicates the type of device event.645645+ * 0 - DisconnEvt646646+ * 1 - USBRst647647+ * 2 - ConnectDone648648+ * 3 - ULStChng649649+ * 4 - WkUpEvt650650+ * 5 - Reserved651651+ * 6 - EOPF652652+ * 7 - SOF653653+ * 8 - Reserved654654+ * 9 - ErrticErr655655+ * 10 - CmdCmplt656656+ * 11 - EvntOverflow657657+ * 12 - VndrDevTstRcved658658+ * @reserved15_12: Reserved, not used659659+ * @event_info: Information about this event660660+ * @reserved31_24: Reserved, not used661661+ */662662+struct dwc3_event_devt {663663+ u32 one_bit:1;664664+ u32 device_event:7;665665+ u32 type:4;666666+ u32 reserved15_12:4;667667+ u32 event_info:8;668668+ u32 reserved31_24:8;669669+} __packed;670670+671671+/**672672+ * struct dwc3_event_gevt - Other Core Events673673+ * @one_bit: indicates this is a non-endpoint event (not used)674674+ * @device_event: indicates it's (0x03) Carkit or (0x04) I2C event.675675+ * @phy_port_number: self-explanatory676676+ * @reserved31_12: Reserved, not used.677677+ */678678+struct dwc3_event_gevt {679679+ u32 one_bit:1;680680+ u32 device_event:7;681681+ u32 phy_port_number:4;682682+ u32 reserved31_12:20;683683+} __packed;684684+685685+/**686686+ * union dwc3_event - representation of Event Buffer contents687687+ * @raw: raw 32-bit event688688+ * @type: the type of the event689689+ * @depevt: Device Endpoint Event690690+ * @devt: Device Event691691+ * @gevt: Global Event692692+ */693693+union dwc3_event {694694+ u32 raw;695695+ struct dwc3_event_type type;696696+ struct dwc3_event_depevt depevt;697697+ struct dwc3_event_devt devt;698698+ struct dwc3_event_gevt gevt;699699+};700700+701701+/*702702+ * DWC3 Features to be used as Driver Data703703+ */704704+705705+#define DWC3_HAS_PERIPHERAL BIT(0)706706+#define DWC3_HAS_XHCI BIT(1)707707+#define DWC3_HAS_OTG BIT(3)708708+709709+#endif /* __DRIVERS_USB_DWC3_CORE_H */
+51
drivers/usb/dwc3/debug.h
···11+/**22+ * debug.h - DesignWare USB3 DRD Controller Debug Header33+ *44+ * Copyright (C) 2010-2011 Texas Instruments Incorporated - http://www.ti.com55+ * All rights reserved.66+ *77+ * Authors: Felipe Balbi <balbi@ti.com>,88+ * Sebastian Andrzej Siewior <bigeasy@linutronix.de>99+ *1010+ * Redistribution and use in source and binary forms, with or without1111+ * modification, are permitted provided that the following conditions1212+ * are met:1313+ * 1. Redistributions of source code must retain the above copyright1414+ * notice, this list of conditions, and the following disclaimer,1515+ * without modification.1616+ * 2. Redistributions in binary form must reproduce the above copyright1717+ * notice, this list of conditions and the following disclaimer in the1818+ * documentation and/or other materials provided with the distribution.1919+ * 3. The names of the above-listed copyright holders may not be used2020+ * to endorse or promote products derived from this software without2121+ * specific prior written permission.2222+ *2323+ * ALTERNATIVELY, this software may be distributed under the terms of the2424+ * GNU General Public License ("GPL") version 2, as published by the Free2525+ * Software Foundation.2626+ *2727+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS2828+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,2929+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR3030+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR3131+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,3232+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,3333+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR3434+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF3535+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING3636+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS3737+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.3838+ */3939+4040+#include "core.h"4141+4242+#ifdef CONFIG_DEBUG_FS4343+extern int dwc3_debugfs_init(struct dwc3 *);4444+extern void dwc3_debugfs_exit(struct dwc3 *);4545+#else4646+static inline int dwc3_debugfs_init(struct dwc3 *d)4747+{ return 0; }4848+static inline void dwc3_debugfs_exit(struct dwc3 *d)4949+{ }5050+#endif5151+
+534
drivers/usb/dwc3/debugfs.c
···11+/**22+ * debugfs.c - DesignWare USB3 DRD Controller DebugFS file33+ *44+ * Copyright (C) 2010-2011 Texas Instruments Incorporated - http://www.ti.com55+ * All rights reserved.66+ *77+ * Authors: Felipe Balbi <balbi@ti.com>,88+ * Sebastian Andrzej Siewior <bigeasy@linutronix.de>99+ *1010+ * Redistribution and use in source and binary forms, with or without1111+ * modification, are permitted provided that the following conditions1212+ * are met:1313+ * 1. Redistributions of source code must retain the above copyright1414+ * notice, this list of conditions, and the following disclaimer,1515+ * without modification.1616+ * 2. Redistributions in binary form must reproduce the above copyright1717+ * notice, this list of conditions and the following disclaimer in the1818+ * documentation and/or other materials provided with the distribution.1919+ * 3. The names of the above-listed copyright holders may not be used2020+ * to endorse or promote products derived from this software without2121+ * specific prior written permission.2222+ *2323+ * ALTERNATIVELY, this software may be distributed under the terms of the2424+ * GNU General Public License ("GPL") version 2, as published by the Free2525+ * Software Foundation.2626+ *2727+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS2828+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,2929+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR3030+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR3131+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,3232+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,3333+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR3434+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF3535+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING3636+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS3737+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.3838+ */3939+4040+#include <linux/kernel.h>4141+#include <linux/slab.h>4242+#include <linux/ptrace.h>4343+#include <linux/types.h>4444+#include <linux/spinlock.h>4545+#include <linux/debugfs.h>4646+#include <linux/seq_file.h>4747+#include <linux/delay.h>4848+4949+#include <asm/uaccess.h>5050+5151+#include "core.h"5252+#include "gadget.h"5353+#include "io.h"5454+5555+struct dwc3_register {5656+ const char *name;5757+ u32 offset;5858+};5959+6060+#define dump_register(nm) \6161+{ \6262+ .name = __stringify(nm), \6363+ .offset = DWC3_ ##nm, \6464+}6565+6666+static const struct dwc3_register dwc3_regs[] = {6767+ dump_register(GSBUSCFG0),6868+ dump_register(GSBUSCFG1),6969+ dump_register(GTXTHRCFG),7070+ dump_register(GRXTHRCFG),7171+ dump_register(GCTL),7272+ dump_register(GEVTEN),7373+ dump_register(GSTS),7474+ dump_register(GSNPSID),7575+ dump_register(GGPIO),7676+ dump_register(GUID),7777+ dump_register(GUCTL),7878+ dump_register(GBUSERRADDR0),7979+ dump_register(GBUSERRADDR1),8080+ dump_register(GPRTBIMAP0),8181+ dump_register(GPRTBIMAP1),8282+ dump_register(GHWPARAMS0),8383+ dump_register(GHWPARAMS1),8484+ dump_register(GHWPARAMS2),8585+ dump_register(GHWPARAMS3),8686+ dump_register(GHWPARAMS4),8787+ dump_register(GHWPARAMS5),8888+ dump_register(GHWPARAMS6),8989+ dump_register(GHWPARAMS7),9090+ dump_register(GDBGFIFOSPACE),9191+ dump_register(GDBGLTSSM),9292+ dump_register(GPRTBIMAP_HS0),9393+ dump_register(GPRTBIMAP_HS1),9494+ dump_register(GPRTBIMAP_FS0),9595+ dump_register(GPRTBIMAP_FS1),9696+9797+ dump_register(GUSB2PHYCFG(0)),9898+ dump_register(GUSB2PHYCFG(1)),9999+ dump_register(GUSB2PHYCFG(2)),100100+ dump_register(GUSB2PHYCFG(3)),101101+ dump_register(GUSB2PHYCFG(4)),102102+ dump_register(GUSB2PHYCFG(5)),103103+ dump_register(GUSB2PHYCFG(6)),104104+ dump_register(GUSB2PHYCFG(7)),105105+ dump_register(GUSB2PHYCFG(8)),106106+ dump_register(GUSB2PHYCFG(9)),107107+ dump_register(GUSB2PHYCFG(10)),108108+ dump_register(GUSB2PHYCFG(11)),109109+ dump_register(GUSB2PHYCFG(12)),110110+ dump_register(GUSB2PHYCFG(13)),111111+ dump_register(GUSB2PHYCFG(14)),112112+ dump_register(GUSB2PHYCFG(15)),113113+114114+ dump_register(GUSB2I2CCTL(0)),115115+ dump_register(GUSB2I2CCTL(1)),116116+ dump_register(GUSB2I2CCTL(2)),117117+ dump_register(GUSB2I2CCTL(3)),118118+ dump_register(GUSB2I2CCTL(4)),119119+ dump_register(GUSB2I2CCTL(5)),120120+ dump_register(GUSB2I2CCTL(6)),121121+ dump_register(GUSB2I2CCTL(7)),122122+ dump_register(GUSB2I2CCTL(8)),123123+ dump_register(GUSB2I2CCTL(9)),124124+ dump_register(GUSB2I2CCTL(10)),125125+ dump_register(GUSB2I2CCTL(11)),126126+ dump_register(GUSB2I2CCTL(12)),127127+ dump_register(GUSB2I2CCTL(13)),128128+ dump_register(GUSB2I2CCTL(14)),129129+ dump_register(GUSB2I2CCTL(15)),130130+131131+ dump_register(GUSB2PHYACC(0)),132132+ dump_register(GUSB2PHYACC(1)),133133+ dump_register(GUSB2PHYACC(2)),134134+ dump_register(GUSB2PHYACC(3)),135135+ dump_register(GUSB2PHYACC(4)),136136+ dump_register(GUSB2PHYACC(5)),137137+ dump_register(GUSB2PHYACC(6)),138138+ dump_register(GUSB2PHYACC(7)),139139+ dump_register(GUSB2PHYACC(8)),140140+ dump_register(GUSB2PHYACC(9)),141141+ dump_register(GUSB2PHYACC(10)),142142+ dump_register(GUSB2PHYACC(11)),143143+ dump_register(GUSB2PHYACC(12)),144144+ dump_register(GUSB2PHYACC(13)),145145+ dump_register(GUSB2PHYACC(14)),146146+ dump_register(GUSB2PHYACC(15)),147147+148148+ dump_register(GUSB3PIPECTL(0)),149149+ dump_register(GUSB3PIPECTL(1)),150150+ dump_register(GUSB3PIPECTL(2)),151151+ dump_register(GUSB3PIPECTL(3)),152152+ dump_register(GUSB3PIPECTL(4)),153153+ dump_register(GUSB3PIPECTL(5)),154154+ dump_register(GUSB3PIPECTL(6)),155155+ dump_register(GUSB3PIPECTL(7)),156156+ dump_register(GUSB3PIPECTL(8)),157157+ dump_register(GUSB3PIPECTL(9)),158158+ dump_register(GUSB3PIPECTL(10)),159159+ dump_register(GUSB3PIPECTL(11)),160160+ dump_register(GUSB3PIPECTL(12)),161161+ dump_register(GUSB3PIPECTL(13)),162162+ dump_register(GUSB3PIPECTL(14)),163163+ dump_register(GUSB3PIPECTL(15)),164164+165165+ dump_register(GTXFIFOSIZ(0)),166166+ dump_register(GTXFIFOSIZ(1)),167167+ dump_register(GTXFIFOSIZ(2)),168168+ dump_register(GTXFIFOSIZ(3)),169169+ dump_register(GTXFIFOSIZ(4)),170170+ dump_register(GTXFIFOSIZ(5)),171171+ dump_register(GTXFIFOSIZ(6)),172172+ dump_register(GTXFIFOSIZ(7)),173173+ dump_register(GTXFIFOSIZ(8)),174174+ dump_register(GTXFIFOSIZ(9)),175175+ dump_register(GTXFIFOSIZ(10)),176176+ dump_register(GTXFIFOSIZ(11)),177177+ dump_register(GTXFIFOSIZ(12)),178178+ dump_register(GTXFIFOSIZ(13)),179179+ dump_register(GTXFIFOSIZ(14)),180180+ dump_register(GTXFIFOSIZ(15)),181181+ dump_register(GTXFIFOSIZ(16)),182182+ dump_register(GTXFIFOSIZ(17)),183183+ dump_register(GTXFIFOSIZ(18)),184184+ dump_register(GTXFIFOSIZ(19)),185185+ dump_register(GTXFIFOSIZ(20)),186186+ dump_register(GTXFIFOSIZ(21)),187187+ dump_register(GTXFIFOSIZ(22)),188188+ dump_register(GTXFIFOSIZ(23)),189189+ dump_register(GTXFIFOSIZ(24)),190190+ dump_register(GTXFIFOSIZ(25)),191191+ dump_register(GTXFIFOSIZ(26)),192192+ dump_register(GTXFIFOSIZ(27)),193193+ dump_register(GTXFIFOSIZ(28)),194194+ dump_register(GTXFIFOSIZ(29)),195195+ dump_register(GTXFIFOSIZ(30)),196196+ dump_register(GTXFIFOSIZ(31)),197197+198198+ dump_register(GRXFIFOSIZ(0)),199199+ dump_register(GRXFIFOSIZ(1)),200200+ dump_register(GRXFIFOSIZ(2)),201201+ dump_register(GRXFIFOSIZ(3)),202202+ dump_register(GRXFIFOSIZ(4)),203203+ dump_register(GRXFIFOSIZ(5)),204204+ dump_register(GRXFIFOSIZ(6)),205205+ dump_register(GRXFIFOSIZ(7)),206206+ dump_register(GRXFIFOSIZ(8)),207207+ dump_register(GRXFIFOSIZ(9)),208208+ dump_register(GRXFIFOSIZ(10)),209209+ dump_register(GRXFIFOSIZ(11)),210210+ dump_register(GRXFIFOSIZ(12)),211211+ dump_register(GRXFIFOSIZ(13)),212212+ dump_register(GRXFIFOSIZ(14)),213213+ dump_register(GRXFIFOSIZ(15)),214214+ dump_register(GRXFIFOSIZ(16)),215215+ dump_register(GRXFIFOSIZ(17)),216216+ dump_register(GRXFIFOSIZ(18)),217217+ dump_register(GRXFIFOSIZ(19)),218218+ dump_register(GRXFIFOSIZ(20)),219219+ dump_register(GRXFIFOSIZ(21)),220220+ dump_register(GRXFIFOSIZ(22)),221221+ dump_register(GRXFIFOSIZ(23)),222222+ dump_register(GRXFIFOSIZ(24)),223223+ dump_register(GRXFIFOSIZ(25)),224224+ dump_register(GRXFIFOSIZ(26)),225225+ dump_register(GRXFIFOSIZ(27)),226226+ dump_register(GRXFIFOSIZ(28)),227227+ dump_register(GRXFIFOSIZ(29)),228228+ dump_register(GRXFIFOSIZ(30)),229229+ dump_register(GRXFIFOSIZ(31)),230230+231231+ dump_register(GEVNTADRLO(0)),232232+ dump_register(GEVNTADRHI(0)),233233+ dump_register(GEVNTSIZ(0)),234234+ dump_register(GEVNTCOUNT(0)),235235+236236+ dump_register(GHWPARAMS8),237237+ dump_register(DCFG),238238+ dump_register(DCTL),239239+ dump_register(DEVTEN),240240+ dump_register(DSTS),241241+ dump_register(DGCMDPAR),242242+ dump_register(DGCMD),243243+ dump_register(DALEPENA),244244+245245+ dump_register(DEPCMDPAR2(0)),246246+ dump_register(DEPCMDPAR2(1)),247247+ dump_register(DEPCMDPAR2(2)),248248+ dump_register(DEPCMDPAR2(3)),249249+ dump_register(DEPCMDPAR2(4)),250250+ dump_register(DEPCMDPAR2(5)),251251+ dump_register(DEPCMDPAR2(6)),252252+ dump_register(DEPCMDPAR2(7)),253253+ dump_register(DEPCMDPAR2(8)),254254+ dump_register(DEPCMDPAR2(9)),255255+ dump_register(DEPCMDPAR2(10)),256256+ dump_register(DEPCMDPAR2(11)),257257+ dump_register(DEPCMDPAR2(12)),258258+ dump_register(DEPCMDPAR2(13)),259259+ dump_register(DEPCMDPAR2(14)),260260+ dump_register(DEPCMDPAR2(15)),261261+ dump_register(DEPCMDPAR2(16)),262262+ dump_register(DEPCMDPAR2(17)),263263+ dump_register(DEPCMDPAR2(18)),264264+ dump_register(DEPCMDPAR2(19)),265265+ dump_register(DEPCMDPAR2(20)),266266+ dump_register(DEPCMDPAR2(21)),267267+ dump_register(DEPCMDPAR2(22)),268268+ dump_register(DEPCMDPAR2(23)),269269+ dump_register(DEPCMDPAR2(24)),270270+ dump_register(DEPCMDPAR2(25)),271271+ dump_register(DEPCMDPAR2(26)),272272+ dump_register(DEPCMDPAR2(27)),273273+ dump_register(DEPCMDPAR2(28)),274274+ dump_register(DEPCMDPAR2(29)),275275+ dump_register(DEPCMDPAR2(30)),276276+ dump_register(DEPCMDPAR2(31)),277277+278278+ dump_register(DEPCMDPAR1(0)),279279+ dump_register(DEPCMDPAR1(1)),280280+ dump_register(DEPCMDPAR1(2)),281281+ dump_register(DEPCMDPAR1(3)),282282+ dump_register(DEPCMDPAR1(4)),283283+ dump_register(DEPCMDPAR1(5)),284284+ dump_register(DEPCMDPAR1(6)),285285+ dump_register(DEPCMDPAR1(7)),286286+ dump_register(DEPCMDPAR1(8)),287287+ dump_register(DEPCMDPAR1(9)),288288+ dump_register(DEPCMDPAR1(10)),289289+ dump_register(DEPCMDPAR1(11)),290290+ dump_register(DEPCMDPAR1(12)),291291+ dump_register(DEPCMDPAR1(13)),292292+ dump_register(DEPCMDPAR1(14)),293293+ dump_register(DEPCMDPAR1(15)),294294+ dump_register(DEPCMDPAR1(16)),295295+ dump_register(DEPCMDPAR1(17)),296296+ dump_register(DEPCMDPAR1(18)),297297+ dump_register(DEPCMDPAR1(19)),298298+ dump_register(DEPCMDPAR1(20)),299299+ dump_register(DEPCMDPAR1(21)),300300+ dump_register(DEPCMDPAR1(22)),301301+ dump_register(DEPCMDPAR1(23)),302302+ dump_register(DEPCMDPAR1(24)),303303+ dump_register(DEPCMDPAR1(25)),304304+ dump_register(DEPCMDPAR1(26)),305305+ dump_register(DEPCMDPAR1(27)),306306+ dump_register(DEPCMDPAR1(28)),307307+ dump_register(DEPCMDPAR1(29)),308308+ dump_register(DEPCMDPAR1(30)),309309+ dump_register(DEPCMDPAR1(31)),310310+311311+ dump_register(DEPCMDPAR0(0)),312312+ dump_register(DEPCMDPAR0(1)),313313+ dump_register(DEPCMDPAR0(2)),314314+ dump_register(DEPCMDPAR0(3)),315315+ dump_register(DEPCMDPAR0(4)),316316+ dump_register(DEPCMDPAR0(5)),317317+ dump_register(DEPCMDPAR0(6)),318318+ dump_register(DEPCMDPAR0(7)),319319+ dump_register(DEPCMDPAR0(8)),320320+ dump_register(DEPCMDPAR0(9)),321321+ dump_register(DEPCMDPAR0(10)),322322+ dump_register(DEPCMDPAR0(11)),323323+ dump_register(DEPCMDPAR0(12)),324324+ dump_register(DEPCMDPAR0(13)),325325+ dump_register(DEPCMDPAR0(14)),326326+ dump_register(DEPCMDPAR0(15)),327327+ dump_register(DEPCMDPAR0(16)),328328+ dump_register(DEPCMDPAR0(17)),329329+ dump_register(DEPCMDPAR0(18)),330330+ dump_register(DEPCMDPAR0(19)),331331+ dump_register(DEPCMDPAR0(20)),332332+ dump_register(DEPCMDPAR0(21)),333333+ dump_register(DEPCMDPAR0(22)),334334+ dump_register(DEPCMDPAR0(23)),335335+ dump_register(DEPCMDPAR0(24)),336336+ dump_register(DEPCMDPAR0(25)),337337+ dump_register(DEPCMDPAR0(26)),338338+ dump_register(DEPCMDPAR0(27)),339339+ dump_register(DEPCMDPAR0(28)),340340+ dump_register(DEPCMDPAR0(29)),341341+ dump_register(DEPCMDPAR0(30)),342342+ dump_register(DEPCMDPAR0(31)),343343+344344+ dump_register(DEPCMD(0)),345345+ dump_register(DEPCMD(1)),346346+ dump_register(DEPCMD(2)),347347+ dump_register(DEPCMD(3)),348348+ dump_register(DEPCMD(4)),349349+ dump_register(DEPCMD(5)),350350+ dump_register(DEPCMD(6)),351351+ dump_register(DEPCMD(7)),352352+ dump_register(DEPCMD(8)),353353+ dump_register(DEPCMD(9)),354354+ dump_register(DEPCMD(10)),355355+ dump_register(DEPCMD(11)),356356+ dump_register(DEPCMD(12)),357357+ dump_register(DEPCMD(13)),358358+ dump_register(DEPCMD(14)),359359+ dump_register(DEPCMD(15)),360360+ dump_register(DEPCMD(16)),361361+ dump_register(DEPCMD(17)),362362+ dump_register(DEPCMD(18)),363363+ dump_register(DEPCMD(19)),364364+ dump_register(DEPCMD(20)),365365+ dump_register(DEPCMD(21)),366366+ dump_register(DEPCMD(22)),367367+ dump_register(DEPCMD(23)),368368+ dump_register(DEPCMD(24)),369369+ dump_register(DEPCMD(25)),370370+ dump_register(DEPCMD(26)),371371+ dump_register(DEPCMD(27)),372372+ dump_register(DEPCMD(28)),373373+ dump_register(DEPCMD(29)),374374+ dump_register(DEPCMD(30)),375375+ dump_register(DEPCMD(31)),376376+377377+ dump_register(OCFG),378378+ dump_register(OCTL),379379+ dump_register(OEVTEN),380380+ dump_register(OSTS),381381+};382382+383383+static int dwc3_regdump_show(struct seq_file *s, void *unused)384384+{385385+ struct dwc3 *dwc = s->private;386386+ int i;387387+388388+ seq_printf(s, "DesignWare USB3 Core Register Dump\n");389389+390390+ for (i = 0; i < ARRAY_SIZE(dwc3_regs); i++) {391391+ seq_printf(s, "%-20s : %08x\n", dwc3_regs[i].name,392392+ dwc3_readl(dwc->regs, dwc3_regs[i].offset));393393+ }394394+395395+ return 0;396396+}397397+398398+static int dwc3_regdump_open(struct inode *inode, struct file *file)399399+{400400+ return single_open(file, dwc3_regdump_show, inode->i_private);401401+}402402+403403+static const struct file_operations dwc3_regdump_fops = {404404+ .open = dwc3_regdump_open,405405+ .read = seq_read,406406+ .release = single_release,407407+};408408+409409+410410+static int dwc3_send_testmode_cmd(struct dwc3 *dwc, int mode)411411+{412412+ u32 timeout = 250;413413+414414+ dwc3_writel(dwc->regs, DWC3_DGCMDPAR, mode);415415+ dwc3_writel(dwc->regs, DWC3_DGCMD, DWC3_DGCMD_RUN_SOC_BUS_LOOPBACK |416416+ DWC3_DEPCMD_CMDACT);417417+ do {418418+ u32 reg;419419+420420+ reg = dwc3_readl(dwc->regs, DWC3_DGCMD);421421+ if (!(reg & DWC3_DEPCMD_CMDACT))422422+ return 0;423423+ timeout--;424424+ if (!timeout)425425+ return -ETIMEDOUT;426426+ mdelay(1);427427+ } while (1);428428+}429429+430430+static struct dwc3_trb_hw trb_0 __aligned(16);431431+static struct dwc3_trb_hw trb_1 __aligned(16);432432+433433+#define BUF_SIZE 4096434434+static int dwc3_testmode_open(struct inode *inode, struct file *file)435435+{436436+ struct dwc3 *dwc = inode->i_private;437437+ struct dwc3_gadget_ep_cmd_params par0;438438+ struct dwc3_gadget_ep_cmd_params par1;439439+ struct dwc3_trb trb;440440+ int ret;441441+ u8 *buf0;442442+ u8 *buf1;443443+444444+ buf0 = kmalloc(BUF_SIZE, GFP_KERNEL);445445+ if (!buf0)446446+ return -ENOMEM;447447+ buf1 = kmalloc(BUF_SIZE, GFP_KERNEL);448448+ if (!buf1)449449+ return -ENOMEM;450450+451451+ memset(buf0, 0xaa, BUF_SIZE);452452+ memset(buf1, 0x33, BUF_SIZE);453453+454454+ memset(&trb, 0, sizeof(trb));455455+ memset(&par0, 0, sizeof(par0));456456+ memset(&par1, 0, sizeof(par1));457457+458458+ trb.lst = 1;459459+ trb.trbctl = DWC3_TRBCTL_NORMAL;460460+ trb.length = BUF_SIZE;461461+ trb.hwo = 1;462462+463463+ trb.bplh = virt_to_phys(buf0);464464+ dwc3_trb_to_hw(&trb, &trb_0);465465+466466+ trb.bplh = virt_to_phys(buf1);467467+ dwc3_trb_to_hw(&trb, &trb_1);468468+469469+ par0.param0.depstrtxfer.transfer_desc_addr_high =470470+ upper_32_bits(virt_to_phys(&trb_0));471471+ par0.param1.depstrtxfer.transfer_desc_addr_low =472472+ lower_32_bits(virt_to_phys(&trb_0));473473+474474+ par1.param0.depstrtxfer.transfer_desc_addr_high =475475+ upper_32_bits(virt_to_phys(&trb_1));476476+ par1.param1.depstrtxfer.transfer_desc_addr_low =477477+ lower_32_bits(virt_to_phys(&trb_1));478478+479479+ dwc3_send_testmode_cmd(dwc, 1);480480+481481+ ret = dwc3_send_gadget_ep_cmd(dwc, 0, DWC3_DEPCMD_STARTTRANSFER, &par0);482482+ ret = dwc3_send_gadget_ep_cmd(dwc, 1, DWC3_DEPCMD_STARTTRANSFER, &par1);483483+484484+ dwc3_send_testmode_cmd(dwc, 0);485485+ return -EBUSY;486486+}487487+488488+static const struct file_operations dwc3_testmode_fops = {489489+ .open = dwc3_testmode_open,490490+ .read = seq_read,491491+ .release = single_release,492492+};493493+494494+int __devinit dwc3_debugfs_init(struct dwc3 *dwc)495495+{496496+ struct dentry *root;497497+ struct dentry *file;498498+ int ret;499499+500500+ root = debugfs_create_dir(dev_name(dwc->dev), NULL);501501+ if (IS_ERR(root)){502502+ ret = PTR_ERR(root);503503+ goto err0;504504+ }505505+506506+ dwc->root = root;507507+508508+ file = debugfs_create_file("regdump", S_IRUGO, root, dwc,509509+ &dwc3_regdump_fops);510510+ if (IS_ERR(file)) {511511+ ret = PTR_ERR(file);512512+ goto err1;513513+ }514514+ file = debugfs_create_file("testmode", S_IRUGO, root, dwc,515515+ &dwc3_testmode_fops);516516+ if (IS_ERR(file)) {517517+ ret = PTR_ERR(file);518518+ goto err1;519519+ }520520+521521+ return 0;522522+523523+err1:524524+ debugfs_remove_recursive(root);525525+526526+err0:527527+ return ret;528528+}529529+530530+void __devexit dwc3_debugfs_exit(struct dwc3 *dwc)531531+{532532+ debugfs_remove_recursive(dwc->root);533533+ dwc->root = NULL;534534+}
+410
drivers/usb/dwc3/dwc3-omap.c
···11+/**22+ * dwc3-omap.c - OMAP Specific Glue layer33+ *44+ * Copyright (C) 2010-2011 Texas Instruments Incorporated - http://www.ti.com55+ * All rights reserved.66+ *77+ * Authors: Felipe Balbi <balbi@ti.com>,88+ * Sebastian Andrzej Siewior <bigeasy@linutronix.de>99+ *1010+ * Redistribution and use in source and binary forms, with or without1111+ * modification, are permitted provided that the following conditions1212+ * are met:1313+ * 1. Redistributions of source code must retain the above copyright1414+ * notice, this list of conditions, and the following disclaimer,1515+ * without modification.1616+ * 2. Redistributions in binary form must reproduce the above copyright1717+ * notice, this list of conditions and the following disclaimer in the1818+ * documentation and/or other materials provided with the distribution.1919+ * 3. The names of the above-listed copyright holders may not be used2020+ * to endorse or promote products derived from this software without2121+ * specific prior written permission.2222+ *2323+ * ALTERNATIVELY, this software may be distributed under the terms of the2424+ * GNU General Public License ("GPL") version 2, as published by the Free2525+ * Software Foundation.2626+ *2727+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS2828+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,2929+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR3030+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR3131+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,3232+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,3333+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR3434+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF3535+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING3636+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS3737+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.3838+ */3939+4040+#include <linux/kernel.h>4141+#include <linux/slab.h>4242+#include <linux/interrupt.h>4343+#include <linux/spinlock.h>4444+#include <linux/platform_device.h>4545+#include <linux/dma-mapping.h>4646+#include <linux/ioport.h>4747+#include <linux/io.h>4848+4949+#include "io.h"5050+5151+/*5252+ * All these registers belong to OMAP's Wrapper around the5353+ * DesignWare USB3 Core.5454+ */5555+5656+#define USBOTGSS_REVISION 0x00005757+#define USBOTGSS_SYSCONFIG 0x00105858+#define USBOTGSS_IRQ_EOI 0x00205959+#define USBOTGSS_IRQSTATUS_RAW_0 0x00246060+#define USBOTGSS_IRQSTATUS_0 0x00286161+#define USBOTGSS_IRQENABLE_SET_0 0x002c6262+#define USBOTGSS_IRQENABLE_CLR_0 0x00306363+#define USBOTGSS_IRQSTATUS_RAW_1 0x00346464+#define USBOTGSS_IRQSTATUS_1 0x00386565+#define USBOTGSS_IRQENABLE_SET_1 0x003c6666+#define USBOTGSS_IRQENABLE_CLR_1 0x00406767+#define USBOTGSS_UTMI_OTG_CTRL 0x00806868+#define USBOTGSS_UTMI_OTG_STATUS 0x00846969+#define USBOTGSS_MMRAM_OFFSET 0x01007070+#define USBOTGSS_FLADJ 0x01047171+#define USBOTGSS_DEBUG_CFG 0x01087272+#define USBOTGSS_DEBUG_DATA 0x010c7373+7474+/* SYSCONFIG REGISTER */7575+#define USBOTGSS_SYSCONFIG_DMADISABLE (1 << 16)7676+#define USBOTGSS_SYSCONFIG_STANDBYMODE(x) ((x) << 4)7777+#define USBOTGSS_SYSCONFIG_IDLEMODE(x) ((x) << 2)7878+7979+/* IRQ_EOI REGISTER */8080+#define USBOTGSS_IRQ_EOI_LINE_NUMBER (1 << 0)8181+8282+/* IRQS0 BITS */8383+#define USBOTGSS_IRQO_COREIRQ_ST (1 << 0)8484+8585+/* IRQ1 BITS */8686+#define USBOTGSS_IRQ1_DMADISABLECLR (1 << 17)8787+#define USBOTGSS_IRQ1_OEVT (1 << 16)8888+#define USBOTGSS_IRQ1_DRVVBUS_RISE (1 << 13)8989+#define USBOTGSS_IRQ1_CHRGVBUS_RISE (1 << 12)9090+#define USBOTGSS_IRQ1_DISCHRGVBUS_RISE (1 << 11)9191+#define USBOTGSS_IRQ1_IDPULLUP_RISE (1 << 8)9292+#define USBOTGSS_IRQ1_DRVVBUS_FALL (1 << 5)9393+#define USBOTGSS_IRQ1_CHRGVBUS_FALL (1 << 4)9494+#define USBOTGSS_IRQ1_DISCHRGVBUS_FALL (1 << 3)9595+#define USBOTGSS_IRQ1_IDPULLUP_FALL (1 << 0)9696+9797+/* UTMI_OTG_CTRL REGISTER */9898+#define USBOTGSS_UTMI_OTG_CTRL_DRVVBUS (1 << 5)9999+#define USBOTGSS_UTMI_OTG_CTRL_CHRGVBUS (1 << 4)100100+#define USBOTGSS_UTMI_OTG_CTRL_DISCHRGVBUS (1 << 3)101101+#define USBOTGSS_UTMI_OTG_CTRL_IDPULLUP (1 << 0)102102+103103+/* UTMI_OTG_STATUS REGISTER */104104+#define USBOTGSS_UTMI_OTG_STATUS_SW_MODE (1 << 31)105105+#define USBOTGSS_UTMI_OTG_STATUS_POWERPRESENT (1 << 9)106106+#define USBOTGSS_UTMI_OTG_STATUS_TXBITSTUFFENABLE (1 << 8)107107+#define USBOTGSS_UTMI_OTG_STATUS_IDDIG (1 << 4)108108+#define USBOTGSS_UTMI_OTG_STATUS_SESSEND (1 << 3)109109+#define USBOTGSS_UTMI_OTG_STATUS_SESSVALID (1 << 2)110110+#define USBOTGSS_UTMI_OTG_STATUS_VBUSVALID (1 << 1)111111+112112+struct dwc3_omap {113113+ /* device lock */114114+ spinlock_t lock;115115+116116+ struct platform_device *dwc3;117117+ struct device *dev;118118+119119+ int irq;120120+ void __iomem *base;121121+122122+ void *context;123123+ u32 resource_size;124124+125125+ u32 dma_status:1;126126+};127127+128128+#ifdef CONFIG_PM129129+static int dwc3_omap_suspend(struct device *dev)130130+{131131+ struct dwc3_omap *omap = dev_get_drvdata(dev);132132+133133+ memcpy_fromio(omap->context, omap->base, omap->resource_size);134134+135135+ return 0;136136+}137137+138138+static int dwc3_omap_resume(struct device *dev)139139+{140140+ struct dwc3_omap *omap = dev_get_drvdata(dev);141141+142142+ memcpy_toio(omap->base, omap->context, omap->resource_size);143143+144144+ return 0;145145+}146146+147147+static int dwc3_omap_idle(struct device *dev)148148+{149149+ struct dwc3_omap *omap = dev_get_drvdata(dev);150150+ u32 reg;151151+152152+ /* stop DMA Engine */153153+ reg = dwc3_readl(omap->base, USBOTGSS_SYSCONFIG);154154+ reg &= ~(USBOTGSS_SYSCONFIG_DMADISABLE);155155+ dwc3_writel(omap->base, USBOTGSS_SYSCONFIG, reg);156156+157157+ return 0;158158+}159159+160160+static UNIVERSAL_DEV_PM_OPS(dwc3_omap_pm_ops, dwc3_omap_suspend,161161+ dwc3_omap_resume, dwc3_omap_idle);162162+163163+#define DEV_PM_OPS (&dwc3_omap_pm_ops)164164+#else165165+#define DEV_PM_OPS NULL166166+#endif167167+168168+static irqreturn_t dwc3_omap_interrupt(int irq, void *_omap)169169+{170170+ struct dwc3_omap *omap = _omap;171171+ u32 reg;172172+ u32 ctrl;173173+174174+ spin_lock(&omap->lock);175175+176176+ reg = dwc3_readl(omap->base, USBOTGSS_IRQSTATUS_1);177177+ ctrl = dwc3_readl(omap->base, USBOTGSS_UTMI_OTG_CTRL);178178+179179+ if (reg & USBOTGSS_IRQ1_DMADISABLECLR) {180180+ dev_dbg(omap->base, "DMA Disable was Cleared\n");181181+ omap->dma_status = false;182182+ }183183+184184+ if (reg & USBOTGSS_IRQ1_OEVT)185185+ dev_dbg(omap->base, "OTG Event\n");186186+187187+ if (reg & USBOTGSS_IRQ1_DRVVBUS_RISE) {188188+ dev_dbg(omap->base, "DRVVBUS Rise\n");189189+ ctrl |= USBOTGSS_UTMI_OTG_CTRL_DRVVBUS;190190+ }191191+192192+ if (reg & USBOTGSS_IRQ1_CHRGVBUS_RISE) {193193+ dev_dbg(omap->base, "CHRGVBUS Rise\n");194194+ ctrl |= USBOTGSS_UTMI_OTG_CTRL_CHRGVBUS;195195+ }196196+197197+ if (reg & USBOTGSS_IRQ1_DISCHRGVBUS_RISE) {198198+ dev_dbg(omap->base, "DISCHRGVBUS Rise\n");199199+ ctrl |= USBOTGSS_UTMI_OTG_CTRL_DISCHRGVBUS;200200+ }201201+202202+ if (reg & USBOTGSS_IRQ1_IDPULLUP_RISE) {203203+ dev_dbg(omap->base, "IDPULLUP Rise\n");204204+ ctrl |= USBOTGSS_UTMI_OTG_CTRL_IDPULLUP;205205+ }206206+207207+ if (reg & USBOTGSS_IRQ1_DRVVBUS_FALL) {208208+ dev_dbg(omap->base, "DRVVBUS Fall\n");209209+ ctrl &= ~USBOTGSS_UTMI_OTG_CTRL_DRVVBUS;210210+ }211211+212212+ if (reg & USBOTGSS_IRQ1_CHRGVBUS_FALL) {213213+ dev_dbg(omap->base, "CHRGVBUS Fall\n");214214+ ctrl &= ~USBOTGSS_UTMI_OTG_CTRL_CHRGVBUS;215215+ }216216+217217+ if (reg & USBOTGSS_IRQ1_DISCHRGVBUS_FALL) {218218+ dev_dbg(omap->base, "DISCHRGVBUS Fall\n");219219+ ctrl &= ~USBOTGSS_UTMI_OTG_CTRL_DISCHRGVBUS;220220+ }221221+222222+ if (reg & USBOTGSS_IRQ1_IDPULLUP_FALL) {223223+ dev_dbg(omap->base, "IDPULLUP Fall\n");224224+ ctrl &= ~USBOTGSS_UTMI_OTG_CTRL_IDPULLUP;225225+ }226226+227227+ dwc3_writel(omap->base, USBOTGSS_UTMI_OTG_CTRL, ctrl);228228+229229+ spin_unlock(&omap->lock);230230+231231+ return IRQ_HANDLED;232232+}233233+234234+static int __devinit dwc3_omap_probe(struct platform_device *pdev)235235+{236236+ struct platform_device *dwc3;237237+ struct dwc3_omap *omap;238238+ struct resource *res;239239+240240+ int ret = -ENOMEM;241241+ int irq;242242+243243+ u32 reg;244244+245245+ void __iomem *base;246246+ void *context;247247+248248+ omap = kzalloc(sizeof(*omap), GFP_KERNEL);249249+ if (!omap) {250250+ dev_err(&pdev->dev, "not enough memory\n");251251+ goto err0;252252+ }253253+254254+ platform_set_drvdata(pdev, omap);255255+256256+ irq = platform_get_irq(pdev, 1);257257+ if (irq < 0) {258258+ dev_err(&pdev->dev, "missing IRQ resource\n");259259+ ret = -EINVAL;260260+ goto err1;261261+ }262262+263263+ res = platform_get_resource(pdev, IORESOURCE_MEM, 1);264264+ if (!res) {265265+ dev_err(&pdev->dev, "missing memory base resource\n");266266+ ret = -EINVAL;267267+ goto err1;268268+ }269269+270270+ base = ioremap_nocache(res->start, resource_size(res));271271+ if (!base) {272272+ dev_err(&pdev->dev, "ioremap failed\n");273273+ goto err1;274274+ }275275+276276+ dwc3 = platform_device_alloc("dwc3-omap", -1);277277+ if (!dwc3) {278278+ dev_err(&pdev->dev, "couldn't allocate dwc3 device\n");279279+ goto err2;280280+ }281281+282282+ context = kzalloc(resource_size(res), GFP_KERNEL);283283+ if (!context) {284284+ dev_err(&pdev->dev, "couldn't allocate dwc3 context memory\n");285285+ goto err3;286286+ }287287+288288+ spin_lock_init(&omap->lock);289289+ dma_set_coherent_mask(&dwc3->dev, pdev->dev.coherent_dma_mask);290290+291291+ dwc3->dev.parent = &pdev->dev;292292+ dwc3->dev.dma_mask = pdev->dev.dma_mask;293293+ dwc3->dev.dma_parms = pdev->dev.dma_parms;294294+ omap->resource_size = resource_size(res);295295+ omap->context = context;296296+ omap->dev = &pdev->dev;297297+ omap->irq = irq;298298+ omap->base = base;299299+ omap->dwc3 = dwc3;300300+301301+ /* check the DMA Status */302302+ reg = dwc3_readl(omap->base, USBOTGSS_SYSCONFIG);303303+ omap->dma_status = !!(reg & USBOTGSS_SYSCONFIG_DMADISABLE);304304+305305+ ret = request_irq(omap->irq, dwc3_omap_interrupt, 0,306306+ "dwc3-wrapper", omap);307307+ if (ret) {308308+ dev_err(&pdev->dev, "failed to request IRQ #%d --> %d\n",309309+ omap->irq, ret);310310+ goto err4;311311+ }312312+313313+ /* enable all IRQs */314314+ dwc3_writel(omap->base, USBOTGSS_IRQENABLE_SET_0, 0x01);315315+316316+ reg = (USBOTGSS_IRQ1_DMADISABLECLR |317317+ USBOTGSS_IRQ1_OEVT |318318+ USBOTGSS_IRQ1_DRVVBUS_RISE |319319+ USBOTGSS_IRQ1_CHRGVBUS_RISE |320320+ USBOTGSS_IRQ1_DISCHRGVBUS_RISE |321321+ USBOTGSS_IRQ1_IDPULLUP_RISE |322322+ USBOTGSS_IRQ1_DRVVBUS_FALL |323323+ USBOTGSS_IRQ1_CHRGVBUS_FALL |324324+ USBOTGSS_IRQ1_DISCHRGVBUS_FALL |325325+ USBOTGSS_IRQ1_IDPULLUP_FALL);326326+327327+ dwc3_writel(omap->base, USBOTGSS_IRQENABLE_SET_1, reg);328328+329329+ ret = platform_device_add_resources(dwc3, pdev->resource,330330+ pdev->num_resources);331331+ if (ret) {332332+ dev_err(&pdev->dev, "couldn't add resources to dwc3 device\n");333333+ goto err5;334334+ }335335+336336+ ret = platform_device_add(dwc3);337337+ if (ret) {338338+ dev_err(&pdev->dev, "failed to register dwc3 device\n");339339+ goto err5;340340+ }341341+342342+ return 0;343343+344344+err5:345345+ free_irq(omap->irq, omap);346346+347347+err4:348348+ kfree(omap->context);349349+350350+err3:351351+ platform_device_put(dwc3);352352+353353+err2:354354+ iounmap(base);355355+356356+err1:357357+ kfree(omap);358358+359359+err0:360360+ return ret;361361+}362362+363363+static int __devexit dwc3_omap_remove(struct platform_device *pdev)364364+{365365+ struct dwc3_omap *omap = platform_get_drvdata(pdev);366366+367367+ platform_device_unregister(omap->dwc3);368368+369369+ free_irq(omap->irq, omap);370370+ iounmap(omap->base);371371+372372+ kfree(omap->context);373373+ kfree(omap);374374+375375+ return 0;376376+}377377+378378+static const struct of_device_id of_dwc3_matach[] = {379379+ {380380+ "ti,dwc3",381381+ },382382+ { },383383+};384384+MODULE_DEVICE_TABLE(of, of_dwc3_matach);385385+386386+static struct platform_driver dwc3_omap_driver = {387387+ .probe = dwc3_omap_probe,388388+ .remove = __devexit_p(dwc3_omap_remove),389389+ .driver = {390390+ .name = "omap-dwc3",391391+ .pm = DEV_PM_OPS,392392+ .of_match_table = of_dwc3_matach,393393+ },394394+};395395+396396+MODULE_AUTHOR("Felipe Balbi <balbi@ti.com>");397397+MODULE_LICENSE("Dual BSD/GPL");398398+MODULE_DESCRIPTION("DesignWare USB3 OMAP Glue Layer");399399+400400+static int __devinit dwc3_omap_init(void)401401+{402402+ return platform_driver_register(&dwc3_omap_driver);403403+}404404+module_init(dwc3_omap_init);405405+406406+static void __exit dwc3_omap_exit(void)407407+{408408+ platform_driver_unregister(&dwc3_omap_driver);409409+}410410+module_exit(dwc3_omap_exit);
+220
drivers/usb/dwc3/dwc3-pci.c
···11+/**22+ * dwc3-pci.c - PCI Specific glue layer33+ *44+ * Copyright (C) 2010-2011 Texas Instruments Incorporated - http://www.ti.com55+ * All rights reserved.66+ *77+ * Authors: Felipe Balbi <balbi@ti.com>,88+ * Sebastian Andrzej Siewior <bigeasy@linutronix.de>99+ *1010+ * Redistribution and use in source and binary forms, with or without1111+ * modification, are permitted provided that the following conditions1212+ * are met:1313+ * 1. Redistributions of source code must retain the above copyright1414+ * notice, this list of conditions, and the following disclaimer,1515+ * without modification.1616+ * 2. Redistributions in binary form must reproduce the above copyright1717+ * notice, this list of conditions and the following disclaimer in the1818+ * documentation and/or other materials provided with the distribution.1919+ * 3. The names of the above-listed copyright holders may not be used2020+ * to endorse or promote products derived from this software without2121+ * specific prior written permission.2222+ *2323+ * ALTERNATIVELY, this software may be distributed under the terms of the2424+ * GNU General Public License ("GPL") version 2, as published by the Free2525+ * Software Foundation.2626+ *2727+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS2828+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,2929+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR3030+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR3131+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,3232+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,3333+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR3434+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF3535+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING3636+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS3737+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.3838+ */3939+4040+#include <linux/kernel.h>4141+#include <linux/module.h>4242+#include <linux/slab.h>4343+#include <linux/pci.h>4444+#include <linux/platform_device.h>4545+4646+/* FIXME define these in <linux/pci_ids.h> */4747+#define PCI_VENDOR_ID_SYNOPSYS 0x16c34848+#define PCI_DEVICE_ID_SYNOPSYS_HAPSUSB3 0xabcd4949+5050+#define DWC3_PCI_DEVS_POSSIBLE 325151+5252+struct dwc3_pci {5353+ struct device *dev;5454+ struct platform_device *dwc3;5555+};5656+5757+static DECLARE_BITMAP(dwc3_pci_devs, DWC3_PCI_DEVS_POSSIBLE);5858+5959+static int dwc3_pci_get_device_id(struct dwc3_pci *glue)6060+{6161+ int id;6262+6363+again:6464+ id = find_first_zero_bit(dwc3_pci_devs, DWC3_PCI_DEVS_POSSIBLE);6565+ if (id < DWC3_PCI_DEVS_POSSIBLE) {6666+ int old;6767+6868+ old = test_and_set_bit(id, dwc3_pci_devs);6969+ if (old)7070+ goto again;7171+ } else {7272+ dev_err(glue->dev, "no space for new device\n");7373+ id = -ENOMEM;7474+ }7575+7676+ return 0;7777+}7878+7979+static void dwc3_pci_put_device_id(struct dwc3_pci *glue, int id)8080+{8181+ int ret;8282+8383+ if (id < 0)8484+ return;8585+8686+ ret = test_bit(id, dwc3_pci_devs);8787+ WARN(!ret, "Device: %s\nID %d not in use\n",8888+ dev_driver_string(glue->dev), id);8989+ clear_bit(id, dwc3_pci_devs);9090+}9191+9292+static int __devinit dwc3_pci_probe(struct pci_dev *pci,9393+ const struct pci_device_id *id)9494+{9595+ struct resource res[2];9696+ struct platform_device *dwc3;9797+ struct dwc3_pci *glue;9898+ int ret = -ENOMEM;9999+ int devid;100100+101101+ glue = kzalloc(sizeof(*glue), GFP_KERNEL);102102+ if (!glue) {103103+ dev_err(&pci->dev, "not enough memory\n");104104+ goto err0;105105+ }106106+107107+ glue->dev = &pci->dev;108108+109109+ ret = pci_enable_device(pci);110110+ if (ret) {111111+ dev_err(&pci->dev, "failed to enable pci device\n");112112+ goto err1;113113+ }114114+115115+ pci_set_power_state(pci, PCI_D0);116116+ pci_set_master(pci);117117+118118+ devid = dwc3_pci_get_device_id(glue);119119+ if (devid < 0)120120+ goto err2;121121+122122+ dwc3 = platform_device_alloc("dwc3-pci", devid);123123+ if (!dwc3) {124124+ dev_err(&pci->dev, "couldn't allocate dwc3 device\n");125125+ goto err3;126126+ }127127+128128+ memset(res, 0x00, sizeof(struct resource) * ARRAY_SIZE(res));129129+130130+ res[0].start = pci_resource_start(pci, 0);131131+ res[0].end = pci_resource_end(pci, 0);132132+ res[0].name = "dwc_usb3";133133+ res[0].flags = IORESOURCE_MEM;134134+135135+ res[1].start = pci->irq;136136+ res[1].name = "dwc_usb3";137137+ res[1].flags = IORESOURCE_IRQ;138138+139139+ ret = platform_device_add_resources(dwc3, res, ARRAY_SIZE(res));140140+ if (ret) {141141+ dev_err(&pci->dev, "couldn't add resources to dwc3 device\n");142142+ goto err4;143143+ }144144+145145+ pci_set_drvdata(pci, glue);146146+147147+ dma_set_coherent_mask(&dwc3->dev, pci->dev.coherent_dma_mask);148148+149149+ dwc3->dev.dma_mask = pci->dev.dma_mask;150150+ dwc3->dev.dma_parms = pci->dev.dma_parms;151151+ dwc3->dev.parent = &pci->dev;152152+ glue->dwc3 = dwc3;153153+154154+ ret = platform_device_add(dwc3);155155+ if (ret) {156156+ dev_err(&pci->dev, "failed to register dwc3 device\n");157157+ goto err4;158158+ }159159+160160+ return 0;161161+162162+err4:163163+ pci_set_drvdata(pci, NULL);164164+ platform_device_put(dwc3);165165+166166+err3:167167+ dwc3_pci_put_device_id(glue, devid);168168+169169+err2:170170+ pci_disable_device(pci);171171+172172+err1:173173+ kfree(pci);174174+175175+err0:176176+ return ret;177177+}178178+179179+static void __devexit dwc3_pci_remove(struct pci_dev *pci)180180+{181181+ struct dwc3_pci *glue = pci_get_drvdata(pci);182182+183183+ dwc3_pci_put_device_id(glue, glue->dwc3->id);184184+ platform_device_unregister(glue->dwc3);185185+ pci_set_drvdata(pci, NULL);186186+ pci_disable_device(pci);187187+ kfree(glue);188188+}189189+190190+static DEFINE_PCI_DEVICE_TABLE(dwc3_pci_id_table) = {191191+ {192192+ PCI_DEVICE(PCI_VENDOR_ID_SYNOPSYS,193193+ PCI_DEVICE_ID_SYNOPSYS_HAPSUSB3),194194+ },195195+ { } /* Terminating Entry */196196+};197197+MODULE_DEVICE_TABLE(pci, dwc3_pci_id_table);198198+199199+static struct pci_driver dwc3_pci_driver = {200200+ .name = "pci-dwc3",201201+ .id_table = dwc3_pci_id_table,202202+ .probe = dwc3_pci_probe,203203+ .remove = __devexit_p(dwc3_pci_remove),204204+};205205+206206+MODULE_AUTHOR("Felipe Balbi <balbi@ti.com>");207207+MODULE_LICENSE("Dual BSD/GPL");208208+MODULE_DESCRIPTION("DesignWare USB3 PCI Glue Layer");209209+210210+static int __devinit dwc3_pci_init(void)211211+{212212+ return pci_register_driver(&dwc3_pci_driver);213213+}214214+module_init(dwc3_pci_init);215215+216216+static void __exit dwc3_pci_exit(void)217217+{218218+ pci_unregister_driver(&dwc3_pci_driver);219219+}220220+module_exit(dwc3_pci_exit);
+782
drivers/usb/dwc3/ep0.c
···11+/**22+ * ep0.c - DesignWare USB3 DRD Controller Endpoint 0 Handling33+ *44+ * Copyright (C) 2010-2011 Texas Instruments Incorporated - http://www.ti.com55+ * All rights reserved.66+ *77+ * Authors: Felipe Balbi <balbi@ti.com>,88+ * Sebastian Andrzej Siewior <bigeasy@linutronix.de>99+ *1010+ * Redistribution and use in source and binary forms, with or without1111+ * modification, are permitted provided that the following conditions1212+ * are met:1313+ * 1. Redistributions of source code must retain the above copyright1414+ * notice, this list of conditions, and the following disclaimer,1515+ * without modification.1616+ * 2. Redistributions in binary form must reproduce the above copyright1717+ * notice, this list of conditions and the following disclaimer in the1818+ * documentation and/or other materials provided with the distribution.1919+ * 3. The names of the above-listed copyright holders may not be used2020+ * to endorse or promote products derived from this software without2121+ * specific prior written permission.2222+ *2323+ * ALTERNATIVELY, this software may be distributed under the terms of the2424+ * GNU General Public License ("GPL") version 2, as published by the Free2525+ * Software Foundation.2626+ *2727+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS2828+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,2929+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR3030+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR3131+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,3232+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,3333+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR3434+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF3535+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING3636+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS3737+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.3838+ */3939+4040+#include <linux/kernel.h>4141+#include <linux/slab.h>4242+#include <linux/spinlock.h>4343+#include <linux/platform_device.h>4444+#include <linux/pm_runtime.h>4545+#include <linux/interrupt.h>4646+#include <linux/io.h>4747+#include <linux/list.h>4848+#include <linux/dma-mapping.h>4949+5050+#include <linux/usb/ch9.h>5151+#include <linux/usb/gadget.h>5252+5353+#include "core.h"5454+#include "gadget.h"5555+#include "io.h"5656+5757+static void dwc3_ep0_inspect_setup(struct dwc3 *dwc,5858+ const struct dwc3_event_depevt *event);5959+6060+static const char *dwc3_ep0_state_string(enum dwc3_ep0_state state)6161+{6262+ switch (state) {6363+ case EP0_UNCONNECTED:6464+ return "Unconnected";6565+ case EP0_IDLE:6666+ return "Idle";6767+ case EP0_IN_DATA_PHASE:6868+ return "IN Data Phase";6969+ case EP0_OUT_DATA_PHASE:7070+ return "OUT Data Phase";7171+ case EP0_IN_WAIT_GADGET:7272+ return "IN Wait Gadget";7373+ case EP0_OUT_WAIT_GADGET:7474+ return "OUT Wait Gadget";7575+ case EP0_IN_WAIT_NRDY:7676+ return "IN Wait NRDY";7777+ case EP0_OUT_WAIT_NRDY:7878+ return "OUT Wait NRDY";7979+ case EP0_IN_STATUS_PHASE:8080+ return "IN Status Phase";8181+ case EP0_OUT_STATUS_PHASE:8282+ return "OUT Status Phase";8383+ case EP0_STALL:8484+ return "Stall";8585+ default:8686+ return "UNKNOWN";8787+ }8888+}8989+9090+static int dwc3_ep0_start_trans(struct dwc3 *dwc, u8 epnum, dma_addr_t buf_dma,9191+ u32 len)9292+{9393+ struct dwc3_gadget_ep_cmd_params params;9494+ struct dwc3_trb_hw *trb_hw;9595+ struct dwc3_trb trb;9696+ struct dwc3_ep *dep;9797+9898+ int ret;9999+100100+ dep = dwc->eps[epnum];101101+102102+ trb_hw = dwc->ep0_trb;103103+ memset(&trb, 0, sizeof(trb));104104+105105+ switch (dwc->ep0state) {106106+ case EP0_IDLE:107107+ trb.trbctl = DWC3_TRBCTL_CONTROL_SETUP;108108+ break;109109+110110+ case EP0_IN_WAIT_NRDY:111111+ case EP0_OUT_WAIT_NRDY:112112+ case EP0_IN_STATUS_PHASE:113113+ case EP0_OUT_STATUS_PHASE:114114+ if (dwc->three_stage_setup)115115+ trb.trbctl = DWC3_TRBCTL_CONTROL_STATUS3;116116+ else117117+ trb.trbctl = DWC3_TRBCTL_CONTROL_STATUS2;118118+119119+ if (dwc->ep0state == EP0_IN_WAIT_NRDY)120120+ dwc->ep0state = EP0_IN_STATUS_PHASE;121121+ else if (dwc->ep0state == EP0_OUT_WAIT_NRDY)122122+ dwc->ep0state = EP0_OUT_STATUS_PHASE;123123+ break;124124+125125+ case EP0_IN_WAIT_GADGET:126126+ dwc->ep0state = EP0_IN_WAIT_NRDY;127127+ return 0;128128+ break;129129+130130+ case EP0_OUT_WAIT_GADGET:131131+ dwc->ep0state = EP0_OUT_WAIT_NRDY;132132+ return 0;133133+134134+ break;135135+136136+ case EP0_IN_DATA_PHASE:137137+ case EP0_OUT_DATA_PHASE:138138+ trb.trbctl = DWC3_TRBCTL_CONTROL_DATA;139139+ break;140140+141141+ default:142142+ dev_err(dwc->dev, "%s() can't in state %d\n", __func__,143143+ dwc->ep0state);144144+ return -EINVAL;145145+ }146146+147147+ trb.bplh = buf_dma;148148+ trb.length = len;149149+150150+ trb.hwo = 1;151151+ trb.lst = 1;152152+ trb.ioc = 1;153153+ trb.isp_imi = 1;154154+155155+ dwc3_trb_to_hw(&trb, trb_hw);156156+157157+ memset(¶ms, 0, sizeof(params));158158+ params.param0.depstrtxfer.transfer_desc_addr_high =159159+ upper_32_bits(dwc->ep0_trb_addr);160160+ params.param1.depstrtxfer.transfer_desc_addr_low =161161+ lower_32_bits(dwc->ep0_trb_addr);162162+163163+ ret = dwc3_send_gadget_ep_cmd(dwc, dep->number,164164+ DWC3_DEPCMD_STARTTRANSFER, ¶ms);165165+ if (ret < 0) {166166+ dev_dbg(dwc->dev, "failed to send STARTTRANSFER command\n");167167+ return ret;168168+ }169169+170170+ dep->res_trans_idx = dwc3_gadget_ep_get_transfer_index(dwc,171171+ dep->number);172172+173173+ return 0;174174+}175175+176176+static int __dwc3_gadget_ep0_queue(struct dwc3_ep *dep,177177+ struct dwc3_request *req)178178+{179179+ struct dwc3 *dwc = dep->dwc;180180+ int ret;181181+182182+ req->request.actual = 0;183183+ req->request.status = -EINPROGRESS;184184+ req->direction = dep->direction;185185+ req->epnum = dep->number;186186+187187+ list_add_tail(&req->list, &dep->request_list);188188+ dwc3_map_buffer_to_dma(req);189189+190190+ ret = dwc3_ep0_start_trans(dwc, dep->number, req->request.dma,191191+ req->request.length);192192+ if (ret < 0) {193193+ list_del(&req->list);194194+ dwc3_unmap_buffer_from_dma(req);195195+ }196196+197197+ return ret;198198+}199199+200200+int dwc3_gadget_ep0_queue(struct usb_ep *ep, struct usb_request *request,201201+ gfp_t gfp_flags)202202+{203203+ struct dwc3_request *req = to_dwc3_request(request);204204+ struct dwc3_ep *dep = to_dwc3_ep(ep);205205+ struct dwc3 *dwc = dep->dwc;206206+207207+ unsigned long flags;208208+209209+ int ret;210210+211211+ switch (dwc->ep0state) {212212+ case EP0_IN_DATA_PHASE:213213+ case EP0_IN_WAIT_GADGET:214214+ case EP0_IN_WAIT_NRDY:215215+ case EP0_IN_STATUS_PHASE:216216+ dep = dwc->eps[1];217217+ break;218218+219219+ case EP0_OUT_DATA_PHASE:220220+ case EP0_OUT_WAIT_GADGET:221221+ case EP0_OUT_WAIT_NRDY:222222+ case EP0_OUT_STATUS_PHASE:223223+ dep = dwc->eps[0];224224+ break;225225+ default:226226+ return -EINVAL;227227+ }228228+229229+ spin_lock_irqsave(&dwc->lock, flags);230230+ if (!dep->desc) {231231+ dev_dbg(dwc->dev, "trying to queue request %p to disabled %s\n",232232+ request, dep->name);233233+ ret = -ESHUTDOWN;234234+ goto out;235235+ }236236+237237+ /* we share one TRB for ep0/1 */238238+ if (!list_empty(&dwc->eps[0]->request_list) ||239239+ !list_empty(&dwc->eps[1]->request_list) ||240240+ dwc->ep0_status_pending) {241241+ ret = -EBUSY;242242+ goto out;243243+ }244244+245245+ dev_vdbg(dwc->dev, "queueing request %p to %s length %d, state '%s'\n",246246+ request, dep->name, request->length,247247+ dwc3_ep0_state_string(dwc->ep0state));248248+249249+ ret = __dwc3_gadget_ep0_queue(dep, req);250250+251251+out:252252+ spin_unlock_irqrestore(&dwc->lock, flags);253253+254254+ return ret;255255+}256256+257257+static void dwc3_ep0_stall_and_restart(struct dwc3 *dwc)258258+{259259+ /* stall is always issued on EP0 */260260+ __dwc3_gadget_ep_set_halt(dwc->eps[0], 1);261261+ dwc->eps[0]->flags &= ~DWC3_EP_STALL;262262+ dwc->ep0state = EP0_IDLE;263263+ dwc3_ep0_out_start(dwc);264264+}265265+266266+void dwc3_ep0_out_start(struct dwc3 *dwc)267267+{268268+ struct dwc3_ep *dep;269269+ int ret;270270+271271+ dep = dwc->eps[0];272272+273273+ ret = dwc3_ep0_start_trans(dwc, 0, dwc->ctrl_req_addr, 8);274274+ WARN_ON(ret < 0);275275+}276276+277277+/*278278+ * Send a zero length packet for the status phase of the control transfer279279+ */280280+static void dwc3_ep0_do_setup_status(struct dwc3 *dwc,281281+ const struct dwc3_event_depevt *event)282282+{283283+ struct dwc3_ep *dep;284284+ int ret;285285+ u32 epnum;286286+287287+ epnum = event->endpoint_number;288288+ dep = dwc->eps[epnum];289289+290290+ if (epnum)291291+ dwc->ep0state = EP0_IN_STATUS_PHASE;292292+ else293293+ dwc->ep0state = EP0_OUT_STATUS_PHASE;294294+295295+ /*296296+ * Not sure Why I need a buffer for a zero transfer. Maybe the297297+ * HW reacts strange on a NULL pointer298298+ */299299+ ret = dwc3_ep0_start_trans(dwc, epnum, dwc->ctrl_req_addr, 0);300300+ if (ret) {301301+ dev_dbg(dwc->dev, "failed to start transfer, stalling\n");302302+ dwc3_ep0_stall_and_restart(dwc);303303+ }304304+}305305+306306+static struct dwc3_ep *dwc3_wIndex_to_dep(struct dwc3 *dwc, __le16 wIndex_le)307307+{308308+ struct dwc3_ep *dep;309309+ u32 windex = le16_to_cpu(wIndex_le);310310+ u32 epnum;311311+312312+ epnum = (windex & USB_ENDPOINT_NUMBER_MASK) << 1;313313+ if ((windex & USB_ENDPOINT_DIR_MASK) == USB_DIR_IN)314314+ epnum |= 1;315315+316316+ dep = dwc->eps[epnum];317317+ if (dep->flags & DWC3_EP_ENABLED)318318+ return dep;319319+320320+ return NULL;321321+}322322+323323+static void dwc3_ep0_send_status_response(struct dwc3 *dwc)324324+{325325+ u32 epnum;326326+327327+ if (dwc->ep0state == EP0_IN_DATA_PHASE)328328+ epnum = 1;329329+ else330330+ epnum = 0;331331+332332+ dwc3_ep0_start_trans(dwc, epnum, dwc->ctrl_req_addr,333333+ dwc->ep0_usb_req.length);334334+ dwc->ep0_status_pending = 1;335335+}336336+337337+/*338338+ * ch 9.4.5339339+ */340340+static int dwc3_ep0_handle_status(struct dwc3 *dwc, struct usb_ctrlrequest *ctrl)341341+{342342+ struct dwc3_ep *dep;343343+ u32 recip;344344+ u16 usb_status = 0;345345+ __le16 *response_pkt;346346+347347+ recip = ctrl->bRequestType & USB_RECIP_MASK;348348+ switch (recip) {349349+ case USB_RECIP_DEVICE:350350+ /*351351+ * We are self-powered. U1/U2/LTM will be set later352352+ * once we handle this states. RemoteWakeup is 0 on SS353353+ */354354+ usb_status |= dwc->is_selfpowered << USB_DEVICE_SELF_POWERED;355355+ break;356356+357357+ case USB_RECIP_INTERFACE:358358+ /*359359+ * Function Remote Wake Capable D0360360+ * Function Remote Wakeup D1361361+ */362362+ break;363363+364364+ case USB_RECIP_ENDPOINT:365365+ dep = dwc3_wIndex_to_dep(dwc, ctrl->wIndex);366366+ if (!dep)367367+ return -EINVAL;368368+369369+ if (dep->flags & DWC3_EP_STALL)370370+ usb_status = 1 << USB_ENDPOINT_HALT;371371+ break;372372+ default:373373+ return -EINVAL;374374+ };375375+376376+ response_pkt = (__le16 *) dwc->setup_buf;377377+ *response_pkt = cpu_to_le16(usb_status);378378+ dwc->ep0_usb_req.length = sizeof(*response_pkt);379379+ dwc3_ep0_send_status_response(dwc);380380+381381+ return 0;382382+}383383+384384+static int dwc3_ep0_handle_feature(struct dwc3 *dwc,385385+ struct usb_ctrlrequest *ctrl, int set)386386+{387387+ struct dwc3_ep *dep;388388+ u32 recip;389389+ u32 wValue;390390+ u32 wIndex;391391+ u32 reg;392392+ int ret;393393+ u32 mode;394394+395395+ wValue = le16_to_cpu(ctrl->wValue);396396+ wIndex = le16_to_cpu(ctrl->wIndex);397397+ recip = ctrl->bRequestType & USB_RECIP_MASK;398398+ switch (recip) {399399+ case USB_RECIP_DEVICE:400400+401401+ /*402402+ * 9.4.1 says only only for SS, in AddressState only for403403+ * default control pipe404404+ */405405+ switch (wValue) {406406+ case USB_DEVICE_U1_ENABLE:407407+ case USB_DEVICE_U2_ENABLE:408408+ case USB_DEVICE_LTM_ENABLE:409409+ if (dwc->dev_state != DWC3_CONFIGURED_STATE)410410+ return -EINVAL;411411+ if (dwc->speed != DWC3_DSTS_SUPERSPEED)412412+ return -EINVAL;413413+ }414414+415415+ /* XXX add U[12] & LTM */416416+ switch (wValue) {417417+ case USB_DEVICE_REMOTE_WAKEUP:418418+ break;419419+ case USB_DEVICE_U1_ENABLE:420420+ break;421421+ case USB_DEVICE_U2_ENABLE:422422+ break;423423+ case USB_DEVICE_LTM_ENABLE:424424+ break;425425+426426+ case USB_DEVICE_TEST_MODE:427427+ if ((wIndex & 0xff) != 0)428428+ return -EINVAL;429429+ if (!set)430430+ return -EINVAL;431431+432432+ mode = wIndex >> 8;433433+ reg = dwc3_readl(dwc->regs, DWC3_DCTL);434434+ reg &= ~DWC3_DCTL_TSTCTRL_MASK;435435+436436+ switch (mode) {437437+ case TEST_J:438438+ case TEST_K:439439+ case TEST_SE0_NAK:440440+ case TEST_PACKET:441441+ case TEST_FORCE_EN:442442+ reg |= mode << 1;443443+ break;444444+ default:445445+ return -EINVAL;446446+ }447447+ dwc3_writel(dwc->regs, DWC3_DCTL, reg);448448+ break;449449+ default:450450+ return -EINVAL;451451+ }452452+ break;453453+454454+ case USB_RECIP_INTERFACE:455455+ switch (wValue) {456456+ case USB_INTRF_FUNC_SUSPEND:457457+ if (wIndex & USB_INTRF_FUNC_SUSPEND_LP)458458+ /* XXX enable Low power suspend */459459+ ;460460+ if (wIndex & USB_INTRF_FUNC_SUSPEND_RW)461461+ /* XXX enable remote wakeup */462462+ ;463463+ break;464464+ default:465465+ return -EINVAL;466466+ }467467+ break;468468+469469+ case USB_RECIP_ENDPOINT:470470+ switch (wValue) {471471+ case USB_ENDPOINT_HALT:472472+473473+ dep = dwc3_wIndex_to_dep(dwc, ctrl->wIndex);474474+ if (!dep)475475+ return -EINVAL;476476+ ret = __dwc3_gadget_ep_set_halt(dep, set);477477+ if (ret)478478+ return -EINVAL;479479+ break;480480+ default:481481+ return -EINVAL;482482+ }483483+ break;484484+485485+ default:486486+ return -EINVAL;487487+ };488488+489489+ dwc->ep0state = EP0_IN_WAIT_NRDY;490490+491491+ return 0;492492+}493493+494494+static int dwc3_ep0_set_address(struct dwc3 *dwc, struct usb_ctrlrequest *ctrl)495495+{496496+ int ret = 0;497497+ u32 addr;498498+ u32 reg;499499+500500+ addr = le16_to_cpu(ctrl->wValue);501501+ if (addr > 127)502502+ return -EINVAL;503503+504504+ switch (dwc->dev_state) {505505+ case DWC3_DEFAULT_STATE:506506+ case DWC3_ADDRESS_STATE:507507+ /*508508+ * Not sure if we should program DevAddr now or later509509+ */510510+ reg = dwc3_readl(dwc->regs, DWC3_DCFG);511511+ reg &= ~(DWC3_DCFG_DEVADDR_MASK);512512+ reg |= DWC3_DCFG_DEVADDR(addr);513513+ dwc3_writel(dwc->regs, DWC3_DCFG, reg);514514+515515+ if (addr)516516+ dwc->dev_state = DWC3_ADDRESS_STATE;517517+ else518518+ dwc->dev_state = DWC3_DEFAULT_STATE;519519+ break;520520+521521+ case DWC3_CONFIGURED_STATE:522522+ ret = -EINVAL;523523+ break;524524+ }525525+ dwc->ep0state = EP0_IN_WAIT_NRDY;526526+ return ret;527527+}528528+529529+static int dwc3_ep0_delegate_req(struct dwc3 *dwc, struct usb_ctrlrequest *ctrl)530530+{531531+ int ret;532532+533533+ spin_unlock(&dwc->lock);534534+ ret = dwc->gadget_driver->setup(&dwc->gadget, ctrl);535535+ spin_lock(&dwc->lock);536536+ return ret;537537+}538538+539539+static int dwc3_ep0_set_config(struct dwc3 *dwc, struct usb_ctrlrequest *ctrl)540540+{541541+ u32 cfg;542542+ int ret;543543+544544+ cfg = le16_to_cpu(ctrl->wValue);545545+546546+ switch (dwc->dev_state) {547547+ case DWC3_DEFAULT_STATE:548548+ return -EINVAL;549549+ break;550550+551551+ case DWC3_ADDRESS_STATE:552552+ ret = dwc3_ep0_delegate_req(dwc, ctrl);553553+ /* if the cfg matches and the cfg is non zero */554554+ if (!ret && cfg)555555+ dwc->dev_state = DWC3_CONFIGURED_STATE;556556+ break;557557+558558+ case DWC3_CONFIGURED_STATE:559559+ ret = dwc3_ep0_delegate_req(dwc, ctrl);560560+ if (!cfg)561561+ dwc->dev_state = DWC3_ADDRESS_STATE;562562+ break;563563+ }564564+ return 0;565565+}566566+567567+static int dwc3_ep0_std_request(struct dwc3 *dwc, struct usb_ctrlrequest *ctrl)568568+{569569+ int ret;570570+571571+ switch (ctrl->bRequest) {572572+ case USB_REQ_GET_STATUS:573573+ dev_vdbg(dwc->dev, "USB_REQ_GET_STATUS\n");574574+ ret = dwc3_ep0_handle_status(dwc, ctrl);575575+ break;576576+ case USB_REQ_CLEAR_FEATURE:577577+ dev_vdbg(dwc->dev, "USB_REQ_CLEAR_FEATURE\n");578578+ ret = dwc3_ep0_handle_feature(dwc, ctrl, 0);579579+ break;580580+ case USB_REQ_SET_FEATURE:581581+ dev_vdbg(dwc->dev, "USB_REQ_SET_FEATURE\n");582582+ ret = dwc3_ep0_handle_feature(dwc, ctrl, 1);583583+ break;584584+ case USB_REQ_SET_ADDRESS:585585+ dev_vdbg(dwc->dev, "USB_REQ_SET_ADDRESS\n");586586+ ret = dwc3_ep0_set_address(dwc, ctrl);587587+ break;588588+ case USB_REQ_SET_CONFIGURATION:589589+ dev_vdbg(dwc->dev, "USB_REQ_SET_CONFIGURATION\n");590590+ ret = dwc3_ep0_set_config(dwc, ctrl);591591+ break;592592+ default:593593+ dev_vdbg(dwc->dev, "Forwarding to gadget driver\n");594594+ ret = dwc3_ep0_delegate_req(dwc, ctrl);595595+ break;596596+ };597597+598598+ return ret;599599+}600600+601601+static void dwc3_ep0_inspect_setup(struct dwc3 *dwc,602602+ const struct dwc3_event_depevt *event)603603+{604604+ struct usb_ctrlrequest *ctrl = dwc->ctrl_req;605605+ int ret;606606+ u32 len;607607+608608+ if (!dwc->gadget_driver)609609+ goto err;610610+611611+ len = le16_to_cpu(ctrl->wLength);612612+ if (!len) {613613+ dwc->ep0state = EP0_IN_WAIT_GADGET;614614+ dwc->three_stage_setup = 0;615615+ } else {616616+ dwc->three_stage_setup = 1;617617+ if (ctrl->bRequestType & USB_DIR_IN)618618+ dwc->ep0state = EP0_IN_DATA_PHASE;619619+ else620620+ dwc->ep0state = EP0_OUT_DATA_PHASE;621621+ }622622+623623+ if ((ctrl->bRequestType & USB_TYPE_MASK) == USB_TYPE_STANDARD)624624+ ret = dwc3_ep0_std_request(dwc, ctrl);625625+ else626626+ ret = dwc3_ep0_delegate_req(dwc, ctrl);627627+628628+ if (ret >= 0)629629+ return;630630+631631+err:632632+ dwc3_ep0_stall_and_restart(dwc);633633+}634634+635635+static void dwc3_ep0_complete_data(struct dwc3 *dwc,636636+ const struct dwc3_event_depevt *event)637637+{638638+ struct dwc3_request *r = NULL;639639+ struct usb_request *ur;640640+ struct dwc3_trb trb;641641+ struct dwc3_ep *dep;642642+ u32 transfered;643643+ u8 epnum;644644+645645+ epnum = event->endpoint_number;646646+ dep = dwc->eps[epnum];647647+648648+ if (!dwc->ep0_status_pending) {649649+ r = next_request(&dep->request_list);650650+ ur = &r->request;651651+ } else {652652+ ur = &dwc->ep0_usb_req;653653+ dwc->ep0_status_pending = 0;654654+ }655655+656656+ dwc3_trb_to_nat(dwc->ep0_trb, &trb);657657+658658+ transfered = ur->length - trb.length;659659+ ur->actual += transfered;660660+661661+ if ((epnum & 1) && ur->actual < ur->length) {662662+ /* for some reason we did not get everything out */663663+664664+ dwc3_ep0_stall_and_restart(dwc);665665+ dwc3_gadget_giveback(dep, r, -ECONNRESET);666666+ } else {667667+ /*668668+ * handle the case where we have to send a zero packet. This669669+ * seems to be case when req.length > maxpacket. Could it be?670670+ */671671+ /* The transfer is complete, wait for HOST */672672+ if (epnum & 1)673673+ dwc->ep0state = EP0_IN_WAIT_NRDY;674674+ else675675+ dwc->ep0state = EP0_OUT_WAIT_NRDY;676676+677677+ if (r)678678+ dwc3_gadget_giveback(dep, r, 0);679679+ }680680+}681681+682682+static void dwc3_ep0_complete_req(struct dwc3 *dwc,683683+ const struct dwc3_event_depevt *event)684684+{685685+ struct dwc3_request *r;686686+ struct dwc3_ep *dep;687687+ u8 epnum;688688+689689+ epnum = event->endpoint_number;690690+ dep = dwc->eps[epnum];691691+692692+ if (!list_empty(&dep->request_list)) {693693+ r = next_request(&dep->request_list);694694+695695+ dwc3_gadget_giveback(dep, r, 0);696696+ }697697+698698+ dwc->ep0state = EP0_IDLE;699699+ dwc3_ep0_out_start(dwc);700700+}701701+702702+static void dwc3_ep0_xfer_complete(struct dwc3 *dwc,703703+ const struct dwc3_event_depevt *event)704704+{705705+ switch (dwc->ep0state) {706706+ case EP0_IDLE:707707+ dwc3_ep0_inspect_setup(dwc, event);708708+ break;709709+710710+ case EP0_IN_DATA_PHASE:711711+ case EP0_OUT_DATA_PHASE:712712+ dwc3_ep0_complete_data(dwc, event);713713+ break;714714+715715+ case EP0_IN_STATUS_PHASE:716716+ case EP0_OUT_STATUS_PHASE:717717+ dwc3_ep0_complete_req(dwc, event);718718+ break;719719+720720+ case EP0_IN_WAIT_NRDY:721721+ case EP0_OUT_WAIT_NRDY:722722+ case EP0_IN_WAIT_GADGET:723723+ case EP0_OUT_WAIT_GADGET:724724+ case EP0_UNCONNECTED:725725+ case EP0_STALL:726726+ break;727727+ }728728+}729729+730730+static void dwc3_ep0_xfernotready(struct dwc3 *dwc,731731+ const struct dwc3_event_depevt *event)732732+{733733+ switch (dwc->ep0state) {734734+ case EP0_IN_WAIT_GADGET:735735+ dwc->ep0state = EP0_IN_WAIT_NRDY;736736+ break;737737+ case EP0_OUT_WAIT_GADGET:738738+ dwc->ep0state = EP0_OUT_WAIT_NRDY;739739+ break;740740+741741+ case EP0_IN_WAIT_NRDY:742742+ case EP0_OUT_WAIT_NRDY:743743+ dwc3_ep0_do_setup_status(dwc, event);744744+ break;745745+746746+ case EP0_IDLE:747747+ case EP0_IN_STATUS_PHASE:748748+ case EP0_OUT_STATUS_PHASE:749749+ case EP0_IN_DATA_PHASE:750750+ case EP0_OUT_DATA_PHASE:751751+ case EP0_UNCONNECTED:752752+ case EP0_STALL:753753+ break;754754+ }755755+}756756+757757+void dwc3_ep0_interrupt(struct dwc3 *dwc,758758+ const const struct dwc3_event_depevt *event)759759+{760760+ u8 epnum = event->endpoint_number;761761+762762+ dev_dbg(dwc->dev, "%s while ep%d%s in state '%s'\n",763763+ dwc3_ep_event_string(event->endpoint_event),764764+ epnum, (epnum & 1) ? "in" : "out",765765+ dwc3_ep0_state_string(dwc->ep0state));766766+767767+ switch (event->endpoint_event) {768768+ case DWC3_DEPEVT_XFERCOMPLETE:769769+ dwc3_ep0_xfer_complete(dwc, event);770770+ break;771771+772772+ case DWC3_DEPEVT_XFERNOTREADY:773773+ dwc3_ep0_xfernotready(dwc, event);774774+ break;775775+776776+ case DWC3_DEPEVT_XFERINPROGRESS:777777+ case DWC3_DEPEVT_RXTXFIFOEVT:778778+ case DWC3_DEPEVT_STREAMEVT:779779+ case DWC3_DEPEVT_EPCMDCMPLT:780780+ break;781781+ }782782+}
+2062
drivers/usb/dwc3/gadget.c
···11+/**22+ * gadget.c - DesignWare USB3 DRD Controller Gadget Framework Link33+ *44+ * Copyright (C) 2010-2011 Texas Instruments Incorporated - http://www.ti.com55+ * All rights reserved.66+ *77+ * Authors: Felipe Balbi <balbi@ti.com>,88+ * Sebastian Andrzej Siewior <bigeasy@linutronix.de>99+ *1010+ * Redistribution and use in source and binary forms, with or without1111+ * modification, are permitted provided that the following conditions1212+ * are met:1313+ * 1. Redistributions of source code must retain the above copyright1414+ * notice, this list of conditions, and the following disclaimer,1515+ * without modification.1616+ * 2. Redistributions in binary form must reproduce the above copyright1717+ * notice, this list of conditions and the following disclaimer in the1818+ * documentation and/or other materials provided with the distribution.1919+ * 3. The names of the above-listed copyright holders may not be used2020+ * to endorse or promote products derived from this software without2121+ * specific prior written permission.2222+ *2323+ * ALTERNATIVELY, this software may be distributed under the terms of the2424+ * GNU General Public License ("GPL") version 2, as published by the Free2525+ * Software Foundation.2626+ *2727+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS2828+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,2929+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR3030+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR3131+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,3232+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,3333+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR3434+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF3535+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING3636+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS3737+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.3838+ */3939+4040+#include <linux/kernel.h>4141+#include <linux/delay.h>4242+#include <linux/slab.h>4343+#include <linux/spinlock.h>4444+#include <linux/platform_device.h>4545+#include <linux/pm_runtime.h>4646+#include <linux/interrupt.h>4747+#include <linux/io.h>4848+#include <linux/list.h>4949+#include <linux/dma-mapping.h>5050+5151+#include <linux/usb/ch9.h>5252+#include <linux/usb/gadget.h>5353+5454+#include "core.h"5555+#include "gadget.h"5656+#include "io.h"5757+5858+#define DMA_ADDR_INVALID (~(dma_addr_t)0)5959+6060+void dwc3_map_buffer_to_dma(struct dwc3_request *req)6161+{6262+ struct dwc3 *dwc = req->dep->dwc;6363+6464+ if (req->request.dma == DMA_ADDR_INVALID) {6565+ req->request.dma = dma_map_single(dwc->dev, req->request.buf,6666+ req->request.length, req->direction6767+ ? DMA_TO_DEVICE : DMA_FROM_DEVICE);6868+ req->mapped = true;6969+ } else {7070+ dma_sync_single_for_device(dwc->dev, req->request.dma,7171+ req->request.length, req->direction7272+ ? DMA_TO_DEVICE : DMA_FROM_DEVICE);7373+ req->mapped = false;7474+ }7575+}7676+7777+void dwc3_unmap_buffer_from_dma(struct dwc3_request *req)7878+{7979+ struct dwc3 *dwc = req->dep->dwc;8080+8181+ if (req->mapped) {8282+ dma_unmap_single(dwc->dev, req->request.dma,8383+ req->request.length, req->direction8484+ ? DMA_TO_DEVICE : DMA_FROM_DEVICE);8585+ req->mapped = 0;8686+ } else {8787+ dma_sync_single_for_cpu(dwc->dev, req->request.dma,8888+ req->request.length, req->direction8989+ ? DMA_TO_DEVICE : DMA_FROM_DEVICE);9090+ }9191+}9292+9393+void dwc3_gadget_giveback(struct dwc3_ep *dep, struct dwc3_request *req,9494+ int status)9595+{9696+ struct dwc3 *dwc = dep->dwc;9797+9898+ if (req->queued) {9999+ dep->busy_slot++;100100+ /*101101+ * Skip LINK TRB. We can't use req->trb and check for102102+ * DWC3_TRBCTL_LINK_TRB because it points the TRB we just103103+ * completed (not the LINK TRB).104104+ */105105+ if (((dep->busy_slot & DWC3_TRB_MASK) == DWC3_TRB_NUM - 1) &&106106+ usb_endpoint_xfer_isoc(dep->desc))107107+ dep->busy_slot++;108108+ }109109+ list_del(&req->list);110110+111111+ if (req->request.status == -EINPROGRESS)112112+ req->request.status = status;113113+114114+ dwc3_unmap_buffer_from_dma(req);115115+116116+ dev_dbg(dwc->dev, "request %p from %s completed %d/%d ===> %d\n",117117+ req, dep->name, req->request.actual,118118+ req->request.length, status);119119+120120+ spin_unlock(&dwc->lock);121121+ req->request.complete(&req->dep->endpoint, &req->request);122122+ spin_lock(&dwc->lock);123123+}124124+125125+static const char *dwc3_gadget_ep_cmd_string(u8 cmd)126126+{127127+ switch (cmd) {128128+ case DWC3_DEPCMD_DEPSTARTCFG:129129+ return "Start New Configuration";130130+ case DWC3_DEPCMD_ENDTRANSFER:131131+ return "End Transfer";132132+ case DWC3_DEPCMD_UPDATETRANSFER:133133+ return "Update Transfer";134134+ case DWC3_DEPCMD_STARTTRANSFER:135135+ return "Start Transfer";136136+ case DWC3_DEPCMD_CLEARSTALL:137137+ return "Clear Stall";138138+ case DWC3_DEPCMD_SETSTALL:139139+ return "Set Stall";140140+ case DWC3_DEPCMD_GETSEQNUMBER:141141+ return "Get Data Sequence Number";142142+ case DWC3_DEPCMD_SETTRANSFRESOURCE:143143+ return "Set Endpoint Transfer Resource";144144+ case DWC3_DEPCMD_SETEPCONFIG:145145+ return "Set Endpoint Configuration";146146+ default:147147+ return "UNKNOWN command";148148+ }149149+}150150+151151+int dwc3_send_gadget_ep_cmd(struct dwc3 *dwc, unsigned ep,152152+ unsigned cmd, struct dwc3_gadget_ep_cmd_params *params)153153+{154154+ struct dwc3_ep *dep = dwc->eps[ep];155155+ unsigned long timeout = 500;156156+ u32 reg;157157+158158+ dev_vdbg(dwc->dev, "%s: cmd '%s' params %08x %08x %08x\n",159159+ dep->name,160160+ dwc3_gadget_ep_cmd_string(cmd), params->param0.raw,161161+ params->param1.raw, params->param2.raw);162162+163163+ dwc3_writel(dwc->regs, DWC3_DEPCMDPAR0(ep), params->param0.raw);164164+ dwc3_writel(dwc->regs, DWC3_DEPCMDPAR1(ep), params->param1.raw);165165+ dwc3_writel(dwc->regs, DWC3_DEPCMDPAR2(ep), params->param2.raw);166166+167167+ dwc3_writel(dwc->regs, DWC3_DEPCMD(ep), cmd | DWC3_DEPCMD_CMDACT);168168+ do {169169+ reg = dwc3_readl(dwc->regs, DWC3_DEPCMD(ep));170170+ if (!(reg & DWC3_DEPCMD_CMDACT)) {171171+ dev_vdbg(dwc->dev, "CMD Compl Status %d DEPCMD %04x\n",172172+ ((reg & 0xf000) >> 12), reg);173173+ return 0;174174+ }175175+176176+ /*177177+ * XXX Figure out a sane timeout here. 500ms is way too much.178178+ * We can't sleep here, because it is also called from179179+ * interrupt context.180180+ */181181+ timeout--;182182+ if (!timeout)183183+ return -ETIMEDOUT;184184+185185+ mdelay(1);186186+ } while (1);187187+}188188+189189+static dma_addr_t dwc3_trb_dma_offset(struct dwc3_ep *dep,190190+ struct dwc3_trb_hw *trb)191191+{192192+ u32 offset = trb - dep->trb_pool;193193+194194+ return dep->trb_pool_dma + offset;195195+}196196+197197+static int dwc3_alloc_trb_pool(struct dwc3_ep *dep)198198+{199199+ struct dwc3 *dwc = dep->dwc;200200+201201+ if (dep->trb_pool)202202+ return 0;203203+204204+ if (dep->number == 0 || dep->number == 1)205205+ return 0;206206+207207+ dep->trb_pool = dma_alloc_coherent(dwc->dev,208208+ sizeof(struct dwc3_trb) * DWC3_TRB_NUM,209209+ &dep->trb_pool_dma, GFP_KERNEL);210210+ if (!dep->trb_pool) {211211+ dev_err(dep->dwc->dev, "failed to allocate trb pool for %s\n",212212+ dep->name);213213+ return -ENOMEM;214214+ }215215+216216+ return 0;217217+}218218+219219+static void dwc3_free_trb_pool(struct dwc3_ep *dep)220220+{221221+ struct dwc3 *dwc = dep->dwc;222222+223223+ dma_free_coherent(dwc->dev, sizeof(struct dwc3_trb) * DWC3_TRB_NUM,224224+ dep->trb_pool, dep->trb_pool_dma);225225+226226+ dep->trb_pool = NULL;227227+ dep->trb_pool_dma = 0;228228+}229229+230230+static int dwc3_gadget_start_config(struct dwc3 *dwc, struct dwc3_ep *dep)231231+{232232+ struct dwc3_gadget_ep_cmd_params params;233233+ u32 cmd;234234+235235+ memset(¶ms, 0x00, sizeof(params));236236+237237+ if (dep->number != 1) {238238+ cmd = DWC3_DEPCMD_DEPSTARTCFG;239239+ /* XferRscIdx == 0 for ep0 and 2 for the remaining */240240+ if (dep->number > 1)241241+ cmd |= DWC3_DEPCMD_PARAM(2);242242+243243+ return dwc3_send_gadget_ep_cmd(dwc, 0, cmd, ¶ms);244244+ }245245+246246+ return 0;247247+}248248+249249+static int dwc3_gadget_set_ep_config(struct dwc3 *dwc, struct dwc3_ep *dep,250250+ const struct usb_endpoint_descriptor *desc)251251+{252252+ struct dwc3_gadget_ep_cmd_params params;253253+254254+ memset(¶ms, 0x00, sizeof(params));255255+256256+ params.param0.depcfg.ep_type = usb_endpoint_type(desc);257257+ params.param0.depcfg.max_packet_size = usb_endpoint_maxp(desc);258258+259259+ params.param1.depcfg.xfer_complete_enable = true;260260+ params.param1.depcfg.xfer_not_ready_enable = true;261261+262262+ if (usb_endpoint_xfer_isoc(desc))263263+ params.param1.depcfg.xfer_in_progress_enable = true;264264+265265+ /*266266+ * We are doing 1:1 mapping for endpoints, meaning267267+ * Physical Endpoints 2 maps to Logical Endpoint 2 and268268+ * so on. We consider the direction bit as part of the physical269269+ * endpoint number. So USB endpoint 0x81 is 0x03.270270+ */271271+ params.param1.depcfg.ep_number = dep->number;272272+273273+ /*274274+ * We must use the lower 16 TX FIFOs even though275275+ * HW might have more276276+ */277277+ if (dep->direction)278278+ params.param0.depcfg.fifo_number = dep->number >> 1;279279+280280+ if (desc->bInterval) {281281+ params.param1.depcfg.binterval_m1 = desc->bInterval - 1;282282+ dep->interval = 1 << (desc->bInterval - 1);283283+ }284284+285285+ return dwc3_send_gadget_ep_cmd(dwc, dep->number,286286+ DWC3_DEPCMD_SETEPCONFIG, ¶ms);287287+}288288+289289+static int dwc3_gadget_set_xfer_resource(struct dwc3 *dwc, struct dwc3_ep *dep)290290+{291291+ struct dwc3_gadget_ep_cmd_params params;292292+293293+ memset(¶ms, 0x00, sizeof(params));294294+295295+ params.param0.depxfercfg.number_xfer_resources = 1;296296+297297+ return dwc3_send_gadget_ep_cmd(dwc, dep->number,298298+ DWC3_DEPCMD_SETTRANSFRESOURCE, ¶ms);299299+}300300+301301+/**302302+ * __dwc3_gadget_ep_enable - Initializes a HW endpoint303303+ * @dep: endpoint to be initialized304304+ * @desc: USB Endpoint Descriptor305305+ *306306+ * Caller should take care of locking307307+ */308308+static int __dwc3_gadget_ep_enable(struct dwc3_ep *dep,309309+ const struct usb_endpoint_descriptor *desc)310310+{311311+ struct dwc3 *dwc = dep->dwc;312312+ u32 reg;313313+ int ret = -ENOMEM;314314+315315+ if (!(dep->flags & DWC3_EP_ENABLED)) {316316+ ret = dwc3_gadget_start_config(dwc, dep);317317+ if (ret)318318+ return ret;319319+ }320320+321321+ ret = dwc3_gadget_set_ep_config(dwc, dep, desc);322322+ if (ret)323323+ return ret;324324+325325+ if (!(dep->flags & DWC3_EP_ENABLED)) {326326+ struct dwc3_trb_hw *trb_st_hw;327327+ struct dwc3_trb_hw *trb_link_hw;328328+ struct dwc3_trb trb_link;329329+330330+ ret = dwc3_gadget_set_xfer_resource(dwc, dep);331331+ if (ret)332332+ return ret;333333+334334+ dep->desc = desc;335335+ dep->type = usb_endpoint_type(desc);336336+ dep->flags |= DWC3_EP_ENABLED;337337+338338+ reg = dwc3_readl(dwc->regs, DWC3_DALEPENA);339339+ reg |= DWC3_DALEPENA_EP(dep->number);340340+ dwc3_writel(dwc->regs, DWC3_DALEPENA, reg);341341+342342+ if (!usb_endpoint_xfer_isoc(desc))343343+ return 0;344344+345345+ memset(&trb_link, 0, sizeof(trb_link));346346+347347+ /* Link TRB for ISOC. The HWO but is never reset */348348+ trb_st_hw = &dep->trb_pool[0];349349+350350+ trb_link.bplh = dwc3_trb_dma_offset(dep, trb_st_hw);351351+ trb_link.trbctl = DWC3_TRBCTL_LINK_TRB;352352+ trb_link.hwo = true;353353+354354+ trb_link_hw = &dep->trb_pool[DWC3_TRB_NUM - 1];355355+ dwc3_trb_to_hw(&trb_link, trb_link_hw);356356+ }357357+358358+ return 0;359359+}360360+361361+static void dwc3_gadget_nuke_reqs(struct dwc3_ep *dep, const int status)362362+{363363+ struct dwc3_request *req;364364+365365+ while (!list_empty(&dep->request_list)) {366366+ req = next_request(&dep->request_list);367367+368368+ dwc3_gadget_giveback(dep, req, status);369369+ }370370+ /* nuke queued TRBs as well on command complete */371371+ dep->flags |= DWC3_EP_WILL_SHUTDOWN;372372+}373373+374374+/**375375+ * __dwc3_gadget_ep_disable - Disables a HW endpoint376376+ * @dep: the endpoint to disable377377+ *378378+ * Caller should take care of locking379379+ */380380+static void dwc3_stop_active_transfer(struct dwc3 *dwc, u32 epnum);381381+static int __dwc3_gadget_ep_disable(struct dwc3_ep *dep)382382+{383383+ struct dwc3 *dwc = dep->dwc;384384+ u32 reg;385385+386386+ dep->flags &= ~DWC3_EP_ENABLED;387387+ dwc3_stop_active_transfer(dwc, dep->number);388388+ dwc3_gadget_nuke_reqs(dep, -ESHUTDOWN);389389+390390+ reg = dwc3_readl(dwc->regs, DWC3_DALEPENA);391391+ reg &= ~DWC3_DALEPENA_EP(dep->number);392392+ dwc3_writel(dwc->regs, DWC3_DALEPENA, reg);393393+394394+ dep->desc = NULL;395395+ dep->type = 0;396396+397397+ return 0;398398+}399399+400400+/* -------------------------------------------------------------------------- */401401+402402+static int dwc3_gadget_ep0_enable(struct usb_ep *ep,403403+ const struct usb_endpoint_descriptor *desc)404404+{405405+ return -EINVAL;406406+}407407+408408+static int dwc3_gadget_ep0_disable(struct usb_ep *ep)409409+{410410+ return -EINVAL;411411+}412412+413413+/* -------------------------------------------------------------------------- */414414+415415+static int dwc3_gadget_ep_enable(struct usb_ep *ep,416416+ const struct usb_endpoint_descriptor *desc)417417+{418418+ struct dwc3_ep *dep;419419+ struct dwc3 *dwc;420420+ unsigned long flags;421421+ int ret;422422+423423+ if (!ep || !desc || desc->bDescriptorType != USB_DT_ENDPOINT) {424424+ pr_debug("dwc3: invalid parameters\n");425425+ return -EINVAL;426426+ }427427+428428+ if (!desc->wMaxPacketSize) {429429+ pr_debug("dwc3: missing wMaxPacketSize\n");430430+ return -EINVAL;431431+ }432432+433433+ dep = to_dwc3_ep(ep);434434+ dwc = dep->dwc;435435+436436+ switch (usb_endpoint_type(desc)) {437437+ case USB_ENDPOINT_XFER_CONTROL:438438+ strncat(dep->name, "-control", sizeof(dep->name));439439+ break;440440+ case USB_ENDPOINT_XFER_ISOC:441441+ strncat(dep->name, "-isoc", sizeof(dep->name));442442+ break;443443+ case USB_ENDPOINT_XFER_BULK:444444+ strncat(dep->name, "-bulk", sizeof(dep->name));445445+ break;446446+ case USB_ENDPOINT_XFER_INT:447447+ strncat(dep->name, "-int", sizeof(dep->name));448448+ break;449449+ default:450450+ dev_err(dwc->dev, "invalid endpoint transfer type\n");451451+ }452452+453453+ if (dep->flags & DWC3_EP_ENABLED) {454454+ dev_WARN_ONCE(dwc->dev, true, "%s is already enabled\n",455455+ dep->name);456456+ return 0;457457+ }458458+459459+ dev_vdbg(dwc->dev, "Enabling %s\n", dep->name);460460+461461+ spin_lock_irqsave(&dwc->lock, flags);462462+ ret = __dwc3_gadget_ep_enable(dep, desc);463463+ spin_unlock_irqrestore(&dwc->lock, flags);464464+465465+ return ret;466466+}467467+468468+static int dwc3_gadget_ep_disable(struct usb_ep *ep)469469+{470470+ struct dwc3_ep *dep;471471+ struct dwc3 *dwc;472472+ unsigned long flags;473473+ int ret;474474+475475+ if (!ep) {476476+ pr_debug("dwc3: invalid parameters\n");477477+ return -EINVAL;478478+ }479479+480480+ dep = to_dwc3_ep(ep);481481+ dwc = dep->dwc;482482+483483+ if (!(dep->flags & DWC3_EP_ENABLED)) {484484+ dev_WARN_ONCE(dwc->dev, true, "%s is already disabled\n",485485+ dep->name);486486+ return 0;487487+ }488488+489489+ snprintf(dep->name, sizeof(dep->name), "ep%d%s",490490+ dep->number >> 1,491491+ (dep->number & 1) ? "in" : "out");492492+493493+ spin_lock_irqsave(&dwc->lock, flags);494494+ ret = __dwc3_gadget_ep_disable(dep);495495+ spin_unlock_irqrestore(&dwc->lock, flags);496496+497497+ return ret;498498+}499499+500500+static struct usb_request *dwc3_gadget_ep_alloc_request(struct usb_ep *ep,501501+ gfp_t gfp_flags)502502+{503503+ struct dwc3_request *req;504504+ struct dwc3_ep *dep = to_dwc3_ep(ep);505505+ struct dwc3 *dwc = dep->dwc;506506+507507+ req = kzalloc(sizeof(*req), gfp_flags);508508+ if (!req) {509509+ dev_err(dwc->dev, "not enough memory\n");510510+ return NULL;511511+ }512512+513513+ req->epnum = dep->number;514514+ req->dep = dep;515515+ req->request.dma = DMA_ADDR_INVALID;516516+517517+ return &req->request;518518+}519519+520520+static void dwc3_gadget_ep_free_request(struct usb_ep *ep,521521+ struct usb_request *request)522522+{523523+ struct dwc3_request *req = to_dwc3_request(request);524524+525525+ kfree(req);526526+}527527+528528+/*529529+ * dwc3_prepare_trbs - setup TRBs from requests530530+ * @dep: endpoint for which requests are being prepared531531+ * @starting: true if the endpoint is idle and no requests are queued.532532+ *533533+ * The functions goes through the requests list and setups TRBs for the534534+ * transfers. The functions returns once there are not more TRBs available or535535+ * it run out of requests.536536+ */537537+static struct dwc3_request *dwc3_prepare_trbs(struct dwc3_ep *dep,538538+ bool starting)539539+{540540+ struct dwc3_request *req, *n, *ret = NULL;541541+ struct dwc3_trb_hw *trb_hw;542542+ struct dwc3_trb trb;543543+ u32 trbs_left;544544+545545+ BUILD_BUG_ON_NOT_POWER_OF_2(DWC3_TRB_NUM);546546+547547+ /* the first request must not be queued */548548+ trbs_left = (dep->busy_slot - dep->free_slot) & DWC3_TRB_MASK;549549+ /*550550+ * if busy & slot are equal than it is either full or empty. If we are551551+ * starting to proceed requests then we are empty. Otherwise we ar552552+ * full and don't do anything553553+ */554554+ if (!trbs_left) {555555+ if (!starting)556556+ return NULL;557557+ trbs_left = DWC3_TRB_NUM;558558+ /*559559+ * In case we start from scratch, we queue the ISOC requests560560+ * starting from slot 1. This is done because we use ring561561+ * buffer and have no LST bit to stop us. Instead, we place562562+ * IOC bit TRB_NUM/4. We try to avoid to having an interrupt563563+ * after the first request so we start at slot 1 and have564564+ * 7 requests proceed before we hit the first IOC.565565+ * Other transfer types don't use the ring buffer and are566566+ * processed from the first TRB until the last one. Since we567567+ * don't wrap around we have to start at the beginning.568568+ */569569+ if (usb_endpoint_xfer_isoc(dep->desc)) {570570+ dep->busy_slot = 1;571571+ dep->free_slot = 1;572572+ } else {573573+ dep->busy_slot = 0;574574+ dep->free_slot = 0;575575+ }576576+ }577577+578578+ /* The last TRB is a link TRB, not used for xfer */579579+ if ((trbs_left <= 1) && usb_endpoint_xfer_isoc(dep->desc))580580+ return NULL;581581+582582+ list_for_each_entry_safe(req, n, &dep->request_list, list) {583583+ unsigned int last_one = 0;584584+ unsigned int cur_slot;585585+586586+ trb_hw = &dep->trb_pool[dep->free_slot & DWC3_TRB_MASK];587587+ cur_slot = dep->free_slot;588588+ dep->free_slot++;589589+590590+ /* Skip the LINK-TRB on ISOC */591591+ if (((cur_slot & DWC3_TRB_MASK) == DWC3_TRB_NUM - 1) &&592592+ usb_endpoint_xfer_isoc(dep->desc))593593+ continue;594594+595595+ dwc3_gadget_move_request_queued(req);596596+ memset(&trb, 0, sizeof(trb));597597+ trbs_left--;598598+599599+ /* Is our TRB pool empty? */600600+ if (!trbs_left)601601+ last_one = 1;602602+ /* Is this the last request? */603603+ if (list_empty(&dep->request_list))604604+ last_one = 1;605605+606606+ /*607607+ * FIXME we shouldn't need to set LST bit always but we are608608+ * facing some weird problem with the Hardware where it doesn't609609+ * complete even though it has been previously started.610610+ *611611+ * While we're debugging the problem, as a workaround to612612+ * multiple TRBs handling, use only one TRB at a time.613613+ */614614+ last_one = 1;615615+616616+ req->trb = trb_hw;617617+ if (!ret)618618+ ret = req;619619+620620+ trb.bplh = req->request.dma;621621+622622+ if (usb_endpoint_xfer_isoc(dep->desc)) {623623+ trb.isp_imi = true;624624+ trb.csp = true;625625+ } else {626626+ trb.lst = last_one;627627+ }628628+629629+ switch (usb_endpoint_type(dep->desc)) {630630+ case USB_ENDPOINT_XFER_CONTROL:631631+ trb.trbctl = DWC3_TRBCTL_CONTROL_SETUP;632632+ break;633633+634634+ case USB_ENDPOINT_XFER_ISOC:635635+ trb.trbctl = DWC3_TRBCTL_ISOCHRONOUS;636636+637637+ /* IOC every DWC3_TRB_NUM / 4 so we can refill */638638+ if (!(cur_slot % (DWC3_TRB_NUM / 4)))639639+ trb.ioc = last_one;640640+ break;641641+642642+ case USB_ENDPOINT_XFER_BULK:643643+ case USB_ENDPOINT_XFER_INT:644644+ trb.trbctl = DWC3_TRBCTL_NORMAL;645645+ break;646646+ default:647647+ /*648648+ * This is only possible with faulty memory because we649649+ * checked it already :)650650+ */651651+ BUG();652652+ }653653+654654+ trb.length = req->request.length;655655+ trb.hwo = true;656656+657657+ dwc3_trb_to_hw(&trb, trb_hw);658658+ req->trb_dma = dwc3_trb_dma_offset(dep, trb_hw);659659+660660+ if (last_one)661661+ break;662662+ }663663+664664+ return ret;665665+}666666+667667+static int __dwc3_gadget_kick_transfer(struct dwc3_ep *dep, u16 cmd_param,668668+ int start_new)669669+{670670+ struct dwc3_gadget_ep_cmd_params params;671671+ struct dwc3_request *req;672672+ struct dwc3 *dwc = dep->dwc;673673+ int ret;674674+ u32 cmd;675675+676676+ if (start_new && (dep->flags & DWC3_EP_BUSY)) {677677+ dev_vdbg(dwc->dev, "%s: endpoint busy\n", dep->name);678678+ return -EBUSY;679679+ }680680+ dep->flags &= ~DWC3_EP_PENDING_REQUEST;681681+682682+ /*683683+ * If we are getting here after a short-out-packet we don't enqueue any684684+ * new requests as we try to set the IOC bit only on the last request.685685+ */686686+ if (start_new) {687687+ if (list_empty(&dep->req_queued))688688+ dwc3_prepare_trbs(dep, start_new);689689+690690+ /* req points to the first request which will be sent */691691+ req = next_request(&dep->req_queued);692692+ } else {693693+ /*694694+ * req points to the first request where HWO changed695695+ * from 0 to 1696696+ */697697+ req = dwc3_prepare_trbs(dep, start_new);698698+ }699699+ if (!req) {700700+ dep->flags |= DWC3_EP_PENDING_REQUEST;701701+ return 0;702702+ }703703+704704+ memset(¶ms, 0, sizeof(params));705705+ params.param0.depstrtxfer.transfer_desc_addr_high =706706+ upper_32_bits(req->trb_dma);707707+ params.param1.depstrtxfer.transfer_desc_addr_low =708708+ lower_32_bits(req->trb_dma);709709+710710+ if (start_new)711711+ cmd = DWC3_DEPCMD_STARTTRANSFER;712712+ else713713+ cmd = DWC3_DEPCMD_UPDATETRANSFER;714714+715715+ cmd |= DWC3_DEPCMD_PARAM(cmd_param);716716+ ret = dwc3_send_gadget_ep_cmd(dwc, dep->number, cmd, ¶ms);717717+ if (ret < 0) {718718+ dev_dbg(dwc->dev, "failed to send STARTTRANSFER command\n");719719+720720+ /*721721+ * FIXME we need to iterate over the list of requests722722+ * here and stop, unmap, free and del each of the linked723723+ * requests instead of we do now.724724+ */725725+ dwc3_unmap_buffer_from_dma(req);726726+ list_del(&req->list);727727+ return ret;728728+ }729729+730730+ dep->flags |= DWC3_EP_BUSY;731731+ dep->res_trans_idx = dwc3_gadget_ep_get_transfer_index(dwc,732732+ dep->number);733733+ if (!dep->res_trans_idx)734734+ printk_once(KERN_ERR "%s() res_trans_idx is invalid\n", __func__);735735+ return 0;736736+}737737+738738+static int __dwc3_gadget_ep_queue(struct dwc3_ep *dep, struct dwc3_request *req)739739+{740740+ req->request.actual = 0;741741+ req->request.status = -EINPROGRESS;742742+ req->direction = dep->direction;743743+ req->epnum = dep->number;744744+745745+ /*746746+ * We only add to our list of requests now and747747+ * start consuming the list once we get XferNotReady748748+ * IRQ.749749+ *750750+ * That way, we avoid doing anything that we don't need751751+ * to do now and defer it until the point we receive a752752+ * particular token from the Host side.753753+ *754754+ * This will also avoid Host cancelling URBs due to too755755+ * many NACKs.756756+ */757757+ dwc3_map_buffer_to_dma(req);758758+ list_add_tail(&req->list, &dep->request_list);759759+760760+ /*761761+ * There is one special case: XferNotReady with762762+ * empty list of requests. We need to kick the763763+ * transfer here in that situation, otherwise764764+ * we will be NAKing forever.765765+ *766766+ * If we get XferNotReady before gadget driver767767+ * has a chance to queue a request, we will ACK768768+ * the IRQ but won't be able to receive the data769769+ * until the next request is queued. The following770770+ * code is handling exactly that.771771+ */772772+ if (dep->flags & DWC3_EP_PENDING_REQUEST) {773773+ int ret;774774+ int start_trans;775775+776776+ start_trans = 1;777777+ if (usb_endpoint_xfer_isoc(dep->endpoint.desc) &&778778+ dep->flags & DWC3_EP_BUSY)779779+ start_trans = 0;780780+781781+ ret = __dwc3_gadget_kick_transfer(dep, 0, start_trans);782782+ if (ret && ret != -EBUSY) {783783+ struct dwc3 *dwc = dep->dwc;784784+785785+ dev_dbg(dwc->dev, "%s: failed to kick transfers\n",786786+ dep->name);787787+ }788788+ };789789+790790+ return 0;791791+}792792+793793+static int dwc3_gadget_ep_queue(struct usb_ep *ep, struct usb_request *request,794794+ gfp_t gfp_flags)795795+{796796+ struct dwc3_request *req = to_dwc3_request(request);797797+ struct dwc3_ep *dep = to_dwc3_ep(ep);798798+ struct dwc3 *dwc = dep->dwc;799799+800800+ unsigned long flags;801801+802802+ int ret;803803+804804+ if (!dep->desc) {805805+ dev_dbg(dwc->dev, "trying to queue request %p to disabled %s\n",806806+ request, ep->name);807807+ return -ESHUTDOWN;808808+ }809809+810810+ dev_vdbg(dwc->dev, "queing request %p to %s length %d\n",811811+ request, ep->name, request->length);812812+813813+ spin_lock_irqsave(&dwc->lock, flags);814814+ ret = __dwc3_gadget_ep_queue(dep, req);815815+ spin_unlock_irqrestore(&dwc->lock, flags);816816+817817+ return ret;818818+}819819+820820+static int dwc3_gadget_ep_dequeue(struct usb_ep *ep,821821+ struct usb_request *request)822822+{823823+ struct dwc3_request *req = to_dwc3_request(request);824824+ struct dwc3_request *r = NULL;825825+826826+ struct dwc3_ep *dep = to_dwc3_ep(ep);827827+ struct dwc3 *dwc = dep->dwc;828828+829829+ unsigned long flags;830830+ int ret = 0;831831+832832+ spin_lock_irqsave(&dwc->lock, flags);833833+834834+ list_for_each_entry(r, &dep->request_list, list) {835835+ if (r == req)836836+ break;837837+ }838838+839839+ if (r != req) {840840+ list_for_each_entry(r, &dep->req_queued, list) {841841+ if (r == req)842842+ break;843843+ }844844+ if (r == req) {845845+ /* wait until it is processed */846846+ dwc3_stop_active_transfer(dwc, dep->number);847847+ goto out0;848848+ }849849+ dev_err(dwc->dev, "request %p was not queued to %s\n",850850+ request, ep->name);851851+ ret = -EINVAL;852852+ goto out0;853853+ }854854+855855+ /* giveback the request */856856+ dwc3_gadget_giveback(dep, req, -ECONNRESET);857857+858858+out0:859859+ spin_unlock_irqrestore(&dwc->lock, flags);860860+861861+ return ret;862862+}863863+864864+int __dwc3_gadget_ep_set_halt(struct dwc3_ep *dep, int value)865865+{866866+ struct dwc3_gadget_ep_cmd_params params;867867+ struct dwc3 *dwc = dep->dwc;868868+ int ret;869869+870870+ memset(¶ms, 0x00, sizeof(params));871871+872872+ if (value) {873873+ if (dep->number == 0 || dep->number == 1)874874+ dwc->ep0state = EP0_STALL;875875+876876+ ret = dwc3_send_gadget_ep_cmd(dwc, dep->number,877877+ DWC3_DEPCMD_SETSTALL, ¶ms);878878+ if (ret)879879+ dev_err(dwc->dev, "failed to %s STALL on %s\n",880880+ value ? "set" : "clear",881881+ dep->name);882882+ else883883+ dep->flags |= DWC3_EP_STALL;884884+ } else {885885+ ret = dwc3_send_gadget_ep_cmd(dwc, dep->number,886886+ DWC3_DEPCMD_CLEARSTALL, ¶ms);887887+ if (ret)888888+ dev_err(dwc->dev, "failed to %s STALL on %s\n",889889+ value ? "set" : "clear",890890+ dep->name);891891+ else892892+ dep->flags &= ~DWC3_EP_STALL;893893+ }894894+ return ret;895895+}896896+897897+static int dwc3_gadget_ep_set_halt(struct usb_ep *ep, int value)898898+{899899+ struct dwc3_ep *dep = to_dwc3_ep(ep);900900+ struct dwc3 *dwc = dep->dwc;901901+902902+ unsigned long flags;903903+904904+ int ret;905905+906906+ spin_lock_irqsave(&dwc->lock, flags);907907+908908+ if (usb_endpoint_xfer_isoc(dep->desc)) {909909+ dev_err(dwc->dev, "%s is of Isochronous type\n", dep->name);910910+ ret = -EINVAL;911911+ goto out;912912+ }913913+914914+ ret = __dwc3_gadget_ep_set_halt(dep, value);915915+out:916916+ spin_unlock_irqrestore(&dwc->lock, flags);917917+918918+ return ret;919919+}920920+921921+static int dwc3_gadget_ep_set_wedge(struct usb_ep *ep)922922+{923923+ struct dwc3_ep *dep = to_dwc3_ep(ep);924924+925925+ dep->flags |= DWC3_EP_WEDGE;926926+927927+ return usb_ep_set_halt(ep);928928+}929929+930930+/* -------------------------------------------------------------------------- */931931+932932+static struct usb_endpoint_descriptor dwc3_gadget_ep0_desc = {933933+ .bLength = USB_DT_ENDPOINT_SIZE,934934+ .bDescriptorType = USB_DT_ENDPOINT,935935+ .bmAttributes = USB_ENDPOINT_XFER_CONTROL,936936+};937937+938938+static const struct usb_ep_ops dwc3_gadget_ep0_ops = {939939+ .enable = dwc3_gadget_ep0_enable,940940+ .disable = dwc3_gadget_ep0_disable,941941+ .alloc_request = dwc3_gadget_ep_alloc_request,942942+ .free_request = dwc3_gadget_ep_free_request,943943+ .queue = dwc3_gadget_ep0_queue,944944+ .dequeue = dwc3_gadget_ep_dequeue,945945+ .set_halt = dwc3_gadget_ep_set_halt,946946+ .set_wedge = dwc3_gadget_ep_set_wedge,947947+};948948+949949+static const struct usb_ep_ops dwc3_gadget_ep_ops = {950950+ .enable = dwc3_gadget_ep_enable,951951+ .disable = dwc3_gadget_ep_disable,952952+ .alloc_request = dwc3_gadget_ep_alloc_request,953953+ .free_request = dwc3_gadget_ep_free_request,954954+ .queue = dwc3_gadget_ep_queue,955955+ .dequeue = dwc3_gadget_ep_dequeue,956956+ .set_halt = dwc3_gadget_ep_set_halt,957957+ .set_wedge = dwc3_gadget_ep_set_wedge,958958+};959959+960960+/* -------------------------------------------------------------------------- */961961+962962+static int dwc3_gadget_get_frame(struct usb_gadget *g)963963+{964964+ struct dwc3 *dwc = gadget_to_dwc(g);965965+ u32 reg;966966+967967+ reg = dwc3_readl(dwc->regs, DWC3_DSTS);968968+ return DWC3_DSTS_SOFFN(reg);969969+}970970+971971+static int dwc3_gadget_wakeup(struct usb_gadget *g)972972+{973973+ struct dwc3 *dwc = gadget_to_dwc(g);974974+975975+ unsigned long timeout;976976+ unsigned long flags;977977+978978+ u32 reg;979979+980980+ int ret = 0;981981+982982+ u8 link_state;983983+ u8 speed;984984+985985+ spin_lock_irqsave(&dwc->lock, flags);986986+987987+ /*988988+ * According to the Databook Remote wakeup request should989989+ * be issued only when the device is in early suspend state.990990+ *991991+ * We can check that via USB Link State bits in DSTS register.992992+ */993993+ reg = dwc3_readl(dwc->regs, DWC3_DSTS);994994+995995+ speed = reg & DWC3_DSTS_CONNECTSPD;996996+ if (speed == DWC3_DSTS_SUPERSPEED) {997997+ dev_dbg(dwc->dev, "no wakeup on SuperSpeed\n");998998+ ret = -EINVAL;999999+ goto out;10001000+ }10011001+10021002+ link_state = DWC3_DSTS_USBLNKST(reg);10031003+10041004+ switch (link_state) {10051005+ case DWC3_LINK_STATE_RX_DET: /* in HS, means Early Suspend */10061006+ case DWC3_LINK_STATE_U3: /* in HS, means SUSPEND */10071007+ break;10081008+ default:10091009+ dev_dbg(dwc->dev, "can't wakeup from link state %d\n",10101010+ link_state);10111011+ ret = -EINVAL;10121012+ goto out;10131013+ }10141014+10151015+ reg = dwc3_readl(dwc->regs, DWC3_DCTL);10161016+10171017+ /*10181018+ * Switch link state to Recovery. In HS/FS/LS this means10191019+ * RemoteWakeup Request10201020+ */10211021+ reg |= DWC3_DCTL_ULSTCHNG_RECOVERY;10221022+ dwc3_writel(dwc->regs, DWC3_DCTL, reg);10231023+10241024+ /* wait for at least 2000us */10251025+ usleep_range(2000, 2500);10261026+10271027+ /* write zeroes to Link Change Request */10281028+ reg &= ~DWC3_DCTL_ULSTCHNGREQ_MASK;10291029+ dwc3_writel(dwc->regs, DWC3_DCTL, reg);10301030+10311031+ /* pool until Link State change to ON */10321032+ timeout = jiffies + msecs_to_jiffies(100);10331033+10341034+ while (!(time_after(jiffies, timeout))) {10351035+ reg = dwc3_readl(dwc->regs, DWC3_DSTS);10361036+10371037+ /* in HS, means ON */10381038+ if (DWC3_DSTS_USBLNKST(reg) == DWC3_LINK_STATE_U0)10391039+ break;10401040+ }10411041+10421042+ if (DWC3_DSTS_USBLNKST(reg) != DWC3_LINK_STATE_U0) {10431043+ dev_err(dwc->dev, "failed to send remote wakeup\n");10441044+ ret = -EINVAL;10451045+ }10461046+10471047+out:10481048+ spin_unlock_irqrestore(&dwc->lock, flags);10491049+10501050+ return ret;10511051+}10521052+10531053+static int dwc3_gadget_set_selfpowered(struct usb_gadget *g,10541054+ int is_selfpowered)10551055+{10561056+ struct dwc3 *dwc = gadget_to_dwc(g);10571057+10581058+ dwc->is_selfpowered = !!is_selfpowered;10591059+10601060+ return 0;10611061+}10621062+10631063+static void dwc3_gadget_run_stop(struct dwc3 *dwc, int is_on)10641064+{10651065+ u32 reg;10661066+ unsigned long timeout = 500;10671067+10681068+ reg = dwc3_readl(dwc->regs, DWC3_DCTL);10691069+ if (is_on)10701070+ reg |= DWC3_DCTL_RUN_STOP;10711071+ else10721072+ reg &= ~DWC3_DCTL_RUN_STOP;10731073+10741074+ dwc3_writel(dwc->regs, DWC3_DCTL, reg);10751075+10761076+ do {10771077+ reg = dwc3_readl(dwc->regs, DWC3_DSTS);10781078+ if (is_on) {10791079+ if (!(reg & DWC3_DSTS_DEVCTRLHLT))10801080+ break;10811081+ } else {10821082+ if (reg & DWC3_DSTS_DEVCTRLHLT)10831083+ break;10841084+ }10851085+ /*10861086+ * XXX reduce the 500ms delay10871087+ */10881088+ timeout--;10891089+ if (!timeout)10901090+ break;10911091+ mdelay(1);10921092+ } while (1);10931093+10941094+ dev_vdbg(dwc->dev, "gadget %s data soft-%s\n",10951095+ dwc->gadget_driver10961096+ ? dwc->gadget_driver->function : "no-function",10971097+ is_on ? "connect" : "disconnect");10981098+}10991099+11001100+static int dwc3_gadget_pullup(struct usb_gadget *g, int is_on)11011101+{11021102+ struct dwc3 *dwc = gadget_to_dwc(g);11031103+ unsigned long flags;11041104+11051105+ is_on = !!is_on;11061106+11071107+ spin_lock_irqsave(&dwc->lock, flags);11081108+ dwc3_gadget_run_stop(dwc, is_on);11091109+ spin_unlock_irqrestore(&dwc->lock, flags);11101110+11111111+ return 0;11121112+}11131113+11141114+static int dwc3_gadget_start(struct usb_gadget *g,11151115+ struct usb_gadget_driver *driver)11161116+{11171117+ struct dwc3 *dwc = gadget_to_dwc(g);11181118+ struct dwc3_ep *dep;11191119+ unsigned long flags;11201120+ int ret = 0;11211121+ u32 reg;11221122+11231123+ spin_lock_irqsave(&dwc->lock, flags);11241124+11251125+ if (dwc->gadget_driver) {11261126+ dev_err(dwc->dev, "%s is already bound to %s\n",11271127+ dwc->gadget.name,11281128+ dwc->gadget_driver->driver.name);11291129+ ret = -EBUSY;11301130+ goto err0;11311131+ }11321132+11331133+ dwc->gadget_driver = driver;11341134+ dwc->gadget.dev.driver = &driver->driver;11351135+11361136+ reg = dwc3_readl(dwc->regs, DWC3_GCTL);11371137+11381138+ /*11391139+ * REVISIT: power down scale might be different11401140+ * depending on PHY used, need to pass that via platform_data11411141+ */11421142+ reg |= DWC3_GCTL_PWRDNSCALE(0x61a)11431143+ | DWC3_GCTL_PRTCAPDIR(DWC3_GCTL_PRTCAP_DEVICE);11441144+ reg &= ~DWC3_GCTL_DISSCRAMBLE;11451145+11461146+ /*11471147+ * WORKAROUND: DWC3 revisions <1.90a have a bug11481148+ * when The device fails to connect at SuperSpeed11491149+ * and falls back to high-speed mode which causes11501150+ * the device to enter in a Connect/Disconnect loop11511151+ */11521152+ if (dwc->revision < DWC3_REVISION_190A)11531153+ reg |= DWC3_GCTL_U2RSTECN;11541154+11551155+ dwc3_writel(dwc->regs, DWC3_GCTL, reg);11561156+11571157+ reg = dwc3_readl(dwc->regs, DWC3_DCFG);11581158+ reg &= ~(DWC3_DCFG_SPEED_MASK);11591159+ reg |= DWC3_DCFG_SUPERSPEED;11601160+ dwc3_writel(dwc->regs, DWC3_DCFG, reg);11611161+11621162+ /* Start with SuperSpeed Default */11631163+ dwc3_gadget_ep0_desc.wMaxPacketSize = cpu_to_le16(512);11641164+11651165+ dep = dwc->eps[0];11661166+ ret = __dwc3_gadget_ep_enable(dep, &dwc3_gadget_ep0_desc);11671167+ if (ret) {11681168+ dev_err(dwc->dev, "failed to enable %s\n", dep->name);11691169+ goto err0;11701170+ }11711171+11721172+ dep = dwc->eps[1];11731173+ ret = __dwc3_gadget_ep_enable(dep, &dwc3_gadget_ep0_desc);11741174+ if (ret) {11751175+ dev_err(dwc->dev, "failed to enable %s\n", dep->name);11761176+ goto err1;11771177+ }11781178+11791179+ /* begin to receive SETUP packets */11801180+ dwc->ep0state = EP0_IDLE;11811181+ dwc3_ep0_out_start(dwc);11821182+11831183+ spin_unlock_irqrestore(&dwc->lock, flags);11841184+11851185+ return 0;11861186+11871187+err1:11881188+ __dwc3_gadget_ep_disable(dwc->eps[0]);11891189+11901190+err0:11911191+ spin_unlock_irqrestore(&dwc->lock, flags);11921192+11931193+ return ret;11941194+}11951195+11961196+static int dwc3_gadget_stop(struct usb_gadget *g,11971197+ struct usb_gadget_driver *driver)11981198+{11991199+ struct dwc3 *dwc = gadget_to_dwc(g);12001200+ unsigned long flags;12011201+12021202+ spin_lock_irqsave(&dwc->lock, flags);12031203+12041204+ __dwc3_gadget_ep_disable(dwc->eps[0]);12051205+ __dwc3_gadget_ep_disable(dwc->eps[1]);12061206+12071207+ dwc->gadget_driver = NULL;12081208+ dwc->gadget.dev.driver = NULL;12091209+12101210+ spin_unlock_irqrestore(&dwc->lock, flags);12111211+12121212+ return 0;12131213+}12141214+static const struct usb_gadget_ops dwc3_gadget_ops = {12151215+ .get_frame = dwc3_gadget_get_frame,12161216+ .wakeup = dwc3_gadget_wakeup,12171217+ .set_selfpowered = dwc3_gadget_set_selfpowered,12181218+ .pullup = dwc3_gadget_pullup,12191219+ .udc_start = dwc3_gadget_start,12201220+ .udc_stop = dwc3_gadget_stop,12211221+};12221222+12231223+/* -------------------------------------------------------------------------- */12241224+12251225+static int __devinit dwc3_gadget_init_endpoints(struct dwc3 *dwc)12261226+{12271227+ struct dwc3_ep *dep;12281228+ u8 epnum;12291229+12301230+ INIT_LIST_HEAD(&dwc->gadget.ep_list);12311231+12321232+ for (epnum = 0; epnum < DWC3_ENDPOINTS_NUM; epnum++) {12331233+ dep = kzalloc(sizeof(*dep), GFP_KERNEL);12341234+ if (!dep) {12351235+ dev_err(dwc->dev, "can't allocate endpoint %d\n",12361236+ epnum);12371237+ return -ENOMEM;12381238+ }12391239+12401240+ dep->dwc = dwc;12411241+ dep->number = epnum;12421242+ dwc->eps[epnum] = dep;12431243+12441244+ snprintf(dep->name, sizeof(dep->name), "ep%d%s", epnum >> 1,12451245+ (epnum & 1) ? "in" : "out");12461246+ dep->endpoint.name = dep->name;12471247+ dep->direction = (epnum & 1);12481248+12491249+ if (epnum == 0 || epnum == 1) {12501250+ dep->endpoint.maxpacket = 512;12511251+ dep->endpoint.ops = &dwc3_gadget_ep0_ops;12521252+ if (!epnum)12531253+ dwc->gadget.ep0 = &dep->endpoint;12541254+ } else {12551255+ int ret;12561256+12571257+ dep->endpoint.maxpacket = 1024;12581258+ dep->endpoint.ops = &dwc3_gadget_ep_ops;12591259+ list_add_tail(&dep->endpoint.ep_list,12601260+ &dwc->gadget.ep_list);12611261+12621262+ ret = dwc3_alloc_trb_pool(dep);12631263+ if (ret) {12641264+ dev_err(dwc->dev, "%s: failed to allocate TRB pool\n", dep->name);12651265+ return ret;12661266+ }12671267+ }12681268+ INIT_LIST_HEAD(&dep->request_list);12691269+ INIT_LIST_HEAD(&dep->req_queued);12701270+ }12711271+12721272+ return 0;12731273+}12741274+12751275+static void dwc3_gadget_free_endpoints(struct dwc3 *dwc)12761276+{12771277+ struct dwc3_ep *dep;12781278+ u8 epnum;12791279+12801280+ for (epnum = 0; epnum < DWC3_ENDPOINTS_NUM; epnum++) {12811281+ dep = dwc->eps[epnum];12821282+ dwc3_free_trb_pool(dep);12831283+12841284+ if (epnum != 0 && epnum != 1)12851285+ list_del(&dep->endpoint.ep_list);12861286+12871287+ kfree(dep);12881288+ }12891289+}12901290+12911291+static void dwc3_gadget_release(struct device *dev)12921292+{12931293+ dev_dbg(dev, "%s\n", __func__);12941294+}12951295+12961296+/* -------------------------------------------------------------------------- */12971297+static int dwc3_cleanup_done_reqs(struct dwc3 *dwc, struct dwc3_ep *dep,12981298+ const struct dwc3_event_depevt *event, int status)12991299+{13001300+ struct dwc3_request *req;13011301+ struct dwc3_trb trb;13021302+ unsigned int count;13031303+ unsigned int s_pkt = 0;13041304+13051305+ do {13061306+ req = next_request(&dep->req_queued);13071307+ if (!req)13081308+ break;13091309+13101310+ dwc3_trb_to_nat(req->trb, &trb);13111311+13121312+ if (trb.hwo) {13131313+ dev_err(dwc->dev, "%s's TRB (%p) still owned by HW\n",13141314+ dep->name, req->trb);13151315+ continue;13161316+ }13171317+ count = trb.length;13181318+13191319+ if (dep->direction) {13201320+ if (count) {13211321+ dev_err(dwc->dev, "incomplete IN transfer %s\n",13221322+ dep->name);13231323+ status = -ECONNRESET;13241324+ }13251325+ } else {13261326+ if (count && (event->status & DEPEVT_STATUS_SHORT))13271327+ s_pkt = 1;13281328+ }13291329+13301330+ /*13311331+ * We assume here we will always receive the entire data block13321332+ * which we should receive. Meaning, if we program RX to13331333+ * receive 4K but we receive only 2K, we assume that's all we13341334+ * should receive and we simply bounce the request back to the13351335+ * gadget driver for further processing.13361336+ */13371337+ req->request.actual += req->request.length - count;13381338+ dwc3_gadget_giveback(dep, req, status);13391339+ if (s_pkt)13401340+ break;13411341+ if ((event->status & DEPEVT_STATUS_LST) && trb.lst)13421342+ break;13431343+ if ((event->status & DEPEVT_STATUS_IOC) && trb.ioc)13441344+ break;13451345+ } while (1);13461346+13471347+ if ((event->status & DEPEVT_STATUS_IOC) && trb.ioc)13481348+ return 0;13491349+ return 1;13501350+}13511351+13521352+static void dwc3_endpoint_transfer_complete(struct dwc3 *dwc,13531353+ struct dwc3_ep *dep, const struct dwc3_event_depevt *event,13541354+ int start_new)13551355+{13561356+ unsigned status = 0;13571357+ int clean_busy;13581358+13591359+ if (event->status & DEPEVT_STATUS_BUSERR)13601360+ status = -ECONNRESET;13611361+13621362+ clean_busy = dwc3_cleanup_done_reqs(dwc, dep, event, status);13631363+ if (clean_busy)13641364+ dep->flags &= ~DWC3_EP_BUSY;13651365+}13661366+13671367+static void dwc3_gadget_start_isoc(struct dwc3 *dwc,13681368+ struct dwc3_ep *dep, const struct dwc3_event_depevt *event)13691369+{13701370+ u32 uf;13711371+13721372+ if (list_empty(&dep->request_list)) {13731373+ dev_vdbg(dwc->dev, "ISOC ep %s run out for requests.\n",13741374+ dep->name);13751375+ return;13761376+ }13771377+13781378+ if (event->parameters) {13791379+ u32 mask;13801380+13811381+ mask = ~(dep->interval - 1);13821382+ uf = event->parameters & mask;13831383+ /* 4 micro frames in the future */13841384+ uf += dep->interval * 4;13851385+ } else {13861386+ uf = 0;13871387+ }13881388+13891389+ __dwc3_gadget_kick_transfer(dep, uf, 1);13901390+}13911391+13921392+static void dwc3_process_ep_cmd_complete(struct dwc3_ep *dep,13931393+ const struct dwc3_event_depevt *event)13941394+{13951395+ struct dwc3 *dwc = dep->dwc;13961396+ struct dwc3_event_depevt mod_ev = *event;13971397+13981398+ /*13991399+ * We were asked to remove one requests. It is possible that this14001400+ * request and a few other were started together and have the same14011401+ * transfer index. Since we stopped the complete endpoint we don't14021402+ * know how many requests were already completed (and not yet)14031403+ * reported and how could be done (later). We purge them all until14041404+ * the end of the list.14051405+ */14061406+ mod_ev.status = DEPEVT_STATUS_LST;14071407+ dwc3_cleanup_done_reqs(dwc, dep, &mod_ev, -ESHUTDOWN);14081408+ dep->flags &= ~DWC3_EP_BUSY;14091409+ /* pending requets are ignored and are queued on XferNotReady */14101410+14111411+ if (dep->flags & DWC3_EP_WILL_SHUTDOWN) {14121412+ while (!list_empty(&dep->req_queued)) {14131413+ struct dwc3_request *req;14141414+14151415+ req = next_request(&dep->req_queued);14161416+ dwc3_gadget_giveback(dep, req, -ESHUTDOWN);14171417+ }14181418+ dep->flags &= DWC3_EP_WILL_SHUTDOWN;14191419+ }14201420+}14211421+14221422+static void dwc3_ep_cmd_compl(struct dwc3_ep *dep,14231423+ const struct dwc3_event_depevt *event)14241424+{14251425+ u32 param = event->parameters;14261426+ u32 cmd_type = (param >> 8) & ((1 << 5) - 1);14271427+14281428+ switch (cmd_type) {14291429+ case DWC3_DEPCMD_ENDTRANSFER:14301430+ dwc3_process_ep_cmd_complete(dep, event);14311431+ break;14321432+ case DWC3_DEPCMD_STARTTRANSFER:14331433+ dep->res_trans_idx = param & 0x7f;14341434+ break;14351435+ default:14361436+ printk(KERN_ERR "%s() unknown /unexpected type: %d\n",14371437+ __func__, cmd_type);14381438+ break;14391439+ };14401440+}14411441+14421442+static void dwc3_endpoint_interrupt(struct dwc3 *dwc,14431443+ const struct dwc3_event_depevt *event)14441444+{14451445+ struct dwc3_ep *dep;14461446+ u8 epnum = event->endpoint_number;14471447+14481448+ dep = dwc->eps[epnum];14491449+14501450+ dev_vdbg(dwc->dev, "%s: %s\n", dep->name,14511451+ dwc3_ep_event_string(event->endpoint_event));14521452+14531453+ if (epnum == 0 || epnum == 1) {14541454+ dwc3_ep0_interrupt(dwc, event);14551455+ return;14561456+ }14571457+14581458+ switch (event->endpoint_event) {14591459+ case DWC3_DEPEVT_XFERCOMPLETE:14601460+ if (usb_endpoint_xfer_isoc(dep->desc)) {14611461+ dev_dbg(dwc->dev, "%s is an Isochronous endpoint\n",14621462+ dep->name);14631463+ return;14641464+ }14651465+14661466+ dwc3_endpoint_transfer_complete(dwc, dep, event, 1);14671467+ break;14681468+ case DWC3_DEPEVT_XFERINPROGRESS:14691469+ if (!usb_endpoint_xfer_isoc(dep->desc)) {14701470+ dev_dbg(dwc->dev, "%s is not an Isochronous endpoint\n",14711471+ dep->name);14721472+ return;14731473+ }14741474+14751475+ dwc3_endpoint_transfer_complete(dwc, dep, event, 0);14761476+ break;14771477+ case DWC3_DEPEVT_XFERNOTREADY:14781478+ if (usb_endpoint_xfer_isoc(dep->desc)) {14791479+ dwc3_gadget_start_isoc(dwc, dep, event);14801480+ } else {14811481+ int ret;14821482+14831483+ dev_vdbg(dwc->dev, "%s: reason %s\n",14841484+ dep->name, event->status14851485+ ? "Transfer Active"14861486+ : "Transfer Not Active");14871487+14881488+ ret = __dwc3_gadget_kick_transfer(dep, 0, 1);14891489+ if (!ret || ret == -EBUSY)14901490+ return;14911491+14921492+ dev_dbg(dwc->dev, "%s: failed to kick transfers\n",14931493+ dep->name);14941494+ }14951495+14961496+ break;14971497+ case DWC3_DEPEVT_RXTXFIFOEVT:14981498+ dev_dbg(dwc->dev, "%s FIFO Overrun\n", dep->name);14991499+ break;15001500+ case DWC3_DEPEVT_STREAMEVT:15011501+ dev_dbg(dwc->dev, "%s Stream Event\n", dep->name);15021502+ break;15031503+ case DWC3_DEPEVT_EPCMDCMPLT:15041504+ dwc3_ep_cmd_compl(dep, event);15051505+ break;15061506+ }15071507+}15081508+15091509+static void dwc3_disconnect_gadget(struct dwc3 *dwc)15101510+{15111511+ if (dwc->gadget_driver && dwc->gadget_driver->disconnect) {15121512+ spin_unlock(&dwc->lock);15131513+ dwc->gadget_driver->disconnect(&dwc->gadget);15141514+ spin_lock(&dwc->lock);15151515+ }15161516+}15171517+15181518+static void dwc3_stop_active_transfer(struct dwc3 *dwc, u32 epnum)15191519+{15201520+ struct dwc3_ep *dep;15211521+ struct dwc3_gadget_ep_cmd_params params;15221522+ u32 cmd;15231523+ int ret;15241524+15251525+ dep = dwc->eps[epnum];15261526+15271527+ if (dep->res_trans_idx) {15281528+ cmd = DWC3_DEPCMD_ENDTRANSFER;15291529+ cmd |= DWC3_DEPCMD_HIPRI_FORCERM | DWC3_DEPCMD_CMDIOC;15301530+ cmd |= DWC3_DEPCMD_PARAM(dep->res_trans_idx);15311531+ memset(¶ms, 0, sizeof(params));15321532+ ret = dwc3_send_gadget_ep_cmd(dwc, dep->number, cmd, ¶ms);15331533+ WARN_ON_ONCE(ret);15341534+ }15351535+}15361536+15371537+static void dwc3_stop_active_transfers(struct dwc3 *dwc)15381538+{15391539+ u32 epnum;15401540+15411541+ for (epnum = 2; epnum < DWC3_ENDPOINTS_NUM; epnum++) {15421542+ struct dwc3_ep *dep;15431543+15441544+ dep = dwc->eps[epnum];15451545+ if (!(dep->flags & DWC3_EP_ENABLED))15461546+ continue;15471547+15481548+ __dwc3_gadget_ep_disable(dep);15491549+ }15501550+}15511551+15521552+static void dwc3_clear_stall_all_ep(struct dwc3 *dwc)15531553+{15541554+ u32 epnum;15551555+15561556+ for (epnum = 1; epnum < DWC3_ENDPOINTS_NUM; epnum++) {15571557+ struct dwc3_ep *dep;15581558+ struct dwc3_gadget_ep_cmd_params params;15591559+ int ret;15601560+15611561+ dep = dwc->eps[epnum];15621562+15631563+ if (!(dep->flags & DWC3_EP_STALL))15641564+ continue;15651565+15661566+ dep->flags &= ~DWC3_EP_STALL;15671567+15681568+ memset(¶ms, 0, sizeof(params));15691569+ ret = dwc3_send_gadget_ep_cmd(dwc, dep->number,15701570+ DWC3_DEPCMD_CLEARSTALL, ¶ms);15711571+ WARN_ON_ONCE(ret);15721572+ }15731573+}15741574+15751575+static void dwc3_gadget_disconnect_interrupt(struct dwc3 *dwc)15761576+{15771577+ dev_vdbg(dwc->dev, "%s\n", __func__);15781578+#if 015791579+ XXX15801580+ U1/U2 is powersave optimization. Skip it for now. Anyway we need to15811581+ enable it before we can disable it.15821582+15831583+ reg = dwc3_readl(dwc->regs, DWC3_DCTL);15841584+ reg &= ~DWC3_DCTL_INITU1ENA;15851585+ dwc3_writel(dwc->regs, DWC3_DCTL, reg);15861586+15871587+ reg &= ~DWC3_DCTL_INITU2ENA;15881588+ dwc3_writel(dwc->regs, DWC3_DCTL, reg);15891589+#endif15901590+15911591+ dwc3_stop_active_transfers(dwc);15921592+ dwc3_disconnect_gadget(dwc);15931593+15941594+ dwc->gadget.speed = USB_SPEED_UNKNOWN;15951595+}15961596+15971597+static void dwc3_gadget_usb3_phy_power(struct dwc3 *dwc, int on)15981598+{15991599+ u32 reg;16001600+16011601+ reg = dwc3_readl(dwc->regs, DWC3_GUSB3PIPECTL(0));16021602+16031603+ if (on)16041604+ reg &= ~DWC3_GUSB3PIPECTL_SUSPHY;16051605+ else16061606+ reg |= DWC3_GUSB3PIPECTL_SUSPHY;16071607+16081608+ dwc3_writel(dwc->regs, DWC3_GUSB3PIPECTL(0), reg);16091609+}16101610+16111611+static void dwc3_gadget_usb2_phy_power(struct dwc3 *dwc, int on)16121612+{16131613+ u32 reg;16141614+16151615+ reg = dwc3_readl(dwc->regs, DWC3_GUSB2PHYCFG(0));16161616+16171617+ if (on)16181618+ reg &= ~DWC3_GUSB2PHYCFG_SUSPHY;16191619+ else16201620+ reg |= DWC3_GUSB2PHYCFG_SUSPHY;16211621+16221622+ dwc3_writel(dwc->regs, DWC3_GUSB2PHYCFG(0), reg);16231623+}16241624+16251625+static void dwc3_gadget_reset_interrupt(struct dwc3 *dwc)16261626+{16271627+ u32 reg;16281628+16291629+ dev_vdbg(dwc->dev, "%s\n", __func__);16301630+16311631+ /* Enable PHYs */16321632+ dwc3_gadget_usb2_phy_power(dwc, true);16331633+ dwc3_gadget_usb3_phy_power(dwc, true);16341634+16351635+ if (dwc->gadget.speed != USB_SPEED_UNKNOWN)16361636+ dwc3_disconnect_gadget(dwc);16371637+16381638+ reg = dwc3_readl(dwc->regs, DWC3_DCTL);16391639+ reg &= ~DWC3_DCTL_TSTCTRL_MASK;16401640+ dwc3_writel(dwc->regs, DWC3_DCTL, reg);16411641+16421642+ dwc3_stop_active_transfers(dwc);16431643+ dwc3_clear_stall_all_ep(dwc);16441644+16451645+ /* Reset device address to zero */16461646+ reg = dwc3_readl(dwc->regs, DWC3_DCFG);16471647+ reg &= ~(DWC3_DCFG_DEVADDR_MASK);16481648+ dwc3_writel(dwc->regs, DWC3_DCFG, reg);16491649+16501650+ /*16511651+ * Wait for RxFifo to drain16521652+ *16531653+ * REVISIT probably shouldn't wait forever.16541654+ * In case Hardware ends up in a screwed up16551655+ * case, we error out, notify the user and,16561656+ * maybe, WARN() or BUG() but leave the rest16571657+ * of the kernel working fine.16581658+ *16591659+ * REVISIT the below is rather CPU intensive,16601660+ * maybe we should read and if it doesn't work16611661+ * sleep (not busy wait) for a few useconds.16621662+ *16631663+ * REVISIT why wait until the RXFIFO is empty anyway?16641664+ */16651665+ while (!(dwc3_readl(dwc->regs, DWC3_DSTS)16661666+ & DWC3_DSTS_RXFIFOEMPTY))16671667+ cpu_relax();16681668+}16691669+16701670+static void dwc3_update_ram_clk_sel(struct dwc3 *dwc, u32 speed)16711671+{16721672+ u32 reg;16731673+ u32 usb30_clock = DWC3_GCTL_CLK_BUS;16741674+16751675+ /*16761676+ * We change the clock only at SS but I dunno why I would want to do16771677+ * this. Maybe it becomes part of the power saving plan.16781678+ */16791679+16801680+ if (speed != DWC3_DSTS_SUPERSPEED)16811681+ return;16821682+16831683+ /*16841684+ * RAMClkSel is reset to 0 after USB reset, so it must be reprogrammed16851685+ * each time on Connect Done.16861686+ */16871687+ if (!usb30_clock)16881688+ return;16891689+16901690+ reg = dwc3_readl(dwc->regs, DWC3_GCTL);16911691+ reg |= DWC3_GCTL_RAMCLKSEL(usb30_clock);16921692+ dwc3_writel(dwc->regs, DWC3_GCTL, reg);16931693+}16941694+16951695+static void dwc3_gadget_disable_phy(struct dwc3 *dwc, u8 speed)16961696+{16971697+ switch (speed) {16981698+ case USB_SPEED_SUPER:16991699+ dwc3_gadget_usb2_phy_power(dwc, false);17001700+ break;17011701+ case USB_SPEED_HIGH:17021702+ case USB_SPEED_FULL:17031703+ case USB_SPEED_LOW:17041704+ dwc3_gadget_usb3_phy_power(dwc, false);17051705+ break;17061706+ }17071707+}17081708+17091709+static void dwc3_gadget_conndone_interrupt(struct dwc3 *dwc)17101710+{17111711+ struct dwc3_gadget_ep_cmd_params params;17121712+ struct dwc3_ep *dep;17131713+ int ret;17141714+ u32 reg;17151715+ u8 speed;17161716+17171717+ dev_vdbg(dwc->dev, "%s\n", __func__);17181718+17191719+ memset(¶ms, 0x00, sizeof(params));17201720+17211721+ dwc->ep0state = EP0_IDLE;17221722+ reg = dwc3_readl(dwc->regs, DWC3_DSTS);17231723+ speed = reg & DWC3_DSTS_CONNECTSPD;17241724+ dwc->speed = speed;17251725+17261726+ dwc3_update_ram_clk_sel(dwc, speed);17271727+17281728+ switch (speed) {17291729+ case DWC3_DCFG_SUPERSPEED:17301730+ dwc3_gadget_ep0_desc.wMaxPacketSize = cpu_to_le16(512);17311731+ dwc->gadget.ep0->maxpacket = 512;17321732+ dwc->gadget.speed = USB_SPEED_SUPER;17331733+ break;17341734+ case DWC3_DCFG_HIGHSPEED:17351735+ dwc3_gadget_ep0_desc.wMaxPacketSize = cpu_to_le16(64);17361736+ dwc->gadget.ep0->maxpacket = 64;17371737+ dwc->gadget.speed = USB_SPEED_HIGH;17381738+ break;17391739+ case DWC3_DCFG_FULLSPEED2:17401740+ case DWC3_DCFG_FULLSPEED1:17411741+ dwc3_gadget_ep0_desc.wMaxPacketSize = cpu_to_le16(64);17421742+ dwc->gadget.ep0->maxpacket = 64;17431743+ dwc->gadget.speed = USB_SPEED_FULL;17441744+ break;17451745+ case DWC3_DCFG_LOWSPEED:17461746+ dwc3_gadget_ep0_desc.wMaxPacketSize = cpu_to_le16(8);17471747+ dwc->gadget.ep0->maxpacket = 8;17481748+ dwc->gadget.speed = USB_SPEED_LOW;17491749+ break;17501750+ }17511751+17521752+ /* Disable unneded PHY */17531753+ dwc3_gadget_disable_phy(dwc, dwc->gadget.speed);17541754+17551755+ dep = dwc->eps[0];17561756+ ret = __dwc3_gadget_ep_enable(dep, &dwc3_gadget_ep0_desc);17571757+ if (ret) {17581758+ dev_err(dwc->dev, "failed to enable %s\n", dep->name);17591759+ return;17601760+ }17611761+17621762+ dep = dwc->eps[1];17631763+ ret = __dwc3_gadget_ep_enable(dep, &dwc3_gadget_ep0_desc);17641764+ if (ret) {17651765+ dev_err(dwc->dev, "failed to enable %s\n", dep->name);17661766+ return;17671767+ }17681768+17691769+ /*17701770+ * Configure PHY via GUSB3PIPECTLn if required.17711771+ *17721772+ * Update GTXFIFOSIZn17731773+ *17741774+ * In both cases reset values should be sufficient.17751775+ */17761776+}17771777+17781778+static void dwc3_gadget_wakeup_interrupt(struct dwc3 *dwc)17791779+{17801780+ dev_vdbg(dwc->dev, "%s\n", __func__);17811781+17821782+ /*17831783+ * TODO take core out of low power mode when that's17841784+ * implemented.17851785+ */17861786+17871787+ dwc->gadget_driver->resume(&dwc->gadget);17881788+}17891789+17901790+static void dwc3_gadget_linksts_change_interrupt(struct dwc3 *dwc,17911791+ unsigned int evtinfo)17921792+{17931793+ dev_vdbg(dwc->dev, "%s\n", __func__);17941794+17951795+ /* The fith bit says SuperSpeed yes or no. */17961796+ dwc->link_state = evtinfo & DWC3_LINK_STATE_MASK;17971797+}17981798+17991799+static void dwc3_gadget_interrupt(struct dwc3 *dwc,18001800+ const struct dwc3_event_devt *event)18011801+{18021802+ switch (event->type) {18031803+ case DWC3_DEVICE_EVENT_DISCONNECT:18041804+ dwc3_gadget_disconnect_interrupt(dwc);18051805+ break;18061806+ case DWC3_DEVICE_EVENT_RESET:18071807+ dwc3_gadget_reset_interrupt(dwc);18081808+ break;18091809+ case DWC3_DEVICE_EVENT_CONNECT_DONE:18101810+ dwc3_gadget_conndone_interrupt(dwc);18111811+ break;18121812+ case DWC3_DEVICE_EVENT_WAKEUP:18131813+ dwc3_gadget_wakeup_interrupt(dwc);18141814+ break;18151815+ case DWC3_DEVICE_EVENT_LINK_STATUS_CHANGE:18161816+ dwc3_gadget_linksts_change_interrupt(dwc, event->event_info);18171817+ break;18181818+ case DWC3_DEVICE_EVENT_EOPF:18191819+ dev_vdbg(dwc->dev, "End of Periodic Frame\n");18201820+ break;18211821+ case DWC3_DEVICE_EVENT_SOF:18221822+ dev_vdbg(dwc->dev, "Start of Periodic Frame\n");18231823+ break;18241824+ case DWC3_DEVICE_EVENT_ERRATIC_ERROR:18251825+ dev_vdbg(dwc->dev, "Erratic Error\n");18261826+ break;18271827+ case DWC3_DEVICE_EVENT_CMD_CMPL:18281828+ dev_vdbg(dwc->dev, "Command Complete\n");18291829+ break;18301830+ case DWC3_DEVICE_EVENT_OVERFLOW:18311831+ dev_vdbg(dwc->dev, "Overflow\n");18321832+ break;18331833+ default:18341834+ dev_dbg(dwc->dev, "UNKNOWN IRQ %d\n", event->type);18351835+ }18361836+}18371837+18381838+static void dwc3_process_event_entry(struct dwc3 *dwc,18391839+ const union dwc3_event *event)18401840+{18411841+ /* Endpoint IRQ, handle it and return early */18421842+ if (event->type.is_devspec == 0) {18431843+ /* depevt */18441844+ return dwc3_endpoint_interrupt(dwc, &event->depevt);18451845+ }18461846+18471847+ switch (event->type.type) {18481848+ case DWC3_EVENT_TYPE_DEV:18491849+ dwc3_gadget_interrupt(dwc, &event->devt);18501850+ break;18511851+ /* REVISIT what to do with Carkit and I2C events ? */18521852+ default:18531853+ dev_err(dwc->dev, "UNKNOWN IRQ type %d\n", event->raw);18541854+ }18551855+}18561856+18571857+static irqreturn_t dwc3_process_event_buf(struct dwc3 *dwc, u32 buf)18581858+{18591859+ struct dwc3_event_buffer *evt;18601860+ int left;18611861+ u32 count;18621862+18631863+ count = dwc3_readl(dwc->regs, DWC3_GEVNTCOUNT(buf));18641864+ count &= DWC3_GEVNTCOUNT_MASK;18651865+ if (!count)18661866+ return IRQ_NONE;18671867+18681868+ evt = dwc->ev_buffs[buf];18691869+ left = count;18701870+18711871+ while (left > 0) {18721872+ union dwc3_event event;18731873+18741874+ memcpy(&event.raw, (evt->buf + evt->lpos), sizeof(event.raw));18751875+ dwc3_process_event_entry(dwc, &event);18761876+ /*18771877+ * XXX we wrap around correctly to the next entry as almost all18781878+ * entries are 4 bytes in size. There is one entry which has 1218791879+ * bytes which is a regular entry followed by 8 bytes data. ATM18801880+ * I don't know how things are organized if were get next to the18811881+ * a boundary so I worry about that once we try to handle that.18821882+ */18831883+ evt->lpos = (evt->lpos + 4) % DWC3_EVENT_BUFFERS_SIZE;18841884+ left -= 4;18851885+18861886+ dwc3_writel(dwc->regs, DWC3_GEVNTCOUNT(buf), 4);18871887+ }18881888+18891889+ return IRQ_HANDLED;18901890+}18911891+18921892+static irqreturn_t dwc3_interrupt(int irq, void *_dwc)18931893+{18941894+ struct dwc3 *dwc = _dwc;18951895+ int i;18961896+ irqreturn_t ret = IRQ_NONE;18971897+18981898+ spin_lock(&dwc->lock);18991899+19001900+ for (i = 0; i < DWC3_EVENT_BUFFERS_NUM; i++) {19011901+ irqreturn_t status;19021902+19031903+ status = dwc3_process_event_buf(dwc, i);19041904+ if (status == IRQ_HANDLED)19051905+ ret = status;19061906+ }19071907+19081908+ spin_unlock(&dwc->lock);19091909+19101910+ return ret;19111911+}19121912+19131913+/**19141914+ * dwc3_gadget_init - Initializes gadget related registers19151915+ * @dwc: Pointer to out controller context structure19161916+ *19171917+ * Returns 0 on success otherwise negative errno.19181918+ */19191919+int __devinit dwc3_gadget_init(struct dwc3 *dwc)19201920+{19211921+ u32 reg;19221922+ int ret;19231923+ int irq;19241924+19251925+ dwc->ctrl_req = dma_alloc_coherent(dwc->dev, sizeof(*dwc->ctrl_req),19261926+ &dwc->ctrl_req_addr, GFP_KERNEL);19271927+ if (!dwc->ctrl_req) {19281928+ dev_err(dwc->dev, "failed to allocate ctrl request\n");19291929+ ret = -ENOMEM;19301930+ goto err0;19311931+ }19321932+19331933+ dwc->ep0_trb = dma_alloc_coherent(dwc->dev, sizeof(*dwc->ep0_trb),19341934+ &dwc->ep0_trb_addr, GFP_KERNEL);19351935+ if (!dwc->ep0_trb) {19361936+ dev_err(dwc->dev, "failed to allocate ep0 trb\n");19371937+ ret = -ENOMEM;19381938+ goto err1;19391939+ }19401940+19411941+ dwc->setup_buf = dma_alloc_coherent(dwc->dev,19421942+ sizeof(*dwc->setup_buf) * 2,19431943+ &dwc->setup_buf_addr, GFP_KERNEL);19441944+ if (!dwc->setup_buf) {19451945+ dev_err(dwc->dev, "failed to allocate setup buffer\n");19461946+ ret = -ENOMEM;19471947+ goto err2;19481948+ }19491949+19501950+ dev_set_name(&dwc->gadget.dev, "gadget");19511951+19521952+ dwc->gadget.ops = &dwc3_gadget_ops;19531953+ dwc->gadget.is_dualspeed = true;19541954+ dwc->gadget.speed = USB_SPEED_UNKNOWN;19551955+ dwc->gadget.dev.parent = dwc->dev;19561956+19571957+ dma_set_coherent_mask(&dwc->gadget.dev, dwc->dev->coherent_dma_mask);19581958+19591959+ dwc->gadget.dev.dma_parms = dwc->dev->dma_parms;19601960+ dwc->gadget.dev.dma_mask = dwc->dev->dma_mask;19611961+ dwc->gadget.dev.release = dwc3_gadget_release;19621962+ dwc->gadget.name = "dwc3-gadget";19631963+19641964+ /*19651965+ * REVISIT: Here we should clear all pending IRQs to be19661966+ * sure we're starting from a well known location.19671967+ */19681968+19691969+ ret = dwc3_gadget_init_endpoints(dwc);19701970+ if (ret)19711971+ goto err3;19721972+19731973+ irq = platform_get_irq(to_platform_device(dwc->dev), 0);19741974+19751975+ ret = request_irq(irq, dwc3_interrupt, IRQF_SHARED,19761976+ "dwc3", dwc);19771977+ if (ret) {19781978+ dev_err(dwc->dev, "failed to request irq #%d --> %d\n",19791979+ irq, ret);19801980+ goto err4;19811981+ }19821982+19831983+ /* Enable all but Start and End of Frame IRQs */19841984+ reg = (DWC3_DEVTEN_VNDRDEVTSTRCVEDEN |19851985+ DWC3_DEVTEN_EVNTOVERFLOWEN |19861986+ DWC3_DEVTEN_CMDCMPLTEN |19871987+ DWC3_DEVTEN_ERRTICERREN |19881988+ DWC3_DEVTEN_WKUPEVTEN |19891989+ DWC3_DEVTEN_ULSTCNGEN |19901990+ DWC3_DEVTEN_CONNECTDONEEN |19911991+ DWC3_DEVTEN_USBRSTEN |19921992+ DWC3_DEVTEN_DISCONNEVTEN);19931993+ dwc3_writel(dwc->regs, DWC3_DEVTEN, reg);19941994+19951995+ ret = device_register(&dwc->gadget.dev);19961996+ if (ret) {19971997+ dev_err(dwc->dev, "failed to register gadget device\n");19981998+ put_device(&dwc->gadget.dev);19991999+ goto err5;20002000+ }20012001+20022002+ ret = usb_add_gadget_udc(dwc->dev, &dwc->gadget);20032003+ if (ret) {20042004+ dev_err(dwc->dev, "failed to register udc\n");20052005+ goto err6;20062006+ }20072007+20082008+ return 0;20092009+20102010+err6:20112011+ device_unregister(&dwc->gadget.dev);20122012+20132013+err5:20142014+ dwc3_writel(dwc->regs, DWC3_DEVTEN, 0x00);20152015+ free_irq(irq, dwc);20162016+20172017+err4:20182018+ dwc3_gadget_free_endpoints(dwc);20192019+20202020+err3:20212021+ dma_free_coherent(dwc->dev, sizeof(*dwc->setup_buf) * 2,20222022+ dwc->setup_buf, dwc->setup_buf_addr);20232023+20242024+err2:20252025+ dma_free_coherent(dwc->dev, sizeof(*dwc->ep0_trb),20262026+ dwc->ep0_trb, dwc->ep0_trb_addr);20272027+20282028+err1:20292029+ dma_free_coherent(dwc->dev, sizeof(*dwc->ctrl_req),20302030+ dwc->ctrl_req, dwc->ctrl_req_addr);20312031+20322032+err0:20332033+ return ret;20342034+}20352035+20362036+void dwc3_gadget_exit(struct dwc3 *dwc)20372037+{20382038+ int irq;20392039+ int i;20402040+20412041+ usb_del_gadget_udc(&dwc->gadget);20422042+ irq = platform_get_irq(to_platform_device(dwc->dev), 0);20432043+20442044+ dwc3_writel(dwc->regs, DWC3_DEVTEN, 0x00);20452045+ free_irq(irq, dwc);20462046+20472047+ for (i = 0; i < ARRAY_SIZE(dwc->eps); i++)20482048+ __dwc3_gadget_ep_disable(dwc->eps[i]);20492049+20502050+ dwc3_gadget_free_endpoints(dwc);20512051+20522052+ dma_free_coherent(dwc->dev, sizeof(*dwc->setup_buf) * 2,20532053+ dwc->setup_buf, dwc->setup_buf_addr);20542054+20552055+ dma_free_coherent(dwc->dev, sizeof(*dwc->ep0_trb),20562056+ dwc->ep0_trb, dwc->ep0_trb_addr);20572057+20582058+ dma_free_coherent(dwc->dev, sizeof(*dwc->ctrl_req),20592059+ dwc->ctrl_req, dwc->ctrl_req_addr);20602060+20612061+ device_unregister(&dwc->gadget.dev);20622062+}
+297
drivers/usb/dwc3/gadget.h
···11+/**22+ * gadget.h - DesignWare USB3 DRD Gadget Header33+ *44+ * Copyright (C) 2010-2011 Texas Instruments Incorporated - http://www.ti.com55+ * All rights reserved.66+ *77+ * Authors: Felipe Balbi <balbi@ti.com>,88+ * Sebastian Andrzej Siewior <bigeasy@linutronix.de>99+ *1010+ * Redistribution and use in source and binary forms, with or without1111+ * modification, are permitted provided that the following conditions1212+ * are met:1313+ * 1. Redistributions of source code must retain the above copyright1414+ * notice, this list of conditions, and the following disclaimer,1515+ * without modification.1616+ * 2. Redistributions in binary form must reproduce the above copyright1717+ * notice, this list of conditions and the following disclaimer in the1818+ * documentation and/or other materials provided with the distribution.1919+ * 3. The names of the above-listed copyright holders may not be used2020+ * to endorse or promote products derived from this software without2121+ * specific prior written permission.2222+ *2323+ * ALTERNATIVELY, this software may be distributed under the terms of the2424+ * GNU General Public License ("GPL") version 2, as published by the Free2525+ * Software Foundation.2626+ *2727+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS2828+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,2929+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR3030+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR3131+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,3232+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,3333+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR3434+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF3535+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING3636+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS3737+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.3838+ */3939+4040+#ifndef __DRIVERS_USB_DWC3_GADGET_H4141+#define __DRIVERS_USB_DWC3_GADGET_H4242+4343+#include <linux/list.h>4444+#include <linux/usb/gadget.h>4545+#include "io.h"4646+4747+struct dwc3;4848+#define to_dwc3_ep(ep) (container_of(ep, struct dwc3_ep, endpoint))4949+#define gadget_to_dwc(g) (container_of(g, struct dwc3, gadget))5050+5151+/**5252+ * struct dwc3_gadget_ep_depcfg_param1 - DEPCMDPAR0 for DEPCFG command5353+ * @interrupt_number: self-explanatory5454+ * @reserved7_5: set to zero5555+ * @xfer_complete_enable: event generated when transfer completed5656+ * @xfer_in_progress_enable: event generated when transfer in progress5757+ * @xfer_not_ready_enable: event generated when transfer not read5858+ * @fifo_error_enable: generates events when FIFO Underrun (IN eps)5959+ * or FIFO Overrun (OUT) eps6060+ * @reserved_12: set to zero6161+ * @stream_event_enable: event generated on stream6262+ * @reserved14_15: set to zero6363+ * @binterval_m1: bInterval minus 16464+ * @stream_capable: this EP is capable of handling streams6565+ * @ep_number: self-explanatory6666+ * @bulk_based: Set to ‘1’ if this isochronous endpoint represents a bulk6767+ * data stream that ignores the relationship of bus time to the6868+ * intervals programmed in TRBs.6969+ * @fifo_based: Set to ‘1’ if this isochronous endpoint represents a7070+ * FIFO-based data stream where TRBs have fixed values and are never7171+ * written back by the core.7272+ */7373+struct dwc3_gadget_ep_depcfg_param1 {7474+ u32 interrupt_number:5;7575+ u32 reserved7_5:3; /* set to zero */7676+ u32 xfer_complete_enable:1;7777+ u32 xfer_in_progress_enable:1;7878+ u32 xfer_not_ready_enable:1;7979+ u32 fifo_error_enable:1; /* IN-underrun, OUT-overrun */8080+ u32 reserved12:1; /* set to zero */8181+ u32 stream_event_enable:1;8282+ u32 reserved14_15:2;8383+ u32 binterval_m1:8; /* bInterval minus 1 */8484+ u32 stream_capable:1;8585+ u32 ep_number:5;8686+ u32 bulk_based:1;8787+ u32 fifo_based:1;8888+} __packed;8989+9090+/**9191+ * struct dwc3_gadget_ep_depcfg_param0 - Parameter 0 for DEPCFG9292+ * @reserved0: set to zero9393+ * @ep_type: Endpoint Type (control, bulk, iso, interrupt)9494+ * @max_packet_size: max packet size in bytes9595+ * @reserved16_14: set to zero9696+ * @fifo_number: self-explanatory9797+ * @burst_size: burst size minus 19898+ * @data_sequence_number: Must be 0 when an endpoint is initially configured9999+ * May be non-zero when an endpoint is configured after a power transition100100+ * that requires a save/restore.101101+ * @ignore_sequence_number: Set to ‘1’ to avoid resetting the sequence102102+ * number. This setting is used by software to modify the DEPEVTEN103103+ * event enable bits without modifying other endpoint settings.104104+ */105105+struct dwc3_gadget_ep_depcfg_param0 {106106+ u32 reserved0:1;107107+ u32 ep_type:2;108108+ u32 max_packet_size:11;109109+ u32 reserved16_14:3;110110+ u32 fifo_number:5;111111+ u32 burst_size:4;112112+ u32 data_sequence_number:5;113113+ u32 ignore_sequence_number:1;114114+} __packed;115115+116116+/**117117+ * struct dwc3_gadget_ep_depxfercfg_param0 - Parameter 0 of DEPXFERCFG118118+ * @number_xfer_resources: Defines the number of Transfer Resources allocated119119+ * to this endpoint. This field must be set to 1.120120+ * @reserved16_31: set to zero;121121+ */122122+struct dwc3_gadget_ep_depxfercfg_param0 {123123+ u32 number_xfer_resources:16;124124+ u32 reserved16_31:16;125125+} __packed;126126+127127+/**128128+ * struct dwc3_gadget_ep_depstrtxfer_param1 - Parameter 1 of DEPSTRTXFER129129+ * @transfer_desc_addr_low: Indicates the lower 32 bits of the external130130+ * memory's start address for the transfer descriptor. Because TRBs131131+ * must be aligned to a 16-byte boundary, the lower 4 bits of this132132+ * address must be 0.133133+ */134134+struct dwc3_gadget_ep_depstrtxfer_param1 {135135+ u32 transfer_desc_addr_low;136136+} __packed;137137+138138+/**139139+ * struct dwc3_gadget_ep_depstrtxfer_param1 - Parameter 1 of DEPSTRTXFER140140+ * @transfer_desc_addr_high: Indicates the higher 32 bits of the external141141+ * memory’s start address for the transfer descriptor.142142+ */143143+struct dwc3_gadget_ep_depstrtxfer_param0 {144144+ u32 transfer_desc_addr_high;145145+} __packed;146146+147147+struct dwc3_gadget_ep_cmd_params {148148+ union {149149+ u32 raw;150150+ } param2;151151+152152+ union {153153+ u32 raw;154154+ struct dwc3_gadget_ep_depcfg_param1 depcfg;155155+ struct dwc3_gadget_ep_depstrtxfer_param1 depstrtxfer;156156+ } param1;157157+158158+ union {159159+ u32 raw;160160+ struct dwc3_gadget_ep_depcfg_param0 depcfg;161161+ struct dwc3_gadget_ep_depxfercfg_param0 depxfercfg;162162+ struct dwc3_gadget_ep_depstrtxfer_param0 depstrtxfer;163163+ } param0;164164+} __packed;165165+166166+/* -------------------------------------------------------------------------- */167167+168168+struct dwc3_request {169169+ struct usb_request request;170170+ struct list_head list;171171+ struct dwc3_ep *dep;172172+173173+ u8 epnum;174174+ struct dwc3_trb_hw *trb;175175+ dma_addr_t trb_dma;176176+177177+ unsigned direction:1;178178+ unsigned mapped:1;179179+ unsigned queued:1;180180+};181181+#define to_dwc3_request(r) (container_of(r, struct dwc3_request, request))182182+183183+static inline struct dwc3_request *next_request(struct list_head *list)184184+{185185+ if (list_empty(list))186186+ return NULL;187187+188188+ return list_first_entry(list, struct dwc3_request, list);189189+}190190+191191+static inline void dwc3_gadget_move_request_queued(struct dwc3_request *req)192192+{193193+ struct dwc3_ep *dep = req->dep;194194+195195+ req->queued = true;196196+ list_move_tail(&req->list, &dep->req_queued);197197+}198198+199199+#if defined(CONFIG_USB_GADGET_DWC3) || defined(CONFIG_USB_GADGET_DWC3_MODULE)200200+int dwc3_gadget_init(struct dwc3 *dwc);201201+void dwc3_gadget_exit(struct dwc3 *dwc);202202+#else203203+static inline int dwc3_gadget_init(struct dwc3 *dwc) { return 0; }204204+static inline void dwc3_gadget_exit(struct dwc3 *dwc) { }205205+static inline int dwc3_send_gadget_ep_cmd(struct dwc3 *dwc, unsigned ep,206206+ unsigned cmd, struct dwc3_gadget_ep_cmd_params *params)207207+{208208+ return 0;209209+}210210+#endif211211+212212+void dwc3_gadget_giveback(struct dwc3_ep *dep, struct dwc3_request *req,213213+ int status);214214+215215+void dwc3_ep0_interrupt(struct dwc3 *dwc, const struct dwc3_event_depevt *event);216216+void dwc3_ep0_out_start(struct dwc3 *dwc);217217+int dwc3_gadget_ep0_queue(struct usb_ep *ep, struct usb_request *request,218218+ gfp_t gfp_flags);219219+int __dwc3_gadget_ep_set_halt(struct dwc3_ep *dep, int value);220220+int dwc3_send_gadget_ep_cmd(struct dwc3 *dwc, unsigned ep,221221+ unsigned cmd, struct dwc3_gadget_ep_cmd_params *params);222222+void dwc3_map_buffer_to_dma(struct dwc3_request *req);223223+void dwc3_unmap_buffer_from_dma(struct dwc3_request *req);224224+225225+/**226226+ * dwc3_gadget_ep_get_transfer_index - Gets transfer index from HW227227+ * @dwc: DesignWare USB3 Pointer228228+ * @number: DWC endpoint number229229+ *230230+ * Caller should take care of locking231231+ */232232+static inline u32 dwc3_gadget_ep_get_transfer_index(struct dwc3 *dwc, u8 number)233233+{234234+ u32 res_id;235235+236236+ res_id = dwc3_readl(dwc->regs, DWC3_DEPCMD(number));237237+238238+ return DWC3_DEPCMD_GET_RSC_IDX(res_id);239239+}240240+241241+/**242242+ * dwc3_gadget_event_string - returns event name243243+ * @event: the event code244244+ */245245+static inline const char *dwc3_gadget_event_string(u8 event)246246+{247247+ switch (event) {248248+ case DWC3_DEVICE_EVENT_DISCONNECT:249249+ return "Disconnect";250250+ case DWC3_DEVICE_EVENT_RESET:251251+ return "Reset";252252+ case DWC3_DEVICE_EVENT_CONNECT_DONE:253253+ return "Connection Done";254254+ case DWC3_DEVICE_EVENT_LINK_STATUS_CHANGE:255255+ return "Link Status Change";256256+ case DWC3_DEVICE_EVENT_WAKEUP:257257+ return "WakeUp";258258+ case DWC3_DEVICE_EVENT_EOPF:259259+ return "End-Of-Frame";260260+ case DWC3_DEVICE_EVENT_SOF:261261+ return "Start-Of-Frame";262262+ case DWC3_DEVICE_EVENT_ERRATIC_ERROR:263263+ return "Erratic Error";264264+ case DWC3_DEVICE_EVENT_CMD_CMPL:265265+ return "Command Complete";266266+ case DWC3_DEVICE_EVENT_OVERFLOW:267267+ return "Overflow";268268+ }269269+270270+ return "UNKNOWN";271271+}272272+273273+/**274274+ * dwc3_ep_event_string - returns event name275275+ * @event: then event code276276+ */277277+static inline const char *dwc3_ep_event_string(u8 event)278278+{279279+ switch (event) {280280+ case DWC3_DEPEVT_XFERCOMPLETE:281281+ return "Transfer Complete";282282+ case DWC3_DEPEVT_XFERINPROGRESS:283283+ return "Transfer In-Progress";284284+ case DWC3_DEPEVT_XFERNOTREADY:285285+ return "Transfer Not Ready";286286+ case DWC3_DEPEVT_RXTXFIFOEVT:287287+ return "FIFO";288288+ case DWC3_DEPEVT_STREAMEVT:289289+ return "Stream";290290+ case DWC3_DEPEVT_EPCMDCMPLT:291291+ return "Endpoint Command Complete";292292+ }293293+294294+ return "UNKNOWN";295295+}296296+297297+#endif /* __DRIVERS_USB_DWC3_GADGET_H */
+55
drivers/usb/dwc3/io.h
···11+/**22+ * io.h - DesignWare USB3 DRD IO Header33+ *44+ * Copyright (C) 2010-2011 Texas Instruments Incorporated - http://www.ti.com55+ * All rights reserved.66+ *77+ * Authors: Felipe Balbi <balbi@ti.com>,88+ * Sebastian Andrzej Siewior <bigeasy@linutronix.de>99+ *1010+ * Redistribution and use in source and binary forms, with or without1111+ * modification, are permitted provided that the following conditions1212+ * are met:1313+ * 1. Redistributions of source code must retain the above copyright1414+ * notice, this list of conditions, and the following disclaimer,1515+ * without modification.1616+ * 2. Redistributions in binary form must reproduce the above copyright1717+ * notice, this list of conditions and the following disclaimer in the1818+ * documentation and/or other materials provided with the distribution.1919+ * 3. The names of the above-listed copyright holders may not be used2020+ * to endorse or promote products derived from this software without2121+ * specific prior written permission.2222+ *2323+ * ALTERNATIVELY, this software may be distributed under the terms of the2424+ * GNU General Public License ("GPL") version 2, as published by the Free2525+ * Software Foundation.2626+ *2727+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS2828+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,2929+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR3030+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR3131+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,3232+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,3333+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR3434+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF3535+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING3636+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS3737+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.3838+ */3939+4040+#ifndef __DRIVERS_USB_DWC3_IO_H4141+#define __DRIVERS_USB_DWC3_IO_H4242+4343+#include <asm/io.h>4444+4545+static inline u32 dwc3_readl(void __iomem *base, u32 offset)4646+{4747+ return readl(base + offset);4848+}4949+5050+static inline void dwc3_writel(void __iomem *base, u32 offset, u32 value)5151+{5252+ writel(value, base + offset);5353+}5454+5555+#endif /* __DRIVERS_USB_DWC3_IO_H */
+16-5
drivers/usb/gadget/Kconfig
···255255 integrated into the S3C64XX series SoC.256256257257config USB_IMX258258- tristate "Freescale IMX USB Peripheral Controller"259259- depends on ARCH_MX1258258+ tristate "Freescale i.MX1 USB Peripheral Controller"259259+ depends on ARCH_MXC260260 help261261- Freescale's IMX series include an integrated full speed262262- USB 1.1 device controller. The controller in the IMX series263263- is register-compatible.261261+ Freescale's i.MX1 includes an integrated full speed262262+ USB 1.1 device controller.264263265264 It has Six fixed-function endpoints, as well as endpoint266265 zero (for control transfers).···301302 help302303 PXA9xx Processor series include a high speed USB2.0 device303304 controller, which support high speed and full speed USB peripheral.305305+306306+config USB_GADGET_DWC3307307+ tristate "DesignWare USB3.0 (DRD) Controller"308308+ depends on USB_DWC3309309+ select USB_GADGET_DUALSPEED310310+ select USB_GADGET_SUPERSPEED311311+ help312312+ DesignWare USB3.0 controller is a SuperSpeed USB3.0 Controller313313+ which can be configured for peripheral-only, host-only, hub-only314314+ and Dual-Role operation. This Controller was first integrated into315315+ the OMAP5 series of processors. More information about the OMAP5316316+ version of this controller, refer to http://www.ti.com/omap5.304317305318#306319# Controllers available in both integrated and discrete versions
···439439 * maximum packet size.440440 * For SS devices the wMaxPacketSize is limited by 1024.441441 */442442- max = le16_to_cpu(desc->wMaxPacketSize) & 0x7ff;442442+ max = usb_endpoint_maxp(desc) & 0x7ff;443443444444 /* drivers must not request bad settings, since lower levels445445 * (hardware or its drivers) may not check. some endpoints···12771277 int tmp;1278127812791279 /* high bandwidth mode */12801280- tmp = le16_to_cpu(ep->desc->wMaxPacketSize);12801280+ tmp = usb_endpoint_maxp(ep->desc);12811281 tmp = (tmp >> 11) & 0x03;12821282 tmp *= 8 /* applies to entire frame */;12831283 limit += limit * tmp;
+1-1
drivers/usb/gadget/epautoconf.c
···158158 * where it's an output parameter representing the full speed limit.159159 * the usb spec fixes high speed bulk maxpacket at 512 bytes.160160 */161161- max = 0x7ff & le16_to_cpu(desc->wMaxPacketSize);161161+ max = 0x7ff & usb_endpoint_maxp(desc);162162 switch (type) {163163 case USB_ENDPOINT_XFER_INT:164164 /* INT: limit 64 bytes full speed, 1024 high/super speed */
···540540 int reval = 0;541541 u16 max = 0;542542543543- max = le16_to_cpu(desc->wMaxPacketSize);543543+ max = usb_endpoint_maxp(desc);544544545545 /* check the max package size validate for this endpoint */546546 /* Refer to USB2.0 spec table 9-13,
+1-1
drivers/usb/gadget/fsl_udc_core.c
···559559 if (!udc->driver || (udc->gadget.speed == USB_SPEED_UNKNOWN))560560 return -ESHUTDOWN;561561562562- max = le16_to_cpu(desc->wMaxPacketSize);562562+ max = usb_endpoint_maxp(desc);563563564564 /* Disable automatic zlp generation. Driver is responsible to indicate565565 * explicitly through req->req.zero. This is needed to enable multi-td
···493493 return -ESHUTDOWN;494494495495 direction = ep_dir(ep);496496- max = le16_to_cpu(desc->wMaxPacketSize);496496+ max = usb_endpoint_maxp(desc);497497498498 /*499499 * disable HW zero length termination select
+1-1
drivers/usb/gadget/net2272.c
···204204 if (!dev->driver || dev->gadget.speed == USB_SPEED_UNKNOWN)205205 return -ESHUTDOWN;206206207207- max = le16_to_cpu(desc->wMaxPacketSize) & 0x1fff;207207+ max = usb_endpoint_maxp(desc) & 0x1fff;208208209209 spin_lock_irqsave(&dev->lock, flags);210210 _ep->maxpacket = max & 0x7fff;
+2-2
drivers/usb/gadget/net2280.c
···169169 return -EDOM;170170171171 /* sanity check ep-e/ep-f since their fifos are small */172172- max = le16_to_cpu (desc->wMaxPacketSize) & 0x1fff;172172+ max = usb_endpoint_maxp (desc) & 0x1fff;173173 if (ep->num > 4 && max > 64)174174 return -ERANGE;175175···16401640 default:16411641 val = "iso"; break;16421642 }; val; }),16431643- le16_to_cpu (d->wMaxPacketSize) & 0x1fff,16431643+ usb_endpoint_maxp (d) & 0x1fff,16441644 ep->dma ? "dma" : "pio", ep->fifo_size16451645 );16461646 } else /* ep0 should only have one transfer queued */
···22972297 return -EINVAL;22982298 }2299229923002300- mps = le16_to_cpu(desc->wMaxPacketSize);23002300+ mps = usb_endpoint_maxp(desc);2301230123022302 /* note, we handle this here instead of s3c_hsotg_set_ep_maxpacket */23032303
···10821082 if (!dev->driver || dev->gadget.speed == USB_SPEED_UNKNOWN)10831083 return -ESHUTDOWN;1084108410851085- max = le16_to_cpu(desc->wMaxPacketSize) & 0x1fff;10851085+ max = usb_endpoint_maxp(desc) & 0x1fff;1086108610871087 local_irq_save (flags);10881088 _ep->maxpacket = max & 0x7ff;
+10-3
drivers/usb/host/Kconfig
···544544 will be called "hwa-hc".545545546546config USB_IMX21_HCD547547- tristate "iMX21 HCD support"548548- depends on USB && ARM && MACH_MX21547547+ tristate "i.MX21 HCD support"548548+ depends on USB && ARM && ARCH_MXC549549 help550550 This driver enables support for the on-chip USB host in the551551- iMX21 processor.551551+ i.MX21 processor.552552553553 To compile this driver as a module, choose M here: the554554 module will be called "imx21-hcd".···578578config USB_OCTEON2_COMMON579579 bool580580 default y if USB_OCTEON_EHCI || USB_OCTEON_OHCI581581+582582+config USB_PXA168_EHCI583583+ bool "Marvell PXA168 on-chip EHCI HCD support"584584+ depends on USB_EHCI_HCD && ARCH_MMP585585+ help586586+ Enable support for Marvell PXA168 SoC's on-chip EHCI587587+ host controller
+1-1
drivers/usb/host/ehci-au1xxx.c
···293293 /* here we "know" root ports should always stay powered */294294 ehci_port_power(ehci, 1);295295296296- hcd->state = HC_STATE_SUSPENDED;296296+ ehci->rh_state = EHCI_RH_SUSPENDED;297297298298 return 0;299299}
+15-2
drivers/usb/host/ehci-dbg.c
···697697}698698#undef DBG_SCHED_LIMIT699699700700+static const char *rh_state_string(struct ehci_hcd *ehci)701701+{702702+ switch (ehci->rh_state) {703703+ case EHCI_RH_HALTED:704704+ return "halted";705705+ case EHCI_RH_SUSPENDED:706706+ return "suspended";707707+ case EHCI_RH_RUNNING:708708+ return "running";709709+ }710710+ return "?";711711+}712712+700713static ssize_t fill_registers_buffer(struct debug_buffer *buf)701714{702715 struct usb_hcd *hcd;···743730 temp = scnprintf (next, size,744731 "bus %s, device %s\n"745732 "%s\n"746746- "EHCI %x.%02x, hcd state %d\n",733733+ "EHCI %x.%02x, rh state %s\n",747734 hcd->self.controller->bus->name,748735 dev_name(hcd->self.controller),749736 hcd->product_desc,750750- i >> 8, i & 0x0ff, hcd->state);737737+ i >> 8, i & 0x0ff, rh_state_string(ehci));751738 size -= temp;752739 next += temp;753740
···238238 error = handshake(ehci, ptr, mask, done, usec);239239 if (error) {240240 ehci_halt(ehci);241241- ehci_to_hcd(ehci)->state = HC_STATE_HALT;241241+ ehci->rh_state = EHCI_RH_HALTED;242242 ehci_err(ehci, "force halt; handshake %p %08x %08x -> %d\n",243243 ptr, mask, done, error);244244 }···278278 command |= CMD_RESET;279279 dbg_cmd (ehci, "reset", command);280280 ehci_writel(ehci, command, &ehci->regs->command);281281- ehci_to_hcd(ehci)->state = HC_STATE_HALT;281281+ ehci->rh_state = EHCI_RH_HALTED;282282 ehci->next_statechange = jiffies;283283 retval = handshake (ehci, &ehci->regs->command,284284 CMD_RESET, 0, 250 * 1000);···307307 u32 temp;308308309309#ifdef DEBUG310310- if (!HC_IS_RUNNING (ehci_to_hcd(ehci)->state))310310+ if (ehci->rh_state != EHCI_RH_RUNNING)311311 BUG ();312312#endif313313···356356 */357357 if (ehci->reclaim358358 && !timer_pending(&ehci->iaa_watchdog)359359- && HC_IS_RUNNING(ehci_to_hcd(ehci)->state)) {359359+ && ehci->rh_state == EHCI_RH_RUNNING) {360360 u32 cmd, status;361361362362 /* If we get here, IAA is *REALLY* late. It's barely···496496 * misplace IRQs, and should let us run completely without IRQs.497497 * such lossage has been observed on both VT6202 and VT8235.498498 */499499- if (HC_IS_RUNNING (ehci_to_hcd(ehci)->state) &&499499+ if (ehci->rh_state == EHCI_RH_RUNNING &&500500 (ehci->async->qh_next.ptr != NULL ||501501 ehci->periodic_sched != 0))502502 timer_action (ehci, TIMER_IO_WATCHDOG);···516516 del_timer_sync(&ehci->iaa_watchdog);517517518518 spin_lock_irq(&ehci->lock);519519- if (HC_IS_RUNNING (hcd->state))519519+ if (ehci->rh_state == EHCI_RH_RUNNING)520520 ehci_quiesce (ehci);521521522522 ehci_silence_controller(ehci);···741741 * be started before the port switching actions could complete.742742 */743743 down_write(&ehci_cf_port_reset_rwsem);744744- hcd->state = HC_STATE_RUNNING;744744+ ehci->rh_state = EHCI_RH_RUNNING;745745 ehci_writel(ehci, FLAG_CF, &ehci->regs->configured_flag);746746 ehci_readl(ehci, &ehci->regs->command); /* unblock posted writes */747747 msleep(5);···788788789789 /* Shared IRQ? */790790 masked_status = status & INTR_MASK;791791- if (!masked_status || unlikely(hcd->state == HC_STATE_HALT)) {791791+ if (!masked_status || unlikely(ehci->rh_state == EHCI_RH_HALTED)) {792792 spin_unlock(&ehci->lock);793793 return IRQ_NONE;794794 }···952952static void unlink_async (struct ehci_hcd *ehci, struct ehci_qh *qh)953953{954954 /* failfast */955955- if (!HC_IS_RUNNING(ehci_to_hcd(ehci)->state) && ehci->reclaim)955955+ if (ehci->rh_state != EHCI_RH_RUNNING && ehci->reclaim)956956 end_unlink_async(ehci);957957958958 /* If the QH isn't linked then there's nothing we can do···10791079 goto idle_timeout;10801080 }1081108110821082- if (!HC_IS_RUNNING (hcd->state))10821082+ if (ehci->rh_state != EHCI_RH_RUNNING)10831083 qh->qh_state = QH_STATE_IDLE;10841084 switch (qh->qh_state) {10851085 case QH_STATE_LINKED:···12891289#ifdef CONFIG_SPARC_LEON12901290#include "ehci-grlib.c"12911291#define PLATFORM_DRIVER ehci_grlib_driver12921292+#endif12931293+12941294+#ifdef CONFIG_USB_PXA168_EHCI12951295+#include "ehci-pxa168.c"12961296+#define PLATFORM_DRIVER ehci_pxa168_driver12971297+#endif12981298+12991299+#ifdef CONFIG_NLM_XLR13001300+#include "ehci-xls.c"13011301+#define PLATFORM_DRIVER ehci_xls_driver12921302#endif1293130312941304#if !defined(PCI_DRIVER) && !defined(PLATFORM_DRIVER) && \
+4-6
drivers/usb/host/ehci-hub.c
···236236 }237237238238 /* stop schedules, clean any completed work */239239- if (HC_IS_RUNNING(hcd->state)) {239239+ if (ehci->rh_state == EHCI_RH_RUNNING)240240 ehci_quiesce (ehci);241241- hcd->state = HC_STATE_QUIESCING;242242- }243241 ehci->command = ehci_readl(ehci, &ehci->regs->command);244242 ehci_work(ehci);245243···311313312314 /* turn off now-idle HC */313315 ehci_halt (ehci);314314- hcd->state = HC_STATE_SUSPENDED;316316+ ehci->rh_state = EHCI_RH_SUSPENDED;315317316318 if (ehci->reclaim)317319 end_unlink_async(ehci);···380382381383 /* restore CMD_RUN, framelist size, and irq threshold */382384 ehci_writel(ehci, ehci->command, &ehci->regs->command);385385+ ehci->rh_state = EHCI_RH_RUNNING;383386384387 /* Some controller/firmware combinations need a delay during which385388 * they set up the port statuses. See Bugzilla #8190. */···450451 }451452452453 ehci->next_statechange = jiffies + msecs_to_jiffies(5);453453- hcd->state = HC_STATE_RUNNING;454454455455 /* Now we can safely re-enable irqs */456456 ehci_writel(ehci, INTR_MASK, &ehci->regs->intr_enable);···561563 u32 ppcd = 0;562564563565 /* if !USB_SUSPEND, root hub timers won't get shut down ... */564564- if (!HC_IS_RUNNING(hcd->state))566566+ if (ehci->rh_state != EHCI_RH_RUNNING)565567 return 0;566568567569 /* init status to no-changes */
+1-1
drivers/usb/host/ehci-pci.c
···439439 /* here we "know" root ports should always stay powered */440440 ehci_port_power(ehci, 1);441441442442- hcd->state = HC_STATE_SUSPENDED;442442+ ehci->rh_state = EHCI_RH_SUSPENDED;443443 return 0;444444}445445#endif
+363
drivers/usb/host/ehci-pxa168.c
···11+/*22+ * drivers/usb/host/ehci-pxa168.c33+ *44+ * Tanmay Upadhyay <tanmay.upadhyay@einfochips.com>55+ *66+ * Based on drivers/usb/host/ehci-orion.c77+ *88+ * This file is licensed under the terms of the GNU General Public99+ * License version 2. This program is licensed "as is" without any1010+ * warranty of any kind, whether express or implied.1111+ */1212+1313+#include <linux/kernel.h>1414+#include <linux/module.h>1515+#include <linux/platform_device.h>1616+#include <linux/clk.h>1717+#include <mach/pxa168.h>1818+1919+#define USB_PHY_CTRL_REG 0x42020+#define USB_PHY_PLL_REG 0x82121+#define USB_PHY_TX_REG 0xc2222+2323+#define FBDIV_SHIFT 42424+2525+#define ICP_SHIFT 122626+#define ICP_15 22727+#define ICP_20 32828+#define ICP_25 42929+3030+#define KVCO_SHIFT 153131+3232+#define PLLCALI12_SHIFT 253333+#define CALI12_VDD 03434+#define CALI12_09 13535+#define CALI12_10 23636+#define CALI12_11 33737+3838+#define PLLVDD12_SHIFT 273939+#define VDD12_VDD 04040+#define VDD12_10 14141+#define VDD12_11 24242+#define VDD12_12 34343+4444+#define PLLVDD18_SHIFT 294545+#define VDD18_19 04646+#define VDD18_20 14747+#define VDD18_21 24848+#define VDD18_22 34949+5050+5151+#define PLL_READY (1 << 23)5252+#define VCOCAL_START (1 << 21)5353+#define REG_RCAL_START (1 << 12)5454+5555+struct pxa168_usb_drv_data {5656+ struct ehci_hcd ehci;5757+ struct clk *pxa168_usb_clk;5858+ struct resource *usb_phy_res;5959+ void __iomem *usb_phy_reg_base;6060+};6161+6262+static int ehci_pxa168_setup(struct usb_hcd *hcd)6363+{6464+ struct ehci_hcd *ehci = hcd_to_ehci(hcd);6565+ int retval;6666+6767+ ehci_reset(ehci);6868+ retval = ehci_halt(ehci);6969+ if (retval)7070+ return retval;7171+7272+ /*7373+ * data structure init7474+ */7575+ retval = ehci_init(hcd);7676+ if (retval)7777+ return retval;7878+7979+ hcd->has_tt = 1;8080+8181+ ehci_port_power(ehci, 0);8282+8383+ return retval;8484+}8585+8686+static const struct hc_driver ehci_pxa168_hc_driver = {8787+ .description = hcd_name,8888+ .product_desc = "Marvell PXA168 EHCI",8989+ .hcd_priv_size = sizeof(struct pxa168_usb_drv_data),9090+9191+ /*9292+ * generic hardware linkage9393+ */9494+ .irq = ehci_irq,9595+ .flags = HCD_MEMORY | HCD_USB2,9696+9797+ /*9898+ * basic lifecycle operations9999+ */100100+ .reset = ehci_pxa168_setup,101101+ .start = ehci_run,102102+ .stop = ehci_stop,103103+ .shutdown = ehci_shutdown,104104+105105+ /*106106+ * managing i/o requests and associated device resources107107+ */108108+ .urb_enqueue = ehci_urb_enqueue,109109+ .urb_dequeue = ehci_urb_dequeue,110110+ .endpoint_disable = ehci_endpoint_disable,111111+ .endpoint_reset = ehci_endpoint_reset,112112+113113+ /*114114+ * scheduling support115115+ */116116+ .get_frame_number = ehci_get_frame,117117+118118+ /*119119+ * root hub support120120+ */121121+ .hub_status_data = ehci_hub_status_data,122122+ .hub_control = ehci_hub_control,123123+ .bus_suspend = ehci_bus_suspend,124124+ .bus_resume = ehci_bus_resume,125125+ .relinquish_port = ehci_relinquish_port,126126+ .port_handed_over = ehci_port_handed_over,127127+128128+ .clear_tt_buffer_complete = ehci_clear_tt_buffer_complete,129129+};130130+131131+static int pxa168_usb_phy_init(struct platform_device *pdev)132132+{133133+ struct resource *res;134134+ void __iomem *usb_phy_reg_base;135135+ struct pxa168_usb_pdata *pdata;136136+ struct pxa168_usb_drv_data *drv_data;137137+ struct usb_hcd *hcd = platform_get_drvdata(pdev);138138+ unsigned long reg_val;139139+ int pll_retry_cont = 10000, err = 0;140140+141141+ drv_data = (struct pxa168_usb_drv_data *)hcd->hcd_priv;142142+ pdata = (struct pxa168_usb_pdata *)pdev->dev.platform_data;143143+144144+ res = platform_get_resource(pdev, IORESOURCE_MEM, 1);145145+ if (!res) {146146+ dev_err(&pdev->dev,147147+ "Found HC with no PHY register addr. Check %s setup!\n",148148+ dev_name(&pdev->dev));149149+ return -ENODEV;150150+ }151151+152152+ if (!request_mem_region(res->start, resource_size(res),153153+ ehci_pxa168_hc_driver.description)) {154154+ dev_dbg(&pdev->dev, "controller already in use\n");155155+ return -EBUSY;156156+ }157157+158158+ usb_phy_reg_base = ioremap(res->start, resource_size(res));159159+ if (usb_phy_reg_base == NULL) {160160+ dev_dbg(&pdev->dev, "error mapping memory\n");161161+ err = -EFAULT;162162+ goto err1;163163+ }164164+ drv_data->usb_phy_reg_base = usb_phy_reg_base;165165+ drv_data->usb_phy_res = res;166166+167167+ /* If someone wants to init USB phy in board specific way */168168+ if (pdata && pdata->phy_init)169169+ return pdata->phy_init(usb_phy_reg_base);170170+171171+ /* Power up the PHY and PLL */172172+ writel(readl(usb_phy_reg_base + USB_PHY_CTRL_REG) | 0x3,173173+ usb_phy_reg_base + USB_PHY_CTRL_REG);174174+175175+ /* Configure PHY PLL */176176+ reg_val = readl(usb_phy_reg_base + USB_PHY_PLL_REG) & ~(0x7e03ffff);177177+ reg_val |= (VDD18_22 << PLLVDD18_SHIFT | VDD12_12 << PLLVDD12_SHIFT |178178+ CALI12_11 << PLLCALI12_SHIFT | 3 << KVCO_SHIFT |179179+ ICP_15 << ICP_SHIFT | 0xee << FBDIV_SHIFT | 0xb);180180+ writel(reg_val, usb_phy_reg_base + USB_PHY_PLL_REG);181181+182182+ /* Make sure PHY PLL is ready */183183+ while (!(readl(usb_phy_reg_base + USB_PHY_PLL_REG) & PLL_READY)) {184184+ if (!(pll_retry_cont--)) {185185+ dev_dbg(&pdev->dev, "USB PHY PLL not ready\n");186186+ err = -EIO;187187+ goto err2;188188+ }189189+ }190190+191191+ /* Toggle VCOCAL_START bit of U2PLL for PLL calibration */192192+ udelay(200);193193+ writel(readl(usb_phy_reg_base + USB_PHY_PLL_REG) | VCOCAL_START,194194+ usb_phy_reg_base + USB_PHY_PLL_REG);195195+ udelay(40);196196+ writel(readl(usb_phy_reg_base + USB_PHY_PLL_REG) & ~VCOCAL_START,197197+ usb_phy_reg_base + USB_PHY_PLL_REG);198198+199199+ /* Toggle REG_RCAL_START bit of U2PTX for impedance calibration */200200+ udelay(400);201201+ writel(readl(usb_phy_reg_base + USB_PHY_TX_REG) | REG_RCAL_START,202202+ usb_phy_reg_base + USB_PHY_TX_REG);203203+ udelay(40);204204+ writel(readl(usb_phy_reg_base + USB_PHY_TX_REG) & ~REG_RCAL_START,205205+ usb_phy_reg_base + USB_PHY_TX_REG);206206+207207+ /* Make sure PHY PLL is ready again */208208+ pll_retry_cont = 0;209209+ while (!(readl(usb_phy_reg_base + USB_PHY_PLL_REG) & PLL_READY)) {210210+ if (!(pll_retry_cont--)) {211211+ dev_dbg(&pdev->dev, "USB PHY PLL not ready\n");212212+ err = -EIO;213213+ goto err2;214214+ }215215+ }216216+217217+ return 0;218218+err2:219219+ iounmap(usb_phy_reg_base);220220+err1:221221+ release_mem_region(res->start, resource_size(res));222222+ return err;223223+}224224+225225+static int __devinit ehci_pxa168_drv_probe(struct platform_device *pdev)226226+{227227+ struct resource *res;228228+ struct usb_hcd *hcd;229229+ struct ehci_hcd *ehci;230230+ struct pxa168_usb_drv_data *drv_data;231231+ void __iomem *regs;232232+ int irq, err = 0;233233+234234+ if (usb_disabled())235235+ return -ENODEV;236236+237237+ pr_debug("Initializing pxa168-SoC USB Host Controller\n");238238+239239+ irq = platform_get_irq(pdev, 0);240240+ if (irq <= 0) {241241+ dev_err(&pdev->dev,242242+ "Found HC with no IRQ. Check %s setup!\n",243243+ dev_name(&pdev->dev));244244+ err = -ENODEV;245245+ goto err1;246246+ }247247+248248+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);249249+ if (!res) {250250+ dev_err(&pdev->dev,251251+ "Found HC with no register addr. Check %s setup!\n",252252+ dev_name(&pdev->dev));253253+ err = -ENODEV;254254+ goto err1;255255+ }256256+257257+ if (!request_mem_region(res->start, resource_size(res),258258+ ehci_pxa168_hc_driver.description)) {259259+ dev_dbg(&pdev->dev, "controller already in use\n");260260+ err = -EBUSY;261261+ goto err1;262262+ }263263+264264+ regs = ioremap(res->start, resource_size(res));265265+ if (regs == NULL) {266266+ dev_dbg(&pdev->dev, "error mapping memory\n");267267+ err = -EFAULT;268268+ goto err2;269269+ }270270+271271+ hcd = usb_create_hcd(&ehci_pxa168_hc_driver,272272+ &pdev->dev, dev_name(&pdev->dev));273273+ if (!hcd) {274274+ err = -ENOMEM;275275+ goto err3;276276+ }277277+278278+ drv_data = (struct pxa168_usb_drv_data *)hcd->hcd_priv;279279+280280+ /* Enable USB clock */281281+ drv_data->pxa168_usb_clk = clk_get(&pdev->dev, "PXA168-USBCLK");282282+ if (IS_ERR(drv_data->pxa168_usb_clk)) {283283+ dev_err(&pdev->dev, "Couldn't get USB clock\n");284284+ err = PTR_ERR(drv_data->pxa168_usb_clk);285285+ goto err4;286286+ }287287+ clk_enable(drv_data->pxa168_usb_clk);288288+289289+ err = pxa168_usb_phy_init(pdev);290290+ if (err) {291291+ dev_err(&pdev->dev, "USB PHY initialization failed\n");292292+ goto err5;293293+ }294294+295295+ hcd->rsrc_start = res->start;296296+ hcd->rsrc_len = resource_size(res);297297+ hcd->regs = regs;298298+299299+ ehci = hcd_to_ehci(hcd);300300+ ehci->caps = hcd->regs + 0x100;301301+ ehci->regs = hcd->regs + 0x100 +302302+ HC_LENGTH(ehci_readl(ehci, &ehci->caps->hc_capbase));303303+ ehci->hcs_params = ehci_readl(ehci, &ehci->caps->hcs_params);304304+ hcd->has_tt = 1;305305+ ehci->sbrn = 0x20;306306+307307+ err = usb_add_hcd(hcd, irq, IRQF_SHARED | IRQF_DISABLED);308308+ if (err)309309+ goto err5;310310+311311+ return 0;312312+313313+err5:314314+ clk_disable(drv_data->pxa168_usb_clk);315315+ clk_put(drv_data->pxa168_usb_clk);316316+err4:317317+ usb_put_hcd(hcd);318318+err3:319319+ iounmap(regs);320320+err2:321321+ release_mem_region(res->start, resource_size(res));322322+err1:323323+ dev_err(&pdev->dev, "init %s fail, %d\n",324324+ dev_name(&pdev->dev), err);325325+326326+ return err;327327+}328328+329329+static int __exit ehci_pxa168_drv_remove(struct platform_device *pdev)330330+{331331+ struct usb_hcd *hcd = platform_get_drvdata(pdev);332332+ struct pxa168_usb_drv_data *drv_data =333333+ (struct pxa168_usb_drv_data *)hcd->hcd_priv;334334+335335+ usb_remove_hcd(hcd);336336+337337+ /* Power down PHY & PLL */338338+ writel(readl(drv_data->usb_phy_reg_base + USB_PHY_CTRL_REG) & (~0x3),339339+ drv_data->usb_phy_reg_base + USB_PHY_CTRL_REG);340340+341341+ clk_disable(drv_data->pxa168_usb_clk);342342+ clk_put(drv_data->pxa168_usb_clk);343343+344344+ iounmap(hcd->regs);345345+ release_mem_region(hcd->rsrc_start, hcd->rsrc_len);346346+347347+ iounmap(drv_data->usb_phy_reg_base);348348+ release_mem_region(drv_data->usb_phy_res->start,349349+ resource_size(drv_data->usb_phy_res));350350+351351+ usb_put_hcd(hcd);352352+353353+ return 0;354354+}355355+356356+MODULE_ALIAS("platform:pxa168-ehci");357357+358358+static struct platform_driver ehci_pxa168_driver = {359359+ .probe = ehci_pxa168_drv_probe,360360+ .remove = __exit_p(ehci_pxa168_drv_remove),361361+ .shutdown = usb_hcd_platform_shutdown,362362+ .driver.name = "pxa168-ehci",363363+};
+10-12
drivers/usb/host/ehci-q.c
···153153 spin_lock_irqsave(&ehci->lock, flags);154154 qh->clearing_tt = 0;155155 if (qh->qh_state == QH_STATE_IDLE && !list_empty(&qh->qtd_list)156156- && HC_IS_RUNNING(hcd->state))156156+ && ehci->rh_state == EHCI_RH_RUNNING)157157 qh_link_async(ehci, qh);158158 spin_unlock_irqrestore(&ehci->lock, flags);159159}···425425426426 /* stop scanning when we reach qtds the hc is using */427427 } else if (likely (!stopped428428- && HC_IS_RUNNING (ehci_to_hcd(ehci)->state))) {428428+ && ehci->rh_state == EHCI_RH_RUNNING)) {429429 break;430430431431 /* scan the whole queue for unlinks whenever it stops */···433433 stopped = 1;434434435435 /* cancel everything if we halt, suspend, etc */436436- if (!HC_IS_RUNNING(ehci_to_hcd(ehci)->state))436436+ if (ehci->rh_state != EHCI_RH_RUNNING)437437 last_status = -ESHUTDOWN;438438439439 /* this qtd is active; skip it unless a previous qtd···977977 /* in case a clear of CMD_ASE didn't take yet */978978 (void)handshake(ehci, &ehci->regs->status,979979 STS_ASS, 0, 150);980980- cmd |= CMD_ASE | CMD_RUN;980980+ cmd |= CMD_ASE;981981 ehci_writel(ehci, cmd, &ehci->regs->command);982982- ehci_to_hcd(ehci)->state = HC_STATE_RUNNING;983982 /* posted write need not be known to HC yet ... */984983 }985984 }···1167116811681169 qh_completions (ehci, qh);1169117011701170- if (!list_empty (&qh->qtd_list)11711171- && HC_IS_RUNNING (ehci_to_hcd(ehci)->state))11711171+ if (!list_empty(&qh->qtd_list) && ehci->rh_state == EHCI_RH_RUNNING) {11721172 qh_link_async (ehci, qh);11731173- else {11731173+ } else {11741174 /* it's not free to turn the async schedule on/off; leave it11751175 * active but idle for a while once it empties.11761176 */11771177- if (HC_IS_RUNNING (ehci_to_hcd(ehci)->state)11771177+ if (ehci->rh_state == EHCI_RH_RUNNING11781178 && ehci->async->qh_next.qh == NULL)11791179 timer_action (ehci, TIMER_ASYNC_OFF);11801180 }···12091211 /* stop async schedule right now? */12101212 if (unlikely (qh == ehci->async)) {12111213 /* can't get here without STS_ASS set */12121212- if (ehci_to_hcd(ehci)->state != HC_STATE_HALT12141214+ if (ehci->rh_state != EHCI_RH_HALTED12131215 && !ehci->reclaim) {12141216 /* ... and CMD_IAAD clear */12151217 ehci_writel(ehci, cmd & ~CMD_ASE,···12351237 wmb ();1236123812371239 /* If the controller isn't running, we don't have to wait for it */12381238- if (unlikely(!HC_IS_RUNNING(ehci_to_hcd(ehci)->state))) {12401240+ if (unlikely(ehci->rh_state != EHCI_RH_RUNNING)) {12391241 /* if (unlikely (qh->reclaim != 0))12401242 * this will recurse, probably not much12411243 */···12581260 enum ehci_timer_action action = TIMER_IO_WATCHDOG;1259126112601262 timer_action_done (ehci, TIMER_ASYNC_SHRINK);12611261- stopped = !HC_IS_RUNNING(ehci_to_hcd(ehci)->state);12631263+ stopped = (ehci->rh_state != EHCI_RH_RUNNING);1262126412631265 ehci->qh_scan_next = ehci->async->qh_next.qh;12641266 while (ehci->qh_scan_next) {
+1-1
drivers/usb/host/ehci-s5p.c
···270270 /* here we "know" root ports should always stay powered */271271 ehci_port_power(ehci, 1);272272273273- hcd->state = HC_STATE_SUSPENDED;273273+ ehci->rh_state = EHCI_RH_SUSPENDED;274274275275 return 0;276276}
+5-6
drivers/usb/host/ehci-sched.c
···479479 cmd = ehci_readl(ehci, &ehci->regs->command) | CMD_PSE;480480 ehci_writel(ehci, cmd, &ehci->regs->command);481481 /* posted write ... PSS happens later */482482- ehci_to_hcd(ehci)->state = HC_STATE_RUNNING;483482484483 /* make sure ehci_work scans these */485484 ehci->next_uframe = ehci_readl(ehci, &ehci->regs->frame_index)···676677677678 /* reschedule QH iff another request is queued */678679 if (!list_empty(&qh->qtd_list) &&679679- HC_IS_RUNNING(ehci_to_hcd(ehci)->state)) {680680+ ehci->rh_state == EHCI_RH_RUNNING) {680681 rc = qh_schedule(ehci, qh);681682682683 /* An error here likely indicates handshake failure···22742275 * Touches as few pages as possible: cache-friendly.22752276 */22762277 now_uframe = ehci->next_uframe;22772277- if (HC_IS_RUNNING(ehci_to_hcd(ehci)->state)) {22782278+ if (ehci->rh_state == EHCI_RH_RUNNING) {22782279 clock = ehci_readl(ehci, &ehci->regs->frame_index);22792280 clock_frame = (clock >> 3) & (ehci->periodic_size - 1);22802281 } else {···23092310 union ehci_shadow temp;23102311 int live;2311231223122312- live = HC_IS_RUNNING (ehci_to_hcd(ehci)->state);23132313+ live = (ehci->rh_state == EHCI_RH_RUNNING);23132314 switch (hc32_to_cpu(ehci, type)) {23142315 case Q_TYPE_QH:23152316 /* handle any completions */···24342435 * We can't advance our scan without collecting the ISO24352436 * transfers that are still pending in this frame.24362437 */24372437- if (incomplete && HC_IS_RUNNING(ehci_to_hcd(ehci)->state)) {24382438+ if (incomplete && ehci->rh_state == EHCI_RH_RUNNING) {24382439 ehci->next_uframe = now_uframe;24392440 break;24402441 }···24502451 if (now_uframe == clock) {24512452 unsigned now;2452245324532453- if (!HC_IS_RUNNING (ehci_to_hcd(ehci)->state)24542454+ if (ehci->rh_state != EHCI_RH_RUNNING24542455 || ehci->periodic_sched == 0)24552456 break;24562457 ehci->next_uframe = now_uframe;
+161
drivers/usb/host/ehci-xls.c
···11+/*22+ * EHCI HCD for Netlogic XLS processors.33+ *44+ * (C) Copyright 2011 Netlogic Microsystems Inc.55+ *66+ * Based on various ehci-*.c drivers77+ *88+ * This file is subject to the terms and conditions of the GNU General Public99+ * License. See the file COPYING in the main directory of this archive for1010+ * more details.1111+ */1212+1313+#include <linux/platform_device.h>1414+1515+static int ehci_xls_setup(struct usb_hcd *hcd)1616+{1717+ int retval;1818+ struct ehci_hcd *ehci = hcd_to_ehci(hcd);1919+2020+ ehci->caps = hcd->regs;2121+ ehci->regs = hcd->regs +2222+ HC_LENGTH(ehci_readl(ehci, &ehci->caps->hc_capbase));2323+ dbg_hcs_params(ehci, "reset");2424+ dbg_hcc_params(ehci, "reset");2525+2626+ /* cache this readonly data; minimize chip reads */2727+ ehci->hcs_params = ehci_readl(ehci, &ehci->caps->hcs_params);2828+2929+ retval = ehci_halt(ehci);3030+ if (retval)3131+ return retval;3232+3333+ /* data structure init */3434+ retval = ehci_init(hcd);3535+ if (retval)3636+ return retval;3737+3838+ ehci_reset(ehci);3939+4040+ return retval;4141+}4242+4343+int ehci_xls_probe_internal(const struct hc_driver *driver,4444+ struct platform_device *pdev)4545+{4646+ struct usb_hcd *hcd;4747+ struct resource *res;4848+ int retval, irq;4949+5050+ /* Get our IRQ from an earlier registered Platform Resource */5151+ irq = platform_get_irq(pdev, 0);5252+ if (irq < 0) {5353+ dev_err(&pdev->dev, "Found HC with no IRQ. Check %s setup!\n",5454+ dev_name(&pdev->dev));5555+ return -ENODEV;5656+ }5757+5858+ /* Get our Memory Handle */5959+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);6060+ if (!res) {6161+ dev_err(&pdev->dev, "Error: MMIO Handle %s setup!\n",6262+ dev_name(&pdev->dev));6363+ return -ENODEV;6464+ }6565+ hcd = usb_create_hcd(driver, &pdev->dev, dev_name(&pdev->dev));6666+ if (!hcd) {6767+ retval = -ENOMEM;6868+ goto err1;6969+ }7070+7171+ hcd->rsrc_start = res->start;7272+ hcd->rsrc_len = res->end - res->start + 1;7373+7474+ if (!request_mem_region(hcd->rsrc_start, hcd->rsrc_len,7575+ driver->description)) {7676+ dev_dbg(&pdev->dev, "controller already in use\n");7777+ retval = -EBUSY;7878+ goto err2;7979+ }8080+ hcd->regs = ioremap_nocache(hcd->rsrc_start, hcd->rsrc_len);8181+8282+ if (hcd->regs == NULL) {8383+ dev_dbg(&pdev->dev, "error mapping memory\n");8484+ retval = -EFAULT;8585+ goto err3;8686+ }8787+8888+ retval = usb_add_hcd(hcd, irq, IRQF_SHARED);8989+ if (retval != 0)9090+ goto err4;9191+ return retval;9292+9393+err4:9494+ iounmap(hcd->regs);9595+err3:9696+ release_mem_region(hcd->rsrc_start, hcd->rsrc_len);9797+err2:9898+ usb_put_hcd(hcd);9999+err1:100100+ dev_err(&pdev->dev, "init %s fail, %d\n", dev_name(&pdev->dev),101101+ retval);102102+ return retval;103103+}104104+105105+static struct hc_driver ehci_xls_hc_driver = {106106+ .description = hcd_name,107107+ .product_desc = "XLS EHCI Host Controller",108108+ .hcd_priv_size = sizeof(struct ehci_hcd),109109+ .irq = ehci_irq,110110+ .flags = HCD_USB2 | HCD_MEMORY,111111+ .reset = ehci_xls_setup,112112+ .start = ehci_run,113113+ .stop = ehci_stop,114114+ .shutdown = ehci_shutdown,115115+116116+ .urb_enqueue = ehci_urb_enqueue,117117+ .urb_dequeue = ehci_urb_dequeue,118118+ .endpoint_disable = ehci_endpoint_disable,119119+ .endpoint_reset = ehci_endpoint_reset,120120+121121+ .get_frame_number = ehci_get_frame,122122+123123+ .hub_status_data = ehci_hub_status_data,124124+ .hub_control = ehci_hub_control,125125+ .bus_suspend = ehci_bus_suspend,126126+ .bus_resume = ehci_bus_resume,127127+ .relinquish_port = ehci_relinquish_port,128128+ .port_handed_over = ehci_port_handed_over,129129+130130+ .clear_tt_buffer_complete = ehci_clear_tt_buffer_complete,131131+};132132+133133+static int ehci_xls_probe(struct platform_device *pdev)134134+{135135+ if (usb_disabled())136136+ return -ENODEV;137137+138138+ return ehci_xls_probe_internal(&ehci_xls_hc_driver, pdev);139139+}140140+141141+static int ehci_xls_remove(struct platform_device *pdev)142142+{143143+ struct usb_hcd *hcd = platform_get_drvdata(pdev);144144+145145+ usb_remove_hcd(hcd);146146+ iounmap(hcd->regs);147147+ release_mem_region(hcd->rsrc_start, hcd->rsrc_len);148148+ usb_put_hcd(hcd);149149+ return 0;150150+}151151+152152+MODULE_ALIAS("ehci-xls");153153+154154+static struct platform_driver ehci_xls_driver = {155155+ .probe = ehci_xls_probe,156156+ .remove = ehci_xls_remove,157157+ .shutdown = usb_hcd_platform_shutdown,158158+ .driver = {159159+ .name = "ehci-xls",160160+ },161161+};
+7
drivers/usb/host/ehci.h
···62626363#define EHCI_MAX_ROOT_PORTS 15 /* see HCS_N_PORTS */64646565+enum ehci_rh_state {6666+ EHCI_RH_HALTED,6767+ EHCI_RH_SUSPENDED,6868+ EHCI_RH_RUNNING6969+};7070+6571struct ehci_hcd { /* one per controller */6672 /* glue to PCI and HCD framework */6773 struct ehci_caps __iomem *caps;···76707771 __u32 hcs_params; /* cached register copy */7872 spinlock_t lock;7373+ enum ehci_rh_state rh_state;79748075 /* async schedule support */8176 struct ehci_qh *async;
+4-1
drivers/usb/host/fhci-hcd.c
···621621 goto err_pram;622622 }623623624624- pram_addr = cpm_muram_alloc_fixed(iprop[2], FHCI_PRAM_SIZE);624624+ pram_addr = cpm_muram_alloc(FHCI_PRAM_SIZE, 64);625625 if (IS_ERR_VALUE(pram_addr)) {626626 dev_err(dev, "failed to allocate usb pram\n");627627 ret = -ENOMEM;628628 goto err_pram;629629 }630630+631631+ qe_issue_cmd(QE_ASSIGN_PAGE_TO_DEVICE, QE_CR_SUBBLOCK_USB,632632+ QE_CR_PROTOCOL_UNSPECIFIED, pram_addr);630633 fhci->pram = cpm_muram_addr(pram_addr);631634632635 /* GPIOs and pins */
+3-3
drivers/usb/host/isp1362-hcd.c
···23582358 unsigned long flags;23592359 int clkrdy = 0;2360236023612361- pr_info("%s:\n", __func__);23612361+ pr_debug("%s:\n", __func__);2362236223632363 if (isp1362_hcd->board && isp1362_hcd->board->reset) {23642364 isp1362_hcd->board->reset(hcd->self.controller, 1);···23952395 unsigned long flags;23962396 u32 tmp;2397239723982398- pr_info("%s:\n", __func__);23982398+ pr_debug("%s:\n", __func__);2399239924002400 del_timer_sync(&hcd->rh_timer);24012401···25232523 u16 chipid;25242524 unsigned long flags;2525252525262526- pr_info("%s:\n", __func__);25262526+ pr_debug("%s:\n", __func__);2527252725282528 spin_lock_irqsave(&isp1362_hcd->lock, flags);25292529 chipid = isp1362_read_reg16(isp1362_hcd, HCCHIPID);
+253-148
drivers/usb/host/isp1760-hcd.c
···2121#include <linux/uaccess.h>2222#include <linux/io.h>2323#include <linux/mm.h>2424+#include <linux/timer.h>2425#include <asm/unaligned.h>2526#include <asm/cacheflush.h>2627···4039 int int_done_map;4140 struct memory_chunk memory_pool[BLOCKS];4241 struct list_head controlqhs, bulkqhs, interruptqhs;4343- int active_ptds;44424543 /* periodic schedule support */4644#define DEFAULT_I_TDPS 1024···114114 u32 toggle;115115 u32 ping;116116 int slot;117117+ int tt_buffer_dirty; /* See USB2.0 spec section 11.17.5 */117118};118119119120struct urb_listitem {···490489 16 : 32, (priv->devflags & ISP1760_FLAG_ANALOG_OC) ?491490 "analog" : "digital");492491493493- /* This is weird: at the first plug-in of a device there seems to be494494- one packet queued that never gets returned? */495495- priv->active_ptds = -1;496496-497492 /* ATL reset */498493 reg_write32(hcd->regs, HC_HW_MODE_CTRL, hwmode | ALL_ATX_RESET);499494 mdelay(10);···509512 priv->hcs_params = reg_read32(hcd->regs, HC_HCSPARAMS);510513511514 return priv_init(hcd);512512-}513513-514514-static void isp1760_init_maps(struct usb_hcd *hcd)515515-{516516- /*set last maps, for iso its only 1, else 32 tds bitmap*/517517- reg_write32(hcd->regs, HC_ATL_PTD_LASTPTD_REG, 0x80000000);518518- reg_write32(hcd->regs, HC_INT_PTD_LASTPTD_REG, 0x80000000);519519- reg_write32(hcd->regs, HC_ISO_PTD_LASTPTD_REG, 0x00000001);520520-521521- reg_write32(hcd->regs, HC_ATL_PTD_SKIPMAP_REG, 0xffffffff);522522- reg_write32(hcd->regs, HC_INT_PTD_SKIPMAP_REG, 0xffffffff);523523- reg_write32(hcd->regs, HC_ISO_PTD_SKIPMAP_REG, 0xffffffff);524524-525525- reg_write32(hcd->regs, HC_BUFFER_STATUS_REG,526526- ATL_BUF_FILL | INT_BUF_FILL);527527-}528528-529529-static void isp1760_enable_interrupts(struct usb_hcd *hcd)530530-{531531- reg_write32(hcd->regs, HC_ATL_IRQ_MASK_AND_REG, 0);532532- reg_write32(hcd->regs, HC_ATL_IRQ_MASK_OR_REG, 0xffffffff);533533- reg_write32(hcd->regs, HC_INT_IRQ_MASK_AND_REG, 0);534534- reg_write32(hcd->regs, HC_INT_IRQ_MASK_OR_REG, 0xffffffff);535535- reg_write32(hcd->regs, HC_ISO_IRQ_MASK_AND_REG, 0);536536- reg_write32(hcd->regs, HC_ISO_IRQ_MASK_OR_REG, 0xffffffff);537537- /* step 23 passed */538538-}539539-540540-static int isp1760_run(struct usb_hcd *hcd)541541-{542542- int retval;543543- u32 temp;544544- u32 command;545545- u32 chipid;546546-547547- hcd->uses_new_polling = 1;548548-549549- hcd->state = HC_STATE_RUNNING;550550- isp1760_enable_interrupts(hcd);551551- temp = reg_read32(hcd->regs, HC_HW_MODE_CTRL);552552- reg_write32(hcd->regs, HC_HW_MODE_CTRL, temp | HW_GLOBAL_INTR_EN);553553-554554- command = reg_read32(hcd->regs, HC_USBCMD);555555- command &= ~(CMD_LRESET|CMD_RESET);556556- command |= CMD_RUN;557557- reg_write32(hcd->regs, HC_USBCMD, command);558558-559559- retval = handshake(hcd, HC_USBCMD, CMD_RUN, CMD_RUN, 250 * 1000);560560- if (retval)561561- return retval;562562-563563- /*564564- * XXX565565- * Spec says to write FLAG_CF as last config action, priv code grabs566566- * the semaphore while doing so.567567- */568568- down_write(&ehci_cf_port_reset_rwsem);569569- reg_write32(hcd->regs, HC_CONFIGFLAG, FLAG_CF);570570-571571- retval = handshake(hcd, HC_CONFIGFLAG, FLAG_CF, FLAG_CF, 250 * 1000);572572- up_write(&ehci_cf_port_reset_rwsem);573573- if (retval)574574- return retval;575575-576576- chipid = reg_read32(hcd->regs, HC_CHIP_ID_REG);577577- dev_info(hcd->self.controller, "USB ISP %04x HW rev. %d started\n",578578- chipid & 0xffff, chipid >> 16);579579-580580- /* PTD Register Init Part 2, Step 28 */581581- /* enable INTs */582582- isp1760_init_maps(hcd);583583-584584- /* GRR this is run-once init(), being done every time the HC starts.585585- * So long as they're part of class devices, we can't do it init()586586- * since the class device isn't created that early.587587- */588588- return 0;589515}590516591517static u32 base_to_chip(u32 base)···733813 WARN_ON(slots[slot].qh);734814 WARN_ON(qtd->status != QTD_PAYLOAD_ALLOC);735815736736- slots[slot].qtd = qtd;737737- slots[slot].qh = qh;738738- qh->slot = slot;739739- qtd->status = QTD_XFER_STARTED; /* Set this before writing ptd, since740740- interrupt routine may preempt and expects this value. */741741- ptd_write(hcd->regs, ptd_offset, slot, ptd);742742- priv->active_ptds++;743743-744816 /* Make sure done map has not triggered from some unlinked transfer */745817 if (ptd_offset == ATL_PTD_OFFSET) {746818 priv->atl_done_map |= reg_read32(hcd->regs,747819 HC_ATL_PTD_DONEMAP_REG);748748- priv->atl_done_map &= ~(1 << qh->slot);820820+ priv->atl_done_map &= ~(1 << slot);821821+ } else {822822+ priv->int_done_map |= reg_read32(hcd->regs,823823+ HC_INT_PTD_DONEMAP_REG);824824+ priv->int_done_map &= ~(1 << slot);825825+ }749826827827+ qh->slot = slot;828828+ qtd->status = QTD_XFER_STARTED;829829+ slots[slot].timestamp = jiffies;830830+ slots[slot].qtd = qtd;831831+ slots[slot].qh = qh;832832+ ptd_write(hcd->regs, ptd_offset, slot, ptd);833833+834834+ if (ptd_offset == ATL_PTD_OFFSET) {750835 skip_map = reg_read32(hcd->regs, HC_ATL_PTD_SKIPMAP_REG);751836 skip_map &= ~(1 << qh->slot);752837 reg_write32(hcd->regs, HC_ATL_PTD_SKIPMAP_REG, skip_map);753838 } else {754754- priv->int_done_map |= reg_read32(hcd->regs,755755- HC_INT_PTD_DONEMAP_REG);756756- priv->int_done_map &= ~(1 << qh->slot);757757-758839 skip_map = reg_read32(hcd->regs, HC_INT_PTD_SKIPMAP_REG);759840 skip_map &= ~(1 << qh->slot);760841 reg_write32(hcd->regs, HC_INT_PTD_SKIPMAP_REG, skip_map);···779858 if (qtd->status < QTD_XFER_COMPLETE)780859 break;781860782782- if (list_is_last(&qtd->qtd_list, &qh->qtd_list))783783- last_qtd = 1;784784- else785785- last_qtd = qtd->urb != qtd_next->urb;861861+ last_qtd = last_qtd_of_urb(qtd, qh);786862787863 if ((!last_qtd) && (qtd->status == QTD_RETIRE))788864 qtd_next->status = QTD_RETIRE;···820902 urb_listitem = kmem_cache_zalloc(urb_listitem_cachep,821903 GFP_ATOMIC);822904 if (unlikely(!urb_listitem))823823- break;905905+ break; /* Try again on next call */824906 urb_listitem->urb = qtd->urb;825907 list_add_tail(&urb_listitem->urb_list, urb_list);826908 }···845927 WARN_ON(1);846928 return;847929 }930930+931931+ /* Make sure this endpoint's TT buffer is clean before queueing ptds */932932+ if (qh->tt_buffer_dirty)933933+ return;848934849935 if (usb_pipeint(list_entry(qh->qtd_list.next, struct isp1760_qtd,850936 qtd_list)->urb->pipe)) {···10901168 return PTD_STATE_QTD_DONE;10911169}1092117010931093-static irqreturn_t isp1760_irq(struct usb_hcd *hcd)11711171+static void handle_done_ptds(struct usb_hcd *hcd)10941172{10951173 struct isp1760_hcd *priv = hcd_to_priv(hcd);10961096- u32 imask;10971097- irqreturn_t irqret = IRQ_NONE;10981174 struct ptd ptd;10991175 struct isp1760_qh *qh;11001176 int slot;···11011181 u32 ptd_offset;11021182 struct isp1760_qtd *qtd;11031183 int modified;11041104- static int last_active_ptds;11051105- int int_skip_map, atl_skip_map;11841184+ int skip_map;1106118511071107- spin_lock(&priv->lock);11861186+ skip_map = reg_read32(hcd->regs, HC_INT_PTD_SKIPMAP_REG);11871187+ priv->int_done_map &= ~skip_map;11881188+ skip_map = reg_read32(hcd->regs, HC_ATL_PTD_SKIPMAP_REG);11891189+ priv->atl_done_map &= ~skip_map;1108119011091109- if (!(hcd->state & HC_STATE_RUNNING))11101110- goto leave;11111111-11121112- imask = reg_read32(hcd->regs, HC_INTERRUPT_REG);11131113- if (unlikely(!imask))11141114- goto leave;11151115- reg_write32(hcd->regs, HC_INTERRUPT_REG, imask); /* Clear */11161116-11171117- int_skip_map = reg_read32(hcd->regs, HC_INT_PTD_SKIPMAP_REG);11181118- atl_skip_map = reg_read32(hcd->regs, HC_ATL_PTD_SKIPMAP_REG);11191119- priv->int_done_map |= reg_read32(hcd->regs, HC_INT_PTD_DONEMAP_REG);11201120- priv->atl_done_map |= reg_read32(hcd->regs, HC_ATL_PTD_DONEMAP_REG);11211121- priv->int_done_map &= ~int_skip_map;11221122- priv->atl_done_map &= ~atl_skip_map;11231123-11241124- modified = priv->int_done_map | priv->atl_done_map;11911191+ modified = priv->int_done_map || priv->atl_done_map;1125119211261193 while (priv->int_done_map || priv->atl_done_map) {11271194 if (priv->int_done_map) {···11471240 slots[slot].qtd = NULL;11481241 qh = slots[slot].qh;11491242 slots[slot].qh = NULL;11501150- priv->active_ptds--;11511243 qh->slot = -1;1152124411531245 WARN_ON(qtd->status != QTD_XFER_STARTED);···1187128111881282 case PTD_STATE_URB_RETIRE:11891283 qtd->status = QTD_RETIRE;12841284+ if ((qtd->urb->dev->speed != USB_SPEED_HIGH) &&12851285+ (qtd->urb->status != -EPIPE) &&12861286+ (qtd->urb->status != -EREMOTEIO)) {12871287+ qh->tt_buffer_dirty = 1;12881288+ if (usb_hub_clear_tt_buffer(qtd->urb))12891289+ /* Clear failed; let's hope things work12901290+ anyway */12911291+ qh->tt_buffer_dirty = 0;12921292+ }11901293 qtd = NULL;11911294 qh->toggle = 0;11921295 qh->ping = 0;···1226131112271312 if (modified)12281313 schedule_ptds(hcd);13141314+}1229131512301230- /* ISP1760 Errata 2 explains that interrupts may be missed (or not12311231- happen?) if two USB devices are running simultaneously. Perhaps12321232- this happens when a PTD is finished during interrupt handling;12331233- enable SOF interrupts if PTDs are still scheduled when exiting this12341234- interrupt handler, just to be safe. */13161316+static irqreturn_t isp1760_irq(struct usb_hcd *hcd)13171317+{13181318+ struct isp1760_hcd *priv = hcd_to_priv(hcd);13191319+ u32 imask;13201320+ irqreturn_t irqret = IRQ_NONE;1235132112361236- if (priv->active_ptds != last_active_ptds) {12371237- if (priv->active_ptds > 0)12381238- reg_write32(hcd->regs, HC_INTERRUPT_ENABLE,12391239- INTERRUPT_ENABLE_SOT_MASK);12401240- else12411241- reg_write32(hcd->regs, HC_INTERRUPT_ENABLE,12421242- INTERRUPT_ENABLE_MASK);12431243- last_active_ptds = priv->active_ptds;12441244- }13221322+ spin_lock(&priv->lock);13231323+13241324+ if (!(hcd->state & HC_STATE_RUNNING))13251325+ goto leave;13261326+13271327+ imask = reg_read32(hcd->regs, HC_INTERRUPT_REG);13281328+ if (unlikely(!imask))13291329+ goto leave;13301330+ reg_write32(hcd->regs, HC_INTERRUPT_REG, imask); /* Clear */13311331+13321332+ priv->int_done_map |= reg_read32(hcd->regs, HC_INT_PTD_DONEMAP_REG);13331333+ priv->atl_done_map |= reg_read32(hcd->regs, HC_ATL_PTD_DONEMAP_REG);13341334+13351335+ handle_done_ptds(hcd);1245133612461337 irqret = IRQ_HANDLED;12471338leave:12481339 spin_unlock(&priv->lock);1249134012501341 return irqret;13421342+}13431343+13441344+/*13451345+ * Workaround for problem described in chip errata 2:13461346+ *13471347+ * Sometimes interrupts are not generated when ATL (not INT?) completion occurs.13481348+ * One solution suggested in the errata is to use SOF interrupts _instead_of_13491349+ * ATL done interrupts (the "instead of" might be important since it seems13501350+ * enabling ATL interrupts also causes the chip to sometimes - rarely - "forget"13511351+ * to set the PTD's done bit in addition to not generating an interrupt!).13521352+ *13531353+ * So if we use SOF + ATL interrupts, we sometimes get stale PTDs since their13541354+ * done bit is not being set. This is bad - it blocks the endpoint until reboot.13551355+ *13561356+ * If we use SOF interrupts only, we get latency between ptd completion and the13571357+ * actual handling. This is very noticeable in testusb runs which takes several13581358+ * minutes longer without ATL interrupts.13591359+ *13601360+ * A better solution is to run the code below every SLOT_CHECK_PERIOD ms. If it13611361+ * finds active ATL slots which are older than SLOT_TIMEOUT ms, it checks the13621362+ * slot's ACTIVE and VALID bits. If these are not set, the ptd is considered13631363+ * completed and its done map bit is set.13641364+ *13651365+ * The values of SLOT_TIMEOUT and SLOT_CHECK_PERIOD have been arbitrarily chosen13661366+ * not to cause too much lag when this HW bug occurs, while still hopefully13671367+ * ensuring that the check does not falsely trigger.13681368+ */13691369+#define SLOT_TIMEOUT 30013701370+#define SLOT_CHECK_PERIOD 20013711371+static struct timer_list errata2_timer;13721372+13731373+void errata2_function(unsigned long data)13741374+{13751375+ struct usb_hcd *hcd = (struct usb_hcd *) data;13761376+ struct isp1760_hcd *priv = hcd_to_priv(hcd);13771377+ int slot;13781378+ struct ptd ptd;13791379+ unsigned long spinflags;13801380+13811381+ spin_lock_irqsave(&priv->lock, spinflags);13821382+13831383+ for (slot = 0; slot < 32; slot++)13841384+ if (priv->atl_slots[slot].qh && time_after(jiffies,13851385+ priv->atl_slots[slot].timestamp +13861386+ SLOT_TIMEOUT * HZ / 1000)) {13871387+ ptd_read(hcd->regs, ATL_PTD_OFFSET, slot, &ptd);13881388+ if (!FROM_DW0_VALID(ptd.dw0) &&13891389+ !FROM_DW3_ACTIVE(ptd.dw3))13901390+ priv->atl_done_map |= 1 << slot;13911391+ }13921392+13931393+ if (priv->atl_done_map)13941394+ handle_done_ptds(hcd);13951395+13961396+ spin_unlock_irqrestore(&priv->lock, spinflags);13971397+13981398+ errata2_timer.expires = jiffies + SLOT_CHECK_PERIOD * HZ / 1000;13991399+ add_timer(&errata2_timer);14001400+}14011401+14021402+static int isp1760_run(struct usb_hcd *hcd)14031403+{14041404+ int retval;14051405+ u32 temp;14061406+ u32 command;14071407+ u32 chipid;14081408+14091409+ hcd->uses_new_polling = 1;14101410+14111411+ hcd->state = HC_STATE_RUNNING;14121412+14131413+ /* Set PTD interrupt AND & OR maps */14141414+ reg_write32(hcd->regs, HC_ATL_IRQ_MASK_AND_REG, 0);14151415+ reg_write32(hcd->regs, HC_ATL_IRQ_MASK_OR_REG, 0xffffffff);14161416+ reg_write32(hcd->regs, HC_INT_IRQ_MASK_AND_REG, 0);14171417+ reg_write32(hcd->regs, HC_INT_IRQ_MASK_OR_REG, 0xffffffff);14181418+ reg_write32(hcd->regs, HC_ISO_IRQ_MASK_AND_REG, 0);14191419+ reg_write32(hcd->regs, HC_ISO_IRQ_MASK_OR_REG, 0xffffffff);14201420+ /* step 23 passed */14211421+14221422+ temp = reg_read32(hcd->regs, HC_HW_MODE_CTRL);14231423+ reg_write32(hcd->regs, HC_HW_MODE_CTRL, temp | HW_GLOBAL_INTR_EN);14241424+14251425+ command = reg_read32(hcd->regs, HC_USBCMD);14261426+ command &= ~(CMD_LRESET|CMD_RESET);14271427+ command |= CMD_RUN;14281428+ reg_write32(hcd->regs, HC_USBCMD, command);14291429+14301430+ retval = handshake(hcd, HC_USBCMD, CMD_RUN, CMD_RUN, 250 * 1000);14311431+ if (retval)14321432+ return retval;14331433+14341434+ /*14351435+ * XXX14361436+ * Spec says to write FLAG_CF as last config action, priv code grabs14371437+ * the semaphore while doing so.14381438+ */14391439+ down_write(&ehci_cf_port_reset_rwsem);14401440+ reg_write32(hcd->regs, HC_CONFIGFLAG, FLAG_CF);14411441+14421442+ retval = handshake(hcd, HC_CONFIGFLAG, FLAG_CF, FLAG_CF, 250 * 1000);14431443+ up_write(&ehci_cf_port_reset_rwsem);14441444+ if (retval)14451445+ return retval;14461446+14471447+ init_timer(&errata2_timer);14481448+ errata2_timer.function = errata2_function;14491449+ errata2_timer.data = (unsigned long) hcd;14501450+ errata2_timer.expires = jiffies + SLOT_CHECK_PERIOD * HZ / 1000;14511451+ add_timer(&errata2_timer);14521452+14531453+ chipid = reg_read32(hcd->regs, HC_CHIP_ID_REG);14541454+ dev_info(hcd->self.controller, "USB ISP %04x HW rev. %d started\n",14551455+ chipid & 0xffff, chipid >> 16);14561456+14571457+ /* PTD Register Init Part 2, Step 28 */14581458+14591459+ /* Setup registers controlling PTD checking */14601460+ reg_write32(hcd->regs, HC_ATL_PTD_LASTPTD_REG, 0x80000000);14611461+ reg_write32(hcd->regs, HC_INT_PTD_LASTPTD_REG, 0x80000000);14621462+ reg_write32(hcd->regs, HC_ISO_PTD_LASTPTD_REG, 0x00000001);14631463+ reg_write32(hcd->regs, HC_ATL_PTD_SKIPMAP_REG, 0xffffffff);14641464+ reg_write32(hcd->regs, HC_INT_PTD_SKIPMAP_REG, 0xffffffff);14651465+ reg_write32(hcd->regs, HC_ISO_PTD_SKIPMAP_REG, 0xffffffff);14661466+ reg_write32(hcd->regs, HC_BUFFER_STATUS_REG,14671467+ ATL_BUF_FILL | INT_BUF_FILL);14681468+14691469+ /* GRR this is run-once init(), being done every time the HC starts.14701470+ * So long as they're part of class devices, we can't do it init()14711471+ * since the class device isn't created that early.14721472+ */14731473+ return 0;12511474}1252147512531476static int qtd_fill(struct isp1760_qtd *qtd, void *databuffer, size_t len)···15561503 packetize_urb(hcd, urb, &new_qtds, mem_flags);15571504 if (list_empty(&new_qtds))15581505 return -ENOMEM;15591559- urb->hcpriv = NULL; /* Used to signal unlink to interrupt handler */1560150615611507 retval = 0;15621508 spin_lock_irqsave(&priv->lock, spinflags);···15831531 qh = qh_alloc(GFP_ATOMIC);15841532 if (!qh) {15851533 retval = -ENOMEM;15341534+ usb_hcd_unlink_urb_from_ep(hcd, urb);15861535 goto out;15871536 }15881537 list_add_tail(&qh->qh_list, ep_queue);···16231570 }1624157116251572 qh->slot = -1;16261626- priv->active_ptds--;15731573+}15741574+15751575+/*15761576+ * Retire the qtds beginning at 'qtd' and belonging all to the same urb, killing15771577+ * any active transfer belonging to the urb in the process.15781578+ */15791579+static void dequeue_urb_from_qtd(struct usb_hcd *hcd, struct isp1760_qh *qh,15801580+ struct isp1760_qtd *qtd)15811581+{15821582+ struct urb *urb;15831583+ int urb_was_running;15841584+15851585+ urb = qtd->urb;15861586+ urb_was_running = 0;15871587+ list_for_each_entry_from(qtd, &qh->qtd_list, qtd_list) {15881588+ if (qtd->urb != urb)15891589+ break;15901590+15911591+ if (qtd->status >= QTD_XFER_STARTED)15921592+ urb_was_running = 1;15931593+ if (last_qtd_of_urb(qtd, qh) &&15941594+ (qtd->status >= QTD_XFER_COMPLETE))15951595+ urb_was_running = 0;15961596+15971597+ if (qtd->status == QTD_XFER_STARTED)15981598+ kill_transfer(hcd, urb, qh);15991599+ qtd->status = QTD_RETIRE;16001600+ }16011601+16021602+ if ((urb->dev->speed != USB_SPEED_HIGH) && urb_was_running) {16031603+ qh->tt_buffer_dirty = 1;16041604+ if (usb_hub_clear_tt_buffer(urb))16051605+ /* Clear failed; let's hope things work anyway */16061606+ qh->tt_buffer_dirty = 0;16071607+ }16271608}1628160916291610static int isp1760_urb_dequeue(struct usb_hcd *hcd, struct urb *urb,···1682159516831596 list_for_each_entry(qtd, &qh->qtd_list, qtd_list)16841597 if (qtd->urb == urb) {16851685- if (qtd->status == QTD_XFER_STARTED)16861686- kill_transfer(hcd, urb, qh);16871687- qtd->status = QTD_RETIRE;15981598+ dequeue_urb_from_qtd(hcd, qh, qtd);15991599+ break;16881600 }1689160116901602 urb->status = status;···17081622 if (!qh)17091623 goto out;1710162417111711- list_for_each_entry(qtd, &qh->qtd_list, qtd_list) {17121712- if (qtd->status == QTD_XFER_STARTED)17131713- kill_transfer(hcd, qtd->urb, qh);17141714- qtd->status = QTD_RETIRE;17151715- qtd->urb->status = -ECONNRESET;17161716- }16251625+ list_for_each_entry(qtd, &qh->qtd_list, qtd_list)16261626+ if (qtd->status != QTD_RETIRE) {16271627+ dequeue_urb_from_qtd(hcd, qh, qtd);16281628+ qtd->urb->status = -ECONNRESET;16291629+ }1717163017181631 ep->hcpriv = NULL;17191632 /* Cannot free qh here since it will be parsed by schedule_ptds() */···21062021 struct isp1760_hcd *priv = hcd_to_priv(hcd);21072022 u32 temp;2108202320242024+ del_timer(&errata2_timer);20252025+21092026 isp1760_hub_control(hcd, ClearPortFeature, USB_PORT_FEAT_POWER, 1,21102027 NULL, 0);21112028 mdelay(20);···21352048 reg_write32(hcd->regs, HC_USBCMD, command);21362049}2137205020512051+static void isp1760_clear_tt_buffer_complete(struct usb_hcd *hcd,20522052+ struct usb_host_endpoint *ep)20532053+{20542054+ struct isp1760_hcd *priv = hcd_to_priv(hcd);20552055+ struct isp1760_qh *qh = ep->hcpriv;20562056+ unsigned long spinflags;20572057+20582058+ if (!qh)20592059+ return;20602060+20612061+ spin_lock_irqsave(&priv->lock, spinflags);20622062+ qh->tt_buffer_dirty = 0;20632063+ schedule_ptds(hcd);20642064+ spin_unlock_irqrestore(&priv->lock, spinflags);20652065+}20662066+20672067+21382068static const struct hc_driver isp1760_hc_driver = {21392069 .description = "isp1760-hcd",21402070 .product_desc = "NXP ISP1760 USB Host Controller",···21682064 .get_frame_number = isp1760_get_frame,21692065 .hub_status_data = isp1760_hub_status_data,21702066 .hub_control = isp1760_hub_control,20672067+ .clear_tt_buffer_complete = isp1760_clear_tt_buffer_complete,21712068};2172206921732070int __init init_kmem_once(void)
···359359 endpoint = &iface_desc->endpoint[0].desc;360360 if (!dev->bulk_in_endpointAddr && usb_endpoint_is_bulk_in(endpoint)) {361361 /* we found a bulk in endpoint */362362- dev->orig_bi_size = le16_to_cpu(endpoint->wMaxPacketSize);362362+ dev->orig_bi_size = usb_endpoint_maxp(endpoint);363363 dev->bulk_in_size = 0x200; /* works _much_ faster */364364 dev->bulk_in_endpointAddr = endpoint->bEndpointAddress;365365 dev->bulk_in_buffer =
+1-1
drivers/usb/misc/iowarrior.c
···803803 dev->int_out_endpoint = endpoint;804804 }805805 /* we have to check the report_size often, so remember it in the endianess suitable for our machine */806806- dev->report_size = le16_to_cpu(dev->int_in_endpoint->wMaxPacketSize);806806+ dev->report_size = usb_endpoint_maxp(dev->int_in_endpoint);807807 if ((dev->interface->cur_altsetting->desc.bInterfaceNumber == 0) &&808808 (dev->product_id == USB_DEVICE_ID_CODEMERCS_IOW56))809809 /* IOWarrior56 has wMaxPacketSize different from report size */
+2-2
drivers/usb/misc/ldusb.c
···721721 if (dev->interrupt_out_endpoint == NULL)722722 dev_warn(&intf->dev, "Interrupt out endpoint not found (using control endpoint instead)\n");723723724724- dev->interrupt_in_endpoint_size = le16_to_cpu(dev->interrupt_in_endpoint->wMaxPacketSize);724724+ dev->interrupt_in_endpoint_size = usb_endpoint_maxp(dev->interrupt_in_endpoint);725725 dev->ring_buffer = kmalloc(ring_buffer_size*(sizeof(size_t)+dev->interrupt_in_endpoint_size), GFP_KERNEL);726726 if (!dev->ring_buffer) {727727 dev_err(&intf->dev, "Couldn't allocate ring_buffer\n");···737737 dev_err(&intf->dev, "Couldn't allocate interrupt_in_urb\n");738738 goto error;739739 }740740- dev->interrupt_out_endpoint_size = dev->interrupt_out_endpoint ? le16_to_cpu(dev->interrupt_out_endpoint->wMaxPacketSize) :740740+ dev->interrupt_out_endpoint_size = dev->interrupt_out_endpoint ? usb_endpoint_maxp(dev->interrupt_out_endpoint) :741741 udev->descriptor.bMaxPacketSize0;742742 dev->interrupt_out_buffer = kmalloc(write_buffer_size*dev->interrupt_out_endpoint_size, GFP_KERNEL);743743 if (!dev->interrupt_out_buffer) {
···252252253253config USB_SERIAL_IPW254254 tristate "USB IPWireless (3G UMTS TDD) Driver"255255+ select USB_SERIAL_WWAN255256 help256257 Say Y here if you want to use a IPWireless USB modem such as257258 the ones supplied by Axity3G/Sentech South Africa.
+1-1
drivers/usb/serial/ftdi_sio.c
···14861486 }1487148714881488 /* set max packet size based on descriptor */14891489- priv->max_packet_size = le16_to_cpu(ep_desc->wMaxPacketSize);14891489+ priv->max_packet_size = usb_endpoint_maxp(ep_desc);1490149014911491 dev_info(&udev->dev, "Setting MaxPacketSize %d\n", priv->max_packet_size);14921492}
+2-2
drivers/usb/serial/io_edgeport.c
···3042304230433043 endpoint = &serial->interface->altsetting[0].30443044 endpoint[i].desc;30453045- buffer_size = le16_to_cpu(endpoint->wMaxPacketSize);30453045+ buffer_size = usb_endpoint_maxp(endpoint);30463046 if (!interrupt_in_found &&30473047 (usb_endpoint_is_int_in(endpoint))) {30483048 /* we found a interrupt in endpoint */···31073107 usb_rcvbulkpipe(dev,31083108 endpoint->bEndpointAddress),31093109 edge_serial->bulk_in_buffer,31103110- le16_to_cpu(endpoint->wMaxPacketSize),31103110+ usb_endpoint_maxp(endpoint),31113111 edge_bulk_in_callback,31123112 edge_serial);31133113 bulk_in_found = true;
+31-2
drivers/usb/serial/ipw.c
···4747#include <linux/usb.h>4848#include <linux/usb/serial.h>4949#include <linux/uaccess.h>5050+#include "usb-wwan.h"50515152/*5253 * Version Information···186185187186 /*--2: Start reading from the device */188187 dbg("%s: setting up bulk read callback", __func__);189189- usb_serial_generic_open(tty, port);188188+ usb_wwan_open(tty, port);190189191190 /*--3: Tell the modem to open the floodgates on the rx bulk channel */192191 dbg("%s:asking modem for RxRead (RXBULK_ON)", __func__);···218217219218 kfree(buf_flow_init);220219 return 0;220220+}221221+222222+/* fake probe - only to allocate data structures */223223+static int ipw_probe(struct usb_serial *serial, const struct usb_device_id *id)224224+{225225+ struct usb_wwan_intf_private *data;226226+227227+ data = kzalloc(sizeof(struct usb_wwan_intf_private), GFP_KERNEL);228228+ if (!data)229229+ return -ENOMEM;230230+231231+ spin_lock_init(&data->susp_lock);232232+ usb_set_serial_data(serial, data);233233+ return 0;234234+}235235+236236+static void ipw_release(struct usb_serial *serial)237237+{238238+ struct usb_wwan_intf_private *data = usb_get_serial_data(serial);239239+240240+ usb_wwan_release(serial);241241+ usb_set_serial_data(serial, NULL);242242+ kfree(data);221243}222244223245static void ipw_dtr_rts(struct usb_serial_port *port, int on)···309285 dev_err(&port->dev,310286 "Disabling bulk RxRead failed (error = %d)\n", result);311287312312- usb_serial_generic_close(port);288288+ usb_wwan_close(port);313289}314290315291static struct usb_serial_driver ipw_device = {···321297 .usb_driver = &usb_ipw_driver,322298 .id_table = usb_ipw_ids,323299 .num_ports = 1,300300+ .disconnect = usb_wwan_disconnect,324301 .open = ipw_open,325302 .close = ipw_close,303303+ .probe = ipw_probe,304304+ .attach = usb_wwan_startup,305305+ .release = ipw_release,326306 .dtr_rts = ipw_dtr_rts,307307+ .write = usb_wwan_write,327308};328309329310
···831831832832 dev_dbg(dev, "device found\n");833833834834- set_freezable();835835- /* Wait for the timeout to expire or for a disconnect */834834+ set_freezable_with_signal();835835+ /*836836+ * Wait for the timeout to expire or for a disconnect837837+ *838838+ * We can't freeze in this thread or we risk causing khubd to839839+ * fail to freeze, but we can't be non-freezable either. Nor can840840+ * khubd freeze while waiting for scanning to complete as it may841841+ * hold the device lock, causing a hang when suspending devices.842842+ * So we request a fake signal when freezing and use843843+ * interruptible sleep to kick us out of our wait early when844844+ * freezing happens.845845+ */836846 if (delay_use > 0) {837847 dev_dbg(dev, "waiting for device to settle "838848 "before scanning\n");839839- wait_event_freezable_timeout(us->delay_wait,849849+ wait_event_interruptible_timeout(us->delay_wait,840850 test_bit(US_FLIDX_DONT_SCAN, &us->dflags),841851 delay_use * HZ);842852 }
+1-1
drivers/usb/usb-skeleton.c
···555555 if (!dev->bulk_in_endpointAddr &&556556 usb_endpoint_is_bulk_in(endpoint)) {557557 /* we found a bulk in endpoint */558558- buffer_size = le16_to_cpu(endpoint->wMaxPacketSize);558558+ buffer_size = usb_endpoint_maxp(endpoint);559559 dev->bulk_in_size = buffer_size;560560 dev->bulk_in_endpointAddr = endpoint->bEndpointAddress;561561 dev->bulk_in_buffer = kmalloc(buffer_size, GFP_KERNEL);
+1-1
drivers/usb/wusbcore/wa-hc.c
···4343 /* Fill up Data Transfer EP pointers */4444 wa->dti_epd = &iface->cur_altsetting->endpoint[1].desc;4545 wa->dto_epd = &iface->cur_altsetting->endpoint[2].desc;4646- wa->xfer_result_size = le16_to_cpu(wa->dti_epd->wMaxPacketSize);4646+ wa->xfer_result_size = usb_endpoint_maxp(wa->dti_epd);4747 wa->xfer_result = kmalloc(wa->xfer_result_size, GFP_KERNEL);4848 if (wa->xfer_result == NULL)4949 goto error_xfer_result_alloc;
+1-1
include/linux/usb.h
···15741574 return 0;1575157515761576 /* NOTE: only 0x07ff bits are for packet size... */15771577- return le16_to_cpu(ep->desc.wMaxPacketSize);15771577+ return usb_endpoint_maxp(&ep->desc);15781578}1579157915801580/* ----------------------------------------------------------------------- */
+17
include/linux/usb/ch9.h
···3434#define __LINUX_USB_CH9_H35353636#include <linux/types.h> /* __u8 etc */3737+#include <asm/byteorder.h> /* le16_to_cpu */37383839/*-------------------------------------------------------------------------*/3940···144143#define USB_INTRF_FUNC_SUSPEND 0 /* function suspend */145144146145#define USB_INTR_FUNC_SUSPEND_OPT_MASK 0xFF00146146+/*147147+ * Suspend Options, Table 9-7 USB 3.0 spec148148+ */149149+#define USB_INTRF_FUNC_SUSPEND_LP (1 << (8 + 0))150150+#define USB_INTRF_FUNC_SUSPEND_RW (1 << (8 + 1))147151148152#define USB_ENDPOINT_HALT 0 /* IN/OUT will STALL */149153···574568 const struct usb_endpoint_descriptor *epd)575569{576570 return usb_endpoint_xfer_isoc(epd) && usb_endpoint_dir_out(epd);571571+}572572+573573+/**574574+ * usb_endpoint_maxp - get endpoint's max packet size575575+ * @epd: endpoint to be checked576576+ *577577+ * Returns @epd's max packet578578+ */579579+static inline int usb_endpoint_maxp(const struct usb_endpoint_descriptor *epd)580580+{581581+ return le16_to_cpu(epd->wMaxPacketSize);577582}578583579584/*-------------------------------------------------------------------------*/