usb: musb: core: check link status on resume
The am335x-evmsk support two kinds of suspend: - standby the USB device remains powered while the system goes into suspend - mem the USB device becomes powerless while the system goes into suspend. In the "standby" case the device resumes quickly. In the "mem" case the system hangs for a few seconds. It seems to me that the USB-device has no address (it was disconnected) and the USB stack thinks that it is fully operational and GetPortStatus returns the status from before the suspend so it is not a big help here. This adds a check in the resume path to see if the device mode (A or B) and the speed is the same. If the device went missing between suspend/resume (VBUS went down) then MUSB seems to go into B mode and HS/FS bits are cleared. In that case we clear the port1_status bits and assume a disconnect. Once the stack learns this it does a "logical disconnect" and removes the USB-device quickly. Should the device remain connected during the suspend then MUSB will receives a "CONNECT" interrupt. Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> Signed-off-by: Felipe Balbi <balbi@ti.com>
This commit is contained in:
parent
b4c9f578cb
commit
b87fd2f7aa
@ -2300,6 +2300,8 @@ static int musb_suspend(struct device *dev)
|
||||
static int musb_resume(struct device *dev)
|
||||
{
|
||||
struct musb *musb = dev_to_musb(dev);
|
||||
u8 devctl;
|
||||
u8 mask;
|
||||
|
||||
/*
|
||||
* For static cmos like DaVinci, register values were preserved
|
||||
@ -2313,6 +2315,10 @@ static int musb_resume(struct device *dev)
|
||||
|
||||
musb_restore_context(musb);
|
||||
|
||||
devctl = musb_readb(musb->mregs, MUSB_DEVCTL);
|
||||
mask = MUSB_DEVCTL_BDEVICE | MUSB_DEVCTL_FSDEV | MUSB_DEVCTL_LSDEV;
|
||||
if ((devctl & mask) != (musb->context.devctl & mask))
|
||||
musb->port1_status = 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user