usb: musb: fix device hotplug behind hub
authorBin Liu <b-liu@ti.com>
Tue, 3 Feb 2015 17:02:10 +0000 (11:02 -0600)
committerFelipe Balbi <balbi@ti.com>
Wed, 4 Feb 2015 17:16:47 +0000 (11:16 -0600)
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>
drivers/usb/musb/musb_core.c
drivers/usb/musb/musb_virthub.c

index 34cce3e..e6f4cbf 100644 (file)
@@ -567,6 +567,7 @@ static irqreturn_t musb_stage0_irq(struct musb *musb, u8 int_usb,
 
                                musb->xceiv->otg->state = OTG_STATE_A_HOST;
                                musb->is_active = 1;
+                               musb_host_resume_root_hub(musb);
                                break;
                        case OTG_STATE_B_WAIT_ACON:
                                musb->xceiv->otg->state = OTG_STATE_B_PERIPHERAL;
@@ -2500,6 +2501,12 @@ static int musb_runtime_resume(struct device *dev)
                musb_restore_context(musb);
        first = 0;
 
+       if (musb->need_finish_resume) {
+               musb->need_finish_resume = 0;
+               schedule_delayed_work(&musb->finish_resume_work,
+                               msecs_to_jiffies(20));
+       }
+
        return 0;
 }
 
index 662de58..294e159 100644 (file)
@@ -72,7 +72,6 @@ void musb_host_finish_resume(struct work_struct *work)
        musb->xceiv->otg->state = OTG_STATE_A_HOST;
 
        spin_unlock_irqrestore(&musb->lock, flags);
-       musb_host_resume_root_hub(musb);
 }
 
 void musb_port_suspend(struct musb *musb, bool do_suspend)