Skip to content

Commit 5fbf7a2

Browse files
tmlindgregkh
authored andcommitted
usb: musb: fix idling for suspend after disconnect interrupt
When disconnected as USB B-device, suspend interrupt should come before diconnect interrupt, because the DP/DM pins are shorter than the VBUS/GND pins on the USB connectors. But we sometimes get a suspend interrupt after disconnect interrupt. In that case we have devctl set to 99 with VBUS still valid and musb_pm_runtime_check_session() wrongly thinks we have an active session. We have no other interrupts after disconnect coming in this case at least with the omap2430 glue. Let's fix the issue by checking the interrupt status again with delayed work for the devctl 99 case. In the suspend after disconnect case the devctl session bit has cleared by then and musb can idle. For a typical USB B-device connect case we just continue with normal interrupts. Fixes: 467d5c9 ("usb: musb: Implement session bit based runtime PM for musb-core") Cc: Merlijn Wajer <[email protected]> Cc: Pavel Machek <[email protected]> Cc: Sebastian Reichel <[email protected]> Cc: [email protected] Signed-off-by: Tony Lindgren <[email protected]> Signed-off-by: Bin Liu <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Greg Kroah-Hartman <[email protected]>
1 parent 33786a2 commit 5fbf7a2

File tree

1 file changed

+8
-0
lines changed

1 file changed

+8
-0
lines changed

drivers/usb/musb/musb_core.c

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1840,6 +1840,9 @@ ATTRIBUTE_GROUPS(musb);
18401840
#define MUSB_QUIRK_B_INVALID_VBUS_91 (MUSB_DEVCTL_BDEVICE | \
18411841
(2 << MUSB_DEVCTL_VBUS_SHIFT) | \
18421842
MUSB_DEVCTL_SESSION)
1843+
#define MUSB_QUIRK_B_DISCONNECT_99 (MUSB_DEVCTL_BDEVICE | \
1844+
(3 << MUSB_DEVCTL_VBUS_SHIFT) | \
1845+
MUSB_DEVCTL_SESSION)
18431846
#define MUSB_QUIRK_A_DISCONNECT_19 ((3 << MUSB_DEVCTL_VBUS_SHIFT) | \
18441847
MUSB_DEVCTL_SESSION)
18451848

@@ -1862,6 +1865,11 @@ static void musb_pm_runtime_check_session(struct musb *musb)
18621865
s = MUSB_DEVCTL_FSDEV | MUSB_DEVCTL_LSDEV |
18631866
MUSB_DEVCTL_HR;
18641867
switch (devctl & ~s) {
1868+
case MUSB_QUIRK_B_DISCONNECT_99:
1869+
musb_dbg(musb, "Poll devctl in case of suspend after disconnect\n");
1870+
schedule_delayed_work(&musb->irq_work,
1871+
msecs_to_jiffies(1000));
1872+
break;
18651873
case MUSB_QUIRK_B_INVALID_VBUS_91:
18661874
if (musb->quirk_retries && !musb->flush_irq_work) {
18671875
musb_dbg(musb,

0 commit comments

Comments
 (0)