From 544f43ad83d80d40dd8ba1752479c1724065bd00 Mon Sep 17 00:00:00 2001 From: Debian Kernel Team Date: Fri, 26 Jul 2013 18:02:53 +0000 Subject: [PATCH] rpi_180_105858e4506975bfb3e293f2e815d14eae40958c commit 105858e4506975bfb3e293f2e815d14eae40958c Author: Bryan Kemp Date: Sat Jul 7 16:24:07 2012 -0500 Updating dwc_otg driver to fix issue releasing pcm stream see: https://github.com/raspberrypi/firmware/issues/51 Gbp-Pq: Topic rpi Gbp-Pq: Name rpi_180_105858e4506975bfb3e293f2e815d14eae40958c.patch --- 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 6a89b1eed80..68664e5f4e9 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");