diff options
Diffstat (limited to 'drivers/usb/gadget/imx_udc.c')
-rw-r--r-- | drivers/usb/gadget/imx_udc.c | 33 |
1 files changed, 19 insertions, 14 deletions
diff --git a/drivers/usb/gadget/imx_udc.c b/drivers/usb/gadget/imx_udc.c index 77c5d0a8a06e..9e3fe306301d 100644 --- a/drivers/usb/gadget/imx_udc.c +++ b/drivers/usb/gadget/imx_udc.c | |||
@@ -283,7 +283,7 @@ void imx_ep_stall(struct imx_ep_struct *imx_ep) | |||
283 | imx_flush(imx_ep); | 283 | imx_flush(imx_ep); |
284 | 284 | ||
285 | /* Special care for ep0 */ | 285 | /* Special care for ep0 */ |
286 | if (EP_NO(imx_ep)) { | 286 | if (!EP_NO(imx_ep)) { |
287 | temp = __raw_readl(imx_usb->base + USB_CTRL); | 287 | temp = __raw_readl(imx_usb->base + USB_CTRL); |
288 | __raw_writel(temp | CTRL_CMDOVER | CTRL_CMDERROR, imx_usb->base + USB_CTRL); | 288 | __raw_writel(temp | CTRL_CMDOVER | CTRL_CMDERROR, imx_usb->base + USB_CTRL); |
289 | do { } while (__raw_readl(imx_usb->base + USB_CTRL) & CTRL_CMDOVER); | 289 | do { } while (__raw_readl(imx_usb->base + USB_CTRL) & CTRL_CMDOVER); |
@@ -301,7 +301,7 @@ void imx_ep_stall(struct imx_ep_struct *imx_ep) | |||
301 | break; | 301 | break; |
302 | udelay(20); | 302 | udelay(20); |
303 | } | 303 | } |
304 | if (i == 50) | 304 | if (i == 100) |
305 | D_ERR(imx_usb->dev, "<%s> Non finished stall on %s\n", | 305 | D_ERR(imx_usb->dev, "<%s> Non finished stall on %s\n", |
306 | __func__, imx_ep->ep.name); | 306 | __func__, imx_ep->ep.name); |
307 | } | 307 | } |
@@ -539,10 +539,9 @@ static int handle_ep0(struct imx_ep_struct *imx_ep) | |||
539 | struct imx_request *req = NULL; | 539 | struct imx_request *req = NULL; |
540 | int ret = 0; | 540 | int ret = 0; |
541 | 541 | ||
542 | if (!list_empty(&imx_ep->queue)) | 542 | if (!list_empty(&imx_ep->queue)) { |
543 | req = list_entry(imx_ep->queue.next, struct imx_request, queue); | 543 | req = list_entry(imx_ep->queue.next, struct imx_request, queue); |
544 | 544 | ||
545 | if (req) { | ||
546 | switch (imx_ep->imx_usb->ep0state) { | 545 | switch (imx_ep->imx_usb->ep0state) { |
547 | 546 | ||
548 | case EP0_IN_DATA_PHASE: /* GET_DESCRIPTOR */ | 547 | case EP0_IN_DATA_PHASE: /* GET_DESCRIPTOR */ |
@@ -561,6 +560,10 @@ static int handle_ep0(struct imx_ep_struct *imx_ep) | |||
561 | } | 560 | } |
562 | } | 561 | } |
563 | 562 | ||
563 | else | ||
564 | D_ERR(imx_ep->imx_usb->dev, "<%s> no request on %s\n", | ||
565 | __func__, imx_ep->ep.name); | ||
566 | |||
564 | return ret; | 567 | return ret; |
565 | } | 568 | } |
566 | 569 | ||
@@ -759,7 +762,7 @@ static int imx_ep_queue | |||
759 | */ | 762 | */ |
760 | if (imx_usb->set_config && !EP_NO(imx_ep)) { | 763 | if (imx_usb->set_config && !EP_NO(imx_ep)) { |
761 | imx_usb->set_config = 0; | 764 | imx_usb->set_config = 0; |
762 | D_EPX(imx_usb->dev, | 765 | D_ERR(imx_usb->dev, |
763 | "<%s> gadget reply set config\n", __func__); | 766 | "<%s> gadget reply set config\n", __func__); |
764 | return 0; | 767 | return 0; |
765 | } | 768 | } |
@@ -779,8 +782,6 @@ static int imx_ep_queue | |||
779 | return -ESHUTDOWN; | 782 | return -ESHUTDOWN; |
780 | } | 783 | } |
781 | 784 | ||
782 | local_irq_save(flags); | ||
783 | |||
784 | /* Debug */ | 785 | /* Debug */ |
785 | D_REQ(imx_usb->dev, "<%s> ep%d %s request for [%d] bytes\n", | 786 | D_REQ(imx_usb->dev, "<%s> ep%d %s request for [%d] bytes\n", |
786 | __func__, EP_NO(imx_ep), | 787 | __func__, EP_NO(imx_ep), |
@@ -790,17 +791,18 @@ static int imx_ep_queue | |||
790 | 791 | ||
791 | if (imx_ep->stopped) { | 792 | if (imx_ep->stopped) { |
792 | usb_req->status = -ESHUTDOWN; | 793 | usb_req->status = -ESHUTDOWN; |
793 | ret = -ESHUTDOWN; | 794 | return -ESHUTDOWN; |
794 | goto out; | ||
795 | } | 795 | } |
796 | 796 | ||
797 | if (req->in_use) { | 797 | if (req->in_use) { |
798 | D_ERR(imx_usb->dev, | 798 | D_ERR(imx_usb->dev, |
799 | "<%s> refusing to queue req %p (already queued)\n", | 799 | "<%s> refusing to queue req %p (already queued)\n", |
800 | __func__, req); | 800 | __func__, req); |
801 | goto out; | 801 | return 0; |
802 | } | 802 | } |
803 | 803 | ||
804 | local_irq_save(flags); | ||
805 | |||
804 | usb_req->status = -EINPROGRESS; | 806 | usb_req->status = -EINPROGRESS; |
805 | usb_req->actual = 0; | 807 | usb_req->actual = 0; |
806 | 808 | ||
@@ -810,7 +812,7 @@ static int imx_ep_queue | |||
810 | ret = handle_ep0(imx_ep); | 812 | ret = handle_ep0(imx_ep); |
811 | else | 813 | else |
812 | ret = handle_ep(imx_ep); | 814 | ret = handle_ep(imx_ep); |
813 | out: | 815 | |
814 | local_irq_restore(flags); | 816 | local_irq_restore(flags); |
815 | return ret; | 817 | return ret; |
816 | } | 818 | } |
@@ -1010,10 +1012,8 @@ static irqreturn_t imx_udc_irq(int irq, void *dev) | |||
1010 | dump_usb_stat(__func__, imx_usb); | 1012 | dump_usb_stat(__func__, imx_usb); |
1011 | } | 1013 | } |
1012 | 1014 | ||
1013 | if (!imx_usb->driver) { | 1015 | if (!imx_usb->driver) |
1014 | /*imx_udc_disable(imx_usb);*/ | ||
1015 | goto end_irq; | 1016 | goto end_irq; |
1016 | } | ||
1017 | 1017 | ||
1018 | if (intr & INTR_WAKEUP) { | 1018 | if (intr & INTR_WAKEUP) { |
1019 | if (imx_usb->gadget.speed == USB_SPEED_UNKNOWN | 1019 | if (imx_usb->gadget.speed == USB_SPEED_UNKNOWN |
@@ -1095,6 +1095,11 @@ static irqreturn_t imx_udc_irq(int irq, void *dev) | |||
1095 | } | 1095 | } |
1096 | 1096 | ||
1097 | if (intr & INTR_SOF) { | 1097 | if (intr & INTR_SOF) { |
1098 | /* Copy from Freescale BSP. | ||
1099 | We must enable SOF intr and set CMDOVER. | ||
1100 | Datasheet don't specifiy this action, but it | ||
1101 | is done in Freescale BSP, so just copy it. | ||
1102 | */ | ||
1098 | if (imx_usb->ep0state == EP0_IDLE) { | 1103 | if (imx_usb->ep0state == EP0_IDLE) { |
1099 | temp = __raw_readl(imx_usb->base + USB_CTRL); | 1104 | temp = __raw_readl(imx_usb->base + USB_CTRL); |
1100 | __raw_writel(temp | CTRL_CMDOVER, imx_usb->base + USB_CTRL); | 1105 | __raw_writel(temp | CTRL_CMDOVER, imx_usb->base + USB_CTRL); |