diff options
Diffstat (limited to 'drivers/usb/gadget/r8a66597-udc.c')
-rw-r--r-- | drivers/usb/gadget/r8a66597-udc.c | 28 |
1 files changed, 26 insertions, 2 deletions
diff --git a/drivers/usb/gadget/r8a66597-udc.c b/drivers/usb/gadget/r8a66597-udc.c index 9ca867a85a05..e220fb8091a3 100644 --- a/drivers/usb/gadget/r8a66597-udc.c +++ b/drivers/usb/gadget/r8a66597-udc.c | |||
@@ -966,8 +966,13 @@ static void clear_feature(struct r8a66597 *r8a66597, | |||
966 | u16 w_index = le16_to_cpu(ctrl->wIndex); | 966 | u16 w_index = le16_to_cpu(ctrl->wIndex); |
967 | 967 | ||
968 | ep = r8a66597->epaddr2ep[w_index & USB_ENDPOINT_NUMBER_MASK]; | 968 | ep = r8a66597->epaddr2ep[w_index & USB_ENDPOINT_NUMBER_MASK]; |
969 | pipe_stop(r8a66597, ep->pipenum); | 969 | if (!ep->wedge) { |
970 | control_reg_sqclr(r8a66597, ep->pipenum); | 970 | pipe_stop(r8a66597, ep->pipenum); |
971 | control_reg_sqclr(r8a66597, ep->pipenum); | ||
972 | spin_unlock(&r8a66597->lock); | ||
973 | usb_ep_clear_halt(&ep->ep); | ||
974 | spin_lock(&r8a66597->lock); | ||
975 | } | ||
971 | 976 | ||
972 | control_end(r8a66597, 1); | 977 | control_end(r8a66597, 1); |
973 | 978 | ||
@@ -1340,6 +1345,7 @@ static int r8a66597_set_halt(struct usb_ep *_ep, int value) | |||
1340 | pipe_stall(ep->r8a66597, ep->pipenum); | 1345 | pipe_stall(ep->r8a66597, ep->pipenum); |
1341 | } else { | 1346 | } else { |
1342 | ep->busy = 0; | 1347 | ep->busy = 0; |
1348 | ep->wedge = 0; | ||
1343 | pipe_stop(ep->r8a66597, ep->pipenum); | 1349 | pipe_stop(ep->r8a66597, ep->pipenum); |
1344 | } | 1350 | } |
1345 | 1351 | ||
@@ -1348,6 +1354,23 @@ out: | |||
1348 | return ret; | 1354 | return ret; |
1349 | } | 1355 | } |
1350 | 1356 | ||
1357 | static int r8a66597_set_wedge(struct usb_ep *_ep) | ||
1358 | { | ||
1359 | struct r8a66597_ep *ep; | ||
1360 | unsigned long flags; | ||
1361 | |||
1362 | ep = container_of(_ep, struct r8a66597_ep, ep); | ||
1363 | |||
1364 | if (!ep || !ep->desc) | ||
1365 | return -EINVAL; | ||
1366 | |||
1367 | spin_lock_irqsave(&ep->r8a66597->lock, flags); | ||
1368 | ep->wedge = 1; | ||
1369 | spin_unlock_irqrestore(&ep->r8a66597->lock, flags); | ||
1370 | |||
1371 | return usb_ep_set_halt(_ep); | ||
1372 | } | ||
1373 | |||
1351 | static void r8a66597_fifo_flush(struct usb_ep *_ep) | 1374 | static void r8a66597_fifo_flush(struct usb_ep *_ep) |
1352 | { | 1375 | { |
1353 | struct r8a66597_ep *ep; | 1376 | struct r8a66597_ep *ep; |
@@ -1373,6 +1396,7 @@ static struct usb_ep_ops r8a66597_ep_ops = { | |||
1373 | .dequeue = r8a66597_dequeue, | 1396 | .dequeue = r8a66597_dequeue, |
1374 | 1397 | ||
1375 | .set_halt = r8a66597_set_halt, | 1398 | .set_halt = r8a66597_set_halt, |
1399 | .set_wedge = r8a66597_set_wedge, | ||
1376 | .fifo_flush = r8a66597_fifo_flush, | 1400 | .fifo_flush = r8a66597_fifo_flush, |
1377 | }; | 1401 | }; |
1378 | 1402 | ||