]> Pileus Git - ~andy/linux/blobdiff - drivers/usb/musb/musb_virthub.c
Merge branch 'akpm'
[~andy/linux] / drivers / usb / musb / musb_virthub.c
index bf677acc83db03e781bb786642b1e5121ee1f627..bfe5fe4ebfeeb87b49e6f762aa670d0aed4da8aa 100644 (file)
@@ -78,18 +78,22 @@ static void musb_port_suspend(struct musb *musb, bool do_suspend)
                DBG(3, "Root port suspended, power %02x\n", power);
 
                musb->port1_status |= USB_PORT_STAT_SUSPEND;
-               switch (musb->xceiv.state) {
+               switch (musb->xceiv->state) {
                case OTG_STATE_A_HOST:
-                       musb->xceiv.state = OTG_STATE_A_SUSPEND;
+                       musb->xceiv->state = OTG_STATE_A_SUSPEND;
                        musb->is_active = is_otg_enabled(musb)
-                                       && musb->xceiv.host->b_hnp_enable;
+                                       && musb->xceiv->host->b_hnp_enable;
+                       if (musb->is_active)
+                               mod_timer(&musb->otg_timer, jiffies
+                                       + msecs_to_jiffies(
+                                               OTG_TIME_A_AIDL_BDIS));
                        musb_platform_try_idle(musb, 0);
                        break;
 #ifdef CONFIG_USB_MUSB_OTG
                case OTG_STATE_B_HOST:
-                       musb->xceiv.state = OTG_STATE_B_WAIT_ACON;
+                       musb->xceiv->state = OTG_STATE_B_WAIT_ACON;
                        musb->is_active = is_otg_enabled(musb)
-                                       && musb->xceiv.host->b_hnp_enable;
+                                       && musb->xceiv->host->b_hnp_enable;
                        musb_platform_try_idle(musb, 0);
                        break;
 #endif
@@ -116,7 +120,7 @@ static void musb_port_reset(struct musb *musb, bool do_reset)
        void __iomem    *mbase = musb->mregs;
 
 #ifdef CONFIG_USB_MUSB_OTG
-       if (musb->xceiv.state == OTG_STATE_B_IDLE) {
+       if (musb->xceiv->state == OTG_STATE_B_IDLE) {
                DBG(2, "HNP: Returning from HNP; no hub reset from b_idle\n");
                musb->port1_status &= ~USB_PORT_STAT_RESET;
                return;
@@ -186,14 +190,23 @@ void musb_root_disconnect(struct musb *musb)
        usb_hcd_poll_rh_status(musb_to_hcd(musb));
        musb->is_active = 0;
 
-       switch (musb->xceiv.state) {
-       case OTG_STATE_A_HOST:
+       switch (musb->xceiv->state) {
        case OTG_STATE_A_SUSPEND:
-               musb->xceiv.state = OTG_STATE_A_WAIT_BCON;
+#ifdef CONFIG_USB_MUSB_OTG
+               if (is_otg_enabled(musb)
+                               && musb->xceiv->host->b_hnp_enable) {
+                       musb->xceiv->state = OTG_STATE_A_PERIPHERAL;
+                       musb->g.is_a_peripheral = 1;
+                       break;
+               }
+#endif
+               /* FALLTHROUGH */
+       case OTG_STATE_A_HOST:
+               musb->xceiv->state = OTG_STATE_A_WAIT_BCON;
                musb->is_active = 0;
                break;
        case OTG_STATE_A_WAIT_VFALL:
-               musb->xceiv.state = OTG_STATE_B_IDLE;
+               musb->xceiv->state = OTG_STATE_B_IDLE;
                break;
        default:
                DBG(1, "host disconnect (%s)\n", otg_state_string(musb));
@@ -332,7 +345,7 @@ int musb_hub_control(
                        musb->port1_status |= USB_PORT_STAT_C_SUSPEND << 16;
                        usb_hcd_poll_rh_status(musb_to_hcd(musb));
                        /* NOTE: it might really be A_WAIT_BCON ... */
-                       musb->xceiv.state = OTG_STATE_A_HOST;
+                       musb->xceiv->state = OTG_STATE_A_HOST;
                }
 
                put_unaligned(cpu_to_le32(musb->port1_status