summaryrefslogtreecommitdiffstats
path: root/patches/linux-3.6.11/0079-Updating-dwc_otg-driver-to-fix-issue-releasing-pcm-s.patch
blob: f1cc6d7589b724ff13c03bde2ef041fd09767f49 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
From: Bryan Kemp <bryan@kempville.com>
Date: Sat, 7 Jul 2012 16:24:07 -0500
Subject: [PATCH] Updating dwc_otg driver to fix issue releasing pcm stream
 see: https://github.com/raspberrypi/firmware/issues/51

---
 drivers/usb/host/dwc_otg/dwc_otg_hcd_linux.c | 20 ++++++++++++++++++--
 1 file changed, 18 insertions(+), 2 deletions(-)

diff --git a/drivers/usb/host/dwc_otg/dwc_otg_hcd_linux.c b/drivers/usb/host/dwc_otg/dwc_otg_hcd_linux.c
index 6a89b1e..68664e5 100644
--- a/drivers/usb/host/dwc_otg/dwc_otg_hcd_linux.c
+++ b/drivers/usb/host/dwc_otg/dwc_otg_hcd_linux.c
@@ -70,6 +70,7 @@
 #include "dwc_otg_hcd_if.h"
 #include "dwc_otg_dbg.h"
 #include "dwc_otg_driver.h"
+#include "dwc_otg_hcd.h"
 
 /**
  * Gets the endpoint number from a _bEndpointAddress argument. The endpoint is
@@ -267,6 +268,7 @@ extern unsigned int g_dwc_otg_interrupt_counts[10];
 static int _complete(dwc_otg_hcd_t * hcd, void *urb_handle,
 		     dwc_otg_hcd_urb_t * dwc_otg_urb, int32_t status)
 {
+	uint64_t flags;
 	struct urb *urb = (struct urb *)urb_handle;
 
 #ifdef DEBUG_SOF_FIX
@@ -356,7 +358,9 @@ static int _complete(dwc_otg_hcd_t * hcd, void *urb_handle,
 #if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,30))
 	usb_hcd_giveback_urb(dwc_otg_hcd_to_hcd(hcd), urb);
 #else
+	DWC_SPINLOCK_IRQSAVE(hcd->lock, &flags);
 	usb_hcd_unlink_urb_from_ep(dwc_otg_hcd_to_hcd(hcd), urb);
+	DWC_SPINUNLOCK_IRQRESTORE(hcd->lock, flags);
 	usb_hcd_giveback_urb(dwc_otg_hcd_to_hcd(hcd), urb, status);
 #endif
 	return 0;
@@ -767,6 +771,8 @@ static int urb_dequeue(struct usb_hcd *hcd, struct urb *urb)
 static int urb_dequeue(struct usb_hcd *hcd, struct urb *urb, int status)
 #endif
 {
+	int rc;
+	uint64_t flags;
 	dwc_otg_hcd_t *dwc_otg_hcd;
 	DWC_DEBUGPL(DBG_HCD, "DWC OTG HCD URB Dequeue\n");
 
@@ -788,8 +794,18 @@ static int urb_dequeue(struct usb_hcd *hcd, struct urb *urb, int status)
 #if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,30))
 	usb_hcd_giveback_urb(hcd, urb);
 #else
-	usb_hcd_unlink_urb_from_ep(hcd, urb);
-	usb_hcd_giveback_urb(hcd, urb, status);
+	DWC_SPINLOCK_IRQSAVE(dwc_otg_hcd->lock, &flags);
+	rc = usb_hcd_check_unlink_urb(hcd, urb, status);
+	if(!rc)
+	{
+		usb_hcd_unlink_urb_from_ep(hcd, urb);
+	}
+
+	DWC_SPINUNLOCK_IRQRESTORE(dwc_otg_hcd->lock, flags);
+	if (!rc)
+	{
+		usb_hcd_giveback_urb(hcd, urb, status);
+	}
 #endif
 	if (CHK_DEBUG_LEVEL(DBG_HCDV | DBG_HCD_URB)) {
 		DWC_PRINTF("Called usb_hcd_giveback_urb()\n");