aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/usb/gadget/mv_udc_core.c139
1 files changed, 38 insertions, 101 deletions
diff --git a/drivers/usb/gadget/mv_udc_core.c b/drivers/usb/gadget/mv_udc_core.c
index 635ee47dd4e..0ad321d94f2 100644
--- a/drivers/usb/gadget/mv_udc_core.c
+++ b/drivers/usb/gadget/mv_udc_core.c
@@ -276,11 +276,12 @@ static void done(struct mv_ep *ep, struct mv_req *req, int status)
276 276
277static int queue_dtd(struct mv_ep *ep, struct mv_req *req) 277static int queue_dtd(struct mv_ep *ep, struct mv_req *req)
278{ 278{
279 u32 tmp, epstatus, bit_pos, direction;
280 struct mv_udc *udc; 279 struct mv_udc *udc;
281 struct mv_dqh *dqh; 280 struct mv_dqh *dqh;
281 u32 bit_pos, direction;
282 u32 usbcmd, epstatus;
282 unsigned int loops; 283 unsigned int loops;
283 int readsafe, retval = 0; 284 int retval = 0;
284 285
285 udc = ep->udc; 286 udc = ep->udc;
286 direction = ep_dir(ep); 287 direction = ep_dir(ep);
@@ -293,30 +294,18 @@ static int queue_dtd(struct mv_ep *ep, struct mv_req *req)
293 lastreq = list_entry(ep->queue.prev, struct mv_req, queue); 294 lastreq = list_entry(ep->queue.prev, struct mv_req, queue);
294 lastreq->tail->dtd_next = 295 lastreq->tail->dtd_next =
295 req->head->td_dma & EP_QUEUE_HEAD_NEXT_POINTER_MASK; 296 req->head->td_dma & EP_QUEUE_HEAD_NEXT_POINTER_MASK;
296 if (readl(&udc->op_regs->epprime) & bit_pos) { 297
297 loops = LOOPS(PRIME_TIMEOUT); 298 wmb();
298 while (readl(&udc->op_regs->epprime) & bit_pos) { 299
299 if (loops == 0) { 300 if (readl(&udc->op_regs->epprime) & bit_pos)
300 retval = -ETIME; 301 goto done;
301 goto done; 302
302 }
303 udelay(LOOPS_USEC);
304 loops--;
305 }
306 if (readl(&udc->op_regs->epstatus) & bit_pos)
307 goto done;
308 }
309 readsafe = 0;
310 loops = LOOPS(READSAFE_TIMEOUT); 303 loops = LOOPS(READSAFE_TIMEOUT);
311 while (readsafe == 0) { 304 while (1) {
312 if (loops == 0) {
313 retval = -ETIME;
314 goto done;
315 }
316 /* start with setting the semaphores */ 305 /* start with setting the semaphores */
317 tmp = readl(&udc->op_regs->usbcmd); 306 usbcmd = readl(&udc->op_regs->usbcmd);
318 tmp |= USBCMD_ATDTW_TRIPWIRE_SET; 307 usbcmd |= USBCMD_ATDTW_TRIPWIRE_SET;
319 writel(tmp, &udc->op_regs->usbcmd); 308 writel(usbcmd, &udc->op_regs->usbcmd);
320 309
321 /* read the endpoint status */ 310 /* read the endpoint status */
322 epstatus = readl(&udc->op_regs->epstatus) & bit_pos; 311 epstatus = readl(&udc->op_regs->epstatus) & bit_pos;
@@ -329,98 +318,46 @@ static int queue_dtd(struct mv_ep *ep, struct mv_req *req)
329 * primed. 318 * primed.
330 */ 319 */
331 if (readl(&udc->op_regs->usbcmd) 320 if (readl(&udc->op_regs->usbcmd)
332 & USBCMD_ATDTW_TRIPWIRE_SET) { 321 & USBCMD_ATDTW_TRIPWIRE_SET)
333 readsafe = 1; 322 break;
334 } 323
335 loops--; 324 loops--;
325 if (loops == 0) {
326 dev_err(&udc->dev->dev,
327 "Timeout for ATDTW_TRIPWIRE...\n");
328 retval = -ETIME;
329 goto done;
330 }
336 udelay(LOOPS_USEC); 331 udelay(LOOPS_USEC);
337 } 332 }
338 333
339 /* Clear the semaphore */ 334 /* Clear the semaphore */
340 tmp = readl(&udc->op_regs->usbcmd); 335 usbcmd = readl(&udc->op_regs->usbcmd);
341 tmp &= USBCMD_ATDTW_TRIPWIRE_CLEAR; 336 usbcmd &= USBCMD_ATDTW_TRIPWIRE_CLEAR;
342 writel(tmp, &udc->op_regs->usbcmd); 337 writel(usbcmd, &udc->op_regs->usbcmd);
343
344 /* If endpoint is not active, we activate it now. */
345 if (!epstatus) {
346 if (direction == EP_DIR_IN) {
347 struct mv_dtd *curr_dtd = dma_to_virt(
348 &udc->dev->dev, dqh->curr_dtd_ptr);
349
350 loops = LOOPS(DTD_TIMEOUT);
351 while (curr_dtd->size_ioc_sts
352 & DTD_STATUS_ACTIVE) {
353 if (loops == 0) {
354 retval = -ETIME;
355 goto done;
356 }
357 loops--;
358 udelay(LOOPS_USEC);
359 }
360 }
361 /* No other transfers on the queue */
362 338
363 /* Write dQH next pointer and terminate bit to 0 */ 339 if (epstatus)
364 dqh->next_dtd_ptr = req->head->td_dma 340 goto done;
341 }
342
343 /* Write dQH next pointer and terminate bit to 0 */
344 dqh->next_dtd_ptr = req->head->td_dma
365 & EP_QUEUE_HEAD_NEXT_POINTER_MASK; 345 & EP_QUEUE_HEAD_NEXT_POINTER_MASK;
366 dqh->size_ioc_int_sts = 0;
367 346
368 /* 347 /* clear active and halt bit, in case set from a previous error */
369 * Ensure that updates to the QH will 348 dqh->size_ioc_int_sts &= ~(DTD_STATUS_ACTIVE | DTD_STATUS_HALTED);
370 * occur before priming.
371 */
372 wmb();
373 349
374 /* Prime the Endpoint */ 350 /* Ensure that updates to the QH will occure before priming. */
375 writel(bit_pos, &udc->op_regs->epprime); 351 wmb();
376 }
377 } else {
378 /* Write dQH next pointer and terminate bit to 0 */
379 dqh->next_dtd_ptr = req->head->td_dma
380 & EP_QUEUE_HEAD_NEXT_POINTER_MASK;
381 dqh->size_ioc_int_sts = 0;
382
383 /* Ensure that updates to the QH will occur before priming. */
384 wmb();
385 352
386 /* Prime the Endpoint */ 353 /* Prime the Endpoint */
387 writel(bit_pos, &udc->op_regs->epprime); 354 writel(bit_pos, &udc->op_regs->epprime);
388 355
389 if (direction == EP_DIR_IN) {
390 /* FIXME add status check after prime the IN ep */
391 int prime_again;
392 u32 curr_dtd_ptr = dqh->curr_dtd_ptr;
393
394 loops = LOOPS(DTD_TIMEOUT);
395 prime_again = 0;
396 while ((curr_dtd_ptr != req->head->td_dma)) {
397 curr_dtd_ptr = dqh->curr_dtd_ptr;
398 if (loops == 0) {
399 dev_err(&udc->dev->dev,
400 "failed to prime %s\n",
401 ep->name);
402 retval = -ETIME;
403 goto done;
404 }
405 loops--;
406 udelay(LOOPS_USEC);
407
408 if (loops == (LOOPS(DTD_TIMEOUT) >> 2)) {
409 if (prime_again)
410 goto done;
411 dev_info(&udc->dev->dev,
412 "prime again\n");
413 writel(bit_pos,
414 &udc->op_regs->epprime);
415 prime_again = 1;
416 }
417 }
418 }
419 }
420done: 356done:
421 return retval; 357 return retval;
422} 358}
423 359
360
424static struct mv_dtd *build_dtd(struct mv_req *req, unsigned *length, 361static struct mv_dtd *build_dtd(struct mv_req *req, unsigned *length,
425 dma_addr_t *dma, int *is_last) 362 dma_addr_t *dma, int *is_last)
426{ 363{