diff options
author | Darius Augulis <augulis.darius@gmail.com> | 2009-01-21 08:17:25 -0500 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@suse.de> | 2009-03-24 19:20:28 -0400 |
commit | 8f182e5ddc84a30d7014a753ae359d85b1238e7f (patch) | |
tree | bbc1d0b3d1ac337d1ff1caa6e9c3b88b4966f474 /drivers/usb | |
parent | 664d5df92e88b6ef091048a802b3750f4e989180 (diff) |
USB: imx_udc: Fix IMX UDC gadget bugs
Fix small bugs and add some omptimization in IMX UDC Gadget.
Signed-off-by: Darius Augulis <augulis.darius@gmail.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
Diffstat (limited to 'drivers/usb')
-rw-r--r-- | drivers/usb/gadget/imx_udc.c | 33 | ||||
-rw-r--r-- | drivers/usb/gadget/imx_udc.h | 2 |
2 files changed, 20 insertions, 15 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); |
diff --git a/drivers/usb/gadget/imx_udc.h b/drivers/usb/gadget/imx_udc.h index 850076937d8d..d1dfb2d2fa8b 100644 --- a/drivers/usb/gadget/imx_udc.h +++ b/drivers/usb/gadget/imx_udc.h | |||
@@ -170,7 +170,7 @@ struct imx_udc_struct { | |||
170 | /* #define DEBUG_IRQ */ | 170 | /* #define DEBUG_IRQ */ |
171 | /* #define DEBUG_EPIRQ */ | 171 | /* #define DEBUG_EPIRQ */ |
172 | /* #define DEBUG_DUMP */ | 172 | /* #define DEBUG_DUMP */ |
173 | #define DEBUG_ERR | 173 | /* #define DEBUG_ERR */ |
174 | 174 | ||
175 | #ifdef DEBUG_REQ | 175 | #ifdef DEBUG_REQ |
176 | #define D_REQ(dev, args...) dev_dbg(dev, ## args) | 176 | #define D_REQ(dev, args...) dev_dbg(dev, ## args) |