[02/28] usb: dwc3: ep0: hold our lock in dwc3_gadget_ep0_set_halt

Message ID 1413565804-13061-3-git-send-email-balbi@ti.com
State Accepted
Commit 33fb691b3ea4aca6cab4867e09ea2726c784660a
Headers show

Commit Message

Felipe Balbi Oct. 17, 2014, 5:09 p.m.
dwc3_gadget_ep0_set_halt() will be called without
locks held in some cases, so we must hold the lock
on our own. While at that, also add a version without
locks to be called in certain conditions.

Signed-off-by: Felipe Balbi <balbi@ti.com>
---
 drivers/usb/dwc3/ep0.c    | 16 +++++++++++++++-
 drivers/usb/dwc3/gadget.h |  1 +
 2 files changed, 16 insertions(+), 1 deletion(-)

Patch

diff --git a/drivers/usb/dwc3/ep0.c b/drivers/usb/dwc3/ep0.c
index b359387..36f6158 100644
--- a/drivers/usb/dwc3/ep0.c
+++ b/drivers/usb/dwc3/ep0.c
@@ -271,7 +271,7 @@  static void dwc3_ep0_stall_and_restart(struct dwc3 *dwc)
 	dwc3_ep0_out_start(dwc);
 }
 
-int dwc3_gadget_ep0_set_halt(struct usb_ep *ep, int value)
+int __dwc3_gadget_ep0_set_halt(struct usb_ep *ep, int value)
 {
 	struct dwc3_ep			*dep = to_dwc3_ep(ep);
 	struct dwc3			*dwc = dep->dwc;
@@ -281,6 +281,20 @@  int dwc3_gadget_ep0_set_halt(struct usb_ep *ep, int value)
 	return 0;
 }
 
+int dwc3_gadget_ep0_set_halt(struct usb_ep *ep, int value)
+{
+	struct dwc3_ep			*dep = to_dwc3_ep(ep);
+	struct dwc3			*dwc = dep->dwc;
+	unsigned long			flags;
+	int				ret;
+
+	spin_lock_irqsave(&dwc->lock, flags);
+	ret = __dwc3_gadget_ep0_set_halt(ep, value);
+	spin_unlock_irqrestore(&dwc->lock, flags);
+
+	return ret;
+}
+
 void dwc3_ep0_out_start(struct dwc3 *dwc)
 {
 	int				ret;
diff --git a/drivers/usb/dwc3/gadget.h b/drivers/usb/dwc3/gadget.h
index 178ad89..f889008 100644
--- a/drivers/usb/dwc3/gadget.h
+++ b/drivers/usb/dwc3/gadget.h
@@ -82,6 +82,7 @@  void dwc3_gadget_giveback(struct dwc3_ep *dep, struct dwc3_request *req,
 void dwc3_ep0_interrupt(struct dwc3 *dwc,
 		const struct dwc3_event_depevt *event);
 void dwc3_ep0_out_start(struct dwc3 *dwc);
+int __dwc3_gadget_ep0_set_halt(struct usb_ep *ep, int value);
 int dwc3_gadget_ep0_set_halt(struct usb_ep *ep, int value);
 int dwc3_gadget_ep0_queue(struct usb_ep *ep, struct usb_request *request,
 		gfp_t gfp_flags);