summaryrefslogtreecommitdiffstats
path: root/drivers/usb/renesas_usbhs
diff options
context:
space:
mode:
authorYoshihiro Shimoda <yoshihiro.shimoda.uh@renesas.com>2014-07-09 13:30:13 +0200
committerFelipe Balbi <balbi@ti.com>2014-07-10 15:36:49 +0200
commitdfb87b8bfe09f933abaf387693992089f6f9053e (patch)
tree7fb2238883460948a193c33f7cbe1d672fa0f6ed /drivers/usb/renesas_usbhs
parentusb: renesas_usbhs: fix usbhs_pipe_malloc() to re-enable a pipe. (diff)
downloadlinux-dfb87b8bfe09f933abaf387693992089f6f9053e.tar.xz
linux-dfb87b8bfe09f933abaf387693992089f6f9053e.zip
usb: renesas_usbhs: gadget: fix re-enabling pipe without re-connecting
This patch fixes an issue that the renesas_usbhs driver in gadget mode cannot work correctly even if I disabled DMAC of the driver when I used the g_zero driver and the testusb tool. When a usb cable is re-connected, the renesas_usbhs driver calls the usbhsp_flags_init() (via usbhs_hotplug() --> usbhs_mod_call(start) --> usbhsg_try_start() --> usbhs_pipe_init()). However, the driver doesn't call the usbhsp_flags_init() when usbhsg_ep_disable() is called. So, if a gadget driver calls usb_ep_enable() and usb_ep_disable() again and again, the renesas_usbhs driver will output the following log: renesas_usbhs renesas_usbhs: can't get pipe (BULK) renesas_usbhs renesas_usbhs: wrong recip request Acked-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com> Signed-off-by: Yoshihiro Shimoda <yoshihiro.shimoda.uh@renesas.com> Signed-off-by: Felipe Balbi <balbi@ti.com>
Diffstat (limited to 'drivers/usb/renesas_usbhs')
-rw-r--r--drivers/usb/renesas_usbhs/mod_gadget.c2
-rw-r--r--drivers/usb/renesas_usbhs/pipe.c10
-rw-r--r--drivers/usb/renesas_usbhs/pipe.h1
3 files changed, 13 insertions, 0 deletions
diff --git a/drivers/usb/renesas_usbhs/mod_gadget.c b/drivers/usb/renesas_usbhs/mod_gadget.c
index 458f3766bef1..04e6505777d0 100644
--- a/drivers/usb/renesas_usbhs/mod_gadget.c
+++ b/drivers/usb/renesas_usbhs/mod_gadget.c
@@ -600,8 +600,10 @@ static int usbhsg_ep_enable(struct usb_ep *ep,
static int usbhsg_ep_disable(struct usb_ep *ep)
{
struct usbhsg_uep *uep = usbhsg_ep_to_uep(ep);
+ struct usbhs_pipe *pipe = usbhsg_uep_to_pipe(uep);
usbhsg_pipe_disable(uep);
+ usbhs_pipe_free(pipe);
uep->pipe->mod_private = NULL;
uep->pipe = NULL;
diff --git a/drivers/usb/renesas_usbhs/pipe.c b/drivers/usb/renesas_usbhs/pipe.c
index 239b889ca5b5..75fbcf6b102e 100644
--- a/drivers/usb/renesas_usbhs/pipe.c
+++ b/drivers/usb/renesas_usbhs/pipe.c
@@ -640,6 +640,11 @@ static struct usbhs_pipe *usbhsp_get_pipe(struct usbhs_priv *priv, u32 type)
return pipe;
}
+static void usbhsp_put_pipe(struct usbhs_pipe *pipe)
+{
+ usbhsp_flags_init(pipe);
+}
+
void usbhs_pipe_init(struct usbhs_priv *priv,
int (*dma_map_ctrl)(struct usbhs_pkt *pkt, int map))
{
@@ -727,6 +732,11 @@ struct usbhs_pipe *usbhs_pipe_malloc(struct usbhs_priv *priv,
return pipe;
}
+void usbhs_pipe_free(struct usbhs_pipe *pipe)
+{
+ usbhsp_put_pipe(pipe);
+}
+
void usbhs_pipe_select_fifo(struct usbhs_pipe *pipe, struct usbhs_fifo *fifo)
{
if (pipe->fifo)
diff --git a/drivers/usb/renesas_usbhs/pipe.h b/drivers/usb/renesas_usbhs/pipe.h
index 3e5349879838..406f36d050e4 100644
--- a/drivers/usb/renesas_usbhs/pipe.h
+++ b/drivers/usb/renesas_usbhs/pipe.h
@@ -75,6 +75,7 @@ struct usbhs_pipe_info {
char *usbhs_pipe_name(struct usbhs_pipe *pipe);
struct usbhs_pipe
*usbhs_pipe_malloc(struct usbhs_priv *priv, int endpoint_type, int dir_in);
+void usbhs_pipe_free(struct usbhs_pipe *pipe);
int usbhs_pipe_probe(struct usbhs_priv *priv);
void usbhs_pipe_remove(struct usbhs_priv *priv);
int usbhs_pipe_is_dir_in(struct usbhs_pipe *pipe);