aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb/renesas_usbhs
diff options
context:
space:
mode:
authorKuninori Morimoto <kuninori.morimoto.gx@renesas.com>2011-12-08 21:31:37 -0500
committerFelipe Balbi <balbi@ti.com>2011-12-13 06:06:30 -0500
commit2d833faad260ad074fb1ed0a378f4ccd1b8025b8 (patch)
treec6dc58947216bd0cc4afb48b9542a5acfedb7b4b /drivers/usb/renesas_usbhs
parent6d0376f84446507d07ae83935cbe7538d07c352f (diff)
usb: renesas_usbhs: add force packet remove method
Packet should be force removed when reset/detach Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@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_host.c36
1 files changed, 36 insertions, 0 deletions
diff --git a/drivers/usb/renesas_usbhs/mod_host.c b/drivers/usb/renesas_usbhs/mod_host.c
index 9715a7013734..92dcc7e64630 100644
--- a/drivers/usb/renesas_usbhs/mod_host.c
+++ b/drivers/usb/renesas_usbhs/mod_host.c
@@ -703,6 +703,34 @@ static int usbhsh_queue_push(struct usb_hcd *hcd,
703 return 0; 703 return 0;
704} 704}
705 705
706static void usbhsh_queue_force_pop(struct usbhs_priv *priv,
707 struct usbhs_pipe *pipe)
708{
709 struct usbhs_pkt *pkt;
710
711 while (1) {
712 pkt = usbhs_pkt_pop(pipe, NULL);
713 if (!pkt)
714 break;
715
716 /*
717 * if all packet are gone, usbhsh_endpoint_disable()
718 * will be called.
719 * then, attached device/endpoint/pipe will be detached
720 */
721 usbhsh_queue_done(priv, pkt);
722 }
723}
724
725static void usbhsh_queue_force_pop_all(struct usbhs_priv *priv)
726{
727 struct usbhs_pipe *pos;
728 int i;
729
730 usbhs_for_each_pipe_with_dcp(pos, priv, i)
731 usbhsh_queue_force_pop(priv, pos);
732}
733
706/* 734/*
707 * DCP setup stage 735 * DCP setup stage
708 */ 736 */
@@ -1106,6 +1134,8 @@ static int __usbhsh_hub_port_feature(struct usbhsh_hpriv *hpriv,
1106 USB_PORT_STAT_HIGH_SPEED | 1134 USB_PORT_STAT_HIGH_SPEED |
1107 USB_PORT_STAT_LOW_SPEED); 1135 USB_PORT_STAT_LOW_SPEED);
1108 1136
1137 usbhsh_queue_force_pop_all(priv);
1138
1109 usbhs_bus_send_reset(priv); 1139 usbhs_bus_send_reset(priv);
1110 msleep(20); 1140 msleep(20);
1111 usbhs_bus_send_sof_enable(priv); 1141 usbhs_bus_send_sof_enable(priv);
@@ -1309,6 +1339,12 @@ static int usbhsh_irq_dtch(struct usbhs_priv *priv,
1309 hpriv->mod.irq_attch = usbhsh_irq_attch; 1339 hpriv->mod.irq_attch = usbhsh_irq_attch;
1310 usbhs_irq_callback_update(priv, &hpriv->mod); 1340 usbhs_irq_callback_update(priv, &hpriv->mod);
1311 1341
1342 /*
1343 * usbhsh_queue_force_pop_all() should be called
1344 * after usbhsh_is_running() becomes invalid.
1345 */
1346 usbhsh_queue_force_pop_all(priv);
1347
1312 return 0; 1348 return 0;
1313} 1349}
1314 1350