summaryrefslogtreecommitdiff
path: root/drivers/usb/gadget/fsl_udc_core.c
diff options
context:
space:
mode:
authorBenoit Goby <benoit@android.com>2010-09-20 21:19:37 -0700
committerDan Willemsen <dwillemsen@nvidia.com>2011-11-30 21:36:12 -0800
commit218be4b4be6586485f503c7c068c110a0f76acd0 (patch)
tree0a87ec3779f81b661cb477608138687a70bc9de9 /drivers/usb/gadget/fsl_udc_core.c
parentf5004768dbe63f712cb29a19d7572f7a1264799a (diff)
usb: gadget: fsl_udc: Fix dTDs allocation gfp flags
fsl_build_dtd may be called from atomic context. Don't hardcode the gfp flag to GFP_KERNEL. Pass down to dma_pool_alloc the flag used by the function driver to enqueue the request. Change-Id: Iba1ccf73bbcd648b8c13228157431d2ce52979ef Signed-off-by: Benoit Goby <benoit@android.com>
Diffstat (limited to 'drivers/usb/gadget/fsl_udc_core.c')
-rw-r--r--drivers/usb/gadget/fsl_udc_core.c22
1 files changed, 10 insertions, 12 deletions
diff --git a/drivers/usb/gadget/fsl_udc_core.c b/drivers/usb/gadget/fsl_udc_core.c
index 6439615a2e49..c07f16bebda5 100644
--- a/drivers/usb/gadget/fsl_udc_core.c
+++ b/drivers/usb/gadget/fsl_udc_core.c
@@ -811,7 +811,7 @@ out:
* @is_last: return flag if it is the last dTD of the request
* return: pointer to the built dTD */
static struct ep_td_struct *fsl_build_dtd(struct fsl_req *req, unsigned *length,
- dma_addr_t *dma, int *is_last)
+ dma_addr_t *dma, int *is_last, gfp_t gfp_flags)
{
u32 swap_temp;
struct ep_td_struct *dtd;
@@ -820,7 +820,7 @@ static struct ep_td_struct *fsl_build_dtd(struct fsl_req *req, unsigned *length,
*length = min(req->req.length - req->req.actual,
(unsigned)EP_MAX_LENGTH_TRANSFER);
- dtd = dma_pool_alloc(udc_controller->td_pool, GFP_KERNEL, dma);
+ dtd = dma_pool_alloc(udc_controller->td_pool, gfp_flags, dma);
if (dtd == NULL)
return dtd;
@@ -870,7 +870,7 @@ static struct ep_td_struct *fsl_build_dtd(struct fsl_req *req, unsigned *length,
}
/* Generate dtd chain for a request */
-static int fsl_req_to_dtd(struct fsl_req *req)
+static int fsl_req_to_dtd(struct fsl_req *req, gfp_t gfp_flags)
{
unsigned count;
int is_last;
@@ -879,7 +879,7 @@ static int fsl_req_to_dtd(struct fsl_req *req)
dma_addr_t dma;
do {
- dtd = fsl_build_dtd(req, &count, &dma, &is_last);
+ dtd = fsl_build_dtd(req, &count, &dma, &is_last, gfp_flags);
if (dtd == NULL)
return -ENOMEM;
@@ -953,15 +953,13 @@ fsl_ep_queue(struct usb_ep *_ep, struct usb_request *_req, gfp_t gfp_flags)
req->req.actual = 0;
req->dtd_count = 0;
- spin_lock_irqsave(&udc->lock, flags);
/* build dtds and push them to device queue */
- if (!fsl_req_to_dtd(req)) {
- fsl_queue_td(ep, req);
- } else {
- spin_unlock_irqrestore(&udc->lock, flags);
+ if (fsl_req_to_dtd(req, gfp_flags))
return -ENOMEM;
- }
+
+ spin_lock_irqsave(&udc->lock, flags);
+ fsl_queue_td(ep, req);
/* Update ep0 state */
if ((ep_index(ep) == 0))
@@ -1343,7 +1341,7 @@ static int ep0_prime_status(struct fsl_udc *udc, int direction)
ep_is_in(ep) ? DMA_TO_DEVICE : DMA_FROM_DEVICE);
req->mapped = 1;
- if (fsl_req_to_dtd(req) == 0)
+ if (fsl_req_to_dtd(req, GFP_ATOMIC) == 0)
fsl_queue_td(ep, req);
else
return -ENOMEM;
@@ -1427,7 +1425,7 @@ static void ch9getstatus(struct fsl_udc *udc, u8 request_type, u16 value,
req->mapped = 1;
/* prime the data phase */
- if ((fsl_req_to_dtd(req) == 0))
+ if ((fsl_req_to_dtd(req, GFP_ATOMIC) == 0))
fsl_queue_td(ep, req);
else /* no mem */
goto stall;