From: Tony Lindgren Date: Fri, 24 Aug 2007 05:34:48 +0000 (-0700) Subject: musb_hdrc: Make tusb do a_idle, make OPT A tests more reliable X-Git-Tag: v2.6.23-omap1~147 X-Git-Url: http://pilppa.com/gitweb/?a=commitdiff_plain;h=5523992fcff6787342ad8dd81f909b66462eb69b;p=linux-2.6-omap-h63xx.git musb_hdrc: Make tusb do a_idle, make OPT A tests more reliable This patch makes tusb go to a_idle state when ID is grounded. Also make OPT A tests work more reliably by not allowing less than 2 s VBUS timeouts for a_wait_vrise. Signed-off-by: Tony Lindgren --- diff --git a/drivers/usb/musb/musb_core.c b/drivers/usb/musb/musb_core.c index 82090a18149..2ce4f444a21 100644 --- a/drivers/usb/musb/musb_core.c +++ b/drivers/usb/musb/musb_core.c @@ -323,8 +323,8 @@ void musb_hnp_stop(struct musb *musb) case OTG_STATE_A_WAIT_VFALL: DBG(1, "HNP: Switching back to A-host\n"); musb_g_disconnect(musb); - musb_root_disconnect(musb); musb->xceiv.state = OTG_STATE_A_IDLE; + MUSB_HST_MODE(musb); musb->is_active = 0; break; case OTG_STATE_B_HOST: diff --git a/drivers/usb/musb/tusb6010.c b/drivers/usb/musb/tusb6010.c index 525e24c9d75..36cdcff7b4f 100644 --- a/drivers/usb/musb/tusb6010.c +++ b/drivers/usb/musb/tusb6010.c @@ -421,6 +421,8 @@ static void musb_do_idle(unsigned long _musb) switch (musb->xceiv.state) { case OTG_STATE_A_WAIT_BCON: + case OTG_STATE_A_WAIT_VRISE: + case OTG_STATE_A_IDLE: if ((musb->a_wait_bcon != 0) && (musb->idle_timeout == 0 || time_after(jiffies, musb->idle_timeout))) { @@ -539,19 +541,36 @@ static void tusb_source_power(struct musb *musb, int is_on) conf |= TUSB_DEV_CONF_USB_HOST_MODE; MUSB_HST_MODE(musb); } else { - musb->is_active = 0; + u32 otg_stat; + timer = 0; - /* NOTE: we're skipping A_WAIT_VFALL -> A_IDLE and - * jumping right to B_IDLE... - */ + /* If ID pin is grounded, we want to be a_idle */ + otg_stat = musb_readl(base, TUSB_DEV_OTG_STAT); + if (!(otg_stat & TUSB_DEV_OTG_STAT_ID_STATUS)) { + switch (musb->xceiv.state) { + case OTG_STATE_A_WAIT_VFALL: + musb->is_active = 1; + break; + case OTG_STATE_A_WAIT_VRISE: + musb->is_active = 1; + musb->xceiv.state = OTG_STATE_A_WAIT_VFALL; + break; + default: + musb->is_active = 0; + musb->xceiv.state = OTG_STATE_A_IDLE; + } + musb->xceiv.default_a = 1; + MUSB_HST_MODE(musb); + } else { + musb->is_active = 0; + musb->xceiv.default_a = 0; + musb->xceiv.state = OTG_STATE_B_IDLE; + MUSB_DEV_MODE(musb); + } - musb->xceiv.default_a = 0; - musb->xceiv.state = OTG_STATE_B_IDLE; devctl &= ~MUSB_DEVCTL_SESSION; - conf &= ~TUSB_DEV_CONF_USB_HOST_MODE; - MUSB_DEV_MODE(musb); if (musb->set_clock) musb->set_clock(musb->clock, 0); } @@ -715,8 +734,12 @@ tusb_otg_ints(struct musb *musb, u32 int_src, void __iomem *base) else musb->is_active = 1; - idle_timeout = jiffies - + msecs_to_jiffies(musb->a_wait_bcon); + /* + * OPT FS A TD.4.6 needs few seconds for + * A_WAIT_VRISE + */ + idle_timeout = jiffies + (2 * HZ); + break; case OTG_STATE_A_WAIT_VRISE: /* ignore; A-session-valid < VBUS_VALID/2, @@ -730,6 +753,10 @@ tusb_otg_ints(struct musb *musb, u32 int_src, void __iomem *base) if (musb->vbuserr_retry) { musb->vbuserr_retry--; tusb_source_power(musb, 1); + } else { + musb->vbuserr_retry + = VBUSERR_RETRY_COUNT; + tusb_source_power(musb, 0); } break; default: