diff options
author | Bin Liu <b-liu@ti.com> | 2015-02-03 12:02:10 -0500 |
---|---|---|
committer | Felipe Balbi <balbi@ti.com> | 2015-02-04 12:16:47 -0500 |
commit | 9298b4aad37e8c6962edcdbd0b62620adb207d03 (patch) | |
tree | 485a90278ff48819369d9cd553854a0cd1d69926 | |
parent | 251a17f5aff990ab117590df2a13ef032464c0d3 (diff) |
usb: musb: fix device hotplug behind hub
The commit 889ad3b "usb: musb: try a race-free wakeup" breaks device
hotplug enumeraitonn when the device is connected behind a hub while usb
autosuspend is enabled.
Adding finish_resume_work into runtime resume callback fixes the issue.
Also resume root hub is required to resume the bus from runtime suspend,
so move musb_host_resume_root_hub() back to its original location, where
handles RESUME interrupt.
Signed-off-by: Bin Liu <b-liu@ti.com>
Tested-by: Tony Lindgren <tony@atomide.com>
Signed-off-by: Felipe Balbi <balbi@ti.com>
-rw-r--r-- | drivers/usb/musb/musb_core.c | 7 | ||||
-rw-r--r-- | drivers/usb/musb/musb_virthub.c | 1 |
2 files changed, 7 insertions, 1 deletions
diff --git a/drivers/usb/musb/musb_core.c b/drivers/usb/musb/musb_core.c index 34cce3e38c49..e6f4cbfeed97 100644 --- a/drivers/usb/musb/musb_core.c +++ b/drivers/usb/musb/musb_core.c | |||
@@ -567,6 +567,7 @@ static irqreturn_t musb_stage0_irq(struct musb *musb, u8 int_usb, | |||
567 | 567 | ||
568 | musb->xceiv->otg->state = OTG_STATE_A_HOST; | 568 | musb->xceiv->otg->state = OTG_STATE_A_HOST; |
569 | musb->is_active = 1; | 569 | musb->is_active = 1; |
570 | musb_host_resume_root_hub(musb); | ||
570 | break; | 571 | break; |
571 | case OTG_STATE_B_WAIT_ACON: | 572 | case OTG_STATE_B_WAIT_ACON: |
572 | musb->xceiv->otg->state = OTG_STATE_B_PERIPHERAL; | 573 | musb->xceiv->otg->state = OTG_STATE_B_PERIPHERAL; |
@@ -2500,6 +2501,12 @@ static int musb_runtime_resume(struct device *dev) | |||
2500 | musb_restore_context(musb); | 2501 | musb_restore_context(musb); |
2501 | first = 0; | 2502 | first = 0; |
2502 | 2503 | ||
2504 | if (musb->need_finish_resume) { | ||
2505 | musb->need_finish_resume = 0; | ||
2506 | schedule_delayed_work(&musb->finish_resume_work, | ||
2507 | msecs_to_jiffies(20)); | ||
2508 | } | ||
2509 | |||
2503 | return 0; | 2510 | return 0; |
2504 | } | 2511 | } |
2505 | 2512 | ||
diff --git a/drivers/usb/musb/musb_virthub.c b/drivers/usb/musb/musb_virthub.c index 662de58630e9..294e159f4afe 100644 --- a/drivers/usb/musb/musb_virthub.c +++ b/drivers/usb/musb/musb_virthub.c | |||
@@ -72,7 +72,6 @@ void musb_host_finish_resume(struct work_struct *work) | |||
72 | musb->xceiv->otg->state = OTG_STATE_A_HOST; | 72 | musb->xceiv->otg->state = OTG_STATE_A_HOST; |
73 | 73 | ||
74 | spin_unlock_irqrestore(&musb->lock, flags); | 74 | spin_unlock_irqrestore(&musb->lock, flags); |
75 | musb_host_resume_root_hub(musb); | ||
76 | } | 75 | } |
77 | 76 | ||
78 | void musb_port_suspend(struct musb *musb, bool do_suspend) | 77 | void musb_port_suspend(struct musb *musb, bool do_suspend) |