Call spin_lock_irqsave here to disable interrupt temporary. Or race condition may occurred. Signed-off-by: Neil Zhang <zhangwm@xxxxxxxxxxx> --- drivers/usb/gadget/mv_udc_core.c | 10 +++++++--- 1 files changed, 7 insertions(+), 3 deletions(-) diff --git a/drivers/usb/gadget/mv_udc_core.c b/drivers/usb/gadget/mv_udc_core.c index 9fdf50f..c4ff373 100644 --- a/drivers/usb/gadget/mv_udc_core.c +++ b/drivers/usb/gadget/mv_udc_core.c @@ -499,6 +499,7 @@ static int mv_ep_enable(struct usb_ep *_ep, u16 max = 0; u32 bit_pos, epctrlx, direction; unsigned char zlt = 0, ios = 0, mult = 0; + unsigned long flags; ep = container_of(_ep, struct mv_ep, ep); udc = ep->udc; @@ -519,9 +520,6 @@ static int mv_ep_enable(struct usb_ep *_ep, */ zlt = 1; - /* Get the endpoint queue head address */ - dqh = (struct mv_dqh *)ep->dqh; - bit_pos = 1 << ((direction == EP_DIR_OUT ? 0 : 16) + ep->ep_num); /* Check if the Endpoint is Primed */ @@ -558,6 +556,10 @@ static int mv_ep_enable(struct usb_ep *_ep, default: goto en_done; } + + spin_lock_irqsave(&udc->lock, flags); + /* Get the endpoint queue head address */ + dqh = (struct mv_dqh *)ep->dqh; dqh->max_packet_length = (max << EP_QUEUE_HEAD_MAX_PKT_LEN_POS) | (mult << EP_QUEUE_HEAD_MULT_POS) | (zlt ? EP_QUEUE_HEAD_ZLT_SEL : 0) @@ -602,6 +604,8 @@ static int mv_ep_enable(struct usb_ep *_ep, writel(epctrlx, &udc->op_regs->epctrlx[ep->ep_num]); } + spin_unlock_irqrestore(&udc->lock, flags); + return 0; en_done: return -EINVAL; -- 1.7.1 -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html