patch "usb: musb: Fix host mode error -71 regression" added to usb-linus
Subsystems (3)
This is a note to let you know that I've just added the patch titled
usb: musb: Fix host mode error -71 regression
to my usb git tree which can be found at
git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/usb.git
in the usb-linus branch.
The patch will show up in the next release of the linux-next tree (usually sometime within the next 24 hours during the week.)
The patch will hopefully also be merged in Linus's tree for the next -rc kernel release.
If you have any questions about this process, please let me know.
Quoted 1 line
From
407788b51db6f6aab499d02420082f436abf3238Mon Sep 17 00:00:00 2001
From: Tony Lindgren <[email protected]>
Date: Tue, 24 Jan 2017 09:18:57 -0600
Subject: usb: musb: Fix host mode error -71 regression
Commit 467d5c980709 ("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 commit 9298b4aad37e ("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.
--- drivers/usb/musb/musb_core.c | 15 ++------------- drivers/usb/musb/musb_core.h | 1 - 2 files changed, 2 insertions(+), 14 deletions(-)
drivers/usb/musb/musb_core.c +2 -13
@@ -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)
drivers/usb/musb/musb_core.h +0 -1
@@ -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;
Signature · 1 line
2.11.0