| Felipe Balbi | 72246da | 2011-08-19 18:10:58 +0300 | [diff] [blame] | 1 | /** | 
|  | 2 | * gadget.c - DesignWare USB3 DRD Controller Gadget Framework Link | 
|  | 3 | * | 
|  | 4 | * Copyright (C) 2010-2011 Texas Instruments Incorporated - http://www.ti.com | 
| Felipe Balbi | 72246da | 2011-08-19 18:10:58 +0300 | [diff] [blame] | 5 | * | 
|  | 6 | * Authors: Felipe Balbi <balbi@ti.com>, | 
|  | 7 | *	    Sebastian Andrzej Siewior <bigeasy@linutronix.de> | 
|  | 8 | * | 
|  | 9 | * Redistribution and use in source and binary forms, with or without | 
|  | 10 | * modification, are permitted provided that the following conditions | 
|  | 11 | * are met: | 
|  | 12 | * 1. Redistributions of source code must retain the above copyright | 
|  | 13 | *    notice, this list of conditions, and the following disclaimer, | 
|  | 14 | *    without modification. | 
|  | 15 | * 2. Redistributions in binary form must reproduce the above copyright | 
|  | 16 | *    notice, this list of conditions and the following disclaimer in the | 
|  | 17 | *    documentation and/or other materials provided with the distribution. | 
|  | 18 | * 3. The names of the above-listed copyright holders may not be used | 
|  | 19 | *    to endorse or promote products derived from this software without | 
|  | 20 | *    specific prior written permission. | 
|  | 21 | * | 
|  | 22 | * ALTERNATIVELY, this software may be distributed under the terms of the | 
|  | 23 | * GNU General Public License ("GPL") version 2, as published by the Free | 
|  | 24 | * Software Foundation. | 
|  | 25 | * | 
|  | 26 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS | 
|  | 27 | * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, | 
|  | 28 | * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR | 
|  | 29 | * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR | 
|  | 30 | * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, | 
|  | 31 | * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, | 
|  | 32 | * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR | 
|  | 33 | * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF | 
|  | 34 | * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING | 
|  | 35 | * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | 
|  | 36 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | 
|  | 37 | */ | 
|  | 38 |  | 
|  | 39 | #include <linux/kernel.h> | 
|  | 40 | #include <linux/delay.h> | 
|  | 41 | #include <linux/slab.h> | 
|  | 42 | #include <linux/spinlock.h> | 
|  | 43 | #include <linux/platform_device.h> | 
|  | 44 | #include <linux/pm_runtime.h> | 
|  | 45 | #include <linux/interrupt.h> | 
|  | 46 | #include <linux/io.h> | 
|  | 47 | #include <linux/list.h> | 
|  | 48 | #include <linux/dma-mapping.h> | 
|  | 49 |  | 
|  | 50 | #include <linux/usb/ch9.h> | 
|  | 51 | #include <linux/usb/gadget.h> | 
| Ido Shayevitz | cdeef4c | 2012-05-29 13:17:41 +0200 | [diff] [blame] | 52 | #include <linux/usb/otg.h> | 
| Felipe Balbi | 72246da | 2011-08-19 18:10:58 +0300 | [diff] [blame] | 53 |  | 
|  | 54 | #include "core.h" | 
|  | 55 | #include "gadget.h" | 
|  | 56 | #include "io.h" | 
|  | 57 |  | 
| Felipe Balbi | 04a9bfc | 2012-01-02 18:25:43 +0200 | [diff] [blame] | 58 | /** | 
|  | 59 | * dwc3_gadget_set_test_mode - Enables USB2 Test Modes | 
|  | 60 | * @dwc: pointer to our context structure | 
|  | 61 | * @mode: the mode to set (J, K SE0 NAK, Force Enable) | 
|  | 62 | * | 
|  | 63 | * Caller should take care of locking. This function will | 
|  | 64 | * return 0 on success or -EINVAL if wrong Test Selector | 
|  | 65 | * is passed | 
|  | 66 | */ | 
|  | 67 | int dwc3_gadget_set_test_mode(struct dwc3 *dwc, int mode) | 
|  | 68 | { | 
|  | 69 | u32		reg; | 
|  | 70 |  | 
|  | 71 | reg = dwc3_readl(dwc->regs, DWC3_DCTL); | 
|  | 72 | reg &= ~DWC3_DCTL_TSTCTRL_MASK; | 
|  | 73 |  | 
|  | 74 | switch (mode) { | 
|  | 75 | case TEST_J: | 
|  | 76 | case TEST_K: | 
|  | 77 | case TEST_SE0_NAK: | 
|  | 78 | case TEST_PACKET: | 
|  | 79 | case TEST_FORCE_EN: | 
|  | 80 | reg |= mode << 1; | 
|  | 81 | break; | 
|  | 82 | default: | 
|  | 83 | return -EINVAL; | 
|  | 84 | } | 
|  | 85 |  | 
|  | 86 | dwc3_writel(dwc->regs, DWC3_DCTL, reg); | 
|  | 87 |  | 
|  | 88 | return 0; | 
|  | 89 | } | 
|  | 90 |  | 
| Felipe Balbi | 8598bde | 2012-01-02 18:55:57 +0200 | [diff] [blame] | 91 | /** | 
|  | 92 | * dwc3_gadget_set_link_state - Sets USB Link to a particular State | 
|  | 93 | * @dwc: pointer to our context structure | 
|  | 94 | * @state: the state to put link into | 
|  | 95 | * | 
|  | 96 | * Caller should take care of locking. This function will | 
| Paul Zimmerman | aee63e3 | 2012-02-24 17:32:15 -0800 | [diff] [blame] | 97 | * return 0 on success or -ETIMEDOUT. | 
| Felipe Balbi | 8598bde | 2012-01-02 18:55:57 +0200 | [diff] [blame] | 98 | */ | 
|  | 99 | int dwc3_gadget_set_link_state(struct dwc3 *dwc, enum dwc3_link_state state) | 
|  | 100 | { | 
| Paul Zimmerman | aee63e3 | 2012-02-24 17:32:15 -0800 | [diff] [blame] | 101 | int		retries = 10000; | 
| Felipe Balbi | 8598bde | 2012-01-02 18:55:57 +0200 | [diff] [blame] | 102 | u32		reg; | 
|  | 103 |  | 
|  | 104 | reg = dwc3_readl(dwc->regs, DWC3_DCTL); | 
|  | 105 | reg &= ~DWC3_DCTL_ULSTCHNGREQ_MASK; | 
|  | 106 |  | 
|  | 107 | /* set requested state */ | 
|  | 108 | reg |= DWC3_DCTL_ULSTCHNGREQ(state); | 
|  | 109 | dwc3_writel(dwc->regs, DWC3_DCTL, reg); | 
|  | 110 |  | 
|  | 111 | /* wait for a change in DSTS */ | 
|  | 112 | while (--retries) { | 
|  | 113 | reg = dwc3_readl(dwc->regs, DWC3_DSTS); | 
|  | 114 |  | 
| Felipe Balbi | 8598bde | 2012-01-02 18:55:57 +0200 | [diff] [blame] | 115 | if (DWC3_DSTS_USBLNKST(reg) == state) | 
|  | 116 | return 0; | 
|  | 117 |  | 
| Paul Zimmerman | aee63e3 | 2012-02-24 17:32:15 -0800 | [diff] [blame] | 118 | udelay(5); | 
| Felipe Balbi | 8598bde | 2012-01-02 18:55:57 +0200 | [diff] [blame] | 119 | } | 
|  | 120 |  | 
|  | 121 | dev_vdbg(dwc->dev, "link state change request timed out\n"); | 
|  | 122 |  | 
|  | 123 | return -ETIMEDOUT; | 
|  | 124 | } | 
|  | 125 |  | 
| Felipe Balbi | 457e84b | 2012-01-18 18:04:09 +0200 | [diff] [blame] | 126 | /** | 
|  | 127 | * dwc3_gadget_resize_tx_fifos - reallocate fifo spaces for current use-case | 
|  | 128 | * @dwc: pointer to our context structure | 
|  | 129 | * | 
|  | 130 | * This function will a best effort FIFO allocation in order | 
|  | 131 | * to improve FIFO usage and throughput, while still allowing | 
|  | 132 | * us to enable as many endpoints as possible. | 
|  | 133 | * | 
|  | 134 | * Keep in mind that this operation will be highly dependent | 
|  | 135 | * on the configured size for RAM1 - which contains TxFifo -, | 
|  | 136 | * the amount of endpoints enabled on coreConsultant tool, and | 
|  | 137 | * the width of the Master Bus. | 
|  | 138 | * | 
|  | 139 | * In the ideal world, we would always be able to satisfy the | 
|  | 140 | * following equation: | 
|  | 141 | * | 
|  | 142 | * ((512 + 2 * MDWIDTH-Bytes) + (Number of IN Endpoints - 1) * \ | 
|  | 143 | * (3 * (1024 + MDWIDTH-Bytes) + MDWIDTH-Bytes)) / MDWIDTH-Bytes | 
|  | 144 | * | 
|  | 145 | * Unfortunately, due to many variables that's not always the case. | 
|  | 146 | */ | 
|  | 147 | int dwc3_gadget_resize_tx_fifos(struct dwc3 *dwc) | 
|  | 148 | { | 
|  | 149 | int		last_fifo_depth = 0; | 
|  | 150 | int		ram1_depth; | 
|  | 151 | int		fifo_size; | 
|  | 152 | int		mdwidth; | 
|  | 153 | int		num; | 
|  | 154 |  | 
|  | 155 | if (!dwc->needs_fifo_resize) | 
|  | 156 | return 0; | 
|  | 157 |  | 
|  | 158 | ram1_depth = DWC3_RAM1_DEPTH(dwc->hwparams.hwparams7); | 
|  | 159 | mdwidth = DWC3_MDWIDTH(dwc->hwparams.hwparams0); | 
|  | 160 |  | 
|  | 161 | /* MDWIDTH is represented in bits, we need it in bytes */ | 
|  | 162 | mdwidth >>= 3; | 
|  | 163 |  | 
|  | 164 | /* | 
|  | 165 | * FIXME For now we will only allocate 1 wMaxPacketSize space | 
|  | 166 | * for each enabled endpoint, later patches will come to | 
|  | 167 | * improve this algorithm so that we better use the internal | 
|  | 168 | * FIFO space | 
|  | 169 | */ | 
|  | 170 | for (num = 0; num < DWC3_ENDPOINTS_NUM; num++) { | 
|  | 171 | struct dwc3_ep	*dep = dwc->eps[num]; | 
|  | 172 | int		fifo_number = dep->number >> 1; | 
| Felipe Balbi | 2e81c36 | 2012-02-02 13:01:12 +0200 | [diff] [blame] | 173 | int		mult = 1; | 
| Felipe Balbi | 457e84b | 2012-01-18 18:04:09 +0200 | [diff] [blame] | 174 | int		tmp; | 
|  | 175 |  | 
|  | 176 | if (!(dep->number & 1)) | 
|  | 177 | continue; | 
|  | 178 |  | 
|  | 179 | if (!(dep->flags & DWC3_EP_ENABLED)) | 
|  | 180 | continue; | 
|  | 181 |  | 
| Felipe Balbi | 2e81c36 | 2012-02-02 13:01:12 +0200 | [diff] [blame] | 182 | if (usb_endpoint_xfer_bulk(dep->desc) | 
|  | 183 | || usb_endpoint_xfer_isoc(dep->desc)) | 
|  | 184 | mult = 3; | 
|  | 185 |  | 
|  | 186 | /* | 
|  | 187 | * REVISIT: the following assumes we will always have enough | 
|  | 188 | * space available on the FIFO RAM for all possible use cases. | 
|  | 189 | * Make sure that's true somehow and change FIFO allocation | 
|  | 190 | * accordingly. | 
|  | 191 | * | 
|  | 192 | * If we have Bulk or Isochronous endpoints, we want | 
|  | 193 | * them to be able to be very, very fast. So we're giving | 
|  | 194 | * those endpoints a fifo_size which is enough for 3 full | 
|  | 195 | * packets | 
|  | 196 | */ | 
|  | 197 | tmp = mult * (dep->endpoint.maxpacket + mdwidth); | 
| Felipe Balbi | 457e84b | 2012-01-18 18:04:09 +0200 | [diff] [blame] | 198 | tmp += mdwidth; | 
|  | 199 |  | 
|  | 200 | fifo_size = DIV_ROUND_UP(tmp, mdwidth); | 
| Felipe Balbi | 2e81c36 | 2012-02-02 13:01:12 +0200 | [diff] [blame] | 201 |  | 
| Felipe Balbi | 457e84b | 2012-01-18 18:04:09 +0200 | [diff] [blame] | 202 | fifo_size |= (last_fifo_depth << 16); | 
|  | 203 |  | 
|  | 204 | dev_vdbg(dwc->dev, "%s: Fifo Addr %04x Size %d\n", | 
|  | 205 | dep->name, last_fifo_depth, fifo_size & 0xffff); | 
|  | 206 |  | 
|  | 207 | dwc3_writel(dwc->regs, DWC3_GTXFIFOSIZ(fifo_number), | 
|  | 208 | fifo_size); | 
|  | 209 |  | 
|  | 210 | last_fifo_depth += (fifo_size & 0xffff); | 
|  | 211 | } | 
|  | 212 |  | 
|  | 213 | return 0; | 
|  | 214 | } | 
|  | 215 |  | 
| Felipe Balbi | 72246da | 2011-08-19 18:10:58 +0300 | [diff] [blame] | 216 | void dwc3_gadget_giveback(struct dwc3_ep *dep, struct dwc3_request *req, | 
|  | 217 | int status) | 
|  | 218 | { | 
|  | 219 | struct dwc3			*dwc = dep->dwc; | 
|  | 220 |  | 
|  | 221 | if (req->queued) { | 
| Felipe Balbi | eeb720f | 2011-11-28 12:46:59 +0200 | [diff] [blame] | 222 | if (req->request.num_mapped_sgs) | 
|  | 223 | dep->busy_slot += req->request.num_mapped_sgs; | 
|  | 224 | else | 
|  | 225 | dep->busy_slot++; | 
|  | 226 |  | 
| Felipe Balbi | 72246da | 2011-08-19 18:10:58 +0300 | [diff] [blame] | 227 | /* | 
|  | 228 | * Skip LINK TRB. We can't use req->trb and check for | 
|  | 229 | * DWC3_TRBCTL_LINK_TRB because it points the TRB we just | 
|  | 230 | * completed (not the LINK TRB). | 
|  | 231 | */ | 
|  | 232 | if (((dep->busy_slot & DWC3_TRB_MASK) == DWC3_TRB_NUM - 1) && | 
|  | 233 | usb_endpoint_xfer_isoc(dep->desc)) | 
|  | 234 | dep->busy_slot++; | 
|  | 235 | } | 
|  | 236 | list_del(&req->list); | 
| Felipe Balbi | eeb720f | 2011-11-28 12:46:59 +0200 | [diff] [blame] | 237 | req->trb = NULL; | 
| Felipe Balbi | 72246da | 2011-08-19 18:10:58 +0300 | [diff] [blame] | 238 |  | 
|  | 239 | if (req->request.status == -EINPROGRESS) | 
|  | 240 | req->request.status = status; | 
|  | 241 |  | 
| Felipe Balbi | 0fc9a1b | 2011-12-19 11:32:34 +0200 | [diff] [blame] | 242 | usb_gadget_unmap_request(&dwc->gadget, &req->request, | 
|  | 243 | req->direction); | 
| Felipe Balbi | 72246da | 2011-08-19 18:10:58 +0300 | [diff] [blame] | 244 |  | 
|  | 245 | dev_dbg(dwc->dev, "request %p from %s completed %d/%d ===> %d\n", | 
|  | 246 | req, dep->name, req->request.actual, | 
|  | 247 | req->request.length, status); | 
|  | 248 |  | 
|  | 249 | spin_unlock(&dwc->lock); | 
| Felipe Balbi | 0fc9a1b | 2011-12-19 11:32:34 +0200 | [diff] [blame] | 250 | req->request.complete(&dep->endpoint, &req->request); | 
| Felipe Balbi | 72246da | 2011-08-19 18:10:58 +0300 | [diff] [blame] | 251 | spin_lock(&dwc->lock); | 
|  | 252 | } | 
|  | 253 |  | 
|  | 254 | static const char *dwc3_gadget_ep_cmd_string(u8 cmd) | 
|  | 255 | { | 
|  | 256 | switch (cmd) { | 
|  | 257 | case DWC3_DEPCMD_DEPSTARTCFG: | 
|  | 258 | return "Start New Configuration"; | 
|  | 259 | case DWC3_DEPCMD_ENDTRANSFER: | 
|  | 260 | return "End Transfer"; | 
|  | 261 | case DWC3_DEPCMD_UPDATETRANSFER: | 
|  | 262 | return "Update Transfer"; | 
|  | 263 | case DWC3_DEPCMD_STARTTRANSFER: | 
|  | 264 | return "Start Transfer"; | 
|  | 265 | case DWC3_DEPCMD_CLEARSTALL: | 
|  | 266 | return "Clear Stall"; | 
|  | 267 | case DWC3_DEPCMD_SETSTALL: | 
|  | 268 | return "Set Stall"; | 
|  | 269 | case DWC3_DEPCMD_GETSEQNUMBER: | 
|  | 270 | return "Get Data Sequence Number"; | 
|  | 271 | case DWC3_DEPCMD_SETTRANSFRESOURCE: | 
|  | 272 | return "Set Endpoint Transfer Resource"; | 
|  | 273 | case DWC3_DEPCMD_SETEPCONFIG: | 
|  | 274 | return "Set Endpoint Configuration"; | 
|  | 275 | default: | 
|  | 276 | return "UNKNOWN command"; | 
|  | 277 | } | 
|  | 278 | } | 
|  | 279 |  | 
|  | 280 | int dwc3_send_gadget_ep_cmd(struct dwc3 *dwc, unsigned ep, | 
|  | 281 | unsigned cmd, struct dwc3_gadget_ep_cmd_params *params) | 
|  | 282 | { | 
|  | 283 | struct dwc3_ep		*dep = dwc->eps[ep]; | 
| Sebastian Andrzej Siewior | 61d5824 | 2011-08-29 16:46:38 +0200 | [diff] [blame] | 284 | u32			timeout = 500; | 
| Felipe Balbi | 72246da | 2011-08-19 18:10:58 +0300 | [diff] [blame] | 285 | u32			reg; | 
|  | 286 |  | 
|  | 287 | dev_vdbg(dwc->dev, "%s: cmd '%s' params %08x %08x %08x\n", | 
|  | 288 | dep->name, | 
| Felipe Balbi | dc1c70a | 2011-09-30 10:58:51 +0300 | [diff] [blame] | 289 | dwc3_gadget_ep_cmd_string(cmd), params->param0, | 
|  | 290 | params->param1, params->param2); | 
| Felipe Balbi | 72246da | 2011-08-19 18:10:58 +0300 | [diff] [blame] | 291 |  | 
| Felipe Balbi | dc1c70a | 2011-09-30 10:58:51 +0300 | [diff] [blame] | 292 | dwc3_writel(dwc->regs, DWC3_DEPCMDPAR0(ep), params->param0); | 
|  | 293 | dwc3_writel(dwc->regs, DWC3_DEPCMDPAR1(ep), params->param1); | 
|  | 294 | dwc3_writel(dwc->regs, DWC3_DEPCMDPAR2(ep), params->param2); | 
| Felipe Balbi | 72246da | 2011-08-19 18:10:58 +0300 | [diff] [blame] | 295 |  | 
|  | 296 | dwc3_writel(dwc->regs, DWC3_DEPCMD(ep), cmd | DWC3_DEPCMD_CMDACT); | 
|  | 297 | do { | 
|  | 298 | reg = dwc3_readl(dwc->regs, DWC3_DEPCMD(ep)); | 
|  | 299 | if (!(reg & DWC3_DEPCMD_CMDACT)) { | 
| Felipe Balbi | 164f6e1 | 2011-08-27 20:29:58 +0300 | [diff] [blame] | 300 | dev_vdbg(dwc->dev, "Command Complete --> %d\n", | 
|  | 301 | DWC3_DEPCMD_STATUS(reg)); | 
| Felipe Balbi | 72246da | 2011-08-19 18:10:58 +0300 | [diff] [blame] | 302 | return 0; | 
|  | 303 | } | 
|  | 304 |  | 
|  | 305 | /* | 
| Felipe Balbi | 72246da | 2011-08-19 18:10:58 +0300 | [diff] [blame] | 306 | * We can't sleep here, because it is also called from | 
|  | 307 | * interrupt context. | 
|  | 308 | */ | 
|  | 309 | timeout--; | 
|  | 310 | if (!timeout) | 
|  | 311 | return -ETIMEDOUT; | 
|  | 312 |  | 
| Sebastian Andrzej Siewior | 61d5824 | 2011-08-29 16:46:38 +0200 | [diff] [blame] | 313 | udelay(1); | 
| Felipe Balbi | 72246da | 2011-08-19 18:10:58 +0300 | [diff] [blame] | 314 | } while (1); | 
|  | 315 | } | 
|  | 316 |  | 
| Ido Shayevitz | fa65a58 | 2012-06-06 14:39:54 +0300 | [diff] [blame] | 317 | dma_addr_t dwc3_trb_dma_offset(struct dwc3_ep *dep, | 
| Felipe Balbi | f6bafc6 | 2012-02-06 11:04:53 +0200 | [diff] [blame] | 318 | struct dwc3_trb *trb) | 
| Felipe Balbi | 72246da | 2011-08-19 18:10:58 +0300 | [diff] [blame] | 319 | { | 
| Paul Zimmerman | c439ef8 | 2011-09-30 10:58:45 +0300 | [diff] [blame] | 320 | u32		offset = (char *) trb - (char *) dep->trb_pool; | 
| Felipe Balbi | 72246da | 2011-08-19 18:10:58 +0300 | [diff] [blame] | 321 |  | 
|  | 322 | return dep->trb_pool_dma + offset; | 
|  | 323 | } | 
|  | 324 |  | 
|  | 325 | static int dwc3_alloc_trb_pool(struct dwc3_ep *dep) | 
|  | 326 | { | 
|  | 327 | struct dwc3		*dwc = dep->dwc; | 
|  | 328 |  | 
|  | 329 | if (dep->trb_pool) | 
|  | 330 | return 0; | 
|  | 331 |  | 
|  | 332 | if (dep->number == 0 || dep->number == 1) | 
|  | 333 | return 0; | 
|  | 334 |  | 
|  | 335 | dep->trb_pool = dma_alloc_coherent(dwc->dev, | 
|  | 336 | sizeof(struct dwc3_trb) * DWC3_TRB_NUM, | 
|  | 337 | &dep->trb_pool_dma, GFP_KERNEL); | 
|  | 338 | if (!dep->trb_pool) { | 
|  | 339 | dev_err(dep->dwc->dev, "failed to allocate trb pool for %s\n", | 
|  | 340 | dep->name); | 
|  | 341 | return -ENOMEM; | 
|  | 342 | } | 
|  | 343 |  | 
|  | 344 | return 0; | 
|  | 345 | } | 
|  | 346 |  | 
|  | 347 | static void dwc3_free_trb_pool(struct dwc3_ep *dep) | 
|  | 348 | { | 
|  | 349 | struct dwc3		*dwc = dep->dwc; | 
|  | 350 |  | 
|  | 351 | dma_free_coherent(dwc->dev, sizeof(struct dwc3_trb) * DWC3_TRB_NUM, | 
|  | 352 | dep->trb_pool, dep->trb_pool_dma); | 
|  | 353 |  | 
|  | 354 | dep->trb_pool = NULL; | 
|  | 355 | dep->trb_pool_dma = 0; | 
|  | 356 | } | 
|  | 357 |  | 
|  | 358 | static int dwc3_gadget_start_config(struct dwc3 *dwc, struct dwc3_ep *dep) | 
|  | 359 | { | 
|  | 360 | struct dwc3_gadget_ep_cmd_params params; | 
|  | 361 | u32			cmd; | 
|  | 362 |  | 
|  | 363 | memset(¶ms, 0x00, sizeof(params)); | 
|  | 364 |  | 
|  | 365 | if (dep->number != 1) { | 
|  | 366 | cmd = DWC3_DEPCMD_DEPSTARTCFG; | 
|  | 367 | /* XferRscIdx == 0 for ep0 and 2 for the remaining */ | 
| Paul Zimmerman | b23c843 | 2011-09-30 10:58:42 +0300 | [diff] [blame] | 368 | if (dep->number > 1) { | 
|  | 369 | if (dwc->start_config_issued) | 
|  | 370 | return 0; | 
|  | 371 | dwc->start_config_issued = true; | 
| Felipe Balbi | 72246da | 2011-08-19 18:10:58 +0300 | [diff] [blame] | 372 | cmd |= DWC3_DEPCMD_PARAM(2); | 
| Paul Zimmerman | b23c843 | 2011-09-30 10:58:42 +0300 | [diff] [blame] | 373 | } | 
| Felipe Balbi | 72246da | 2011-08-19 18:10:58 +0300 | [diff] [blame] | 374 |  | 
|  | 375 | return dwc3_send_gadget_ep_cmd(dwc, 0, cmd, ¶ms); | 
|  | 376 | } | 
|  | 377 |  | 
|  | 378 | return 0; | 
|  | 379 | } | 
|  | 380 |  | 
|  | 381 | static int dwc3_gadget_set_ep_config(struct dwc3 *dwc, struct dwc3_ep *dep, | 
| Felipe Balbi | c90bfae | 2011-11-29 13:11:21 +0200 | [diff] [blame] | 382 | const struct usb_endpoint_descriptor *desc, | 
|  | 383 | const struct usb_ss_ep_comp_descriptor *comp_desc) | 
| Felipe Balbi | 72246da | 2011-08-19 18:10:58 +0300 | [diff] [blame] | 384 | { | 
|  | 385 | struct dwc3_gadget_ep_cmd_params params; | 
|  | 386 |  | 
|  | 387 | memset(¶ms, 0x00, sizeof(params)); | 
|  | 388 |  | 
| Felipe Balbi | dc1c70a | 2011-09-30 10:58:51 +0300 | [diff] [blame] | 389 | params.param0 = DWC3_DEPCFG_EP_TYPE(usb_endpoint_type(desc)) | 
|  | 390 | | DWC3_DEPCFG_MAX_PACKET_SIZE(usb_endpoint_maxp(desc)) | 
|  | 391 | | DWC3_DEPCFG_BURST_SIZE(dep->endpoint.maxburst); | 
| Felipe Balbi | 72246da | 2011-08-19 18:10:58 +0300 | [diff] [blame] | 392 |  | 
| Felipe Balbi | dc1c70a | 2011-09-30 10:58:51 +0300 | [diff] [blame] | 393 | params.param1 = DWC3_DEPCFG_XFER_COMPLETE_EN | 
|  | 394 | | DWC3_DEPCFG_XFER_NOT_READY_EN; | 
| Felipe Balbi | 72246da | 2011-08-19 18:10:58 +0300 | [diff] [blame] | 395 |  | 
| Felipe Balbi | 18b7ede | 2012-01-02 13:35:41 +0200 | [diff] [blame] | 396 | if (usb_ss_max_streams(comp_desc) && usb_endpoint_xfer_bulk(desc)) { | 
| Felipe Balbi | dc1c70a | 2011-09-30 10:58:51 +0300 | [diff] [blame] | 397 | params.param1 |= DWC3_DEPCFG_STREAM_CAPABLE | 
|  | 398 | | DWC3_DEPCFG_STREAM_EVENT_EN; | 
| Felipe Balbi | 879631a | 2011-09-30 10:58:47 +0300 | [diff] [blame] | 399 | dep->stream_capable = true; | 
|  | 400 | } | 
|  | 401 |  | 
| Felipe Balbi | 72246da | 2011-08-19 18:10:58 +0300 | [diff] [blame] | 402 | if (usb_endpoint_xfer_isoc(desc)) | 
| Felipe Balbi | dc1c70a | 2011-09-30 10:58:51 +0300 | [diff] [blame] | 403 | params.param1 |= DWC3_DEPCFG_XFER_IN_PROGRESS_EN; | 
| Felipe Balbi | 72246da | 2011-08-19 18:10:58 +0300 | [diff] [blame] | 404 |  | 
|  | 405 | /* | 
|  | 406 | * We are doing 1:1 mapping for endpoints, meaning | 
|  | 407 | * Physical Endpoints 2 maps to Logical Endpoint 2 and | 
|  | 408 | * so on. We consider the direction bit as part of the physical | 
|  | 409 | * endpoint number. So USB endpoint 0x81 is 0x03. | 
|  | 410 | */ | 
| Felipe Balbi | dc1c70a | 2011-09-30 10:58:51 +0300 | [diff] [blame] | 411 | params.param1 |= DWC3_DEPCFG_EP_NUMBER(dep->number); | 
| Felipe Balbi | 72246da | 2011-08-19 18:10:58 +0300 | [diff] [blame] | 412 |  | 
|  | 413 | /* | 
|  | 414 | * We must use the lower 16 TX FIFOs even though | 
|  | 415 | * HW might have more | 
|  | 416 | */ | 
|  | 417 | if (dep->direction) | 
| Felipe Balbi | dc1c70a | 2011-09-30 10:58:51 +0300 | [diff] [blame] | 418 | params.param0 |= DWC3_DEPCFG_FIFO_NUMBER(dep->number >> 1); | 
| Felipe Balbi | 72246da | 2011-08-19 18:10:58 +0300 | [diff] [blame] | 419 |  | 
|  | 420 | if (desc->bInterval) { | 
| Felipe Balbi | dc1c70a | 2011-09-30 10:58:51 +0300 | [diff] [blame] | 421 | params.param1 |= DWC3_DEPCFG_BINTERVAL_M1(desc->bInterval - 1); | 
| Felipe Balbi | 72246da | 2011-08-19 18:10:58 +0300 | [diff] [blame] | 422 | dep->interval = 1 << (desc->bInterval - 1); | 
|  | 423 | } | 
|  | 424 |  | 
|  | 425 | return dwc3_send_gadget_ep_cmd(dwc, dep->number, | 
|  | 426 | DWC3_DEPCMD_SETEPCONFIG, ¶ms); | 
|  | 427 | } | 
|  | 428 |  | 
|  | 429 | static int dwc3_gadget_set_xfer_resource(struct dwc3 *dwc, struct dwc3_ep *dep) | 
|  | 430 | { | 
|  | 431 | struct dwc3_gadget_ep_cmd_params params; | 
|  | 432 |  | 
|  | 433 | memset(¶ms, 0x00, sizeof(params)); | 
|  | 434 |  | 
| Felipe Balbi | dc1c70a | 2011-09-30 10:58:51 +0300 | [diff] [blame] | 435 | params.param0 = DWC3_DEPXFERCFG_NUM_XFER_RES(1); | 
| Felipe Balbi | 72246da | 2011-08-19 18:10:58 +0300 | [diff] [blame] | 436 |  | 
|  | 437 | return dwc3_send_gadget_ep_cmd(dwc, dep->number, | 
|  | 438 | DWC3_DEPCMD_SETTRANSFRESOURCE, ¶ms); | 
|  | 439 | } | 
|  | 440 |  | 
|  | 441 | /** | 
|  | 442 | * __dwc3_gadget_ep_enable - Initializes a HW endpoint | 
|  | 443 | * @dep: endpoint to be initialized | 
|  | 444 | * @desc: USB Endpoint Descriptor | 
|  | 445 | * | 
|  | 446 | * Caller should take care of locking | 
|  | 447 | */ | 
|  | 448 | static int __dwc3_gadget_ep_enable(struct dwc3_ep *dep, | 
| Felipe Balbi | c90bfae | 2011-11-29 13:11:21 +0200 | [diff] [blame] | 449 | const struct usb_endpoint_descriptor *desc, | 
|  | 450 | const struct usb_ss_ep_comp_descriptor *comp_desc) | 
| Felipe Balbi | 72246da | 2011-08-19 18:10:58 +0300 | [diff] [blame] | 451 | { | 
|  | 452 | struct dwc3		*dwc = dep->dwc; | 
|  | 453 | u32			reg; | 
|  | 454 | int			ret = -ENOMEM; | 
|  | 455 |  | 
|  | 456 | if (!(dep->flags & DWC3_EP_ENABLED)) { | 
|  | 457 | ret = dwc3_gadget_start_config(dwc, dep); | 
|  | 458 | if (ret) | 
|  | 459 | return ret; | 
|  | 460 | } | 
|  | 461 |  | 
| Felipe Balbi | c90bfae | 2011-11-29 13:11:21 +0200 | [diff] [blame] | 462 | ret = dwc3_gadget_set_ep_config(dwc, dep, desc, comp_desc); | 
| Felipe Balbi | 72246da | 2011-08-19 18:10:58 +0300 | [diff] [blame] | 463 | if (ret) | 
|  | 464 | return ret; | 
|  | 465 |  | 
|  | 466 | if (!(dep->flags & DWC3_EP_ENABLED)) { | 
| Felipe Balbi | f6bafc6 | 2012-02-06 11:04:53 +0200 | [diff] [blame] | 467 | struct dwc3_trb	*trb_st_hw; | 
|  | 468 | struct dwc3_trb	*trb_link; | 
| Felipe Balbi | 72246da | 2011-08-19 18:10:58 +0300 | [diff] [blame] | 469 |  | 
|  | 470 | ret = dwc3_gadget_set_xfer_resource(dwc, dep); | 
|  | 471 | if (ret) | 
|  | 472 | return ret; | 
|  | 473 |  | 
|  | 474 | dep->desc = desc; | 
| Felipe Balbi | c90bfae | 2011-11-29 13:11:21 +0200 | [diff] [blame] | 475 | dep->comp_desc = comp_desc; | 
| Felipe Balbi | 72246da | 2011-08-19 18:10:58 +0300 | [diff] [blame] | 476 | dep->type = usb_endpoint_type(desc); | 
|  | 477 | dep->flags |= DWC3_EP_ENABLED; | 
|  | 478 |  | 
|  | 479 | reg = dwc3_readl(dwc->regs, DWC3_DALEPENA); | 
|  | 480 | reg |= DWC3_DALEPENA_EP(dep->number); | 
|  | 481 | dwc3_writel(dwc->regs, DWC3_DALEPENA, reg); | 
|  | 482 |  | 
|  | 483 | if (!usb_endpoint_xfer_isoc(desc)) | 
|  | 484 | return 0; | 
|  | 485 |  | 
|  | 486 | memset(&trb_link, 0, sizeof(trb_link)); | 
|  | 487 |  | 
| Paul Zimmerman | 1d04679 | 2012-02-15 18:56:56 -0800 | [diff] [blame] | 488 | /* Link TRB for ISOC. The HWO bit is never reset */ | 
| Felipe Balbi | 72246da | 2011-08-19 18:10:58 +0300 | [diff] [blame] | 489 | trb_st_hw = &dep->trb_pool[0]; | 
|  | 490 |  | 
| Felipe Balbi | f6bafc6 | 2012-02-06 11:04:53 +0200 | [diff] [blame] | 491 | trb_link = &dep->trb_pool[DWC3_TRB_NUM - 1]; | 
| Felipe Balbi | 72246da | 2011-08-19 18:10:58 +0300 | [diff] [blame] | 492 |  | 
| Felipe Balbi | f6bafc6 | 2012-02-06 11:04:53 +0200 | [diff] [blame] | 493 | trb_link->bpl = lower_32_bits(dwc3_trb_dma_offset(dep, trb_st_hw)); | 
|  | 494 | trb_link->bph = upper_32_bits(dwc3_trb_dma_offset(dep, trb_st_hw)); | 
|  | 495 | trb_link->ctrl |= DWC3_TRBCTL_LINK_TRB; | 
|  | 496 | trb_link->ctrl |= DWC3_TRB_CTRL_HWO; | 
| Felipe Balbi | 72246da | 2011-08-19 18:10:58 +0300 | [diff] [blame] | 497 | } | 
|  | 498 |  | 
|  | 499 | return 0; | 
|  | 500 | } | 
|  | 501 |  | 
| Sebastian Andrzej Siewior | 624407f | 2011-08-29 13:56:37 +0200 | [diff] [blame] | 502 | static void dwc3_stop_active_transfer(struct dwc3 *dwc, u32 epnum); | 
|  | 503 | static void dwc3_remove_requests(struct dwc3 *dwc, struct dwc3_ep *dep) | 
| Felipe Balbi | 72246da | 2011-08-19 18:10:58 +0300 | [diff] [blame] | 504 | { | 
|  | 505 | struct dwc3_request		*req; | 
|  | 506 |  | 
| Sebastian Andrzej Siewior | 624407f | 2011-08-29 13:56:37 +0200 | [diff] [blame] | 507 | if (!list_empty(&dep->req_queued)) | 
|  | 508 | dwc3_stop_active_transfer(dwc, dep->number); | 
|  | 509 |  | 
| Felipe Balbi | 72246da | 2011-08-19 18:10:58 +0300 | [diff] [blame] | 510 | while (!list_empty(&dep->request_list)) { | 
|  | 511 | req = next_request(&dep->request_list); | 
|  | 512 |  | 
| Sebastian Andrzej Siewior | 624407f | 2011-08-29 13:56:37 +0200 | [diff] [blame] | 513 | dwc3_gadget_giveback(dep, req, -ESHUTDOWN); | 
| Felipe Balbi | 72246da | 2011-08-19 18:10:58 +0300 | [diff] [blame] | 514 | } | 
| Felipe Balbi | 72246da | 2011-08-19 18:10:58 +0300 | [diff] [blame] | 515 | } | 
|  | 516 |  | 
|  | 517 | /** | 
|  | 518 | * __dwc3_gadget_ep_disable - Disables a HW endpoint | 
|  | 519 | * @dep: the endpoint to disable | 
|  | 520 | * | 
| Sebastian Andrzej Siewior | 624407f | 2011-08-29 13:56:37 +0200 | [diff] [blame] | 521 | * This function also removes requests which are currently processed ny the | 
|  | 522 | * hardware and those which are not yet scheduled. | 
|  | 523 | * Caller should take care of locking. | 
| Felipe Balbi | 72246da | 2011-08-19 18:10:58 +0300 | [diff] [blame] | 524 | */ | 
| Felipe Balbi | 72246da | 2011-08-19 18:10:58 +0300 | [diff] [blame] | 525 | static int __dwc3_gadget_ep_disable(struct dwc3_ep *dep) | 
|  | 526 | { | 
|  | 527 | struct dwc3		*dwc = dep->dwc; | 
|  | 528 | u32			reg; | 
|  | 529 |  | 
| Sebastian Andrzej Siewior | 624407f | 2011-08-29 13:56:37 +0200 | [diff] [blame] | 530 | dwc3_remove_requests(dwc, dep); | 
| Felipe Balbi | 72246da | 2011-08-19 18:10:58 +0300 | [diff] [blame] | 531 |  | 
|  | 532 | reg = dwc3_readl(dwc->regs, DWC3_DALEPENA); | 
|  | 533 | reg &= ~DWC3_DALEPENA_EP(dep->number); | 
|  | 534 | dwc3_writel(dwc->regs, DWC3_DALEPENA, reg); | 
|  | 535 |  | 
| Felipe Balbi | 879631a | 2011-09-30 10:58:47 +0300 | [diff] [blame] | 536 | dep->stream_capable = false; | 
| Felipe Balbi | 72246da | 2011-08-19 18:10:58 +0300 | [diff] [blame] | 537 | dep->desc = NULL; | 
| Ido Shayevitz | f9c56cd | 2012-02-08 13:56:48 +0200 | [diff] [blame] | 538 | dep->endpoint.desc = NULL; | 
| Felipe Balbi | c90bfae | 2011-11-29 13:11:21 +0200 | [diff] [blame] | 539 | dep->comp_desc = NULL; | 
| Felipe Balbi | 72246da | 2011-08-19 18:10:58 +0300 | [diff] [blame] | 540 | dep->type = 0; | 
| Felipe Balbi | 879631a | 2011-09-30 10:58:47 +0300 | [diff] [blame] | 541 | dep->flags = 0; | 
| Felipe Balbi | 72246da | 2011-08-19 18:10:58 +0300 | [diff] [blame] | 542 |  | 
|  | 543 | return 0; | 
|  | 544 | } | 
|  | 545 |  | 
|  | 546 | /* -------------------------------------------------------------------------- */ | 
|  | 547 |  | 
|  | 548 | static int dwc3_gadget_ep0_enable(struct usb_ep *ep, | 
|  | 549 | const struct usb_endpoint_descriptor *desc) | 
|  | 550 | { | 
|  | 551 | return -EINVAL; | 
|  | 552 | } | 
|  | 553 |  | 
|  | 554 | static int dwc3_gadget_ep0_disable(struct usb_ep *ep) | 
|  | 555 | { | 
|  | 556 | return -EINVAL; | 
|  | 557 | } | 
|  | 558 |  | 
|  | 559 | /* -------------------------------------------------------------------------- */ | 
|  | 560 |  | 
|  | 561 | static int dwc3_gadget_ep_enable(struct usb_ep *ep, | 
|  | 562 | const struct usb_endpoint_descriptor *desc) | 
|  | 563 | { | 
|  | 564 | struct dwc3_ep			*dep; | 
|  | 565 | struct dwc3			*dwc; | 
|  | 566 | unsigned long			flags; | 
|  | 567 | int				ret; | 
|  | 568 |  | 
|  | 569 | if (!ep || !desc || desc->bDescriptorType != USB_DT_ENDPOINT) { | 
|  | 570 | pr_debug("dwc3: invalid parameters\n"); | 
|  | 571 | return -EINVAL; | 
|  | 572 | } | 
|  | 573 |  | 
|  | 574 | if (!desc->wMaxPacketSize) { | 
|  | 575 | pr_debug("dwc3: missing wMaxPacketSize\n"); | 
|  | 576 | return -EINVAL; | 
|  | 577 | } | 
|  | 578 |  | 
|  | 579 | dep = to_dwc3_ep(ep); | 
|  | 580 | dwc = dep->dwc; | 
|  | 581 |  | 
|  | 582 | switch (usb_endpoint_type(desc)) { | 
|  | 583 | case USB_ENDPOINT_XFER_CONTROL: | 
| Anton Tikhomirov | 27a78d6 | 2012-02-23 15:38:46 +0900 | [diff] [blame] | 584 | strlcat(dep->name, "-control", sizeof(dep->name)); | 
| Felipe Balbi | 72246da | 2011-08-19 18:10:58 +0300 | [diff] [blame] | 585 | break; | 
|  | 586 | case USB_ENDPOINT_XFER_ISOC: | 
| Anton Tikhomirov | 27a78d6 | 2012-02-23 15:38:46 +0900 | [diff] [blame] | 587 | strlcat(dep->name, "-isoc", sizeof(dep->name)); | 
| Felipe Balbi | 72246da | 2011-08-19 18:10:58 +0300 | [diff] [blame] | 588 | break; | 
|  | 589 | case USB_ENDPOINT_XFER_BULK: | 
| Anton Tikhomirov | 27a78d6 | 2012-02-23 15:38:46 +0900 | [diff] [blame] | 590 | strlcat(dep->name, "-bulk", sizeof(dep->name)); | 
| Felipe Balbi | 72246da | 2011-08-19 18:10:58 +0300 | [diff] [blame] | 591 | break; | 
|  | 592 | case USB_ENDPOINT_XFER_INT: | 
| Anton Tikhomirov | 27a78d6 | 2012-02-23 15:38:46 +0900 | [diff] [blame] | 593 | strlcat(dep->name, "-int", sizeof(dep->name)); | 
| Felipe Balbi | 72246da | 2011-08-19 18:10:58 +0300 | [diff] [blame] | 594 | break; | 
|  | 595 | default: | 
|  | 596 | dev_err(dwc->dev, "invalid endpoint transfer type\n"); | 
|  | 597 | } | 
|  | 598 |  | 
|  | 599 | if (dep->flags & DWC3_EP_ENABLED) { | 
|  | 600 | dev_WARN_ONCE(dwc->dev, true, "%s is already enabled\n", | 
|  | 601 | dep->name); | 
|  | 602 | return 0; | 
|  | 603 | } | 
|  | 604 |  | 
|  | 605 | dev_vdbg(dwc->dev, "Enabling %s\n", dep->name); | 
|  | 606 |  | 
|  | 607 | spin_lock_irqsave(&dwc->lock, flags); | 
| Felipe Balbi | c90bfae | 2011-11-29 13:11:21 +0200 | [diff] [blame] | 608 | ret = __dwc3_gadget_ep_enable(dep, desc, ep->comp_desc); | 
| Felipe Balbi | 72246da | 2011-08-19 18:10:58 +0300 | [diff] [blame] | 609 | spin_unlock_irqrestore(&dwc->lock, flags); | 
|  | 610 |  | 
|  | 611 | return ret; | 
|  | 612 | } | 
|  | 613 |  | 
|  | 614 | static int dwc3_gadget_ep_disable(struct usb_ep *ep) | 
|  | 615 | { | 
|  | 616 | struct dwc3_ep			*dep; | 
|  | 617 | struct dwc3			*dwc; | 
|  | 618 | unsigned long			flags; | 
|  | 619 | int				ret; | 
|  | 620 |  | 
|  | 621 | if (!ep) { | 
|  | 622 | pr_debug("dwc3: invalid parameters\n"); | 
|  | 623 | return -EINVAL; | 
|  | 624 | } | 
|  | 625 |  | 
|  | 626 | dep = to_dwc3_ep(ep); | 
|  | 627 | dwc = dep->dwc; | 
|  | 628 |  | 
|  | 629 | if (!(dep->flags & DWC3_EP_ENABLED)) { | 
|  | 630 | dev_WARN_ONCE(dwc->dev, true, "%s is already disabled\n", | 
|  | 631 | dep->name); | 
|  | 632 | return 0; | 
|  | 633 | } | 
|  | 634 |  | 
|  | 635 | snprintf(dep->name, sizeof(dep->name), "ep%d%s", | 
|  | 636 | dep->number >> 1, | 
|  | 637 | (dep->number & 1) ? "in" : "out"); | 
|  | 638 |  | 
|  | 639 | spin_lock_irqsave(&dwc->lock, flags); | 
|  | 640 | ret = __dwc3_gadget_ep_disable(dep); | 
|  | 641 | spin_unlock_irqrestore(&dwc->lock, flags); | 
|  | 642 |  | 
|  | 643 | return ret; | 
|  | 644 | } | 
|  | 645 |  | 
|  | 646 | static struct usb_request *dwc3_gadget_ep_alloc_request(struct usb_ep *ep, | 
|  | 647 | gfp_t gfp_flags) | 
|  | 648 | { | 
|  | 649 | struct dwc3_request		*req; | 
|  | 650 | struct dwc3_ep			*dep = to_dwc3_ep(ep); | 
|  | 651 | struct dwc3			*dwc = dep->dwc; | 
|  | 652 |  | 
|  | 653 | req = kzalloc(sizeof(*req), gfp_flags); | 
|  | 654 | if (!req) { | 
|  | 655 | dev_err(dwc->dev, "not enough memory\n"); | 
|  | 656 | return NULL; | 
|  | 657 | } | 
|  | 658 |  | 
|  | 659 | req->epnum	= dep->number; | 
|  | 660 | req->dep	= dep; | 
| Felipe Balbi | 72246da | 2011-08-19 18:10:58 +0300 | [diff] [blame] | 661 |  | 
|  | 662 | return &req->request; | 
|  | 663 | } | 
|  | 664 |  | 
|  | 665 | static void dwc3_gadget_ep_free_request(struct usb_ep *ep, | 
|  | 666 | struct usb_request *request) | 
|  | 667 | { | 
|  | 668 | struct dwc3_request		*req = to_dwc3_request(request); | 
|  | 669 |  | 
|  | 670 | kfree(req); | 
|  | 671 | } | 
|  | 672 |  | 
| Felipe Balbi | c71fc37 | 2011-11-22 11:37:34 +0200 | [diff] [blame] | 673 | /** | 
|  | 674 | * dwc3_prepare_one_trb - setup one TRB from one request | 
|  | 675 | * @dep: endpoint for which this request is prepared | 
|  | 676 | * @req: dwc3_request pointer | 
|  | 677 | */ | 
| Felipe Balbi | 68e823e | 2011-11-28 12:25:01 +0200 | [diff] [blame] | 678 | static void dwc3_prepare_one_trb(struct dwc3_ep *dep, | 
| Felipe Balbi | eeb720f | 2011-11-28 12:46:59 +0200 | [diff] [blame] | 679 | struct dwc3_request *req, dma_addr_t dma, | 
|  | 680 | unsigned length, unsigned last, unsigned chain) | 
| Felipe Balbi | c71fc37 | 2011-11-22 11:37:34 +0200 | [diff] [blame] | 681 | { | 
| Felipe Balbi | eeb720f | 2011-11-28 12:46:59 +0200 | [diff] [blame] | 682 | struct dwc3		*dwc = dep->dwc; | 
| Felipe Balbi | f6bafc6 | 2012-02-06 11:04:53 +0200 | [diff] [blame] | 683 | struct dwc3_trb		*trb; | 
| Felipe Balbi | c71fc37 | 2011-11-22 11:37:34 +0200 | [diff] [blame] | 684 |  | 
|  | 685 | unsigned int		cur_slot; | 
|  | 686 |  | 
| Felipe Balbi | eeb720f | 2011-11-28 12:46:59 +0200 | [diff] [blame] | 687 | dev_vdbg(dwc->dev, "%s: req %p dma %08llx length %d%s%s\n", | 
|  | 688 | dep->name, req, (unsigned long long) dma, | 
|  | 689 | length, last ? " last" : "", | 
|  | 690 | chain ? " chain" : ""); | 
|  | 691 |  | 
| Felipe Balbi | f6bafc6 | 2012-02-06 11:04:53 +0200 | [diff] [blame] | 692 | trb = &dep->trb_pool[dep->free_slot & DWC3_TRB_MASK]; | 
| Felipe Balbi | c71fc37 | 2011-11-22 11:37:34 +0200 | [diff] [blame] | 693 | cur_slot = dep->free_slot; | 
|  | 694 | dep->free_slot++; | 
|  | 695 |  | 
|  | 696 | /* Skip the LINK-TRB on ISOC */ | 
|  | 697 | if (((cur_slot & DWC3_TRB_MASK) == DWC3_TRB_NUM - 1) && | 
|  | 698 | usb_endpoint_xfer_isoc(dep->desc)) | 
| Felipe Balbi | 68e823e | 2011-11-28 12:25:01 +0200 | [diff] [blame] | 699 | return; | 
| Felipe Balbi | c71fc37 | 2011-11-22 11:37:34 +0200 | [diff] [blame] | 700 |  | 
| Felipe Balbi | eeb720f | 2011-11-28 12:46:59 +0200 | [diff] [blame] | 701 | if (!req->trb) { | 
|  | 702 | dwc3_gadget_move_request_queued(req); | 
| Felipe Balbi | f6bafc6 | 2012-02-06 11:04:53 +0200 | [diff] [blame] | 703 | req->trb = trb; | 
|  | 704 | req->trb_dma = dwc3_trb_dma_offset(dep, trb); | 
| Felipe Balbi | eeb720f | 2011-11-28 12:46:59 +0200 | [diff] [blame] | 705 | } | 
| Felipe Balbi | c71fc37 | 2011-11-22 11:37:34 +0200 | [diff] [blame] | 706 |  | 
| Felipe Balbi | f6bafc6 | 2012-02-06 11:04:53 +0200 | [diff] [blame] | 707 | trb->size = DWC3_TRB_SIZE_LENGTH(length); | 
|  | 708 | trb->bpl = lower_32_bits(dma); | 
|  | 709 | trb->bph = upper_32_bits(dma); | 
| Felipe Balbi | c71fc37 | 2011-11-22 11:37:34 +0200 | [diff] [blame] | 710 |  | 
|  | 711 | switch (usb_endpoint_type(dep->desc)) { | 
|  | 712 | case USB_ENDPOINT_XFER_CONTROL: | 
| Felipe Balbi | f6bafc6 | 2012-02-06 11:04:53 +0200 | [diff] [blame] | 713 | trb->ctrl = DWC3_TRBCTL_CONTROL_SETUP; | 
| Felipe Balbi | c71fc37 | 2011-11-22 11:37:34 +0200 | [diff] [blame] | 714 | break; | 
|  | 715 |  | 
|  | 716 | case USB_ENDPOINT_XFER_ISOC: | 
| Felipe Balbi | f6bafc6 | 2012-02-06 11:04:53 +0200 | [diff] [blame] | 717 | trb->ctrl = DWC3_TRBCTL_ISOCHRONOUS_FIRST; | 
| Felipe Balbi | c71fc37 | 2011-11-22 11:37:34 +0200 | [diff] [blame] | 718 |  | 
|  | 719 | /* IOC every DWC3_TRB_NUM / 4 so we can refill */ | 
|  | 720 | if (!(cur_slot % (DWC3_TRB_NUM / 4))) | 
| Felipe Balbi | f6bafc6 | 2012-02-06 11:04:53 +0200 | [diff] [blame] | 721 | trb->ctrl |= DWC3_TRB_CTRL_IOC; | 
| Felipe Balbi | c71fc37 | 2011-11-22 11:37:34 +0200 | [diff] [blame] | 722 | break; | 
|  | 723 |  | 
|  | 724 | case USB_ENDPOINT_XFER_BULK: | 
|  | 725 | case USB_ENDPOINT_XFER_INT: | 
| Felipe Balbi | f6bafc6 | 2012-02-06 11:04:53 +0200 | [diff] [blame] | 726 | trb->ctrl = DWC3_TRBCTL_NORMAL; | 
| Felipe Balbi | c71fc37 | 2011-11-22 11:37:34 +0200 | [diff] [blame] | 727 | break; | 
|  | 728 | default: | 
|  | 729 | /* | 
|  | 730 | * This is only possible with faulty memory because we | 
|  | 731 | * checked it already :) | 
|  | 732 | */ | 
|  | 733 | BUG(); | 
|  | 734 | } | 
|  | 735 |  | 
| Felipe Balbi | f6bafc6 | 2012-02-06 11:04:53 +0200 | [diff] [blame] | 736 | if (usb_endpoint_xfer_isoc(dep->desc)) { | 
|  | 737 | trb->ctrl |= DWC3_TRB_CTRL_ISP_IMI; | 
|  | 738 | trb->ctrl |= DWC3_TRB_CTRL_CSP; | 
|  | 739 | } else { | 
|  | 740 | if (chain) | 
|  | 741 | trb->ctrl |= DWC3_TRB_CTRL_CHN; | 
| Felipe Balbi | c71fc37 | 2011-11-22 11:37:34 +0200 | [diff] [blame] | 742 |  | 
| Felipe Balbi | f6bafc6 | 2012-02-06 11:04:53 +0200 | [diff] [blame] | 743 | if (last) | 
|  | 744 | trb->ctrl |= DWC3_TRB_CTRL_LST; | 
|  | 745 | } | 
|  | 746 |  | 
|  | 747 | if (usb_endpoint_xfer_bulk(dep->desc) && dep->stream_capable) | 
|  | 748 | trb->ctrl |= DWC3_TRB_CTRL_SID_SOFN(req->request.stream_id); | 
|  | 749 |  | 
|  | 750 | trb->ctrl |= DWC3_TRB_CTRL_HWO; | 
| Felipe Balbi | c71fc37 | 2011-11-22 11:37:34 +0200 | [diff] [blame] | 751 | } | 
|  | 752 |  | 
| Felipe Balbi | 72246da | 2011-08-19 18:10:58 +0300 | [diff] [blame] | 753 | /* | 
|  | 754 | * dwc3_prepare_trbs - setup TRBs from requests | 
|  | 755 | * @dep: endpoint for which requests are being prepared | 
|  | 756 | * @starting: true if the endpoint is idle and no requests are queued. | 
|  | 757 | * | 
| Paul Zimmerman | 1d04679 | 2012-02-15 18:56:56 -0800 | [diff] [blame] | 758 | * The function goes through the requests list and sets up TRBs for the | 
|  | 759 | * transfers. The function returns once there are no more TRBs available or | 
|  | 760 | * it runs out of requests. | 
| Felipe Balbi | 72246da | 2011-08-19 18:10:58 +0300 | [diff] [blame] | 761 | */ | 
| Felipe Balbi | 68e823e | 2011-11-28 12:25:01 +0200 | [diff] [blame] | 762 | static void dwc3_prepare_trbs(struct dwc3_ep *dep, bool starting) | 
| Felipe Balbi | 72246da | 2011-08-19 18:10:58 +0300 | [diff] [blame] | 763 | { | 
| Felipe Balbi | 68e823e | 2011-11-28 12:25:01 +0200 | [diff] [blame] | 764 | struct dwc3_request	*req, *n; | 
| Felipe Balbi | 72246da | 2011-08-19 18:10:58 +0300 | [diff] [blame] | 765 | u32			trbs_left; | 
| Paul Zimmerman | 8d62cd6 | 2012-02-15 13:35:06 +0200 | [diff] [blame] | 766 | u32			max; | 
| Felipe Balbi | c71fc37 | 2011-11-22 11:37:34 +0200 | [diff] [blame] | 767 | unsigned int		last_one = 0; | 
| Felipe Balbi | 72246da | 2011-08-19 18:10:58 +0300 | [diff] [blame] | 768 |  | 
|  | 769 | BUILD_BUG_ON_NOT_POWER_OF_2(DWC3_TRB_NUM); | 
|  | 770 |  | 
|  | 771 | /* the first request must not be queued */ | 
|  | 772 | trbs_left = (dep->busy_slot - dep->free_slot) & DWC3_TRB_MASK; | 
| Felipe Balbi | c71fc37 | 2011-11-22 11:37:34 +0200 | [diff] [blame] | 773 |  | 
| Paul Zimmerman | 8d62cd6 | 2012-02-15 13:35:06 +0200 | [diff] [blame] | 774 | /* Can't wrap around on a non-isoc EP since there's no link TRB */ | 
|  | 775 | if (!usb_endpoint_xfer_isoc(dep->desc)) { | 
|  | 776 | max = DWC3_TRB_NUM - (dep->free_slot & DWC3_TRB_MASK); | 
|  | 777 | if (trbs_left > max) | 
|  | 778 | trbs_left = max; | 
|  | 779 | } | 
|  | 780 |  | 
| Felipe Balbi | 72246da | 2011-08-19 18:10:58 +0300 | [diff] [blame] | 781 | /* | 
| Paul Zimmerman | 1d04679 | 2012-02-15 18:56:56 -0800 | [diff] [blame] | 782 | * If busy & slot are equal than it is either full or empty. If we are | 
|  | 783 | * starting to process requests then we are empty. Otherwise we are | 
| Felipe Balbi | 72246da | 2011-08-19 18:10:58 +0300 | [diff] [blame] | 784 | * full and don't do anything | 
|  | 785 | */ | 
|  | 786 | if (!trbs_left) { | 
|  | 787 | if (!starting) | 
| Felipe Balbi | 68e823e | 2011-11-28 12:25:01 +0200 | [diff] [blame] | 788 | return; | 
| Felipe Balbi | 72246da | 2011-08-19 18:10:58 +0300 | [diff] [blame] | 789 | trbs_left = DWC3_TRB_NUM; | 
|  | 790 | /* | 
|  | 791 | * In case we start from scratch, we queue the ISOC requests | 
|  | 792 | * starting from slot 1. This is done because we use ring | 
|  | 793 | * buffer and have no LST bit to stop us. Instead, we place | 
| Paul Zimmerman | 1d04679 | 2012-02-15 18:56:56 -0800 | [diff] [blame] | 794 | * IOC bit every TRB_NUM/4. We try to avoid having an interrupt | 
| Felipe Balbi | 72246da | 2011-08-19 18:10:58 +0300 | [diff] [blame] | 795 | * after the first request so we start at slot 1 and have | 
|  | 796 | * 7 requests proceed before we hit the first IOC. | 
|  | 797 | * Other transfer types don't use the ring buffer and are | 
|  | 798 | * processed from the first TRB until the last one. Since we | 
|  | 799 | * don't wrap around we have to start at the beginning. | 
|  | 800 | */ | 
|  | 801 | if (usb_endpoint_xfer_isoc(dep->desc)) { | 
|  | 802 | dep->busy_slot = 1; | 
|  | 803 | dep->free_slot = 1; | 
|  | 804 | } else { | 
|  | 805 | dep->busy_slot = 0; | 
|  | 806 | dep->free_slot = 0; | 
|  | 807 | } | 
|  | 808 | } | 
|  | 809 |  | 
|  | 810 | /* The last TRB is a link TRB, not used for xfer */ | 
|  | 811 | if ((trbs_left <= 1) && usb_endpoint_xfer_isoc(dep->desc)) | 
| Felipe Balbi | 68e823e | 2011-11-28 12:25:01 +0200 | [diff] [blame] | 812 | return; | 
| Felipe Balbi | 72246da | 2011-08-19 18:10:58 +0300 | [diff] [blame] | 813 |  | 
|  | 814 | list_for_each_entry_safe(req, n, &dep->request_list, list) { | 
| Felipe Balbi | eeb720f | 2011-11-28 12:46:59 +0200 | [diff] [blame] | 815 | unsigned	length; | 
|  | 816 | dma_addr_t	dma; | 
| Felipe Balbi | 72246da | 2011-08-19 18:10:58 +0300 | [diff] [blame] | 817 |  | 
| Felipe Balbi | eeb720f | 2011-11-28 12:46:59 +0200 | [diff] [blame] | 818 | if (req->request.num_mapped_sgs > 0) { | 
|  | 819 | struct usb_request *request = &req->request; | 
|  | 820 | struct scatterlist *sg = request->sg; | 
|  | 821 | struct scatterlist *s; | 
|  | 822 | int		i; | 
| Felipe Balbi | 72246da | 2011-08-19 18:10:58 +0300 | [diff] [blame] | 823 |  | 
| Felipe Balbi | eeb720f | 2011-11-28 12:46:59 +0200 | [diff] [blame] | 824 | for_each_sg(sg, s, request->num_mapped_sgs, i) { | 
|  | 825 | unsigned chain = true; | 
| Felipe Balbi | 72246da | 2011-08-19 18:10:58 +0300 | [diff] [blame] | 826 |  | 
| Felipe Balbi | eeb720f | 2011-11-28 12:46:59 +0200 | [diff] [blame] | 827 | length = sg_dma_len(s); | 
|  | 828 | dma = sg_dma_address(s); | 
| Felipe Balbi | 72246da | 2011-08-19 18:10:58 +0300 | [diff] [blame] | 829 |  | 
| Paul Zimmerman | 1d04679 | 2012-02-15 18:56:56 -0800 | [diff] [blame] | 830 | if (i == (request->num_mapped_sgs - 1) || | 
|  | 831 | sg_is_last(s)) { | 
| Felipe Balbi | eeb720f | 2011-11-28 12:46:59 +0200 | [diff] [blame] | 832 | last_one = true; | 
|  | 833 | chain = false; | 
|  | 834 | } | 
| Felipe Balbi | 72246da | 2011-08-19 18:10:58 +0300 | [diff] [blame] | 835 |  | 
| Felipe Balbi | eeb720f | 2011-11-28 12:46:59 +0200 | [diff] [blame] | 836 | trbs_left--; | 
|  | 837 | if (!trbs_left) | 
|  | 838 | last_one = true; | 
| Felipe Balbi | 72246da | 2011-08-19 18:10:58 +0300 | [diff] [blame] | 839 |  | 
| Felipe Balbi | eeb720f | 2011-11-28 12:46:59 +0200 | [diff] [blame] | 840 | if (last_one) | 
|  | 841 | chain = false; | 
| Felipe Balbi | 72246da | 2011-08-19 18:10:58 +0300 | [diff] [blame] | 842 |  | 
| Felipe Balbi | eeb720f | 2011-11-28 12:46:59 +0200 | [diff] [blame] | 843 | dwc3_prepare_one_trb(dep, req, dma, length, | 
|  | 844 | last_one, chain); | 
| Felipe Balbi | 72246da | 2011-08-19 18:10:58 +0300 | [diff] [blame] | 845 |  | 
| Felipe Balbi | eeb720f | 2011-11-28 12:46:59 +0200 | [diff] [blame] | 846 | if (last_one) | 
|  | 847 | break; | 
|  | 848 | } | 
| Felipe Balbi | 72246da | 2011-08-19 18:10:58 +0300 | [diff] [blame] | 849 | } else { | 
| Felipe Balbi | eeb720f | 2011-11-28 12:46:59 +0200 | [diff] [blame] | 850 | dma = req->request.dma; | 
|  | 851 | length = req->request.length; | 
|  | 852 | trbs_left--; | 
|  | 853 |  | 
|  | 854 | if (!trbs_left) | 
|  | 855 | last_one = 1; | 
|  | 856 |  | 
|  | 857 | /* Is this the last request? */ | 
|  | 858 | if (list_is_last(&req->list, &dep->request_list)) | 
|  | 859 | last_one = 1; | 
|  | 860 |  | 
|  | 861 | dwc3_prepare_one_trb(dep, req, dma, length, | 
|  | 862 | last_one, false); | 
|  | 863 |  | 
|  | 864 | if (last_one) | 
|  | 865 | break; | 
| Felipe Balbi | 72246da | 2011-08-19 18:10:58 +0300 | [diff] [blame] | 866 | } | 
| Felipe Balbi | 72246da | 2011-08-19 18:10:58 +0300 | [diff] [blame] | 867 | } | 
| Felipe Balbi | 72246da | 2011-08-19 18:10:58 +0300 | [diff] [blame] | 868 | } | 
|  | 869 |  | 
|  | 870 | static int __dwc3_gadget_kick_transfer(struct dwc3_ep *dep, u16 cmd_param, | 
|  | 871 | int start_new) | 
|  | 872 | { | 
|  | 873 | struct dwc3_gadget_ep_cmd_params params; | 
|  | 874 | struct dwc3_request		*req; | 
|  | 875 | struct dwc3			*dwc = dep->dwc; | 
|  | 876 | int				ret; | 
|  | 877 | u32				cmd; | 
|  | 878 |  | 
|  | 879 | if (start_new && (dep->flags & DWC3_EP_BUSY)) { | 
|  | 880 | dev_vdbg(dwc->dev, "%s: endpoint busy\n", dep->name); | 
|  | 881 | return -EBUSY; | 
|  | 882 | } | 
|  | 883 | dep->flags &= ~DWC3_EP_PENDING_REQUEST; | 
|  | 884 |  | 
|  | 885 | /* | 
|  | 886 | * If we are getting here after a short-out-packet we don't enqueue any | 
|  | 887 | * new requests as we try to set the IOC bit only on the last request. | 
|  | 888 | */ | 
|  | 889 | if (start_new) { | 
|  | 890 | if (list_empty(&dep->req_queued)) | 
|  | 891 | dwc3_prepare_trbs(dep, start_new); | 
|  | 892 |  | 
|  | 893 | /* req points to the first request which will be sent */ | 
|  | 894 | req = next_request(&dep->req_queued); | 
|  | 895 | } else { | 
| Felipe Balbi | 68e823e | 2011-11-28 12:25:01 +0200 | [diff] [blame] | 896 | dwc3_prepare_trbs(dep, start_new); | 
|  | 897 |  | 
| Felipe Balbi | 72246da | 2011-08-19 18:10:58 +0300 | [diff] [blame] | 898 | /* | 
| Paul Zimmerman | 1d04679 | 2012-02-15 18:56:56 -0800 | [diff] [blame] | 899 | * req points to the first request where HWO changed from 0 to 1 | 
| Felipe Balbi | 72246da | 2011-08-19 18:10:58 +0300 | [diff] [blame] | 900 | */ | 
| Felipe Balbi | 68e823e | 2011-11-28 12:25:01 +0200 | [diff] [blame] | 901 | req = next_request(&dep->req_queued); | 
| Felipe Balbi | 72246da | 2011-08-19 18:10:58 +0300 | [diff] [blame] | 902 | } | 
|  | 903 | if (!req) { | 
|  | 904 | dep->flags |= DWC3_EP_PENDING_REQUEST; | 
|  | 905 | return 0; | 
|  | 906 | } | 
|  | 907 |  | 
|  | 908 | memset(¶ms, 0, sizeof(params)); | 
| Felipe Balbi | dc1c70a | 2011-09-30 10:58:51 +0300 | [diff] [blame] | 909 | params.param0 = upper_32_bits(req->trb_dma); | 
|  | 910 | params.param1 = lower_32_bits(req->trb_dma); | 
| Felipe Balbi | 72246da | 2011-08-19 18:10:58 +0300 | [diff] [blame] | 911 |  | 
|  | 912 | if (start_new) | 
|  | 913 | cmd = DWC3_DEPCMD_STARTTRANSFER; | 
|  | 914 | else | 
|  | 915 | cmd = DWC3_DEPCMD_UPDATETRANSFER; | 
|  | 916 |  | 
|  | 917 | cmd |= DWC3_DEPCMD_PARAM(cmd_param); | 
|  | 918 | ret = dwc3_send_gadget_ep_cmd(dwc, dep->number, cmd, ¶ms); | 
|  | 919 | if (ret < 0) { | 
|  | 920 | dev_dbg(dwc->dev, "failed to send STARTTRANSFER command\n"); | 
|  | 921 |  | 
|  | 922 | /* | 
|  | 923 | * FIXME we need to iterate over the list of requests | 
|  | 924 | * here and stop, unmap, free and del each of the linked | 
| Paul Zimmerman | 1d04679 | 2012-02-15 18:56:56 -0800 | [diff] [blame] | 925 | * requests instead of what we do now. | 
| Felipe Balbi | 72246da | 2011-08-19 18:10:58 +0300 | [diff] [blame] | 926 | */ | 
| Felipe Balbi | 0fc9a1b | 2011-12-19 11:32:34 +0200 | [diff] [blame] | 927 | usb_gadget_unmap_request(&dwc->gadget, &req->request, | 
|  | 928 | req->direction); | 
| Felipe Balbi | 72246da | 2011-08-19 18:10:58 +0300 | [diff] [blame] | 929 | list_del(&req->list); | 
|  | 930 | return ret; | 
|  | 931 | } | 
|  | 932 |  | 
|  | 933 | dep->flags |= DWC3_EP_BUSY; | 
|  | 934 | dep->res_trans_idx = dwc3_gadget_ep_get_transfer_index(dwc, | 
|  | 935 | dep->number); | 
| Felipe Balbi | 25b8ff6 | 2011-11-04 12:32:47 +0200 | [diff] [blame] | 936 |  | 
|  | 937 | WARN_ON_ONCE(!dep->res_trans_idx); | 
|  | 938 |  | 
| Felipe Balbi | 72246da | 2011-08-19 18:10:58 +0300 | [diff] [blame] | 939 | return 0; | 
|  | 940 | } | 
|  | 941 |  | 
|  | 942 | static int __dwc3_gadget_ep_queue(struct dwc3_ep *dep, struct dwc3_request *req) | 
|  | 943 | { | 
| Felipe Balbi | 0fc9a1b | 2011-12-19 11:32:34 +0200 | [diff] [blame] | 944 | struct dwc3		*dwc = dep->dwc; | 
|  | 945 | int			ret; | 
|  | 946 |  | 
| Felipe Balbi | 72246da | 2011-08-19 18:10:58 +0300 | [diff] [blame] | 947 | req->request.actual	= 0; | 
|  | 948 | req->request.status	= -EINPROGRESS; | 
|  | 949 | req->direction		= dep->direction; | 
|  | 950 | req->epnum		= dep->number; | 
|  | 951 |  | 
|  | 952 | /* | 
|  | 953 | * We only add to our list of requests now and | 
|  | 954 | * start consuming the list once we get XferNotReady | 
|  | 955 | * IRQ. | 
|  | 956 | * | 
|  | 957 | * That way, we avoid doing anything that we don't need | 
|  | 958 | * to do now and defer it until the point we receive a | 
|  | 959 | * particular token from the Host side. | 
|  | 960 | * | 
|  | 961 | * This will also avoid Host cancelling URBs due to too | 
| Paul Zimmerman | 1d04679 | 2012-02-15 18:56:56 -0800 | [diff] [blame] | 962 | * many NAKs. | 
| Felipe Balbi | 72246da | 2011-08-19 18:10:58 +0300 | [diff] [blame] | 963 | */ | 
| Felipe Balbi | 0fc9a1b | 2011-12-19 11:32:34 +0200 | [diff] [blame] | 964 | ret = usb_gadget_map_request(&dwc->gadget, &req->request, | 
|  | 965 | dep->direction); | 
|  | 966 | if (ret) | 
|  | 967 | return ret; | 
|  | 968 |  | 
| Felipe Balbi | 72246da | 2011-08-19 18:10:58 +0300 | [diff] [blame] | 969 | list_add_tail(&req->list, &dep->request_list); | 
|  | 970 |  | 
|  | 971 | /* | 
|  | 972 | * There is one special case: XferNotReady with | 
|  | 973 | * empty list of requests. We need to kick the | 
|  | 974 | * transfer here in that situation, otherwise | 
|  | 975 | * we will be NAKing forever. | 
|  | 976 | * | 
|  | 977 | * If we get XferNotReady before gadget driver | 
|  | 978 | * has a chance to queue a request, we will ACK | 
|  | 979 | * the IRQ but won't be able to receive the data | 
|  | 980 | * until the next request is queued. The following | 
|  | 981 | * code is handling exactly that. | 
|  | 982 | */ | 
|  | 983 | if (dep->flags & DWC3_EP_PENDING_REQUEST) { | 
|  | 984 | int ret; | 
|  | 985 | int start_trans; | 
|  | 986 |  | 
|  | 987 | start_trans = 1; | 
| Felipe Balbi | 7b7dd02 | 2012-01-18 17:09:17 +0200 | [diff] [blame] | 988 | if (usb_endpoint_xfer_isoc(dep->desc) && | 
| Paul Zimmerman | 1d04679 | 2012-02-15 18:56:56 -0800 | [diff] [blame] | 989 | (dep->flags & DWC3_EP_BUSY)) | 
| Felipe Balbi | 72246da | 2011-08-19 18:10:58 +0300 | [diff] [blame] | 990 | start_trans = 0; | 
|  | 991 |  | 
| Paul Zimmerman | 1d04679 | 2012-02-15 18:56:56 -0800 | [diff] [blame] | 992 | ret = __dwc3_gadget_kick_transfer(dep, 0, start_trans); | 
| Felipe Balbi | 72246da | 2011-08-19 18:10:58 +0300 | [diff] [blame] | 993 | if (ret && ret != -EBUSY) { | 
|  | 994 | struct dwc3	*dwc = dep->dwc; | 
|  | 995 |  | 
|  | 996 | dev_dbg(dwc->dev, "%s: failed to kick transfers\n", | 
|  | 997 | dep->name); | 
|  | 998 | } | 
|  | 999 | }; | 
|  | 1000 |  | 
|  | 1001 | return 0; | 
|  | 1002 | } | 
|  | 1003 |  | 
|  | 1004 | static int dwc3_gadget_ep_queue(struct usb_ep *ep, struct usb_request *request, | 
|  | 1005 | gfp_t gfp_flags) | 
|  | 1006 | { | 
|  | 1007 | struct dwc3_request		*req = to_dwc3_request(request); | 
|  | 1008 | struct dwc3_ep			*dep = to_dwc3_ep(ep); | 
|  | 1009 | struct dwc3			*dwc = dep->dwc; | 
|  | 1010 |  | 
|  | 1011 | unsigned long			flags; | 
|  | 1012 |  | 
|  | 1013 | int				ret; | 
|  | 1014 |  | 
|  | 1015 | if (!dep->desc) { | 
|  | 1016 | dev_dbg(dwc->dev, "trying to queue request %p to disabled %s\n", | 
|  | 1017 | request, ep->name); | 
|  | 1018 | return -ESHUTDOWN; | 
|  | 1019 | } | 
|  | 1020 |  | 
|  | 1021 | dev_vdbg(dwc->dev, "queing request %p to %s length %d\n", | 
|  | 1022 | request, ep->name, request->length); | 
|  | 1023 |  | 
| Manu Gautam | 1c4dbcb | 2012-10-05 13:16:00 +0530 | [diff] [blame] | 1024 | WARN(!dep->direction && (request->length % ep->desc->wMaxPacketSize), | 
|  | 1025 | "trying to queue unaligned request (%d)\n", request->length); | 
|  | 1026 |  | 
| Felipe Balbi | 72246da | 2011-08-19 18:10:58 +0300 | [diff] [blame] | 1027 | spin_lock_irqsave(&dwc->lock, flags); | 
|  | 1028 | ret = __dwc3_gadget_ep_queue(dep, req); | 
|  | 1029 | spin_unlock_irqrestore(&dwc->lock, flags); | 
|  | 1030 |  | 
|  | 1031 | return ret; | 
|  | 1032 | } | 
|  | 1033 |  | 
|  | 1034 | static int dwc3_gadget_ep_dequeue(struct usb_ep *ep, | 
|  | 1035 | struct usb_request *request) | 
|  | 1036 | { | 
|  | 1037 | struct dwc3_request		*req = to_dwc3_request(request); | 
|  | 1038 | struct dwc3_request		*r = NULL; | 
|  | 1039 |  | 
|  | 1040 | struct dwc3_ep			*dep = to_dwc3_ep(ep); | 
|  | 1041 | struct dwc3			*dwc = dep->dwc; | 
|  | 1042 |  | 
|  | 1043 | unsigned long			flags; | 
|  | 1044 | int				ret = 0; | 
|  | 1045 |  | 
|  | 1046 | spin_lock_irqsave(&dwc->lock, flags); | 
|  | 1047 |  | 
|  | 1048 | list_for_each_entry(r, &dep->request_list, list) { | 
|  | 1049 | if (r == req) | 
|  | 1050 | break; | 
|  | 1051 | } | 
|  | 1052 |  | 
|  | 1053 | if (r != req) { | 
|  | 1054 | list_for_each_entry(r, &dep->req_queued, list) { | 
|  | 1055 | if (r == req) | 
|  | 1056 | break; | 
|  | 1057 | } | 
|  | 1058 | if (r == req) { | 
|  | 1059 | /* wait until it is processed */ | 
|  | 1060 | dwc3_stop_active_transfer(dwc, dep->number); | 
|  | 1061 | goto out0; | 
|  | 1062 | } | 
|  | 1063 | dev_err(dwc->dev, "request %p was not queued to %s\n", | 
|  | 1064 | request, ep->name); | 
|  | 1065 | ret = -EINVAL; | 
|  | 1066 | goto out0; | 
|  | 1067 | } | 
|  | 1068 |  | 
|  | 1069 | /* giveback the request */ | 
|  | 1070 | dwc3_gadget_giveback(dep, req, -ECONNRESET); | 
|  | 1071 |  | 
|  | 1072 | out0: | 
|  | 1073 | spin_unlock_irqrestore(&dwc->lock, flags); | 
|  | 1074 |  | 
|  | 1075 | return ret; | 
|  | 1076 | } | 
|  | 1077 |  | 
|  | 1078 | int __dwc3_gadget_ep_set_halt(struct dwc3_ep *dep, int value) | 
|  | 1079 | { | 
|  | 1080 | struct dwc3_gadget_ep_cmd_params	params; | 
|  | 1081 | struct dwc3				*dwc = dep->dwc; | 
|  | 1082 | int					ret; | 
|  | 1083 |  | 
|  | 1084 | memset(¶ms, 0x00, sizeof(params)); | 
|  | 1085 |  | 
|  | 1086 | if (value) { | 
| Felipe Balbi | 0b7836a | 2011-08-30 15:48:08 +0300 | [diff] [blame] | 1087 | if (dep->number == 0 || dep->number == 1) { | 
|  | 1088 | /* | 
|  | 1089 | * Whenever EP0 is stalled, we will restart | 
|  | 1090 | * the state machine, thus moving back to | 
|  | 1091 | * Setup Phase | 
|  | 1092 | */ | 
|  | 1093 | dwc->ep0state = EP0_SETUP_PHASE; | 
|  | 1094 | } | 
| Felipe Balbi | 72246da | 2011-08-19 18:10:58 +0300 | [diff] [blame] | 1095 |  | 
|  | 1096 | ret = dwc3_send_gadget_ep_cmd(dwc, dep->number, | 
|  | 1097 | DWC3_DEPCMD_SETSTALL, ¶ms); | 
|  | 1098 | if (ret) | 
|  | 1099 | dev_err(dwc->dev, "failed to %s STALL on %s\n", | 
|  | 1100 | value ? "set" : "clear", | 
|  | 1101 | dep->name); | 
|  | 1102 | else | 
|  | 1103 | dep->flags |= DWC3_EP_STALL; | 
|  | 1104 | } else { | 
| Paul Zimmerman | 5275455 | 2011-09-30 10:58:44 +0300 | [diff] [blame] | 1105 | if (dep->flags & DWC3_EP_WEDGE) | 
|  | 1106 | return 0; | 
|  | 1107 |  | 
| Felipe Balbi | 72246da | 2011-08-19 18:10:58 +0300 | [diff] [blame] | 1108 | ret = dwc3_send_gadget_ep_cmd(dwc, dep->number, | 
|  | 1109 | DWC3_DEPCMD_CLEARSTALL, ¶ms); | 
|  | 1110 | if (ret) | 
|  | 1111 | dev_err(dwc->dev, "failed to %s STALL on %s\n", | 
|  | 1112 | value ? "set" : "clear", | 
|  | 1113 | dep->name); | 
|  | 1114 | else | 
|  | 1115 | dep->flags &= ~DWC3_EP_STALL; | 
|  | 1116 | } | 
| Paul Zimmerman | 5275455 | 2011-09-30 10:58:44 +0300 | [diff] [blame] | 1117 |  | 
| Felipe Balbi | 72246da | 2011-08-19 18:10:58 +0300 | [diff] [blame] | 1118 | return ret; | 
|  | 1119 | } | 
|  | 1120 |  | 
|  | 1121 | static int dwc3_gadget_ep_set_halt(struct usb_ep *ep, int value) | 
|  | 1122 | { | 
|  | 1123 | struct dwc3_ep			*dep = to_dwc3_ep(ep); | 
|  | 1124 | struct dwc3			*dwc = dep->dwc; | 
|  | 1125 |  | 
|  | 1126 | unsigned long			flags; | 
|  | 1127 |  | 
|  | 1128 | int				ret; | 
|  | 1129 |  | 
|  | 1130 | spin_lock_irqsave(&dwc->lock, flags); | 
|  | 1131 |  | 
|  | 1132 | if (usb_endpoint_xfer_isoc(dep->desc)) { | 
|  | 1133 | dev_err(dwc->dev, "%s is of Isochronous type\n", dep->name); | 
|  | 1134 | ret = -EINVAL; | 
|  | 1135 | goto out; | 
|  | 1136 | } | 
|  | 1137 |  | 
|  | 1138 | ret = __dwc3_gadget_ep_set_halt(dep, value); | 
|  | 1139 | out: | 
|  | 1140 | spin_unlock_irqrestore(&dwc->lock, flags); | 
|  | 1141 |  | 
|  | 1142 | return ret; | 
|  | 1143 | } | 
|  | 1144 |  | 
|  | 1145 | static int dwc3_gadget_ep_set_wedge(struct usb_ep *ep) | 
|  | 1146 | { | 
|  | 1147 | struct dwc3_ep			*dep = to_dwc3_ep(ep); | 
| Paul Zimmerman | 249a456 | 2012-02-24 17:32:16 -0800 | [diff] [blame] | 1148 | struct dwc3			*dwc = dep->dwc; | 
|  | 1149 | unsigned long			flags; | 
| Felipe Balbi | 72246da | 2011-08-19 18:10:58 +0300 | [diff] [blame] | 1150 |  | 
| Paul Zimmerman | 249a456 | 2012-02-24 17:32:16 -0800 | [diff] [blame] | 1151 | spin_lock_irqsave(&dwc->lock, flags); | 
| Felipe Balbi | 72246da | 2011-08-19 18:10:58 +0300 | [diff] [blame] | 1152 | dep->flags |= DWC3_EP_WEDGE; | 
| Paul Zimmerman | 249a456 | 2012-02-24 17:32:16 -0800 | [diff] [blame] | 1153 | spin_unlock_irqrestore(&dwc->lock, flags); | 
| Felipe Balbi | 72246da | 2011-08-19 18:10:58 +0300 | [diff] [blame] | 1154 |  | 
| Paul Zimmerman | 5275455 | 2011-09-30 10:58:44 +0300 | [diff] [blame] | 1155 | return dwc3_gadget_ep_set_halt(ep, 1); | 
| Felipe Balbi | 72246da | 2011-08-19 18:10:58 +0300 | [diff] [blame] | 1156 | } | 
|  | 1157 |  | 
|  | 1158 | /* -------------------------------------------------------------------------- */ | 
|  | 1159 |  | 
|  | 1160 | static struct usb_endpoint_descriptor dwc3_gadget_ep0_desc = { | 
|  | 1161 | .bLength	= USB_DT_ENDPOINT_SIZE, | 
|  | 1162 | .bDescriptorType = USB_DT_ENDPOINT, | 
|  | 1163 | .bmAttributes	= USB_ENDPOINT_XFER_CONTROL, | 
|  | 1164 | }; | 
|  | 1165 |  | 
|  | 1166 | static const struct usb_ep_ops dwc3_gadget_ep0_ops = { | 
|  | 1167 | .enable		= dwc3_gadget_ep0_enable, | 
|  | 1168 | .disable	= dwc3_gadget_ep0_disable, | 
|  | 1169 | .alloc_request	= dwc3_gadget_ep_alloc_request, | 
|  | 1170 | .free_request	= dwc3_gadget_ep_free_request, | 
|  | 1171 | .queue		= dwc3_gadget_ep0_queue, | 
|  | 1172 | .dequeue	= dwc3_gadget_ep_dequeue, | 
|  | 1173 | .set_halt	= dwc3_gadget_ep_set_halt, | 
|  | 1174 | .set_wedge	= dwc3_gadget_ep_set_wedge, | 
|  | 1175 | }; | 
|  | 1176 |  | 
|  | 1177 | static const struct usb_ep_ops dwc3_gadget_ep_ops = { | 
|  | 1178 | .enable		= dwc3_gadget_ep_enable, | 
|  | 1179 | .disable	= dwc3_gadget_ep_disable, | 
|  | 1180 | .alloc_request	= dwc3_gadget_ep_alloc_request, | 
|  | 1181 | .free_request	= dwc3_gadget_ep_free_request, | 
|  | 1182 | .queue		= dwc3_gadget_ep_queue, | 
|  | 1183 | .dequeue	= dwc3_gadget_ep_dequeue, | 
|  | 1184 | .set_halt	= dwc3_gadget_ep_set_halt, | 
|  | 1185 | .set_wedge	= dwc3_gadget_ep_set_wedge, | 
|  | 1186 | }; | 
|  | 1187 |  | 
|  | 1188 | /* -------------------------------------------------------------------------- */ | 
|  | 1189 |  | 
|  | 1190 | static int dwc3_gadget_get_frame(struct usb_gadget *g) | 
|  | 1191 | { | 
|  | 1192 | struct dwc3		*dwc = gadget_to_dwc(g); | 
|  | 1193 | u32			reg; | 
|  | 1194 |  | 
|  | 1195 | reg = dwc3_readl(dwc->regs, DWC3_DSTS); | 
|  | 1196 | return DWC3_DSTS_SOFFN(reg); | 
|  | 1197 | } | 
|  | 1198 |  | 
|  | 1199 | static int dwc3_gadget_wakeup(struct usb_gadget *g) | 
|  | 1200 | { | 
|  | 1201 | struct dwc3		*dwc = gadget_to_dwc(g); | 
|  | 1202 |  | 
|  | 1203 | unsigned long		timeout; | 
|  | 1204 | unsigned long		flags; | 
|  | 1205 |  | 
|  | 1206 | u32			reg; | 
|  | 1207 |  | 
|  | 1208 | int			ret = 0; | 
|  | 1209 |  | 
|  | 1210 | u8			link_state; | 
|  | 1211 | u8			speed; | 
|  | 1212 |  | 
|  | 1213 | spin_lock_irqsave(&dwc->lock, flags); | 
|  | 1214 |  | 
|  | 1215 | /* | 
|  | 1216 | * According to the Databook Remote wakeup request should | 
|  | 1217 | * be issued only when the device is in early suspend state. | 
|  | 1218 | * | 
|  | 1219 | * We can check that via USB Link State bits in DSTS register. | 
|  | 1220 | */ | 
|  | 1221 | reg = dwc3_readl(dwc->regs, DWC3_DSTS); | 
|  | 1222 |  | 
|  | 1223 | speed = reg & DWC3_DSTS_CONNECTSPD; | 
|  | 1224 | if (speed == DWC3_DSTS_SUPERSPEED) { | 
|  | 1225 | dev_dbg(dwc->dev, "no wakeup on SuperSpeed\n"); | 
|  | 1226 | ret = -EINVAL; | 
|  | 1227 | goto out; | 
|  | 1228 | } | 
|  | 1229 |  | 
|  | 1230 | link_state = DWC3_DSTS_USBLNKST(reg); | 
|  | 1231 |  | 
|  | 1232 | switch (link_state) { | 
|  | 1233 | case DWC3_LINK_STATE_RX_DET:	/* in HS, means Early Suspend */ | 
|  | 1234 | case DWC3_LINK_STATE_U3:	/* in HS, means SUSPEND */ | 
|  | 1235 | break; | 
|  | 1236 | default: | 
|  | 1237 | dev_dbg(dwc->dev, "can't wakeup from link state %d\n", | 
|  | 1238 | link_state); | 
|  | 1239 | ret = -EINVAL; | 
|  | 1240 | goto out; | 
|  | 1241 | } | 
|  | 1242 |  | 
| Felipe Balbi | 8598bde | 2012-01-02 18:55:57 +0200 | [diff] [blame] | 1243 | ret = dwc3_gadget_set_link_state(dwc, DWC3_LINK_STATE_RECOV); | 
|  | 1244 | if (ret < 0) { | 
|  | 1245 | dev_err(dwc->dev, "failed to put link in Recovery\n"); | 
|  | 1246 | goto out; | 
|  | 1247 | } | 
| Felipe Balbi | 72246da | 2011-08-19 18:10:58 +0300 | [diff] [blame] | 1248 |  | 
|  | 1249 | /* write zeroes to Link Change Request */ | 
|  | 1250 | reg &= ~DWC3_DCTL_ULSTCHNGREQ_MASK; | 
|  | 1251 | dwc3_writel(dwc->regs, DWC3_DCTL, reg); | 
|  | 1252 |  | 
| Paul Zimmerman | 1d04679 | 2012-02-15 18:56:56 -0800 | [diff] [blame] | 1253 | /* poll until Link State changes to ON */ | 
| Felipe Balbi | 72246da | 2011-08-19 18:10:58 +0300 | [diff] [blame] | 1254 | timeout = jiffies + msecs_to_jiffies(100); | 
|  | 1255 |  | 
| Paul Zimmerman | 1d04679 | 2012-02-15 18:56:56 -0800 | [diff] [blame] | 1256 | while (!time_after(jiffies, timeout)) { | 
| Felipe Balbi | 72246da | 2011-08-19 18:10:58 +0300 | [diff] [blame] | 1257 | reg = dwc3_readl(dwc->regs, DWC3_DSTS); | 
|  | 1258 |  | 
|  | 1259 | /* in HS, means ON */ | 
|  | 1260 | if (DWC3_DSTS_USBLNKST(reg) == DWC3_LINK_STATE_U0) | 
|  | 1261 | break; | 
|  | 1262 | } | 
|  | 1263 |  | 
|  | 1264 | if (DWC3_DSTS_USBLNKST(reg) != DWC3_LINK_STATE_U0) { | 
|  | 1265 | dev_err(dwc->dev, "failed to send remote wakeup\n"); | 
|  | 1266 | ret = -EINVAL; | 
|  | 1267 | } | 
|  | 1268 |  | 
|  | 1269 | out: | 
|  | 1270 | spin_unlock_irqrestore(&dwc->lock, flags); | 
|  | 1271 |  | 
|  | 1272 | return ret; | 
|  | 1273 | } | 
|  | 1274 |  | 
|  | 1275 | static int dwc3_gadget_set_selfpowered(struct usb_gadget *g, | 
|  | 1276 | int is_selfpowered) | 
|  | 1277 | { | 
|  | 1278 | struct dwc3		*dwc = gadget_to_dwc(g); | 
| Paul Zimmerman | 249a456 | 2012-02-24 17:32:16 -0800 | [diff] [blame] | 1279 | unsigned long		flags; | 
| Felipe Balbi | 72246da | 2011-08-19 18:10:58 +0300 | [diff] [blame] | 1280 |  | 
| Paul Zimmerman | 249a456 | 2012-02-24 17:32:16 -0800 | [diff] [blame] | 1281 | spin_lock_irqsave(&dwc->lock, flags); | 
| Felipe Balbi | 72246da | 2011-08-19 18:10:58 +0300 | [diff] [blame] | 1282 | dwc->is_selfpowered = !!is_selfpowered; | 
| Paul Zimmerman | 249a456 | 2012-02-24 17:32:16 -0800 | [diff] [blame] | 1283 | spin_unlock_irqrestore(&dwc->lock, flags); | 
| Felipe Balbi | 72246da | 2011-08-19 18:10:58 +0300 | [diff] [blame] | 1284 |  | 
|  | 1285 | return 0; | 
|  | 1286 | } | 
|  | 1287 |  | 
|  | 1288 | static void dwc3_gadget_run_stop(struct dwc3 *dwc, int is_on) | 
|  | 1289 | { | 
|  | 1290 | u32			reg; | 
| Sebastian Andrzej Siewior | 61d5824 | 2011-08-29 16:46:38 +0200 | [diff] [blame] | 1291 | u32			timeout = 500; | 
| Felipe Balbi | 72246da | 2011-08-19 18:10:58 +0300 | [diff] [blame] | 1292 |  | 
|  | 1293 | reg = dwc3_readl(dwc->regs, DWC3_DCTL); | 
| Felipe Balbi | 8db7ed1 | 2012-01-18 18:32:29 +0200 | [diff] [blame] | 1294 | if (is_on) { | 
|  | 1295 | reg &= ~DWC3_DCTL_TRGTULST_MASK; | 
|  | 1296 | reg |= (DWC3_DCTL_RUN_STOP | 
|  | 1297 | | DWC3_DCTL_TRGTULST_RX_DET); | 
|  | 1298 | } else { | 
| Felipe Balbi | 72246da | 2011-08-19 18:10:58 +0300 | [diff] [blame] | 1299 | reg &= ~DWC3_DCTL_RUN_STOP; | 
| Felipe Balbi | 8db7ed1 | 2012-01-18 18:32:29 +0200 | [diff] [blame] | 1300 | } | 
| Felipe Balbi | 72246da | 2011-08-19 18:10:58 +0300 | [diff] [blame] | 1301 |  | 
|  | 1302 | dwc3_writel(dwc->regs, DWC3_DCTL, reg); | 
|  | 1303 |  | 
|  | 1304 | do { | 
|  | 1305 | reg = dwc3_readl(dwc->regs, DWC3_DSTS); | 
|  | 1306 | if (is_on) { | 
|  | 1307 | if (!(reg & DWC3_DSTS_DEVCTRLHLT)) | 
|  | 1308 | break; | 
|  | 1309 | } else { | 
|  | 1310 | if (reg & DWC3_DSTS_DEVCTRLHLT) | 
|  | 1311 | break; | 
|  | 1312 | } | 
| Felipe Balbi | 72246da | 2011-08-19 18:10:58 +0300 | [diff] [blame] | 1313 | timeout--; | 
|  | 1314 | if (!timeout) | 
|  | 1315 | break; | 
| Sebastian Andrzej Siewior | 61d5824 | 2011-08-29 16:46:38 +0200 | [diff] [blame] | 1316 | udelay(1); | 
| Felipe Balbi | 72246da | 2011-08-19 18:10:58 +0300 | [diff] [blame] | 1317 | } while (1); | 
|  | 1318 |  | 
|  | 1319 | dev_vdbg(dwc->dev, "gadget %s data soft-%s\n", | 
|  | 1320 | dwc->gadget_driver | 
|  | 1321 | ? dwc->gadget_driver->function : "no-function", | 
|  | 1322 | is_on ? "connect" : "disconnect"); | 
|  | 1323 | } | 
|  | 1324 |  | 
|  | 1325 | static int dwc3_gadget_pullup(struct usb_gadget *g, int is_on) | 
|  | 1326 | { | 
|  | 1327 | struct dwc3		*dwc = gadget_to_dwc(g); | 
|  | 1328 | unsigned long		flags; | 
|  | 1329 |  | 
|  | 1330 | is_on = !!is_on; | 
|  | 1331 |  | 
|  | 1332 | spin_lock_irqsave(&dwc->lock, flags); | 
| Ido Shayevitz | cdeef4c | 2012-05-29 13:17:41 +0200 | [diff] [blame] | 1333 |  | 
|  | 1334 | dwc->softconnect = is_on; | 
|  | 1335 |  | 
|  | 1336 | if ((dwc->dotg && !dwc->vbus_active) || | 
|  | 1337 | !dwc->gadget_driver) { | 
|  | 1338 |  | 
|  | 1339 | spin_unlock_irqrestore(&dwc->lock, flags); | 
|  | 1340 |  | 
|  | 1341 | /* | 
|  | 1342 | * Need to wait for vbus_session(on) from otg driver or to | 
|  | 1343 | * the udc_start. | 
|  | 1344 | */ | 
|  | 1345 | return 0; | 
|  | 1346 | } | 
|  | 1347 |  | 
| Felipe Balbi | 72246da | 2011-08-19 18:10:58 +0300 | [diff] [blame] | 1348 | dwc3_gadget_run_stop(dwc, is_on); | 
| Ido Shayevitz | cdeef4c | 2012-05-29 13:17:41 +0200 | [diff] [blame] | 1349 |  | 
|  | 1350 | spin_unlock_irqrestore(&dwc->lock, flags); | 
|  | 1351 |  | 
|  | 1352 | return 0; | 
|  | 1353 | } | 
|  | 1354 |  | 
|  | 1355 | static int dwc3_gadget_vbus_session(struct usb_gadget *_gadget, int is_active) | 
|  | 1356 | { | 
|  | 1357 | struct dwc3 *dwc = gadget_to_dwc(_gadget); | 
|  | 1358 | unsigned long flags; | 
|  | 1359 |  | 
|  | 1360 | if (!dwc->dotg) | 
|  | 1361 | return -EPERM; | 
|  | 1362 |  | 
|  | 1363 | is_active = !!is_active; | 
|  | 1364 |  | 
|  | 1365 | spin_lock_irqsave(&dwc->lock, flags); | 
|  | 1366 |  | 
|  | 1367 | /* Mark that the vbus was powered */ | 
|  | 1368 | dwc->vbus_active = is_active; | 
|  | 1369 |  | 
|  | 1370 | /* | 
|  | 1371 | * Check if upper level usb_gadget_driver was already registerd with | 
|  | 1372 | * this udc controller driver (if dwc3_gadget_start was called) | 
|  | 1373 | */ | 
|  | 1374 | if (dwc->gadget_driver && dwc->softconnect) { | 
|  | 1375 | if (dwc->vbus_active) { | 
|  | 1376 | /* | 
|  | 1377 | * Both vbus was activated by otg and pullup was | 
|  | 1378 | * signaled by the gadget driver. | 
|  | 1379 | */ | 
|  | 1380 | dwc3_gadget_run_stop(dwc, 1); | 
|  | 1381 | } else { | 
|  | 1382 | dwc3_gadget_run_stop(dwc, 0); | 
|  | 1383 | } | 
|  | 1384 | } | 
|  | 1385 |  | 
| Felipe Balbi | 72246da | 2011-08-19 18:10:58 +0300 | [diff] [blame] | 1386 | spin_unlock_irqrestore(&dwc->lock, flags); | 
|  | 1387 |  | 
|  | 1388 | return 0; | 
|  | 1389 | } | 
|  | 1390 |  | 
|  | 1391 | static int dwc3_gadget_start(struct usb_gadget *g, | 
|  | 1392 | struct usb_gadget_driver *driver) | 
|  | 1393 | { | 
|  | 1394 | struct dwc3		*dwc = gadget_to_dwc(g); | 
|  | 1395 | struct dwc3_ep		*dep; | 
|  | 1396 | unsigned long		flags; | 
|  | 1397 | int			ret = 0; | 
|  | 1398 | u32			reg; | 
|  | 1399 |  | 
|  | 1400 | spin_lock_irqsave(&dwc->lock, flags); | 
|  | 1401 |  | 
|  | 1402 | if (dwc->gadget_driver) { | 
|  | 1403 | dev_err(dwc->dev, "%s is already bound to %s\n", | 
|  | 1404 | dwc->gadget.name, | 
|  | 1405 | dwc->gadget_driver->driver.name); | 
|  | 1406 | ret = -EBUSY; | 
|  | 1407 | goto err0; | 
|  | 1408 | } | 
|  | 1409 |  | 
|  | 1410 | dwc->gadget_driver	= driver; | 
|  | 1411 | dwc->gadget.dev.driver	= &driver->driver; | 
|  | 1412 |  | 
| Felipe Balbi | 72246da | 2011-08-19 18:10:58 +0300 | [diff] [blame] | 1413 | reg = dwc3_readl(dwc->regs, DWC3_DCFG); | 
|  | 1414 | reg &= ~(DWC3_DCFG_SPEED_MASK); | 
| Felipe Balbi | 38d2c6c | 2012-03-23 12:20:31 +0200 | [diff] [blame^] | 1415 |  | 
|  | 1416 | /** | 
|  | 1417 | * WORKAROUND: DWC3 revision < 2.20a have an issue | 
|  | 1418 | * which would cause metastability state on Run/Stop | 
|  | 1419 | * bit if we try to force the IP to USB2-only mode. | 
|  | 1420 | * | 
|  | 1421 | * Because of that, we cannot configure the IP to any | 
|  | 1422 | * speed other than the SuperSpeed | 
|  | 1423 | * | 
|  | 1424 | * Refers to: | 
|  | 1425 | * | 
|  | 1426 | * STAR#9000525659: Clock Domain Crossing on DCTL in | 
|  | 1427 | * USB 2.0 Mode | 
|  | 1428 | */ | 
|  | 1429 | if (dwc->revision < DWC3_REVISION_220A) | 
|  | 1430 | reg |= DWC3_DCFG_SUPERSPEED; | 
|  | 1431 | else | 
|  | 1432 | reg |= dwc->maximum_speed; | 
| Felipe Balbi | 72246da | 2011-08-19 18:10:58 +0300 | [diff] [blame] | 1433 | dwc3_writel(dwc->regs, DWC3_DCFG, reg); | 
|  | 1434 |  | 
| Paul Zimmerman | b23c843 | 2011-09-30 10:58:42 +0300 | [diff] [blame] | 1435 | dwc->start_config_issued = false; | 
|  | 1436 |  | 
| Felipe Balbi | 72246da | 2011-08-19 18:10:58 +0300 | [diff] [blame] | 1437 | /* Start with SuperSpeed Default */ | 
|  | 1438 | dwc3_gadget_ep0_desc.wMaxPacketSize = cpu_to_le16(512); | 
|  | 1439 |  | 
|  | 1440 | dep = dwc->eps[0]; | 
| Felipe Balbi | c90bfae | 2011-11-29 13:11:21 +0200 | [diff] [blame] | 1441 | ret = __dwc3_gadget_ep_enable(dep, &dwc3_gadget_ep0_desc, NULL); | 
| Felipe Balbi | 72246da | 2011-08-19 18:10:58 +0300 | [diff] [blame] | 1442 | if (ret) { | 
|  | 1443 | dev_err(dwc->dev, "failed to enable %s\n", dep->name); | 
|  | 1444 | goto err0; | 
|  | 1445 | } | 
|  | 1446 |  | 
|  | 1447 | dep = dwc->eps[1]; | 
| Felipe Balbi | c90bfae | 2011-11-29 13:11:21 +0200 | [diff] [blame] | 1448 | ret = __dwc3_gadget_ep_enable(dep, &dwc3_gadget_ep0_desc, NULL); | 
| Felipe Balbi | 72246da | 2011-08-19 18:10:58 +0300 | [diff] [blame] | 1449 | if (ret) { | 
|  | 1450 | dev_err(dwc->dev, "failed to enable %s\n", dep->name); | 
|  | 1451 | goto err1; | 
|  | 1452 | } | 
|  | 1453 |  | 
|  | 1454 | /* begin to receive SETUP packets */ | 
| Felipe Balbi | c7fcdeb | 2011-08-27 22:28:36 +0300 | [diff] [blame] | 1455 | dwc->ep0state = EP0_SETUP_PHASE; | 
| Felipe Balbi | 72246da | 2011-08-19 18:10:58 +0300 | [diff] [blame] | 1456 | dwc3_ep0_out_start(dwc); | 
|  | 1457 |  | 
|  | 1458 | spin_unlock_irqrestore(&dwc->lock, flags); | 
|  | 1459 |  | 
|  | 1460 | return 0; | 
|  | 1461 |  | 
|  | 1462 | err1: | 
|  | 1463 | __dwc3_gadget_ep_disable(dwc->eps[0]); | 
|  | 1464 |  | 
|  | 1465 | err0: | 
|  | 1466 | spin_unlock_irqrestore(&dwc->lock, flags); | 
|  | 1467 |  | 
|  | 1468 | return ret; | 
|  | 1469 | } | 
|  | 1470 |  | 
|  | 1471 | static int dwc3_gadget_stop(struct usb_gadget *g, | 
|  | 1472 | struct usb_gadget_driver *driver) | 
|  | 1473 | { | 
|  | 1474 | struct dwc3		*dwc = gadget_to_dwc(g); | 
|  | 1475 | unsigned long		flags; | 
|  | 1476 |  | 
|  | 1477 | spin_lock_irqsave(&dwc->lock, flags); | 
|  | 1478 |  | 
|  | 1479 | __dwc3_gadget_ep_disable(dwc->eps[0]); | 
|  | 1480 | __dwc3_gadget_ep_disable(dwc->eps[1]); | 
|  | 1481 |  | 
|  | 1482 | dwc->gadget_driver	= NULL; | 
|  | 1483 | dwc->gadget.dev.driver	= NULL; | 
|  | 1484 |  | 
|  | 1485 | spin_unlock_irqrestore(&dwc->lock, flags); | 
|  | 1486 |  | 
|  | 1487 | return 0; | 
|  | 1488 | } | 
|  | 1489 | static const struct usb_gadget_ops dwc3_gadget_ops = { | 
|  | 1490 | .get_frame		= dwc3_gadget_get_frame, | 
|  | 1491 | .wakeup			= dwc3_gadget_wakeup, | 
|  | 1492 | .set_selfpowered	= dwc3_gadget_set_selfpowered, | 
| Ido Shayevitz | cdeef4c | 2012-05-29 13:17:41 +0200 | [diff] [blame] | 1493 | .vbus_session		= dwc3_gadget_vbus_session, | 
| Felipe Balbi | 72246da | 2011-08-19 18:10:58 +0300 | [diff] [blame] | 1494 | .pullup			= dwc3_gadget_pullup, | 
|  | 1495 | .udc_start		= dwc3_gadget_start, | 
|  | 1496 | .udc_stop		= dwc3_gadget_stop, | 
|  | 1497 | }; | 
|  | 1498 |  | 
|  | 1499 | /* -------------------------------------------------------------------------- */ | 
|  | 1500 |  | 
|  | 1501 | static int __devinit dwc3_gadget_init_endpoints(struct dwc3 *dwc) | 
|  | 1502 | { | 
|  | 1503 | struct dwc3_ep			*dep; | 
|  | 1504 | u8				epnum; | 
|  | 1505 |  | 
|  | 1506 | INIT_LIST_HEAD(&dwc->gadget.ep_list); | 
|  | 1507 |  | 
|  | 1508 | for (epnum = 0; epnum < DWC3_ENDPOINTS_NUM; epnum++) { | 
|  | 1509 | dep = kzalloc(sizeof(*dep), GFP_KERNEL); | 
|  | 1510 | if (!dep) { | 
|  | 1511 | dev_err(dwc->dev, "can't allocate endpoint %d\n", | 
|  | 1512 | epnum); | 
|  | 1513 | return -ENOMEM; | 
|  | 1514 | } | 
|  | 1515 |  | 
|  | 1516 | dep->dwc = dwc; | 
|  | 1517 | dep->number = epnum; | 
|  | 1518 | dwc->eps[epnum] = dep; | 
|  | 1519 |  | 
|  | 1520 | snprintf(dep->name, sizeof(dep->name), "ep%d%s", epnum >> 1, | 
|  | 1521 | (epnum & 1) ? "in" : "out"); | 
|  | 1522 | dep->endpoint.name = dep->name; | 
|  | 1523 | dep->direction = (epnum & 1); | 
|  | 1524 |  | 
|  | 1525 | if (epnum == 0 || epnum == 1) { | 
|  | 1526 | dep->endpoint.maxpacket = 512; | 
|  | 1527 | dep->endpoint.ops = &dwc3_gadget_ep0_ops; | 
|  | 1528 | if (!epnum) | 
|  | 1529 | dwc->gadget.ep0 = &dep->endpoint; | 
|  | 1530 | } else { | 
|  | 1531 | int		ret; | 
|  | 1532 |  | 
|  | 1533 | dep->endpoint.maxpacket = 1024; | 
| Sebastian Andrzej Siewior | 12d36c1 | 2011-11-03 20:27:50 +0100 | [diff] [blame] | 1534 | dep->endpoint.max_streams = 15; | 
| Felipe Balbi | 72246da | 2011-08-19 18:10:58 +0300 | [diff] [blame] | 1535 | dep->endpoint.ops = &dwc3_gadget_ep_ops; | 
|  | 1536 | list_add_tail(&dep->endpoint.ep_list, | 
|  | 1537 | &dwc->gadget.ep_list); | 
|  | 1538 |  | 
|  | 1539 | ret = dwc3_alloc_trb_pool(dep); | 
| Felipe Balbi | 25b8ff6 | 2011-11-04 12:32:47 +0200 | [diff] [blame] | 1540 | if (ret) | 
| Felipe Balbi | 72246da | 2011-08-19 18:10:58 +0300 | [diff] [blame] | 1541 | return ret; | 
| Felipe Balbi | 72246da | 2011-08-19 18:10:58 +0300 | [diff] [blame] | 1542 | } | 
| Felipe Balbi | 25b8ff6 | 2011-11-04 12:32:47 +0200 | [diff] [blame] | 1543 |  | 
| Felipe Balbi | 72246da | 2011-08-19 18:10:58 +0300 | [diff] [blame] | 1544 | INIT_LIST_HEAD(&dep->request_list); | 
|  | 1545 | INIT_LIST_HEAD(&dep->req_queued); | 
|  | 1546 | } | 
|  | 1547 |  | 
|  | 1548 | return 0; | 
|  | 1549 | } | 
|  | 1550 |  | 
|  | 1551 | static void dwc3_gadget_free_endpoints(struct dwc3 *dwc) | 
|  | 1552 | { | 
|  | 1553 | struct dwc3_ep			*dep; | 
|  | 1554 | u8				epnum; | 
|  | 1555 |  | 
|  | 1556 | for (epnum = 0; epnum < DWC3_ENDPOINTS_NUM; epnum++) { | 
|  | 1557 | dep = dwc->eps[epnum]; | 
|  | 1558 | dwc3_free_trb_pool(dep); | 
|  | 1559 |  | 
|  | 1560 | if (epnum != 0 && epnum != 1) | 
|  | 1561 | list_del(&dep->endpoint.ep_list); | 
|  | 1562 |  | 
|  | 1563 | kfree(dep); | 
|  | 1564 | } | 
|  | 1565 | } | 
|  | 1566 |  | 
|  | 1567 | static void dwc3_gadget_release(struct device *dev) | 
|  | 1568 | { | 
|  | 1569 | dev_dbg(dev, "%s\n", __func__); | 
|  | 1570 | } | 
|  | 1571 |  | 
|  | 1572 | /* -------------------------------------------------------------------------- */ | 
|  | 1573 | static int dwc3_cleanup_done_reqs(struct dwc3 *dwc, struct dwc3_ep *dep, | 
|  | 1574 | const struct dwc3_event_depevt *event, int status) | 
|  | 1575 | { | 
|  | 1576 | struct dwc3_request	*req; | 
| Felipe Balbi | f6bafc6 | 2012-02-06 11:04:53 +0200 | [diff] [blame] | 1577 | struct dwc3_trb		*trb; | 
| Felipe Balbi | 72246da | 2011-08-19 18:10:58 +0300 | [diff] [blame] | 1578 | unsigned int		count; | 
|  | 1579 | unsigned int		s_pkt = 0; | 
|  | 1580 |  | 
|  | 1581 | do { | 
|  | 1582 | req = next_request(&dep->req_queued); | 
| Sebastian Andrzej Siewior | d39ee7b | 2011-11-03 10:32:20 +0100 | [diff] [blame] | 1583 | if (!req) { | 
|  | 1584 | WARN_ON_ONCE(1); | 
|  | 1585 | return 1; | 
|  | 1586 | } | 
| Felipe Balbi | 72246da | 2011-08-19 18:10:58 +0300 | [diff] [blame] | 1587 |  | 
| Felipe Balbi | f6bafc6 | 2012-02-06 11:04:53 +0200 | [diff] [blame] | 1588 | trb = req->trb; | 
| Felipe Balbi | 72246da | 2011-08-19 18:10:58 +0300 | [diff] [blame] | 1589 |  | 
| Felipe Balbi | f6bafc6 | 2012-02-06 11:04:53 +0200 | [diff] [blame] | 1590 | if ((trb->ctrl & DWC3_TRB_CTRL_HWO) && status != -ESHUTDOWN) | 
| Sebastian Andrzej Siewior | 0d2f475 | 2011-08-19 19:59:12 +0200 | [diff] [blame] | 1591 | /* | 
|  | 1592 | * We continue despite the error. There is not much we | 
| Paul Zimmerman | 1d04679 | 2012-02-15 18:56:56 -0800 | [diff] [blame] | 1593 | * can do. If we don't clean it up we loop forever. If | 
|  | 1594 | * we skip the TRB then it gets overwritten after a | 
|  | 1595 | * while since we use them in a ring buffer. A BUG() | 
|  | 1596 | * would help. Lets hope that if this occurs, someone | 
| Sebastian Andrzej Siewior | 0d2f475 | 2011-08-19 19:59:12 +0200 | [diff] [blame] | 1597 | * fixes the root cause instead of looking away :) | 
|  | 1598 | */ | 
| Felipe Balbi | 72246da | 2011-08-19 18:10:58 +0300 | [diff] [blame] | 1599 | dev_err(dwc->dev, "%s's TRB (%p) still owned by HW\n", | 
|  | 1600 | dep->name, req->trb); | 
| Felipe Balbi | f6bafc6 | 2012-02-06 11:04:53 +0200 | [diff] [blame] | 1601 | count = trb->size & DWC3_TRB_SIZE_MASK; | 
| Felipe Balbi | 72246da | 2011-08-19 18:10:58 +0300 | [diff] [blame] | 1602 |  | 
|  | 1603 | if (dep->direction) { | 
|  | 1604 | if (count) { | 
|  | 1605 | dev_err(dwc->dev, "incomplete IN transfer %s\n", | 
|  | 1606 | dep->name); | 
|  | 1607 | status = -ECONNRESET; | 
|  | 1608 | } | 
|  | 1609 | } else { | 
|  | 1610 | if (count && (event->status & DEPEVT_STATUS_SHORT)) | 
|  | 1611 | s_pkt = 1; | 
|  | 1612 | } | 
|  | 1613 |  | 
|  | 1614 | /* | 
|  | 1615 | * We assume here we will always receive the entire data block | 
|  | 1616 | * which we should receive. Meaning, if we program RX to | 
|  | 1617 | * receive 4K but we receive only 2K, we assume that's all we | 
|  | 1618 | * should receive and we simply bounce the request back to the | 
|  | 1619 | * gadget driver for further processing. | 
|  | 1620 | */ | 
|  | 1621 | req->request.actual += req->request.length - count; | 
|  | 1622 | dwc3_gadget_giveback(dep, req, status); | 
|  | 1623 | if (s_pkt) | 
|  | 1624 | break; | 
| Felipe Balbi | f6bafc6 | 2012-02-06 11:04:53 +0200 | [diff] [blame] | 1625 | if ((event->status & DEPEVT_STATUS_LST) && | 
|  | 1626 | (trb->ctrl & DWC3_TRB_CTRL_LST)) | 
| Felipe Balbi | 72246da | 2011-08-19 18:10:58 +0300 | [diff] [blame] | 1627 | break; | 
| Felipe Balbi | f6bafc6 | 2012-02-06 11:04:53 +0200 | [diff] [blame] | 1628 | if ((event->status & DEPEVT_STATUS_IOC) && | 
|  | 1629 | (trb->ctrl & DWC3_TRB_CTRL_IOC)) | 
| Felipe Balbi | 72246da | 2011-08-19 18:10:58 +0300 | [diff] [blame] | 1630 | break; | 
|  | 1631 | } while (1); | 
|  | 1632 |  | 
| Felipe Balbi | f6bafc6 | 2012-02-06 11:04:53 +0200 | [diff] [blame] | 1633 | if ((event->status & DEPEVT_STATUS_IOC) && | 
|  | 1634 | (trb->ctrl & DWC3_TRB_CTRL_IOC)) | 
| Felipe Balbi | 72246da | 2011-08-19 18:10:58 +0300 | [diff] [blame] | 1635 | return 0; | 
|  | 1636 | return 1; | 
|  | 1637 | } | 
|  | 1638 |  | 
|  | 1639 | static void dwc3_endpoint_transfer_complete(struct dwc3 *dwc, | 
|  | 1640 | struct dwc3_ep *dep, const struct dwc3_event_depevt *event, | 
|  | 1641 | int start_new) | 
|  | 1642 | { | 
|  | 1643 | unsigned		status = 0; | 
|  | 1644 | int			clean_busy; | 
|  | 1645 |  | 
|  | 1646 | if (event->status & DEPEVT_STATUS_BUSERR) | 
|  | 1647 | status = -ECONNRESET; | 
|  | 1648 |  | 
| Paul Zimmerman | 1d04679 | 2012-02-15 18:56:56 -0800 | [diff] [blame] | 1649 | clean_busy = dwc3_cleanup_done_reqs(dwc, dep, event, status); | 
| Paul Zimmerman | c2df85c | 2012-02-24 17:32:18 -0800 | [diff] [blame] | 1650 | if (clean_busy) | 
| Felipe Balbi | 72246da | 2011-08-19 18:10:58 +0300 | [diff] [blame] | 1651 | dep->flags &= ~DWC3_EP_BUSY; | 
| Felipe Balbi | fae2b90 | 2011-10-14 13:00:30 +0300 | [diff] [blame] | 1652 |  | 
|  | 1653 | /* | 
|  | 1654 | * WORKAROUND: This is the 2nd half of U1/U2 -> U0 workaround. | 
|  | 1655 | * See dwc3_gadget_linksts_change_interrupt() for 1st half. | 
|  | 1656 | */ | 
|  | 1657 | if (dwc->revision < DWC3_REVISION_183A) { | 
|  | 1658 | u32		reg; | 
|  | 1659 | int		i; | 
|  | 1660 |  | 
|  | 1661 | for (i = 0; i < DWC3_ENDPOINTS_NUM; i++) { | 
|  | 1662 | struct dwc3_ep	*dep = dwc->eps[i]; | 
|  | 1663 |  | 
|  | 1664 | if (!(dep->flags & DWC3_EP_ENABLED)) | 
|  | 1665 | continue; | 
|  | 1666 |  | 
|  | 1667 | if (!list_empty(&dep->req_queued)) | 
|  | 1668 | return; | 
|  | 1669 | } | 
|  | 1670 |  | 
|  | 1671 | reg = dwc3_readl(dwc->regs, DWC3_DCTL); | 
|  | 1672 | reg |= dwc->u1u2; | 
|  | 1673 | dwc3_writel(dwc->regs, DWC3_DCTL, reg); | 
|  | 1674 |  | 
|  | 1675 | dwc->u1u2 = 0; | 
|  | 1676 | } | 
| Felipe Balbi | 72246da | 2011-08-19 18:10:58 +0300 | [diff] [blame] | 1677 | } | 
|  | 1678 |  | 
|  | 1679 | static void dwc3_gadget_start_isoc(struct dwc3 *dwc, | 
|  | 1680 | struct dwc3_ep *dep, const struct dwc3_event_depevt *event) | 
|  | 1681 | { | 
| Paul Zimmerman | 9bafa56 | 2012-02-17 14:10:16 -0800 | [diff] [blame] | 1682 | u32 uf, mask; | 
| Felipe Balbi | 72246da | 2011-08-19 18:10:58 +0300 | [diff] [blame] | 1683 |  | 
|  | 1684 | if (list_empty(&dep->request_list)) { | 
|  | 1685 | dev_vdbg(dwc->dev, "ISOC ep %s run out for requests.\n", | 
|  | 1686 | dep->name); | 
|  | 1687 | return; | 
|  | 1688 | } | 
|  | 1689 |  | 
| Paul Zimmerman | 9bafa56 | 2012-02-17 14:10:16 -0800 | [diff] [blame] | 1690 | mask = ~(dep->interval - 1); | 
|  | 1691 | uf = event->parameters & mask; | 
|  | 1692 | /* 4 micro frames in the future */ | 
|  | 1693 | uf += dep->interval * 4; | 
| Felipe Balbi | 72246da | 2011-08-19 18:10:58 +0300 | [diff] [blame] | 1694 |  | 
|  | 1695 | __dwc3_gadget_kick_transfer(dep, uf, 1); | 
|  | 1696 | } | 
|  | 1697 |  | 
|  | 1698 | static void dwc3_process_ep_cmd_complete(struct dwc3_ep *dep, | 
|  | 1699 | const struct dwc3_event_depevt *event) | 
|  | 1700 | { | 
|  | 1701 | struct dwc3 *dwc = dep->dwc; | 
|  | 1702 | struct dwc3_event_depevt mod_ev = *event; | 
|  | 1703 |  | 
|  | 1704 | /* | 
| Paul Zimmerman | 1d04679 | 2012-02-15 18:56:56 -0800 | [diff] [blame] | 1705 | * We were asked to remove one request. It is possible that this | 
|  | 1706 | * request and a few others were started together and have the same | 
| Felipe Balbi | 72246da | 2011-08-19 18:10:58 +0300 | [diff] [blame] | 1707 | * transfer index. Since we stopped the complete endpoint we don't | 
|  | 1708 | * know how many requests were already completed (and not yet) | 
|  | 1709 | * reported and how could be done (later). We purge them all until | 
|  | 1710 | * the end of the list. | 
|  | 1711 | */ | 
|  | 1712 | mod_ev.status = DEPEVT_STATUS_LST; | 
|  | 1713 | dwc3_cleanup_done_reqs(dwc, dep, &mod_ev, -ESHUTDOWN); | 
|  | 1714 | dep->flags &= ~DWC3_EP_BUSY; | 
| Paul Zimmerman | 1d04679 | 2012-02-15 18:56:56 -0800 | [diff] [blame] | 1715 | /* pending requests are ignored and are queued on XferNotReady */ | 
| Felipe Balbi | 72246da | 2011-08-19 18:10:58 +0300 | [diff] [blame] | 1716 | } | 
|  | 1717 |  | 
|  | 1718 | static void dwc3_ep_cmd_compl(struct dwc3_ep *dep, | 
|  | 1719 | const struct dwc3_event_depevt *event) | 
|  | 1720 | { | 
|  | 1721 | u32 param = event->parameters; | 
|  | 1722 | u32 cmd_type = (param >> 8) & ((1 << 5) - 1); | 
|  | 1723 |  | 
|  | 1724 | switch (cmd_type) { | 
|  | 1725 | case DWC3_DEPCMD_ENDTRANSFER: | 
|  | 1726 | dwc3_process_ep_cmd_complete(dep, event); | 
|  | 1727 | break; | 
|  | 1728 | case DWC3_DEPCMD_STARTTRANSFER: | 
|  | 1729 | dep->res_trans_idx = param & 0x7f; | 
|  | 1730 | break; | 
|  | 1731 | default: | 
|  | 1732 | printk(KERN_ERR "%s() unknown /unexpected type: %d\n", | 
|  | 1733 | __func__, cmd_type); | 
|  | 1734 | break; | 
|  | 1735 | }; | 
|  | 1736 | } | 
|  | 1737 |  | 
|  | 1738 | static void dwc3_endpoint_interrupt(struct dwc3 *dwc, | 
|  | 1739 | const struct dwc3_event_depevt *event) | 
|  | 1740 | { | 
|  | 1741 | struct dwc3_ep		*dep; | 
|  | 1742 | u8			epnum = event->endpoint_number; | 
|  | 1743 |  | 
|  | 1744 | dep = dwc->eps[epnum]; | 
|  | 1745 |  | 
|  | 1746 | dev_vdbg(dwc->dev, "%s: %s\n", dep->name, | 
|  | 1747 | dwc3_ep_event_string(event->endpoint_event)); | 
|  | 1748 |  | 
|  | 1749 | if (epnum == 0 || epnum == 1) { | 
|  | 1750 | dwc3_ep0_interrupt(dwc, event); | 
|  | 1751 | return; | 
|  | 1752 | } | 
|  | 1753 |  | 
|  | 1754 | switch (event->endpoint_event) { | 
|  | 1755 | case DWC3_DEPEVT_XFERCOMPLETE: | 
| Paul Zimmerman | c2df85c | 2012-02-24 17:32:18 -0800 | [diff] [blame] | 1756 | dep->res_trans_idx = 0; | 
|  | 1757 |  | 
| Felipe Balbi | 72246da | 2011-08-19 18:10:58 +0300 | [diff] [blame] | 1758 | if (usb_endpoint_xfer_isoc(dep->desc)) { | 
|  | 1759 | dev_dbg(dwc->dev, "%s is an Isochronous endpoint\n", | 
|  | 1760 | dep->name); | 
|  | 1761 | return; | 
|  | 1762 | } | 
|  | 1763 |  | 
|  | 1764 | dwc3_endpoint_transfer_complete(dwc, dep, event, 1); | 
|  | 1765 | break; | 
|  | 1766 | case DWC3_DEPEVT_XFERINPROGRESS: | 
|  | 1767 | if (!usb_endpoint_xfer_isoc(dep->desc)) { | 
|  | 1768 | dev_dbg(dwc->dev, "%s is not an Isochronous endpoint\n", | 
|  | 1769 | dep->name); | 
|  | 1770 | return; | 
|  | 1771 | } | 
|  | 1772 |  | 
|  | 1773 | dwc3_endpoint_transfer_complete(dwc, dep, event, 0); | 
|  | 1774 | break; | 
|  | 1775 | case DWC3_DEPEVT_XFERNOTREADY: | 
|  | 1776 | if (usb_endpoint_xfer_isoc(dep->desc)) { | 
|  | 1777 | dwc3_gadget_start_isoc(dwc, dep, event); | 
|  | 1778 | } else { | 
|  | 1779 | int ret; | 
|  | 1780 |  | 
|  | 1781 | dev_vdbg(dwc->dev, "%s: reason %s\n", | 
| Felipe Balbi | 40aa41f | 2012-01-18 17:06:03 +0200 | [diff] [blame] | 1782 | dep->name, event->status & | 
|  | 1783 | DEPEVT_STATUS_TRANSFER_ACTIVE | 
| Felipe Balbi | 72246da | 2011-08-19 18:10:58 +0300 | [diff] [blame] | 1784 | ? "Transfer Active" | 
|  | 1785 | : "Transfer Not Active"); | 
|  | 1786 |  | 
|  | 1787 | ret = __dwc3_gadget_kick_transfer(dep, 0, 1); | 
|  | 1788 | if (!ret || ret == -EBUSY) | 
|  | 1789 | return; | 
|  | 1790 |  | 
|  | 1791 | dev_dbg(dwc->dev, "%s: failed to kick transfers\n", | 
|  | 1792 | dep->name); | 
|  | 1793 | } | 
|  | 1794 |  | 
|  | 1795 | break; | 
| Felipe Balbi | 879631a | 2011-09-30 10:58:47 +0300 | [diff] [blame] | 1796 | case DWC3_DEPEVT_STREAMEVT: | 
|  | 1797 | if (!usb_endpoint_xfer_bulk(dep->desc)) { | 
|  | 1798 | dev_err(dwc->dev, "Stream event for non-Bulk %s\n", | 
|  | 1799 | dep->name); | 
|  | 1800 | return; | 
|  | 1801 | } | 
|  | 1802 |  | 
|  | 1803 | switch (event->status) { | 
|  | 1804 | case DEPEVT_STREAMEVT_FOUND: | 
|  | 1805 | dev_vdbg(dwc->dev, "Stream %d found and started\n", | 
|  | 1806 | event->parameters); | 
|  | 1807 |  | 
|  | 1808 | break; | 
|  | 1809 | case DEPEVT_STREAMEVT_NOTFOUND: | 
|  | 1810 | /* FALLTHROUGH */ | 
|  | 1811 | default: | 
|  | 1812 | dev_dbg(dwc->dev, "Couldn't find suitable stream\n"); | 
|  | 1813 | } | 
|  | 1814 | break; | 
| Felipe Balbi | 72246da | 2011-08-19 18:10:58 +0300 | [diff] [blame] | 1815 | case DWC3_DEPEVT_RXTXFIFOEVT: | 
|  | 1816 | dev_dbg(dwc->dev, "%s FIFO Overrun\n", dep->name); | 
|  | 1817 | break; | 
| Felipe Balbi | 72246da | 2011-08-19 18:10:58 +0300 | [diff] [blame] | 1818 | case DWC3_DEPEVT_EPCMDCMPLT: | 
|  | 1819 | dwc3_ep_cmd_compl(dep, event); | 
|  | 1820 | break; | 
|  | 1821 | } | 
|  | 1822 | } | 
|  | 1823 |  | 
|  | 1824 | static void dwc3_disconnect_gadget(struct dwc3 *dwc) | 
|  | 1825 | { | 
|  | 1826 | if (dwc->gadget_driver && dwc->gadget_driver->disconnect) { | 
|  | 1827 | spin_unlock(&dwc->lock); | 
|  | 1828 | dwc->gadget_driver->disconnect(&dwc->gadget); | 
|  | 1829 | spin_lock(&dwc->lock); | 
|  | 1830 | } | 
|  | 1831 | } | 
|  | 1832 |  | 
|  | 1833 | static void dwc3_stop_active_transfer(struct dwc3 *dwc, u32 epnum) | 
|  | 1834 | { | 
|  | 1835 | struct dwc3_ep *dep; | 
|  | 1836 | struct dwc3_gadget_ep_cmd_params params; | 
|  | 1837 | u32 cmd; | 
|  | 1838 | int ret; | 
|  | 1839 |  | 
|  | 1840 | dep = dwc->eps[epnum]; | 
|  | 1841 |  | 
| Sebastian Andrzej Siewior | 624407f | 2011-08-29 13:56:37 +0200 | [diff] [blame] | 1842 | WARN_ON(!dep->res_trans_idx); | 
| Felipe Balbi | 72246da | 2011-08-19 18:10:58 +0300 | [diff] [blame] | 1843 | if (dep->res_trans_idx) { | 
|  | 1844 | cmd = DWC3_DEPCMD_ENDTRANSFER; | 
|  | 1845 | cmd |= DWC3_DEPCMD_HIPRI_FORCERM | DWC3_DEPCMD_CMDIOC; | 
|  | 1846 | cmd |= DWC3_DEPCMD_PARAM(dep->res_trans_idx); | 
|  | 1847 | memset(¶ms, 0, sizeof(params)); | 
|  | 1848 | ret = dwc3_send_gadget_ep_cmd(dwc, dep->number, cmd, ¶ms); | 
|  | 1849 | WARN_ON_ONCE(ret); | 
| Sebastian Andrzej Siewior | a1ae9be | 2011-08-22 17:42:18 +0200 | [diff] [blame] | 1850 | dep->res_trans_idx = 0; | 
| Felipe Balbi | 72246da | 2011-08-19 18:10:58 +0300 | [diff] [blame] | 1851 | } | 
|  | 1852 | } | 
|  | 1853 |  | 
|  | 1854 | static void dwc3_stop_active_transfers(struct dwc3 *dwc) | 
|  | 1855 | { | 
|  | 1856 | u32 epnum; | 
|  | 1857 |  | 
|  | 1858 | for (epnum = 2; epnum < DWC3_ENDPOINTS_NUM; epnum++) { | 
|  | 1859 | struct dwc3_ep *dep; | 
|  | 1860 |  | 
|  | 1861 | dep = dwc->eps[epnum]; | 
|  | 1862 | if (!(dep->flags & DWC3_EP_ENABLED)) | 
|  | 1863 | continue; | 
|  | 1864 |  | 
| Sebastian Andrzej Siewior | 624407f | 2011-08-29 13:56:37 +0200 | [diff] [blame] | 1865 | dwc3_remove_requests(dwc, dep); | 
| Felipe Balbi | 72246da | 2011-08-19 18:10:58 +0300 | [diff] [blame] | 1866 | } | 
|  | 1867 | } | 
|  | 1868 |  | 
|  | 1869 | static void dwc3_clear_stall_all_ep(struct dwc3 *dwc) | 
|  | 1870 | { | 
|  | 1871 | u32 epnum; | 
|  | 1872 |  | 
|  | 1873 | for (epnum = 1; epnum < DWC3_ENDPOINTS_NUM; epnum++) { | 
|  | 1874 | struct dwc3_ep *dep; | 
|  | 1875 | struct dwc3_gadget_ep_cmd_params params; | 
|  | 1876 | int ret; | 
|  | 1877 |  | 
|  | 1878 | dep = dwc->eps[epnum]; | 
|  | 1879 |  | 
|  | 1880 | if (!(dep->flags & DWC3_EP_STALL)) | 
|  | 1881 | continue; | 
|  | 1882 |  | 
|  | 1883 | dep->flags &= ~DWC3_EP_STALL; | 
|  | 1884 |  | 
|  | 1885 | memset(¶ms, 0, sizeof(params)); | 
|  | 1886 | ret = dwc3_send_gadget_ep_cmd(dwc, dep->number, | 
|  | 1887 | DWC3_DEPCMD_CLEARSTALL, ¶ms); | 
|  | 1888 | WARN_ON_ONCE(ret); | 
|  | 1889 | } | 
|  | 1890 | } | 
|  | 1891 |  | 
|  | 1892 | static void dwc3_gadget_disconnect_interrupt(struct dwc3 *dwc) | 
|  | 1893 | { | 
|  | 1894 | dev_vdbg(dwc->dev, "%s\n", __func__); | 
|  | 1895 | #if 0 | 
|  | 1896 | XXX | 
|  | 1897 | U1/U2 is powersave optimization. Skip it for now. Anyway we need to | 
|  | 1898 | enable it before we can disable it. | 
|  | 1899 |  | 
|  | 1900 | reg = dwc3_readl(dwc->regs, DWC3_DCTL); | 
|  | 1901 | reg &= ~DWC3_DCTL_INITU1ENA; | 
|  | 1902 | dwc3_writel(dwc->regs, DWC3_DCTL, reg); | 
|  | 1903 |  | 
|  | 1904 | reg &= ~DWC3_DCTL_INITU2ENA; | 
|  | 1905 | dwc3_writel(dwc->regs, DWC3_DCTL, reg); | 
|  | 1906 | #endif | 
|  | 1907 |  | 
|  | 1908 | dwc3_stop_active_transfers(dwc); | 
|  | 1909 | dwc3_disconnect_gadget(dwc); | 
| Paul Zimmerman | b23c843 | 2011-09-30 10:58:42 +0300 | [diff] [blame] | 1910 | dwc->start_config_issued = false; | 
| Felipe Balbi | 72246da | 2011-08-19 18:10:58 +0300 | [diff] [blame] | 1911 |  | 
|  | 1912 | dwc->gadget.speed = USB_SPEED_UNKNOWN; | 
| Felipe Balbi | df62df5 | 2011-10-14 15:11:49 +0300 | [diff] [blame] | 1913 | dwc->setup_packet_pending = false; | 
| Felipe Balbi | 72246da | 2011-08-19 18:10:58 +0300 | [diff] [blame] | 1914 | } | 
|  | 1915 |  | 
|  | 1916 | static void dwc3_gadget_usb3_phy_power(struct dwc3 *dwc, int on) | 
|  | 1917 | { | 
|  | 1918 | u32			reg; | 
|  | 1919 |  | 
|  | 1920 | reg = dwc3_readl(dwc->regs, DWC3_GUSB3PIPECTL(0)); | 
|  | 1921 |  | 
|  | 1922 | if (on) | 
|  | 1923 | reg &= ~DWC3_GUSB3PIPECTL_SUSPHY; | 
|  | 1924 | else | 
|  | 1925 | reg |= DWC3_GUSB3PIPECTL_SUSPHY; | 
|  | 1926 |  | 
|  | 1927 | dwc3_writel(dwc->regs, DWC3_GUSB3PIPECTL(0), reg); | 
|  | 1928 | } | 
|  | 1929 |  | 
|  | 1930 | static void dwc3_gadget_usb2_phy_power(struct dwc3 *dwc, int on) | 
|  | 1931 | { | 
|  | 1932 | u32			reg; | 
|  | 1933 |  | 
|  | 1934 | reg = dwc3_readl(dwc->regs, DWC3_GUSB2PHYCFG(0)); | 
|  | 1935 |  | 
|  | 1936 | if (on) | 
|  | 1937 | reg &= ~DWC3_GUSB2PHYCFG_SUSPHY; | 
|  | 1938 | else | 
|  | 1939 | reg |= DWC3_GUSB2PHYCFG_SUSPHY; | 
|  | 1940 |  | 
|  | 1941 | dwc3_writel(dwc->regs, DWC3_GUSB2PHYCFG(0), reg); | 
|  | 1942 | } | 
|  | 1943 |  | 
|  | 1944 | static void dwc3_gadget_reset_interrupt(struct dwc3 *dwc) | 
|  | 1945 | { | 
|  | 1946 | u32			reg; | 
|  | 1947 |  | 
|  | 1948 | dev_vdbg(dwc->dev, "%s\n", __func__); | 
|  | 1949 |  | 
| Felipe Balbi | df62df5 | 2011-10-14 15:11:49 +0300 | [diff] [blame] | 1950 | /* | 
|  | 1951 | * WORKAROUND: DWC3 revisions <1.88a have an issue which | 
|  | 1952 | * would cause a missing Disconnect Event if there's a | 
|  | 1953 | * pending Setup Packet in the FIFO. | 
|  | 1954 | * | 
|  | 1955 | * There's no suggested workaround on the official Bug | 
|  | 1956 | * report, which states that "unless the driver/application | 
|  | 1957 | * is doing any special handling of a disconnect event, | 
|  | 1958 | * there is no functional issue". | 
|  | 1959 | * | 
|  | 1960 | * Unfortunately, it turns out that we _do_ some special | 
|  | 1961 | * handling of a disconnect event, namely complete all | 
|  | 1962 | * pending transfers, notify gadget driver of the | 
|  | 1963 | * disconnection, and so on. | 
|  | 1964 | * | 
|  | 1965 | * Our suggested workaround is to follow the Disconnect | 
|  | 1966 | * Event steps here, instead, based on a setup_packet_pending | 
|  | 1967 | * flag. Such flag gets set whenever we have a XferNotReady | 
|  | 1968 | * event on EP0 and gets cleared on XferComplete for the | 
|  | 1969 | * same endpoint. | 
|  | 1970 | * | 
|  | 1971 | * Refers to: | 
|  | 1972 | * | 
|  | 1973 | * STAR#9000466709: RTL: Device : Disconnect event not | 
|  | 1974 | * generated if setup packet pending in FIFO | 
|  | 1975 | */ | 
|  | 1976 | if (dwc->revision < DWC3_REVISION_188A) { | 
|  | 1977 | if (dwc->setup_packet_pending) | 
|  | 1978 | dwc3_gadget_disconnect_interrupt(dwc); | 
|  | 1979 | } | 
|  | 1980 |  | 
| Felipe Balbi | 961906e | 2011-12-20 15:37:21 +0200 | [diff] [blame] | 1981 | /* after reset -> Default State */ | 
|  | 1982 | dwc->dev_state = DWC3_DEFAULT_STATE; | 
|  | 1983 |  | 
| Felipe Balbi | 72246da | 2011-08-19 18:10:58 +0300 | [diff] [blame] | 1984 | /* Enable PHYs */ | 
|  | 1985 | dwc3_gadget_usb2_phy_power(dwc, true); | 
|  | 1986 | dwc3_gadget_usb3_phy_power(dwc, true); | 
|  | 1987 |  | 
|  | 1988 | if (dwc->gadget.speed != USB_SPEED_UNKNOWN) | 
|  | 1989 | dwc3_disconnect_gadget(dwc); | 
|  | 1990 |  | 
|  | 1991 | reg = dwc3_readl(dwc->regs, DWC3_DCTL); | 
|  | 1992 | reg &= ~DWC3_DCTL_TSTCTRL_MASK; | 
|  | 1993 | dwc3_writel(dwc->regs, DWC3_DCTL, reg); | 
| Gerard Cauvy | 3b63736 | 2012-02-10 12:21:18 +0200 | [diff] [blame] | 1994 | dwc->test_mode = false; | 
| Felipe Balbi | 72246da | 2011-08-19 18:10:58 +0300 | [diff] [blame] | 1995 |  | 
|  | 1996 | dwc3_stop_active_transfers(dwc); | 
|  | 1997 | dwc3_clear_stall_all_ep(dwc); | 
| Paul Zimmerman | b23c843 | 2011-09-30 10:58:42 +0300 | [diff] [blame] | 1998 | dwc->start_config_issued = false; | 
| Felipe Balbi | 72246da | 2011-08-19 18:10:58 +0300 | [diff] [blame] | 1999 |  | 
|  | 2000 | /* Reset device address to zero */ | 
|  | 2001 | reg = dwc3_readl(dwc->regs, DWC3_DCFG); | 
|  | 2002 | reg &= ~(DWC3_DCFG_DEVADDR_MASK); | 
|  | 2003 | dwc3_writel(dwc->regs, DWC3_DCFG, reg); | 
| Felipe Balbi | 72246da | 2011-08-19 18:10:58 +0300 | [diff] [blame] | 2004 | } | 
|  | 2005 |  | 
|  | 2006 | static void dwc3_update_ram_clk_sel(struct dwc3 *dwc, u32 speed) | 
|  | 2007 | { | 
|  | 2008 | u32 reg; | 
|  | 2009 | u32 usb30_clock = DWC3_GCTL_CLK_BUS; | 
|  | 2010 |  | 
|  | 2011 | /* | 
|  | 2012 | * We change the clock only at SS but I dunno why I would want to do | 
|  | 2013 | * this. Maybe it becomes part of the power saving plan. | 
|  | 2014 | */ | 
|  | 2015 |  | 
|  | 2016 | if (speed != DWC3_DSTS_SUPERSPEED) | 
|  | 2017 | return; | 
|  | 2018 |  | 
|  | 2019 | /* | 
|  | 2020 | * RAMClkSel is reset to 0 after USB reset, so it must be reprogrammed | 
|  | 2021 | * each time on Connect Done. | 
|  | 2022 | */ | 
|  | 2023 | if (!usb30_clock) | 
|  | 2024 | return; | 
|  | 2025 |  | 
|  | 2026 | reg = dwc3_readl(dwc->regs, DWC3_GCTL); | 
|  | 2027 | reg |= DWC3_GCTL_RAMCLKSEL(usb30_clock); | 
|  | 2028 | dwc3_writel(dwc->regs, DWC3_GCTL, reg); | 
|  | 2029 | } | 
|  | 2030 |  | 
|  | 2031 | static void dwc3_gadget_disable_phy(struct dwc3 *dwc, u8 speed) | 
|  | 2032 | { | 
|  | 2033 | switch (speed) { | 
|  | 2034 | case USB_SPEED_SUPER: | 
|  | 2035 | dwc3_gadget_usb2_phy_power(dwc, false); | 
|  | 2036 | break; | 
|  | 2037 | case USB_SPEED_HIGH: | 
|  | 2038 | case USB_SPEED_FULL: | 
|  | 2039 | case USB_SPEED_LOW: | 
|  | 2040 | dwc3_gadget_usb3_phy_power(dwc, false); | 
|  | 2041 | break; | 
|  | 2042 | } | 
|  | 2043 | } | 
|  | 2044 |  | 
|  | 2045 | static void dwc3_gadget_conndone_interrupt(struct dwc3 *dwc) | 
|  | 2046 | { | 
|  | 2047 | struct dwc3_gadget_ep_cmd_params params; | 
|  | 2048 | struct dwc3_ep		*dep; | 
|  | 2049 | int			ret; | 
|  | 2050 | u32			reg; | 
|  | 2051 | u8			speed; | 
|  | 2052 |  | 
|  | 2053 | dev_vdbg(dwc->dev, "%s\n", __func__); | 
|  | 2054 |  | 
|  | 2055 | memset(¶ms, 0x00, sizeof(params)); | 
|  | 2056 |  | 
| Felipe Balbi | 72246da | 2011-08-19 18:10:58 +0300 | [diff] [blame] | 2057 | reg = dwc3_readl(dwc->regs, DWC3_DSTS); | 
|  | 2058 | speed = reg & DWC3_DSTS_CONNECTSPD; | 
|  | 2059 | dwc->speed = speed; | 
|  | 2060 |  | 
|  | 2061 | dwc3_update_ram_clk_sel(dwc, speed); | 
|  | 2062 |  | 
|  | 2063 | switch (speed) { | 
|  | 2064 | case DWC3_DCFG_SUPERSPEED: | 
| Felipe Balbi | 05870c5 | 2011-10-14 14:51:38 +0300 | [diff] [blame] | 2065 | /* | 
|  | 2066 | * WORKAROUND: DWC3 revisions <1.90a have an issue which | 
|  | 2067 | * would cause a missing USB3 Reset event. | 
|  | 2068 | * | 
|  | 2069 | * In such situations, we should force a USB3 Reset | 
|  | 2070 | * event by calling our dwc3_gadget_reset_interrupt() | 
|  | 2071 | * routine. | 
|  | 2072 | * | 
|  | 2073 | * Refers to: | 
|  | 2074 | * | 
|  | 2075 | * STAR#9000483510: RTL: SS : USB3 reset event may | 
|  | 2076 | * not be generated always when the link enters poll | 
|  | 2077 | */ | 
|  | 2078 | if (dwc->revision < DWC3_REVISION_190A) | 
|  | 2079 | dwc3_gadget_reset_interrupt(dwc); | 
|  | 2080 |  | 
| Felipe Balbi | 72246da | 2011-08-19 18:10:58 +0300 | [diff] [blame] | 2081 | dwc3_gadget_ep0_desc.wMaxPacketSize = cpu_to_le16(512); | 
|  | 2082 | dwc->gadget.ep0->maxpacket = 512; | 
|  | 2083 | dwc->gadget.speed = USB_SPEED_SUPER; | 
|  | 2084 | break; | 
|  | 2085 | case DWC3_DCFG_HIGHSPEED: | 
|  | 2086 | dwc3_gadget_ep0_desc.wMaxPacketSize = cpu_to_le16(64); | 
|  | 2087 | dwc->gadget.ep0->maxpacket = 64; | 
|  | 2088 | dwc->gadget.speed = USB_SPEED_HIGH; | 
|  | 2089 | break; | 
|  | 2090 | case DWC3_DCFG_FULLSPEED2: | 
|  | 2091 | case DWC3_DCFG_FULLSPEED1: | 
|  | 2092 | dwc3_gadget_ep0_desc.wMaxPacketSize = cpu_to_le16(64); | 
|  | 2093 | dwc->gadget.ep0->maxpacket = 64; | 
|  | 2094 | dwc->gadget.speed = USB_SPEED_FULL; | 
|  | 2095 | break; | 
|  | 2096 | case DWC3_DCFG_LOWSPEED: | 
|  | 2097 | dwc3_gadget_ep0_desc.wMaxPacketSize = cpu_to_le16(8); | 
|  | 2098 | dwc->gadget.ep0->maxpacket = 8; | 
|  | 2099 | dwc->gadget.speed = USB_SPEED_LOW; | 
|  | 2100 | break; | 
|  | 2101 | } | 
|  | 2102 |  | 
|  | 2103 | /* Disable unneded PHY */ | 
|  | 2104 | dwc3_gadget_disable_phy(dwc, dwc->gadget.speed); | 
|  | 2105 |  | 
|  | 2106 | dep = dwc->eps[0]; | 
| Felipe Balbi | c90bfae | 2011-11-29 13:11:21 +0200 | [diff] [blame] | 2107 | ret = __dwc3_gadget_ep_enable(dep, &dwc3_gadget_ep0_desc, NULL); | 
| Felipe Balbi | 72246da | 2011-08-19 18:10:58 +0300 | [diff] [blame] | 2108 | if (ret) { | 
|  | 2109 | dev_err(dwc->dev, "failed to enable %s\n", dep->name); | 
|  | 2110 | return; | 
|  | 2111 | } | 
|  | 2112 |  | 
|  | 2113 | dep = dwc->eps[1]; | 
| Felipe Balbi | c90bfae | 2011-11-29 13:11:21 +0200 | [diff] [blame] | 2114 | ret = __dwc3_gadget_ep_enable(dep, &dwc3_gadget_ep0_desc, NULL); | 
| Felipe Balbi | 72246da | 2011-08-19 18:10:58 +0300 | [diff] [blame] | 2115 | if (ret) { | 
|  | 2116 | dev_err(dwc->dev, "failed to enable %s\n", dep->name); | 
|  | 2117 | return; | 
|  | 2118 | } | 
|  | 2119 |  | 
|  | 2120 | /* | 
|  | 2121 | * Configure PHY via GUSB3PIPECTLn if required. | 
|  | 2122 | * | 
|  | 2123 | * Update GTXFIFOSIZn | 
|  | 2124 | * | 
|  | 2125 | * In both cases reset values should be sufficient. | 
|  | 2126 | */ | 
|  | 2127 | } | 
|  | 2128 |  | 
|  | 2129 | static void dwc3_gadget_wakeup_interrupt(struct dwc3 *dwc) | 
|  | 2130 | { | 
|  | 2131 | dev_vdbg(dwc->dev, "%s\n", __func__); | 
|  | 2132 |  | 
|  | 2133 | /* | 
|  | 2134 | * TODO take core out of low power mode when that's | 
|  | 2135 | * implemented. | 
|  | 2136 | */ | 
|  | 2137 |  | 
|  | 2138 | dwc->gadget_driver->resume(&dwc->gadget); | 
|  | 2139 | } | 
|  | 2140 |  | 
|  | 2141 | static void dwc3_gadget_linksts_change_interrupt(struct dwc3 *dwc, | 
|  | 2142 | unsigned int evtinfo) | 
|  | 2143 | { | 
| Felipe Balbi | fae2b90 | 2011-10-14 13:00:30 +0300 | [diff] [blame] | 2144 | enum dwc3_link_state	next = evtinfo & DWC3_LINK_STATE_MASK; | 
|  | 2145 |  | 
|  | 2146 | /* | 
|  | 2147 | * WORKAROUND: DWC3 Revisions <1.83a have an issue which, depending | 
|  | 2148 | * on the link partner, the USB session might do multiple entry/exit | 
|  | 2149 | * of low power states before a transfer takes place. | 
|  | 2150 | * | 
|  | 2151 | * Due to this problem, we might experience lower throughput. The | 
|  | 2152 | * suggested workaround is to disable DCTL[12:9] bits if we're | 
|  | 2153 | * transitioning from U1/U2 to U0 and enable those bits again | 
|  | 2154 | * after a transfer completes and there are no pending transfers | 
|  | 2155 | * on any of the enabled endpoints. | 
|  | 2156 | * | 
|  | 2157 | * This is the first half of that workaround. | 
|  | 2158 | * | 
|  | 2159 | * Refers to: | 
|  | 2160 | * | 
|  | 2161 | * STAR#9000446952: RTL: Device SS : if U1/U2 ->U0 takes >128us | 
|  | 2162 | * core send LGO_Ux entering U0 | 
|  | 2163 | */ | 
|  | 2164 | if (dwc->revision < DWC3_REVISION_183A) { | 
|  | 2165 | if (next == DWC3_LINK_STATE_U0) { | 
|  | 2166 | u32	u1u2; | 
|  | 2167 | u32	reg; | 
|  | 2168 |  | 
|  | 2169 | switch (dwc->link_state) { | 
|  | 2170 | case DWC3_LINK_STATE_U1: | 
|  | 2171 | case DWC3_LINK_STATE_U2: | 
|  | 2172 | reg = dwc3_readl(dwc->regs, DWC3_DCTL); | 
|  | 2173 | u1u2 = reg & (DWC3_DCTL_INITU2ENA | 
|  | 2174 | | DWC3_DCTL_ACCEPTU2ENA | 
|  | 2175 | | DWC3_DCTL_INITU1ENA | 
|  | 2176 | | DWC3_DCTL_ACCEPTU1ENA); | 
|  | 2177 |  | 
|  | 2178 | if (!dwc->u1u2) | 
|  | 2179 | dwc->u1u2 = reg & u1u2; | 
|  | 2180 |  | 
|  | 2181 | reg &= ~u1u2; | 
|  | 2182 |  | 
|  | 2183 | dwc3_writel(dwc->regs, DWC3_DCTL, reg); | 
|  | 2184 | break; | 
|  | 2185 | default: | 
|  | 2186 | /* do nothing */ | 
|  | 2187 | break; | 
|  | 2188 | } | 
|  | 2189 | } | 
|  | 2190 | } | 
|  | 2191 |  | 
|  | 2192 | dwc->link_state = next; | 
| Felipe Balbi | 019ac83 | 2011-09-08 21:18:47 +0300 | [diff] [blame] | 2193 |  | 
|  | 2194 | dev_vdbg(dwc->dev, "%s link %d\n", __func__, dwc->link_state); | 
| Felipe Balbi | 72246da | 2011-08-19 18:10:58 +0300 | [diff] [blame] | 2195 | } | 
|  | 2196 |  | 
|  | 2197 | static void dwc3_gadget_interrupt(struct dwc3 *dwc, | 
|  | 2198 | const struct dwc3_event_devt *event) | 
|  | 2199 | { | 
|  | 2200 | switch (event->type) { | 
|  | 2201 | case DWC3_DEVICE_EVENT_DISCONNECT: | 
|  | 2202 | dwc3_gadget_disconnect_interrupt(dwc); | 
|  | 2203 | break; | 
|  | 2204 | case DWC3_DEVICE_EVENT_RESET: | 
|  | 2205 | dwc3_gadget_reset_interrupt(dwc); | 
|  | 2206 | break; | 
|  | 2207 | case DWC3_DEVICE_EVENT_CONNECT_DONE: | 
|  | 2208 | dwc3_gadget_conndone_interrupt(dwc); | 
|  | 2209 | break; | 
|  | 2210 | case DWC3_DEVICE_EVENT_WAKEUP: | 
|  | 2211 | dwc3_gadget_wakeup_interrupt(dwc); | 
|  | 2212 | break; | 
|  | 2213 | case DWC3_DEVICE_EVENT_LINK_STATUS_CHANGE: | 
|  | 2214 | dwc3_gadget_linksts_change_interrupt(dwc, event->event_info); | 
|  | 2215 | break; | 
|  | 2216 | case DWC3_DEVICE_EVENT_EOPF: | 
|  | 2217 | dev_vdbg(dwc->dev, "End of Periodic Frame\n"); | 
|  | 2218 | break; | 
|  | 2219 | case DWC3_DEVICE_EVENT_SOF: | 
|  | 2220 | dev_vdbg(dwc->dev, "Start of Periodic Frame\n"); | 
|  | 2221 | break; | 
|  | 2222 | case DWC3_DEVICE_EVENT_ERRATIC_ERROR: | 
|  | 2223 | dev_vdbg(dwc->dev, "Erratic Error\n"); | 
|  | 2224 | break; | 
|  | 2225 | case DWC3_DEVICE_EVENT_CMD_CMPL: | 
|  | 2226 | dev_vdbg(dwc->dev, "Command Complete\n"); | 
|  | 2227 | break; | 
|  | 2228 | case DWC3_DEVICE_EVENT_OVERFLOW: | 
|  | 2229 | dev_vdbg(dwc->dev, "Overflow\n"); | 
| Pavankumar Kondeti | d393e17 | 2012-06-12 16:07:29 +0530 | [diff] [blame] | 2230 | /* | 
|  | 2231 | * Controllers prior to 2.30a revision has a bug where | 
|  | 2232 | * Overflow Event may overwrite an unacknowledged event | 
|  | 2233 | * in the event buffer.  The severity of the issue depends | 
|  | 2234 | * on the overwritten event type.  Add a warning message | 
|  | 2235 | * saying that an event is overwritten. | 
|  | 2236 | * | 
|  | 2237 | * TODO: In future we may need to see if we can re-enumerate | 
|  | 2238 | * with host. | 
|  | 2239 | */ | 
|  | 2240 | if (dwc->revision < DWC3_REVISION_230A) | 
|  | 2241 | dev_warn(dwc->dev, "Unacknowledged event overwritten\n"); | 
| Felipe Balbi | 72246da | 2011-08-19 18:10:58 +0300 | [diff] [blame] | 2242 | break; | 
| Pavankumar Kondeti | 33fe6f1 | 2012-06-12 16:21:46 +0530 | [diff] [blame] | 2243 | case DWC3_DEVICE_EVENT_VENDOR_DEV_TEST_LMP: | 
|  | 2244 | /* | 
|  | 2245 | * Controllers prior to 2.30a revision has a bug, due to which | 
|  | 2246 | * a vendor device test LMP event can not be filtered.  But | 
|  | 2247 | * this event is not handled in the current code.  This is a | 
|  | 2248 | * special event and 8 bytes of data will follow the event. | 
|  | 2249 | * Handling this event is tricky when event buffer is almost | 
|  | 2250 | * full. Moreover this event will not occur in normal scenario | 
|  | 2251 | * and can only happen with special hosts in testing scenarios. | 
|  | 2252 | * Add a warning message to indicate that this event is received | 
|  | 2253 | * which means that event buffer might have corrupted. | 
|  | 2254 | */ | 
|  | 2255 | if (dwc->revision < DWC3_REVISION_230A) | 
|  | 2256 | dev_warn(dwc->dev, "Vendor Device Test LMP Received\n"); | 
|  | 2257 | break; | 
| Felipe Balbi | 72246da | 2011-08-19 18:10:58 +0300 | [diff] [blame] | 2258 | default: | 
|  | 2259 | dev_dbg(dwc->dev, "UNKNOWN IRQ %d\n", event->type); | 
|  | 2260 | } | 
|  | 2261 | } | 
|  | 2262 |  | 
|  | 2263 | static void dwc3_process_event_entry(struct dwc3 *dwc, | 
|  | 2264 | const union dwc3_event *event) | 
|  | 2265 | { | 
|  | 2266 | /* Endpoint IRQ, handle it and return early */ | 
|  | 2267 | if (event->type.is_devspec == 0) { | 
|  | 2268 | /* depevt */ | 
|  | 2269 | return dwc3_endpoint_interrupt(dwc, &event->depevt); | 
|  | 2270 | } | 
|  | 2271 |  | 
|  | 2272 | switch (event->type.type) { | 
|  | 2273 | case DWC3_EVENT_TYPE_DEV: | 
|  | 2274 | dwc3_gadget_interrupt(dwc, &event->devt); | 
|  | 2275 | break; | 
|  | 2276 | /* REVISIT what to do with Carkit and I2C events ? */ | 
|  | 2277 | default: | 
|  | 2278 | dev_err(dwc->dev, "UNKNOWN IRQ type %d\n", event->raw); | 
|  | 2279 | } | 
|  | 2280 | } | 
|  | 2281 |  | 
|  | 2282 | static irqreturn_t dwc3_process_event_buf(struct dwc3 *dwc, u32 buf) | 
|  | 2283 | { | 
|  | 2284 | struct dwc3_event_buffer *evt; | 
|  | 2285 | int left; | 
|  | 2286 | u32 count; | 
|  | 2287 |  | 
|  | 2288 | count = dwc3_readl(dwc->regs, DWC3_GEVNTCOUNT(buf)); | 
|  | 2289 | count &= DWC3_GEVNTCOUNT_MASK; | 
|  | 2290 | if (!count) | 
|  | 2291 | return IRQ_NONE; | 
|  | 2292 |  | 
|  | 2293 | evt = dwc->ev_buffs[buf]; | 
|  | 2294 | left = count; | 
|  | 2295 |  | 
|  | 2296 | while (left > 0) { | 
|  | 2297 | union dwc3_event event; | 
|  | 2298 |  | 
| Felipe Balbi | d70d844 | 2012-02-06 13:40:17 +0200 | [diff] [blame] | 2299 | event.raw = *(u32 *) (evt->buf + evt->lpos); | 
|  | 2300 |  | 
| Felipe Balbi | 72246da | 2011-08-19 18:10:58 +0300 | [diff] [blame] | 2301 | dwc3_process_event_entry(dwc, &event); | 
|  | 2302 | /* | 
|  | 2303 | * XXX we wrap around correctly to the next entry as almost all | 
|  | 2304 | * entries are 4 bytes in size. There is one entry which has 12 | 
|  | 2305 | * bytes which is a regular entry followed by 8 bytes data. ATM | 
|  | 2306 | * I don't know how things are organized if were get next to the | 
|  | 2307 | * a boundary so I worry about that once we try to handle that. | 
|  | 2308 | */ | 
|  | 2309 | evt->lpos = (evt->lpos + 4) % DWC3_EVENT_BUFFERS_SIZE; | 
|  | 2310 | left -= 4; | 
|  | 2311 |  | 
|  | 2312 | dwc3_writel(dwc->regs, DWC3_GEVNTCOUNT(buf), 4); | 
|  | 2313 | } | 
|  | 2314 |  | 
|  | 2315 | return IRQ_HANDLED; | 
|  | 2316 | } | 
|  | 2317 |  | 
|  | 2318 | static irqreturn_t dwc3_interrupt(int irq, void *_dwc) | 
|  | 2319 | { | 
|  | 2320 | struct dwc3			*dwc = _dwc; | 
|  | 2321 | int				i; | 
|  | 2322 | irqreturn_t			ret = IRQ_NONE; | 
|  | 2323 |  | 
|  | 2324 | spin_lock(&dwc->lock); | 
|  | 2325 |  | 
| Felipe Balbi | 9f622b2 | 2011-10-12 10:31:04 +0300 | [diff] [blame] | 2326 | for (i = 0; i < dwc->num_event_buffers; i++) { | 
| Felipe Balbi | 72246da | 2011-08-19 18:10:58 +0300 | [diff] [blame] | 2327 | irqreturn_t status; | 
|  | 2328 |  | 
|  | 2329 | status = dwc3_process_event_buf(dwc, i); | 
|  | 2330 | if (status == IRQ_HANDLED) | 
|  | 2331 | ret = status; | 
|  | 2332 | } | 
|  | 2333 |  | 
|  | 2334 | spin_unlock(&dwc->lock); | 
|  | 2335 |  | 
|  | 2336 | return ret; | 
|  | 2337 | } | 
|  | 2338 |  | 
|  | 2339 | /** | 
|  | 2340 | * dwc3_gadget_init - Initializes gadget related registers | 
| Paul Zimmerman | 1d04679 | 2012-02-15 18:56:56 -0800 | [diff] [blame] | 2341 | * @dwc: pointer to our controller context structure | 
| Felipe Balbi | 72246da | 2011-08-19 18:10:58 +0300 | [diff] [blame] | 2342 | * | 
|  | 2343 | * Returns 0 on success otherwise negative errno. | 
|  | 2344 | */ | 
|  | 2345 | int __devinit dwc3_gadget_init(struct dwc3 *dwc) | 
|  | 2346 | { | 
|  | 2347 | u32					reg; | 
|  | 2348 | int					ret; | 
|  | 2349 | int					irq; | 
|  | 2350 |  | 
|  | 2351 | dwc->ctrl_req = dma_alloc_coherent(dwc->dev, sizeof(*dwc->ctrl_req), | 
|  | 2352 | &dwc->ctrl_req_addr, GFP_KERNEL); | 
|  | 2353 | if (!dwc->ctrl_req) { | 
|  | 2354 | dev_err(dwc->dev, "failed to allocate ctrl request\n"); | 
|  | 2355 | ret = -ENOMEM; | 
|  | 2356 | goto err0; | 
|  | 2357 | } | 
|  | 2358 |  | 
|  | 2359 | dwc->ep0_trb = dma_alloc_coherent(dwc->dev, sizeof(*dwc->ep0_trb), | 
|  | 2360 | &dwc->ep0_trb_addr, GFP_KERNEL); | 
|  | 2361 | if (!dwc->ep0_trb) { | 
|  | 2362 | dev_err(dwc->dev, "failed to allocate ep0 trb\n"); | 
|  | 2363 | ret = -ENOMEM; | 
|  | 2364 | goto err1; | 
|  | 2365 | } | 
|  | 2366 |  | 
| Felipe Balbi | 0fc9a1b | 2011-12-19 11:32:34 +0200 | [diff] [blame] | 2367 | dwc->setup_buf = kzalloc(sizeof(*dwc->setup_buf) * 2, | 
|  | 2368 | GFP_KERNEL); | 
| Felipe Balbi | 72246da | 2011-08-19 18:10:58 +0300 | [diff] [blame] | 2369 | if (!dwc->setup_buf) { | 
|  | 2370 | dev_err(dwc->dev, "failed to allocate setup buffer\n"); | 
|  | 2371 | ret = -ENOMEM; | 
|  | 2372 | goto err2; | 
|  | 2373 | } | 
|  | 2374 |  | 
| Felipe Balbi | 5812b1c | 2011-08-27 22:07:53 +0300 | [diff] [blame] | 2375 | dwc->ep0_bounce = dma_alloc_coherent(dwc->dev, | 
|  | 2376 | 512, &dwc->ep0_bounce_addr, GFP_KERNEL); | 
|  | 2377 | if (!dwc->ep0_bounce) { | 
|  | 2378 | dev_err(dwc->dev, "failed to allocate ep0 bounce buffer\n"); | 
|  | 2379 | ret = -ENOMEM; | 
|  | 2380 | goto err3; | 
|  | 2381 | } | 
|  | 2382 |  | 
| Felipe Balbi | 72246da | 2011-08-19 18:10:58 +0300 | [diff] [blame] | 2383 | dev_set_name(&dwc->gadget.dev, "gadget"); | 
|  | 2384 |  | 
|  | 2385 | dwc->gadget.ops			= &dwc3_gadget_ops; | 
| Michal Nazarewicz | d327ab5 | 2011-11-19 18:27:37 +0100 | [diff] [blame] | 2386 | dwc->gadget.max_speed		= USB_SPEED_SUPER; | 
| Felipe Balbi | 72246da | 2011-08-19 18:10:58 +0300 | [diff] [blame] | 2387 | dwc->gadget.speed		= USB_SPEED_UNKNOWN; | 
|  | 2388 | dwc->gadget.dev.parent		= dwc->dev; | 
| Felipe Balbi | eeb720f | 2011-11-28 12:46:59 +0200 | [diff] [blame] | 2389 | dwc->gadget.sg_supported	= true; | 
| Felipe Balbi | 72246da | 2011-08-19 18:10:58 +0300 | [diff] [blame] | 2390 |  | 
|  | 2391 | dma_set_coherent_mask(&dwc->gadget.dev, dwc->dev->coherent_dma_mask); | 
|  | 2392 |  | 
|  | 2393 | dwc->gadget.dev.dma_parms	= dwc->dev->dma_parms; | 
|  | 2394 | dwc->gadget.dev.dma_mask	= dwc->dev->dma_mask; | 
|  | 2395 | dwc->gadget.dev.release		= dwc3_gadget_release; | 
|  | 2396 | dwc->gadget.name		= "dwc3-gadget"; | 
|  | 2397 |  | 
|  | 2398 | /* | 
|  | 2399 | * REVISIT: Here we should clear all pending IRQs to be | 
|  | 2400 | * sure we're starting from a well known location. | 
|  | 2401 | */ | 
|  | 2402 |  | 
|  | 2403 | ret = dwc3_gadget_init_endpoints(dwc); | 
|  | 2404 | if (ret) | 
| Felipe Balbi | 5812b1c | 2011-08-27 22:07:53 +0300 | [diff] [blame] | 2405 | goto err4; | 
| Felipe Balbi | 72246da | 2011-08-19 18:10:58 +0300 | [diff] [blame] | 2406 |  | 
|  | 2407 | irq = platform_get_irq(to_platform_device(dwc->dev), 0); | 
|  | 2408 |  | 
|  | 2409 | ret = request_irq(irq, dwc3_interrupt, IRQF_SHARED, | 
|  | 2410 | "dwc3", dwc); | 
|  | 2411 | if (ret) { | 
|  | 2412 | dev_err(dwc->dev, "failed to request irq #%d --> %d\n", | 
|  | 2413 | irq, ret); | 
| Felipe Balbi | 5812b1c | 2011-08-27 22:07:53 +0300 | [diff] [blame] | 2414 | goto err5; | 
| Felipe Balbi | 72246da | 2011-08-19 18:10:58 +0300 | [diff] [blame] | 2415 | } | 
|  | 2416 |  | 
|  | 2417 | /* Enable all but Start and End of Frame IRQs */ | 
| Pavankumar Kondeti | 33fe6f1 | 2012-06-12 16:21:46 +0530 | [diff] [blame] | 2418 | reg = (DWC3_DEVTEN_EVNTOVERFLOWEN | | 
| Felipe Balbi | 72246da | 2011-08-19 18:10:58 +0300 | [diff] [blame] | 2419 | DWC3_DEVTEN_CMDCMPLTEN | | 
|  | 2420 | DWC3_DEVTEN_ERRTICERREN | | 
|  | 2421 | DWC3_DEVTEN_WKUPEVTEN | | 
|  | 2422 | DWC3_DEVTEN_ULSTCNGEN | | 
|  | 2423 | DWC3_DEVTEN_CONNECTDONEEN | | 
|  | 2424 | DWC3_DEVTEN_USBRSTEN | | 
|  | 2425 | DWC3_DEVTEN_DISCONNEVTEN); | 
|  | 2426 | dwc3_writel(dwc->regs, DWC3_DEVTEN, reg); | 
|  | 2427 |  | 
|  | 2428 | ret = device_register(&dwc->gadget.dev); | 
|  | 2429 | if (ret) { | 
|  | 2430 | dev_err(dwc->dev, "failed to register gadget device\n"); | 
|  | 2431 | put_device(&dwc->gadget.dev); | 
| Felipe Balbi | 5812b1c | 2011-08-27 22:07:53 +0300 | [diff] [blame] | 2432 | goto err6; | 
| Felipe Balbi | 72246da | 2011-08-19 18:10:58 +0300 | [diff] [blame] | 2433 | } | 
|  | 2434 |  | 
|  | 2435 | ret = usb_add_gadget_udc(dwc->dev, &dwc->gadget); | 
|  | 2436 | if (ret) { | 
|  | 2437 | dev_err(dwc->dev, "failed to register udc\n"); | 
| Felipe Balbi | 5812b1c | 2011-08-27 22:07:53 +0300 | [diff] [blame] | 2438 | goto err7; | 
| Felipe Balbi | 72246da | 2011-08-19 18:10:58 +0300 | [diff] [blame] | 2439 | } | 
|  | 2440 |  | 
| Ido Shayevitz | cdeef4c | 2012-05-29 13:17:41 +0200 | [diff] [blame] | 2441 | if (dwc->dotg) { | 
|  | 2442 | /* dwc3 otg driver is active (DRD mode + SRPSupport=1) */ | 
|  | 2443 | ret = otg_set_peripheral(&dwc->dotg->otg, &dwc->gadget); | 
|  | 2444 | if (ret) { | 
|  | 2445 | dev_err(dwc->dev, "failed to set peripheral to otg\n"); | 
|  | 2446 | goto err7; | 
|  | 2447 | } | 
| Manu Gautam | b506727 | 2012-07-02 09:53:41 +0530 | [diff] [blame] | 2448 | } else { | 
|  | 2449 | pm_runtime_no_callbacks(&dwc->gadget.dev); | 
|  | 2450 | pm_runtime_set_active(&dwc->gadget.dev); | 
|  | 2451 | pm_runtime_enable(&dwc->gadget.dev); | 
|  | 2452 | pm_runtime_get(&dwc->gadget.dev); | 
| Ido Shayevitz | cdeef4c | 2012-05-29 13:17:41 +0200 | [diff] [blame] | 2453 | } | 
|  | 2454 |  | 
| Felipe Balbi | 72246da | 2011-08-19 18:10:58 +0300 | [diff] [blame] | 2455 | return 0; | 
|  | 2456 |  | 
| Felipe Balbi | 5812b1c | 2011-08-27 22:07:53 +0300 | [diff] [blame] | 2457 | err7: | 
| Felipe Balbi | 72246da | 2011-08-19 18:10:58 +0300 | [diff] [blame] | 2458 | device_unregister(&dwc->gadget.dev); | 
|  | 2459 |  | 
| Felipe Balbi | 5812b1c | 2011-08-27 22:07:53 +0300 | [diff] [blame] | 2460 | err6: | 
| Felipe Balbi | 72246da | 2011-08-19 18:10:58 +0300 | [diff] [blame] | 2461 | dwc3_writel(dwc->regs, DWC3_DEVTEN, 0x00); | 
|  | 2462 | free_irq(irq, dwc); | 
|  | 2463 |  | 
| Felipe Balbi | 5812b1c | 2011-08-27 22:07:53 +0300 | [diff] [blame] | 2464 | err5: | 
| Felipe Balbi | 72246da | 2011-08-19 18:10:58 +0300 | [diff] [blame] | 2465 | dwc3_gadget_free_endpoints(dwc); | 
|  | 2466 |  | 
| Felipe Balbi | 5812b1c | 2011-08-27 22:07:53 +0300 | [diff] [blame] | 2467 | err4: | 
|  | 2468 | dma_free_coherent(dwc->dev, 512, dwc->ep0_bounce, | 
|  | 2469 | dwc->ep0_bounce_addr); | 
|  | 2470 |  | 
| Felipe Balbi | 72246da | 2011-08-19 18:10:58 +0300 | [diff] [blame] | 2471 | err3: | 
| Felipe Balbi | 0fc9a1b | 2011-12-19 11:32:34 +0200 | [diff] [blame] | 2472 | kfree(dwc->setup_buf); | 
| Felipe Balbi | 72246da | 2011-08-19 18:10:58 +0300 | [diff] [blame] | 2473 |  | 
|  | 2474 | err2: | 
|  | 2475 | dma_free_coherent(dwc->dev, sizeof(*dwc->ep0_trb), | 
|  | 2476 | dwc->ep0_trb, dwc->ep0_trb_addr); | 
|  | 2477 |  | 
|  | 2478 | err1: | 
|  | 2479 | dma_free_coherent(dwc->dev, sizeof(*dwc->ctrl_req), | 
|  | 2480 | dwc->ctrl_req, dwc->ctrl_req_addr); | 
|  | 2481 |  | 
|  | 2482 | err0: | 
|  | 2483 | return ret; | 
|  | 2484 | } | 
|  | 2485 |  | 
|  | 2486 | void dwc3_gadget_exit(struct dwc3 *dwc) | 
|  | 2487 | { | 
|  | 2488 | int			irq; | 
| Felipe Balbi | 72246da | 2011-08-19 18:10:58 +0300 | [diff] [blame] | 2489 |  | 
| Manu Gautam | b506727 | 2012-07-02 09:53:41 +0530 | [diff] [blame] | 2490 | if (dwc->dotg) { | 
|  | 2491 | pm_runtime_put(&dwc->gadget.dev); | 
|  | 2492 | pm_runtime_disable(&dwc->gadget.dev); | 
|  | 2493 | } | 
|  | 2494 |  | 
| Felipe Balbi | 72246da | 2011-08-19 18:10:58 +0300 | [diff] [blame] | 2495 | usb_del_gadget_udc(&dwc->gadget); | 
|  | 2496 | irq = platform_get_irq(to_platform_device(dwc->dev), 0); | 
|  | 2497 |  | 
|  | 2498 | dwc3_writel(dwc->regs, DWC3_DEVTEN, 0x00); | 
|  | 2499 | free_irq(irq, dwc); | 
|  | 2500 |  | 
| Felipe Balbi | 72246da | 2011-08-19 18:10:58 +0300 | [diff] [blame] | 2501 | dwc3_gadget_free_endpoints(dwc); | 
|  | 2502 |  | 
| Felipe Balbi | 5812b1c | 2011-08-27 22:07:53 +0300 | [diff] [blame] | 2503 | dma_free_coherent(dwc->dev, 512, dwc->ep0_bounce, | 
|  | 2504 | dwc->ep0_bounce_addr); | 
|  | 2505 |  | 
| Felipe Balbi | 0fc9a1b | 2011-12-19 11:32:34 +0200 | [diff] [blame] | 2506 | kfree(dwc->setup_buf); | 
| Felipe Balbi | 72246da | 2011-08-19 18:10:58 +0300 | [diff] [blame] | 2507 |  | 
|  | 2508 | dma_free_coherent(dwc->dev, sizeof(*dwc->ep0_trb), | 
|  | 2509 | dwc->ep0_trb, dwc->ep0_trb_addr); | 
|  | 2510 |  | 
|  | 2511 | dma_free_coherent(dwc->dev, sizeof(*dwc->ctrl_req), | 
|  | 2512 | dwc->ctrl_req, dwc->ctrl_req_addr); | 
|  | 2513 |  | 
|  | 2514 | device_unregister(&dwc->gadget.dev); | 
|  | 2515 | } |