diff options
Diffstat (limited to 'drivers/usb/musb/musb_virthub.c')
-rw-r--r-- | drivers/usb/musb/musb_virthub.c | 35 |
1 files changed, 24 insertions, 11 deletions
diff --git a/drivers/usb/musb/musb_virthub.c b/drivers/usb/musb/musb_virthub.c index bf677acc83db..bfe5fe4ebfee 100644 --- a/drivers/usb/musb/musb_virthub.c +++ b/drivers/usb/musb/musb_virthub.c | |||
@@ -78,18 +78,22 @@ static void musb_port_suspend(struct musb *musb, bool do_suspend) | |||
78 | DBG(3, "Root port suspended, power %02x\n", power); | 78 | DBG(3, "Root port suspended, power %02x\n", power); |
79 | 79 | ||
80 | musb->port1_status |= USB_PORT_STAT_SUSPEND; | 80 | musb->port1_status |= USB_PORT_STAT_SUSPEND; |
81 | switch (musb->xceiv.state) { | 81 | switch (musb->xceiv->state) { |
82 | case OTG_STATE_A_HOST: | 82 | case OTG_STATE_A_HOST: |
83 | musb->xceiv.state = OTG_STATE_A_SUSPEND; | 83 | musb->xceiv->state = OTG_STATE_A_SUSPEND; |
84 | musb->is_active = is_otg_enabled(musb) | 84 | musb->is_active = is_otg_enabled(musb) |
85 | && musb->xceiv.host->b_hnp_enable; | 85 | && musb->xceiv->host->b_hnp_enable; |
86 | if (musb->is_active) | ||
87 | mod_timer(&musb->otg_timer, jiffies | ||
88 | + msecs_to_jiffies( | ||
89 | OTG_TIME_A_AIDL_BDIS)); | ||
86 | musb_platform_try_idle(musb, 0); | 90 | musb_platform_try_idle(musb, 0); |
87 | break; | 91 | break; |
88 | #ifdef CONFIG_USB_MUSB_OTG | 92 | #ifdef CONFIG_USB_MUSB_OTG |
89 | case OTG_STATE_B_HOST: | 93 | case OTG_STATE_B_HOST: |
90 | musb->xceiv.state = OTG_STATE_B_WAIT_ACON; | 94 | musb->xceiv->state = OTG_STATE_B_WAIT_ACON; |
91 | musb->is_active = is_otg_enabled(musb) | 95 | musb->is_active = is_otg_enabled(musb) |
92 | && musb->xceiv.host->b_hnp_enable; | 96 | && musb->xceiv->host->b_hnp_enable; |
93 | musb_platform_try_idle(musb, 0); | 97 | musb_platform_try_idle(musb, 0); |
94 | break; | 98 | break; |
95 | #endif | 99 | #endif |
@@ -116,7 +120,7 @@ static void musb_port_reset(struct musb *musb, bool do_reset) | |||
116 | void __iomem *mbase = musb->mregs; | 120 | void __iomem *mbase = musb->mregs; |
117 | 121 | ||
118 | #ifdef CONFIG_USB_MUSB_OTG | 122 | #ifdef CONFIG_USB_MUSB_OTG |
119 | if (musb->xceiv.state == OTG_STATE_B_IDLE) { | 123 | if (musb->xceiv->state == OTG_STATE_B_IDLE) { |
120 | DBG(2, "HNP: Returning from HNP; no hub reset from b_idle\n"); | 124 | DBG(2, "HNP: Returning from HNP; no hub reset from b_idle\n"); |
121 | musb->port1_status &= ~USB_PORT_STAT_RESET; | 125 | musb->port1_status &= ~USB_PORT_STAT_RESET; |
122 | return; | 126 | return; |
@@ -186,14 +190,23 @@ void musb_root_disconnect(struct musb *musb) | |||
186 | usb_hcd_poll_rh_status(musb_to_hcd(musb)); | 190 | usb_hcd_poll_rh_status(musb_to_hcd(musb)); |
187 | musb->is_active = 0; | 191 | musb->is_active = 0; |
188 | 192 | ||
189 | switch (musb->xceiv.state) { | 193 | switch (musb->xceiv->state) { |
190 | case OTG_STATE_A_HOST: | ||
191 | case OTG_STATE_A_SUSPEND: | 194 | case OTG_STATE_A_SUSPEND: |
192 | musb->xceiv.state = OTG_STATE_A_WAIT_BCON; | 195 | #ifdef CONFIG_USB_MUSB_OTG |
196 | if (is_otg_enabled(musb) | ||
197 | && musb->xceiv->host->b_hnp_enable) { | ||
198 | musb->xceiv->state = OTG_STATE_A_PERIPHERAL; | ||
199 | musb->g.is_a_peripheral = 1; | ||
200 | break; | ||
201 | } | ||
202 | #endif | ||
203 | /* FALLTHROUGH */ | ||
204 | case OTG_STATE_A_HOST: | ||
205 | musb->xceiv->state = OTG_STATE_A_WAIT_BCON; | ||
193 | musb->is_active = 0; | 206 | musb->is_active = 0; |
194 | break; | 207 | break; |
195 | case OTG_STATE_A_WAIT_VFALL: | 208 | case OTG_STATE_A_WAIT_VFALL: |
196 | musb->xceiv.state = OTG_STATE_B_IDLE; | 209 | musb->xceiv->state = OTG_STATE_B_IDLE; |
197 | break; | 210 | break; |
198 | default: | 211 | default: |
199 | DBG(1, "host disconnect (%s)\n", otg_state_string(musb)); | 212 | DBG(1, "host disconnect (%s)\n", otg_state_string(musb)); |
@@ -332,7 +345,7 @@ int musb_hub_control( | |||
332 | musb->port1_status |= USB_PORT_STAT_C_SUSPEND << 16; | 345 | musb->port1_status |= USB_PORT_STAT_C_SUSPEND << 16; |
333 | usb_hcd_poll_rh_status(musb_to_hcd(musb)); | 346 | usb_hcd_poll_rh_status(musb_to_hcd(musb)); |
334 | /* NOTE: it might really be A_WAIT_BCON ... */ | 347 | /* NOTE: it might really be A_WAIT_BCON ... */ |
335 | musb->xceiv.state = OTG_STATE_A_HOST; | 348 | musb->xceiv->state = OTG_STATE_A_HOST; |
336 | } | 349 | } |
337 | 350 | ||
338 | put_unaligned(cpu_to_le32(musb->port1_status | 351 | put_unaligned(cpu_to_le32(musb->port1_status |