mirror of https://gitee.com/openkylin/linux.git
usb: musb: Fix host mode error -71 regression
Commit467d5c9807
("usb: musb: Implement session bit based runtime PM for musb-core") started implementing musb generic runtime PM support by introducing devctl register session bit based state control. This caused a regression where if a USB mass storage device is connected to a USB hub, we can get: usb 1-1: reset high-speed USB device number 2 using musb-hdrc usb 1-1: device descriptor read/64, error -71 usb 1-1.1: new high-speed USB device number 4 using musb-hdrc This is because before the USB storage device is connected, musb is in OTG_STATE_A_SUSPEND. And we currently only set need_finish_resume in musb_stage0_irq() and the related code calling finish_resume_work in musb_resume() and musb_runtime_resume() never gets called. To fix the issue, we can call schedule_delayed_work() directly in musb_stage0_irq() to have finish_resume_work run. And we should no longer never get interrupts when when suspended. We have changed musb to no longer need pm_runtime_irqsafe(). The need_finish_resume flag was added in commit9298b4aad3
("usb: musb: fix device hotplug behind hub") and no longer applies as far as I can tell. So let's just remove the earlier code that no longer is needed. Fixes:467d5c9807
("usb: musb: Implement session bit based runtime PM for musb-core") Reported-by: Bin Liu <b-liu@ti.com> Signed-off-by: Tony Lindgren <tony@atomide.com> Signed-off-by: Bin Liu <b-liu@ti.com> Cc: stable <stable@vger.kernel.org> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
This commit is contained in:
parent
7a308bb301
commit
407788b51d
|
@ -594,11 +594,11 @@ static irqreturn_t musb_stage0_irq(struct musb *musb, u8 int_usb,
|
|||
| MUSB_PORT_STAT_RESUME;
|
||||
musb->rh_timer = jiffies
|
||||
+ msecs_to_jiffies(USB_RESUME_TIMEOUT);
|
||||
musb->need_finish_resume = 1;
|
||||
|
||||
musb->xceiv->otg->state = OTG_STATE_A_HOST;
|
||||
musb->is_active = 1;
|
||||
musb_host_resume_root_hub(musb);
|
||||
schedule_delayed_work(&musb->finish_resume_work,
|
||||
msecs_to_jiffies(USB_RESUME_TIMEOUT));
|
||||
break;
|
||||
case OTG_STATE_B_WAIT_ACON:
|
||||
musb->xceiv->otg->state = OTG_STATE_B_PERIPHERAL;
|
||||
|
@ -2710,11 +2710,6 @@ static int musb_resume(struct device *dev)
|
|||
mask = MUSB_DEVCTL_BDEVICE | MUSB_DEVCTL_FSDEV | MUSB_DEVCTL_LSDEV;
|
||||
if ((devctl & mask) != (musb->context.devctl & mask))
|
||||
musb->port1_status = 0;
|
||||
if (musb->need_finish_resume) {
|
||||
musb->need_finish_resume = 0;
|
||||
schedule_delayed_work(&musb->finish_resume_work,
|
||||
msecs_to_jiffies(USB_RESUME_TIMEOUT));
|
||||
}
|
||||
|
||||
/*
|
||||
* The USB HUB code expects the device to be in RPM_ACTIVE once it came
|
||||
|
@ -2766,12 +2761,6 @@ static int musb_runtime_resume(struct device *dev)
|
|||
|
||||
musb_restore_context(musb);
|
||||
|
||||
if (musb->need_finish_resume) {
|
||||
musb->need_finish_resume = 0;
|
||||
schedule_delayed_work(&musb->finish_resume_work,
|
||||
msecs_to_jiffies(USB_RESUME_TIMEOUT));
|
||||
}
|
||||
|
||||
spin_lock_irqsave(&musb->lock, flags);
|
||||
error = musb_run_resume_work(musb);
|
||||
if (error)
|
||||
|
|
|
@ -410,7 +410,6 @@ struct musb {
|
|||
|
||||
/* is_suspended means USB B_PERIPHERAL suspend */
|
||||
unsigned is_suspended:1;
|
||||
unsigned need_finish_resume :1;
|
||||
|
||||
/* may_wakeup means remote wakeup is enabled */
|
||||
unsigned may_wakeup:1;
|
||||
|
|
Loading…
Reference in New Issue