]> rtime.felk.cvut.cz Git - sojka/nv-tegra/linux-3.10.git/commitdiff
usb: gadget: tegra: remove spin_unlock/lock pair
authorRohith Seelaboyina <rseelaboyina@nvidia.com>
Wed, 20 Nov 2013 05:36:52 +0000 (11:06 +0530)
committerRohith Seelaboyina <rseelaboyina@nvidia.com>
Thu, 28 Nov 2013 03:48:25 +0000 (19:48 -0800)
Remove the extra spin unlock/lock pain while building
dtd, as data corruption seems to happen by swapping
of dtd when multiple gadget functions are loaded.
This changes will make build dtd as part of Critical
section, there by swapping of dtd's doesnt occur.

Bug 1380570

Change-Id: I69ffc92a294cba13e79e2a02382b0c8f6b8cb28d
Signed-off-by: Rohith Seelaboyina <rseelaboyina@nvidia.com>
Reviewed-on: http://git-master/r/329296
(cherry picked from commit 5551ebc537dcd311188496d2dc0edf96bc1b036a)
Reviewed-on: http://git-master/r/334931
Reviewed-by: Automatic_Commit_Validation_User
Reviewed-by: Venkat Moganty <vmoganty@nvidia.com>
drivers/usb/gadget/tegra_udc.c

index 41dc9318b6645a9b8b2f33aff65ca4f8d397989d..51348d3edc60bcf64daa447a234b52ad012a5060 100644 (file)
@@ -994,10 +994,10 @@ tegra_ep_queue(struct usb_ep *_ep, struct usb_request *_req, gfp_t gfp_flags)
 
        dir = ep_is_in(ep) ? DMA_TO_DEVICE : DMA_FROM_DEVICE;
 
-       spin_unlock_irqrestore(&udc->lock, flags);
-
-       if (!udc->driver || udc->gadget.speed == USB_SPEED_UNKNOWN)
+       if (!udc->driver || udc->gadget.speed == USB_SPEED_UNKNOWN) {
+               spin_unlock_irqrestore(&udc->lock, flags);
                return -ESHUTDOWN;
+       }
 
        req->ep = ep;
 
@@ -1011,8 +1011,10 @@ tegra_ep_queue(struct usb_ep *_ep, struct usb_request *_req, gfp_t gfp_flags)
                dma_set_attr(DMA_ATTR_SKIP_CPU_SYNC, &attrs);
                req->req.dma = dma_map_single_attrs(dev, req->req.buf, ext, dir,
                                                    &attrs);
-               if (dma_mapping_error(dev, req->req.dma))
+               if (dma_mapping_error(dev, req->req.dma)) {
+                       spin_unlock_irqrestore(&udc->lock, flags);
                        return -EAGAIN;
+               }
 
                dma_sync_single_for_device(dev, req->req.dma, orig, dir);
 
@@ -1029,11 +1031,11 @@ tegra_ep_queue(struct usb_ep *_ep, struct usb_request *_req, gfp_t gfp_flags)
 
 
        /* build dtds and push them to device queue */
-       status = tegra_req_to_dtd(req, gfp_flags);
-       if (status)
+       status = tegra_req_to_dtd(req, GFP_ATOMIC);
+       if (status) {
+               spin_unlock_irqrestore(&udc->lock, flags);
                goto err_unmap;
-
-       spin_lock_irqsave(&udc->lock, flags);
+       }
 
        /* re-check if the ep has not been disabled */
        if (unlikely(!ep->desc)) {