diff options
author | Neil Zhang <zhangwm@marvell.com> | 2011-10-12 04:49:33 -0400 |
---|---|---|
committer | Felipe Balbi <balbi@ti.com> | 2011-10-13 13:42:04 -0400 |
commit | 0c70840b22d9f3b762f21a28bface1a42c0c5ba2 (patch) | |
tree | e3bc8a63568dd0ddae3772b54b6ed15dca307d30 /drivers/usb | |
parent | 615268b05f6c719f5151c351022aa79ab73a0898 (diff) |
usb: gadget: mv_udc: rewrite fifo flush
1: Add parameter check.
2: For controller endpoint, we need to flush in and out directions.
3: delete redundant code, make it more readable.
Signed-off-by: Neil Zhang <zhangwm@marvell.com>
Signed-off-by: Felipe Balbi <balbi@ti.com>
Diffstat (limited to 'drivers/usb')
-rw-r--r-- | drivers/usb/gadget/mv_udc_core.c | 45 |
1 files changed, 18 insertions, 27 deletions
diff --git a/drivers/usb/gadget/mv_udc_core.c b/drivers/usb/gadget/mv_udc_core.c index 16bfcb919a72..843a479fa25c 100644 --- a/drivers/usb/gadget/mv_udc_core.c +++ b/drivers/usb/gadget/mv_udc_core.c | |||
@@ -681,37 +681,28 @@ static void mv_ep_fifo_flush(struct usb_ep *_ep) | |||
681 | { | 681 | { |
682 | struct mv_udc *udc; | 682 | struct mv_udc *udc; |
683 | u32 bit_pos, direction; | 683 | u32 bit_pos, direction; |
684 | struct mv_ep *ep = container_of(_ep, struct mv_ep, ep); | 684 | struct mv_ep *ep; |
685 | unsigned int loops; | 685 | unsigned int loops; |
686 | 686 | ||
687 | if (!_ep) | ||
688 | return; | ||
689 | |||
690 | ep = container_of(_ep, struct mv_ep, ep); | ||
691 | if (!ep->desc) | ||
692 | return; | ||
693 | |||
687 | udc = ep->udc; | 694 | udc = ep->udc; |
688 | direction = ep_dir(ep); | 695 | direction = ep_dir(ep); |
689 | bit_pos = 1 << ((direction == EP_DIR_OUT ? 0 : 16) + ep->ep_num); | ||
690 | /* | ||
691 | * Flushing will halt the pipe | ||
692 | * Write 1 to the Flush register | ||
693 | */ | ||
694 | writel(bit_pos, &udc->op_regs->epflush); | ||
695 | 696 | ||
696 | /* Wait until flushing completed */ | 697 | if (ep->ep_num == 0) |
697 | loops = LOOPS(FLUSH_TIMEOUT); | 698 | bit_pos = (1 << 16) | 1; |
698 | while (readl(&udc->op_regs->epflush) & bit_pos) { | 699 | else if (direction == EP_DIR_OUT) |
699 | /* | 700 | bit_pos = 1 << ep->ep_num; |
700 | * ENDPTFLUSH bit should be cleared to indicate this | 701 | else |
701 | * operation is complete | 702 | bit_pos = 1 << (16 + ep->ep_num); |
702 | */ | 703 | |
703 | if (loops == 0) { | ||
704 | dev_err(&udc->dev->dev, | ||
705 | "TIMEOUT for ENDPTFLUSH=0x%x, bit_pos=0x%x\n", | ||
706 | (unsigned)readl(&udc->op_regs->epflush), | ||
707 | (unsigned)bit_pos); | ||
708 | return; | ||
709 | } | ||
710 | loops--; | ||
711 | udelay(LOOPS_USEC); | ||
712 | } | ||
713 | loops = LOOPS(EPSTATUS_TIMEOUT); | 704 | loops = LOOPS(EPSTATUS_TIMEOUT); |
714 | while (readl(&udc->op_regs->epstatus) & bit_pos) { | 705 | do { |
715 | unsigned int inter_loops; | 706 | unsigned int inter_loops; |
716 | 707 | ||
717 | if (loops == 0) { | 708 | if (loops == 0) { |
@@ -726,7 +717,7 @@ static void mv_ep_fifo_flush(struct usb_ep *_ep) | |||
726 | 717 | ||
727 | /* Wait until flushing completed */ | 718 | /* Wait until flushing completed */ |
728 | inter_loops = LOOPS(FLUSH_TIMEOUT); | 719 | inter_loops = LOOPS(FLUSH_TIMEOUT); |
729 | while (readl(&udc->op_regs->epflush) & bit_pos) { | 720 | while (readl(&udc->op_regs->epflush)) { |
730 | /* | 721 | /* |
731 | * ENDPTFLUSH bit should be cleared to indicate this | 722 | * ENDPTFLUSH bit should be cleared to indicate this |
732 | * operation is complete | 723 | * operation is complete |
@@ -743,7 +734,7 @@ static void mv_ep_fifo_flush(struct usb_ep *_ep) | |||
743 | udelay(LOOPS_USEC); | 734 | udelay(LOOPS_USEC); |
744 | } | 735 | } |
745 | loops--; | 736 | loops--; |
746 | } | 737 | } while (readl(&udc->op_regs->epstatus) & bit_pos); |
747 | } | 738 | } |
748 | 739 | ||
749 | /* queues (submits) an I/O request to an endpoint */ | 740 | /* queues (submits) an I/O request to an endpoint */ |