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>
This commit is contained in:
committed by
Greg Kroah-Hartman
parent
664d5df92e
commit
8f182e5ddc
@@ -283,7 +283,7 @@ void imx_ep_stall(struct imx_ep_struct *imx_ep)
|
|||||||
imx_flush(imx_ep);
|
imx_flush(imx_ep);
|
||||||
|
|
||||||
/* Special care for ep0 */
|
/* Special care for ep0 */
|
||||||
if (EP_NO(imx_ep)) {
|
if (!EP_NO(imx_ep)) {
|
||||||
temp = __raw_readl(imx_usb->base + USB_CTRL);
|
temp = __raw_readl(imx_usb->base + USB_CTRL);
|
||||||
__raw_writel(temp | CTRL_CMDOVER | CTRL_CMDERROR, imx_usb->base + USB_CTRL);
|
__raw_writel(temp | CTRL_CMDOVER | CTRL_CMDERROR, imx_usb->base + USB_CTRL);
|
||||||
do { } while (__raw_readl(imx_usb->base + USB_CTRL) & CTRL_CMDOVER);
|
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)
|
|||||||
break;
|
break;
|
||||||
udelay(20);
|
udelay(20);
|
||||||
}
|
}
|
||||||
if (i == 50)
|
if (i == 100)
|
||||||
D_ERR(imx_usb->dev, "<%s> Non finished stall on %s\n",
|
D_ERR(imx_usb->dev, "<%s> Non finished stall on %s\n",
|
||||||
__func__, imx_ep->ep.name);
|
__func__, imx_ep->ep.name);
|
||||||
}
|
}
|
||||||
@@ -539,10 +539,9 @@ static int handle_ep0(struct imx_ep_struct *imx_ep)
|
|||||||
struct imx_request *req = NULL;
|
struct imx_request *req = NULL;
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
|
|
||||||
if (!list_empty(&imx_ep->queue))
|
if (!list_empty(&imx_ep->queue)) {
|
||||||
req = list_entry(imx_ep->queue.next, struct imx_request, queue);
|
req = list_entry(imx_ep->queue.next, struct imx_request, queue);
|
||||||
|
|
||||||
if (req) {
|
|
||||||
switch (imx_ep->imx_usb->ep0state) {
|
switch (imx_ep->imx_usb->ep0state) {
|
||||||
|
|
||||||
case EP0_IN_DATA_PHASE: /* GET_DESCRIPTOR */
|
case EP0_IN_DATA_PHASE: /* GET_DESCRIPTOR */
|
||||||
@@ -561,6 +560,10 @@ static int handle_ep0(struct imx_ep_struct *imx_ep)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
else
|
||||||
|
D_ERR(imx_ep->imx_usb->dev, "<%s> no request on %s\n",
|
||||||
|
__func__, imx_ep->ep.name);
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -759,7 +762,7 @@ static int imx_ep_queue
|
|||||||
*/
|
*/
|
||||||
if (imx_usb->set_config && !EP_NO(imx_ep)) {
|
if (imx_usb->set_config && !EP_NO(imx_ep)) {
|
||||||
imx_usb->set_config = 0;
|
imx_usb->set_config = 0;
|
||||||
D_EPX(imx_usb->dev,
|
D_ERR(imx_usb->dev,
|
||||||
"<%s> gadget reply set config\n", __func__);
|
"<%s> gadget reply set config\n", __func__);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -779,8 +782,6 @@ static int imx_ep_queue
|
|||||||
return -ESHUTDOWN;
|
return -ESHUTDOWN;
|
||||||
}
|
}
|
||||||
|
|
||||||
local_irq_save(flags);
|
|
||||||
|
|
||||||
/* Debug */
|
/* Debug */
|
||||||
D_REQ(imx_usb->dev, "<%s> ep%d %s request for [%d] bytes\n",
|
D_REQ(imx_usb->dev, "<%s> ep%d %s request for [%d] bytes\n",
|
||||||
__func__, EP_NO(imx_ep),
|
__func__, EP_NO(imx_ep),
|
||||||
@@ -790,17 +791,18 @@ static int imx_ep_queue
|
|||||||
|
|
||||||
if (imx_ep->stopped) {
|
if (imx_ep->stopped) {
|
||||||
usb_req->status = -ESHUTDOWN;
|
usb_req->status = -ESHUTDOWN;
|
||||||
ret = -ESHUTDOWN;
|
return -ESHUTDOWN;
|
||||||
goto out;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (req->in_use) {
|
if (req->in_use) {
|
||||||
D_ERR(imx_usb->dev,
|
D_ERR(imx_usb->dev,
|
||||||
"<%s> refusing to queue req %p (already queued)\n",
|
"<%s> refusing to queue req %p (already queued)\n",
|
||||||
__func__, req);
|
__func__, req);
|
||||||
goto out;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
local_irq_save(flags);
|
||||||
|
|
||||||
usb_req->status = -EINPROGRESS;
|
usb_req->status = -EINPROGRESS;
|
||||||
usb_req->actual = 0;
|
usb_req->actual = 0;
|
||||||
|
|
||||||
@@ -810,7 +812,7 @@ static int imx_ep_queue
|
|||||||
ret = handle_ep0(imx_ep);
|
ret = handle_ep0(imx_ep);
|
||||||
else
|
else
|
||||||
ret = handle_ep(imx_ep);
|
ret = handle_ep(imx_ep);
|
||||||
out:
|
|
||||||
local_irq_restore(flags);
|
local_irq_restore(flags);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
@@ -1010,10 +1012,8 @@ static irqreturn_t imx_udc_irq(int irq, void *dev)
|
|||||||
dump_usb_stat(__func__, imx_usb);
|
dump_usb_stat(__func__, imx_usb);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!imx_usb->driver) {
|
if (!imx_usb->driver)
|
||||||
/*imx_udc_disable(imx_usb);*/
|
|
||||||
goto end_irq;
|
goto end_irq;
|
||||||
}
|
|
||||||
|
|
||||||
if (intr & INTR_WAKEUP) {
|
if (intr & INTR_WAKEUP) {
|
||||||
if (imx_usb->gadget.speed == USB_SPEED_UNKNOWN
|
if (imx_usb->gadget.speed == USB_SPEED_UNKNOWN
|
||||||
@@ -1095,6 +1095,11 @@ static irqreturn_t imx_udc_irq(int irq, void *dev)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (intr & INTR_SOF) {
|
if (intr & INTR_SOF) {
|
||||||
|
/* Copy from Freescale BSP.
|
||||||
|
We must enable SOF intr and set CMDOVER.
|
||||||
|
Datasheet don't specifiy this action, but it
|
||||||
|
is done in Freescale BSP, so just copy it.
|
||||||
|
*/
|
||||||
if (imx_usb->ep0state == EP0_IDLE) {
|
if (imx_usb->ep0state == EP0_IDLE) {
|
||||||
temp = __raw_readl(imx_usb->base + USB_CTRL);
|
temp = __raw_readl(imx_usb->base + USB_CTRL);
|
||||||
__raw_writel(temp | CTRL_CMDOVER, imx_usb->base + USB_CTRL);
|
__raw_writel(temp | CTRL_CMDOVER, imx_usb->base + USB_CTRL);
|
||||||
|
@@ -170,7 +170,7 @@ struct imx_udc_struct {
|
|||||||
/* #define DEBUG_IRQ */
|
/* #define DEBUG_IRQ */
|
||||||
/* #define DEBUG_EPIRQ */
|
/* #define DEBUG_EPIRQ */
|
||||||
/* #define DEBUG_DUMP */
|
/* #define DEBUG_DUMP */
|
||||||
#define DEBUG_ERR
|
/* #define DEBUG_ERR */
|
||||||
|
|
||||||
#ifdef DEBUG_REQ
|
#ifdef DEBUG_REQ
|
||||||
#define D_REQ(dev, args...) dev_dbg(dev, ## args)
|
#define D_REQ(dev, args...) dev_dbg(dev, ## args)
|
||||||
|
Reference in New Issue
Block a user