• Andiry Xu's avatar
    xHCI: report USB2 port in resuming as suspend · 8a8ff2f9
    Andiry Xu authored
    When a USB2 port initiate a remote wakeup, software shall ensure that
    resume is signaled for at least 20ms, and then write '0' to the PLS field.
    According to this, xhci driver do the following things:
    
    1. When receive a remote wakeup event in irq_handler, set the resume_done
       value as jiffies + 20ms, and modify rh_timer to poll root hub status at
       that time;
    2. When receive a GetPortStatus request, if the jiffies is after the
       resume_done value, clear the resume signal and resume_done.
    
    However, if usb_port_resume() is called before the rh_timer triggered, it
    will indicate the port as Suspend Cleared and skip the clear resume signal
    part. The device will fail the usb_get_status request in finish_port_resume(),
    and usbcore will try a reset-resume instead. Device will work OK after
    reset-resume, but resume_done value is not cleared in this case, and
    xhci_bus_suspend() will fail because when it finds a non-zero resume_done
    value, it will regard the port as resuming and return -EBUSY.
    
    This causes issue on some platforms that the system fail to suspend
    after remote wakeup from suspend by USB2 devices connected to xHCI port.
    
    To fix this issue, report the port status as suspend if the resume is
    signaling less that 20ms, and usb_port_resume() will wait 25ms and check
    port status again, so xHCI driver can clear the resume signaling and
    resume_done value.
    
    This should be backported to kernels as old as 2.6.37.
    Signed-off-by: default avatarAndiry Xu <andiry.xu@amd.com>
    Signed-off-by: default avatarSarah Sharp <sarah.a.sharp@linux.intel.com>
    Cc: stable@kernel.org
    8a8ff2f9
xhci-hub.c 27.9 KB