summaryrefslogtreecommitdiffstats
path: root/drivers/usb/gadget
diff options
context:
space:
mode:
authorYoshihiro Shimoda <shimoda.yoshihiro@renesas.com>2009-08-20 09:01:06 +0200
committerPaul Mundt <lethal@linux-sh.org>2009-08-21 01:34:08 +0200
commit9e7291c1124655980ab05fc89930de8e218c7d64 (patch)
tree53272e72c8444edc9f9882dfd7863813f0ffe3c3 /drivers/usb/gadget
parentsh: update kfr2r09 defconfig (diff)
downloadlinux-9e7291c1124655980ab05fc89930de8e218c7d64.tar.xz
linux-9e7291c1124655980ab05fc89930de8e218c7d64.zip
usb: r8a66597-udc: implement the set_wedge method
fix the problem that MSC Tests of USBCV detects some warnings. Signed-off-by: Yoshihiro Shimoda <shimoda.yoshihiro@renesas.com> Signed-off-by: Paul Mundt <lethal@linux-sh.org>
Diffstat (limited to 'drivers/usb/gadget')
-rw-r--r--drivers/usb/gadget/r8a66597-udc.c28
-rw-r--r--drivers/usb/gadget/r8a66597-udc.h1
2 files changed, 27 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,
u16 w_index = le16_to_cpu(ctrl->wIndex);
ep = r8a66597->epaddr2ep[w_index & USB_ENDPOINT_NUMBER_MASK];
- pipe_stop(r8a66597, ep->pipenum);
- control_reg_sqclr(r8a66597, ep->pipenum);
+ if (!ep->wedge) {
+ pipe_stop(r8a66597, ep->pipenum);
+ control_reg_sqclr(r8a66597, ep->pipenum);
+ spin_unlock(&r8a66597->lock);
+ usb_ep_clear_halt(&ep->ep);
+ spin_lock(&r8a66597->lock);
+ }
control_end(r8a66597, 1);
@@ -1340,6 +1345,7 @@ static int r8a66597_set_halt(struct usb_ep *_ep, int value)
pipe_stall(ep->r8a66597, ep->pipenum);
} else {
ep->busy = 0;
+ ep->wedge = 0;
pipe_stop(ep->r8a66597, ep->pipenum);
}
@@ -1348,6 +1354,23 @@ out:
return ret;
}
+static int r8a66597_set_wedge(struct usb_ep *_ep)
+{
+ struct r8a66597_ep *ep;
+ unsigned long flags;
+
+ ep = container_of(_ep, struct r8a66597_ep, ep);
+
+ if (!ep || !ep->desc)
+ return -EINVAL;
+
+ spin_lock_irqsave(&ep->r8a66597->lock, flags);
+ ep->wedge = 1;
+ spin_unlock_irqrestore(&ep->r8a66597->lock, flags);
+
+ return usb_ep_set_halt(_ep);
+}
+
static void r8a66597_fifo_flush(struct usb_ep *_ep)
{
struct r8a66597_ep *ep;
@@ -1373,6 +1396,7 @@ static struct usb_ep_ops r8a66597_ep_ops = {
.dequeue = r8a66597_dequeue,
.set_halt = r8a66597_set_halt,
+ .set_wedge = r8a66597_set_wedge,
.fifo_flush = r8a66597_fifo_flush,
};
diff --git a/drivers/usb/gadget/r8a66597-udc.h b/drivers/usb/gadget/r8a66597-udc.h
index e653575d4ceb..03087e7b9190 100644
--- a/drivers/usb/gadget/r8a66597-udc.h
+++ b/drivers/usb/gadget/r8a66597-udc.h
@@ -73,6 +73,7 @@ struct r8a66597_ep {
struct list_head queue;
unsigned busy:1;
+ unsigned wedge:1;
unsigned internal_ccpl:1; /* use only control */
/* this member can able to after r8a66597_enable */