From a7b6574ab1288f0ec0ca4a6d36517b6628cdcd9b Mon Sep 17 00:00:00 2001 From: Tony Lindgren Date: Thu, 27 Sep 2007 14:52:27 -0700 Subject: [PATCH] musb_hdrc: Add timer for returning to host mode from HNP This seems like the only way to deal with interrupted HNP if waiting as a_wait_bcon. Signed-off-by: Tony Lindgren --- drivers/usb/musb/musb_core.c | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-) diff --git a/drivers/usb/musb/musb_core.c b/drivers/usb/musb/musb_core.c index b43803602f3..efaa4fb277a 100644 --- a/drivers/usb/musb/musb_core.c +++ b/drivers/usb/musb/musb_core.c @@ -309,11 +309,17 @@ void musb_otg_timer_func(unsigned long data) unsigned long flags; spin_lock_irqsave(&musb->lock, flags); - if (musb->xceiv.state == OTG_STATE_B_WAIT_ACON) { - DBG(1, "HNP: B_WAIT_ACON timeout; back to B_PERIPHERAL\n"); + switch (musb->xceiv.state) { + case OTG_STATE_B_WAIT_ACON: + DBG(1, "HNP: b_wait_acon timeout; back to b_peripheral\n"); musb_g_disconnect(musb); musb->xceiv.state = OTG_STATE_B_PERIPHERAL; musb->is_active = 0; + break; + case OTG_STATE_A_WAIT_BCON: + DBG(1, "HNP: a_wait_bcon timeout; back to a_host\n"); + musb_hnp_stop(musb); + break; } spin_unlock_irqrestore(&musb->lock, flags); } @@ -649,10 +655,17 @@ static irqreturn_t musb_stage0_irq(struct musb * musb, u8 int_usb, } else if (is_peripheral_capable()) { DBG(1, "BUS RESET as %s\n", otg_state_string(musb)); switch (musb->xceiv.state) { - case OTG_STATE_A_PERIPHERAL: +#ifdef CONFIG_USB_OTG case OTG_STATE_A_WAIT_BCON: /* OPT TD.4.7-900ms */ + DBG(1, "HNP: Setting timer as a_wait_bcon\n"); + musb_otg_timer.data = (unsigned long)musb; + mod_timer(&musb_otg_timer, jiffies + + msecs_to_jiffies(100)); + break; + case OTG_STATE_A_PERIPHERAL: musb_hnp_stop(musb); break; +#endif case OTG_STATE_B_IDLE: musb->xceiv.state = OTG_STATE_B_PERIPHERAL; /* FALLTHROUGH */ -- 2.41.1