xhci: Features for 3.12
In the spirit of "let's stop gossiping around the water cooler and get to work", here's some xHCI patches for 3.12. They include a patch for suspend/resume support for xhci platform hosts, two patches to support showing USB 2.1 link status, and a patch to future-proof the Intel EHCI to xHCI port switchover. Sarah Sharp -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.11 (GNU/Linux) iQIcBAABAgAGBQJR7vxeAAoJEBMGWMLi1Gc56VoQAI9RwDPAjx5aqj2Gg1uAZmh6 x965vdIjrEd+ND5rLS/G1khkTWW7o0SW2rwwuGhMOsrPve6R+Dr+rXoFxvPSpyTZ 1F+eiSNX+lmPtbeSrdNo5u+787yNR0UuvfDP5uIrqcrA3lo6Xc5Sk3qQ7fqEd9rg iSAQ7WwAKgpO40QMOFwTLi257mDfGJPg5d8cwwa9OAe3a7DVFHYfxv1vxmDFlR/w KPgq38hjR5S8Npcl9mC2RpjQoj1e3oO+4kZJX2CPmrRWx7GWAGfg/alDSGzl3zwk A8juRlKQGiFb9LmFwtvtHqolJuBGtTdSj0jPe1MObCw6LWzQcF2RppnTFlt/JHxp mpBRG94QC0ssHkUFhBKIlQLpL1KQiyUiWsBUyjaxtiVUMzZSt482Wnhnwr5lr1sn /WHnVY5MeWuAyFVx79+2KgRRbEaL0OnEGqEaIf/tfZL7D7dbDMkcOsOALguAvI4a 33KKSeiIyNqWcRXhQ9lVVxlsfS6ZFHl9MZvqIbhfO3Uzd4HIW+EdXOo2zx7GIlUO Zds5bpiV8wpDXzVHkY6NMr8HJWrD7pmD22o8tm8wY+LzO4Vxjdyxbvi5waSfPzYv 5FGVd9qN9tAif0xlhDj7GN63cF0rjgoFfBkfZcP+Y0Tvk2Po9mobzLoQwerDI7uJ v5BIoDuGBaDWIycJMYO2 =K3xk -----END PGP SIGNATURE----- Merge tag 'for-usb-next-2013-07-23' of git://git.kernel.org/pub/scm/linux/kernel/git/sarah/xhci into usb-next Sarah writes: xhci: Features for 3.12 In the spirit of "let's stop gossiping around the water cooler and get to work", here's some xHCI patches for 3.12. They include a patch for suspend/resume support for xhci platform hosts, two patches to support showing USB 2.1 link status, and a patch to future-proof the Intel EHCI to xHCI port switchover. Sarah Sharp
This commit is contained in:
commit
7603dee3bd
7 changed files with 187 additions and 177 deletions
|
@ -315,53 +315,11 @@ static int ehci_pci_setup(struct usb_hcd *hcd)
|
|||
* Also they depend on separate root hub suspend/resume.
|
||||
*/
|
||||
|
||||
static bool usb_is_intel_switchable_ehci(struct pci_dev *pdev)
|
||||
{
|
||||
return pdev->class == PCI_CLASS_SERIAL_USB_EHCI &&
|
||||
pdev->vendor == PCI_VENDOR_ID_INTEL &&
|
||||
(pdev->device == 0x1E26 ||
|
||||
pdev->device == 0x8C2D ||
|
||||
pdev->device == 0x8C26 ||
|
||||
pdev->device == 0x9C26);
|
||||
}
|
||||
|
||||
static void ehci_enable_xhci_companion(void)
|
||||
{
|
||||
struct pci_dev *companion = NULL;
|
||||
|
||||
/* The xHCI and EHCI controllers are not on the same PCI slot */
|
||||
for_each_pci_dev(companion) {
|
||||
if (!usb_is_intel_switchable_xhci(companion))
|
||||
continue;
|
||||
usb_enable_xhci_ports(companion);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
static int ehci_pci_resume(struct usb_hcd *hcd, bool hibernated)
|
||||
{
|
||||
struct ehci_hcd *ehci = hcd_to_ehci(hcd);
|
||||
struct pci_dev *pdev = to_pci_dev(hcd->self.controller);
|
||||
|
||||
/* The BIOS on systems with the Intel Panther Point chipset may or may
|
||||
* not support xHCI natively. That means that during system resume, it
|
||||
* may switch the ports back to EHCI so that users can use their
|
||||
* keyboard to select a kernel from GRUB after resume from hibernate.
|
||||
*
|
||||
* The BIOS is supposed to remember whether the OS had xHCI ports
|
||||
* enabled before resume, and switch the ports back to xHCI when the
|
||||
* BIOS/OS semaphore is written, but we all know we can't trust BIOS
|
||||
* writers.
|
||||
*
|
||||
* Unconditionally switch the ports back to xHCI after a system resume.
|
||||
* We can't tell whether the EHCI or xHCI controller will be resumed
|
||||
* first, so we have to do the port switchover in both drivers. Writing
|
||||
* a '1' to the port switchover registers should have no effect if the
|
||||
* port was already switched over.
|
||||
*/
|
||||
if (usb_is_intel_switchable_ehci(pdev))
|
||||
ehci_enable_xhci_companion();
|
||||
|
||||
if (ehci_resume(hcd, hibernated) != 0)
|
||||
(void) ehci_pci_reinit(ehci, pdev);
|
||||
return 0;
|
||||
|
|
|
@ -735,32 +735,6 @@ static int handshake(void __iomem *ptr, u32 mask, u32 done,
|
|||
return -ETIMEDOUT;
|
||||
}
|
||||
|
||||
#define PCI_DEVICE_ID_INTEL_LYNX_POINT_XHCI 0x8C31
|
||||
#define PCI_DEVICE_ID_INTEL_LYNX_POINT_LP_XHCI 0x9C31
|
||||
|
||||
bool usb_is_intel_ppt_switchable_xhci(struct pci_dev *pdev)
|
||||
{
|
||||
return pdev->class == PCI_CLASS_SERIAL_USB_XHCI &&
|
||||
pdev->vendor == PCI_VENDOR_ID_INTEL &&
|
||||
pdev->device == PCI_DEVICE_ID_INTEL_PANTHERPOINT_XHCI;
|
||||
}
|
||||
|
||||
/* The Intel Lynx Point chipset also has switchable ports. */
|
||||
bool usb_is_intel_lpt_switchable_xhci(struct pci_dev *pdev)
|
||||
{
|
||||
return pdev->class == PCI_CLASS_SERIAL_USB_XHCI &&
|
||||
pdev->vendor == PCI_VENDOR_ID_INTEL &&
|
||||
(pdev->device == PCI_DEVICE_ID_INTEL_LYNX_POINT_XHCI ||
|
||||
pdev->device == PCI_DEVICE_ID_INTEL_LYNX_POINT_LP_XHCI);
|
||||
}
|
||||
|
||||
bool usb_is_intel_switchable_xhci(struct pci_dev *pdev)
|
||||
{
|
||||
return usb_is_intel_ppt_switchable_xhci(pdev) ||
|
||||
usb_is_intel_lpt_switchable_xhci(pdev);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(usb_is_intel_switchable_xhci);
|
||||
|
||||
/*
|
||||
* Intel's Panther Point chipset has two host controllers (EHCI and xHCI) that
|
||||
* share some number of ports. These ports can be switched between either
|
||||
|
@ -779,9 +753,23 @@ EXPORT_SYMBOL_GPL(usb_is_intel_switchable_xhci);
|
|||
* terminations before switching the USB 2.0 wires over, so that USB 3.0
|
||||
* devices connect at SuperSpeed, rather than at USB 2.0 speeds.
|
||||
*/
|
||||
void usb_enable_xhci_ports(struct pci_dev *xhci_pdev)
|
||||
void usb_enable_intel_xhci_ports(struct pci_dev *xhci_pdev)
|
||||
{
|
||||
u32 ports_available;
|
||||
bool ehci_found = false;
|
||||
struct pci_dev *companion = NULL;
|
||||
|
||||
/* make sure an intel EHCI controller exists */
|
||||
for_each_pci_dev(companion) {
|
||||
if (companion->class == PCI_CLASS_SERIAL_USB_EHCI &&
|
||||
companion->vendor == PCI_VENDOR_ID_INTEL) {
|
||||
ehci_found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!ehci_found)
|
||||
return;
|
||||
|
||||
/* Don't switchover the ports if the user hasn't compiled the xHCI
|
||||
* driver. Otherwise they will see "dead" USB ports that don't power
|
||||
|
@ -840,7 +828,7 @@ void usb_enable_xhci_ports(struct pci_dev *xhci_pdev)
|
|||
dev_dbg(&xhci_pdev->dev, "USB 2.0 ports that are now switched over "
|
||||
"to xHCI: 0x%x\n", ports_available);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(usb_enable_xhci_ports);
|
||||
EXPORT_SYMBOL_GPL(usb_enable_intel_xhci_ports);
|
||||
|
||||
void usb_disable_xhci_ports(struct pci_dev *xhci_pdev)
|
||||
{
|
||||
|
@ -921,8 +909,8 @@ static void quirk_usb_handoff_xhci(struct pci_dev *pdev)
|
|||
writel(val, base + ext_cap_offset + XHCI_LEGACY_CONTROL_OFFSET);
|
||||
|
||||
hc_init:
|
||||
if (usb_is_intel_switchable_xhci(pdev))
|
||||
usb_enable_xhci_ports(pdev);
|
||||
if (pdev->vendor == PCI_VENDOR_ID_INTEL)
|
||||
usb_enable_intel_xhci_ports(pdev);
|
||||
|
||||
op_reg_base = base + XHCI_HC_LENGTH(readl(base));
|
||||
|
||||
|
|
|
@ -8,8 +8,7 @@ int usb_amd_find_chipset_info(void);
|
|||
void usb_amd_dev_put(void);
|
||||
void usb_amd_quirk_pll_disable(void);
|
||||
void usb_amd_quirk_pll_enable(void);
|
||||
bool usb_is_intel_switchable_xhci(struct pci_dev *pdev);
|
||||
void usb_enable_xhci_ports(struct pci_dev *xhci_pdev);
|
||||
void usb_enable_intel_xhci_ports(struct pci_dev *xhci_pdev);
|
||||
void usb_disable_xhci_ports(struct pci_dev *xhci_pdev);
|
||||
void sb800_prefetch(struct device *dev, int on);
|
||||
#else
|
||||
|
|
|
@ -461,8 +461,15 @@ void xhci_test_and_clear_bit(struct xhci_hcd *xhci, __le32 __iomem **port_array,
|
|||
}
|
||||
}
|
||||
|
||||
/* Updates Link Status for USB 2.1 port */
|
||||
static void xhci_hub_report_usb2_link_state(u32 *status, u32 status_reg)
|
||||
{
|
||||
if ((status_reg & PORT_PLS_MASK) == XDEV_U2)
|
||||
*status |= USB_PORT_STAT_L1;
|
||||
}
|
||||
|
||||
/* Updates Link Status for super Speed port */
|
||||
static void xhci_hub_report_link_state(u32 *status, u32 status_reg)
|
||||
static void xhci_hub_report_usb3_link_state(u32 *status, u32 status_reg)
|
||||
{
|
||||
u32 pls = status_reg & PORT_PLS_MASK;
|
||||
|
||||
|
@ -534,6 +541,120 @@ void xhci_del_comp_mod_timer(struct xhci_hcd *xhci, u32 status, u16 wIndex)
|
|||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Converts a raw xHCI port status into the format that external USB 2.0 or USB
|
||||
* 3.0 hubs use.
|
||||
*
|
||||
* Possible side effects:
|
||||
* - Mark a port as being done with device resume,
|
||||
* and ring the endpoint doorbells.
|
||||
* - Stop the Synopsys redriver Compliance Mode polling.
|
||||
*/
|
||||
static u32 xhci_get_port_status(struct usb_hcd *hcd,
|
||||
struct xhci_bus_state *bus_state,
|
||||
__le32 __iomem **port_array,
|
||||
u16 wIndex, u32 raw_port_status)
|
||||
{
|
||||
struct xhci_hcd *xhci = hcd_to_xhci(hcd);
|
||||
u32 status = 0;
|
||||
int slot_id;
|
||||
|
||||
/* wPortChange bits */
|
||||
if (raw_port_status & PORT_CSC)
|
||||
status |= USB_PORT_STAT_C_CONNECTION << 16;
|
||||
if (raw_port_status & PORT_PEC)
|
||||
status |= USB_PORT_STAT_C_ENABLE << 16;
|
||||
if ((raw_port_status & PORT_OCC))
|
||||
status |= USB_PORT_STAT_C_OVERCURRENT << 16;
|
||||
if ((raw_port_status & PORT_RC))
|
||||
status |= USB_PORT_STAT_C_RESET << 16;
|
||||
/* USB3.0 only */
|
||||
if (hcd->speed == HCD_USB3) {
|
||||
if ((raw_port_status & PORT_PLC))
|
||||
status |= USB_PORT_STAT_C_LINK_STATE << 16;
|
||||
if ((raw_port_status & PORT_WRC))
|
||||
status |= USB_PORT_STAT_C_BH_RESET << 16;
|
||||
}
|
||||
|
||||
if (hcd->speed != HCD_USB3) {
|
||||
if ((raw_port_status & PORT_PLS_MASK) == XDEV_U3
|
||||
&& (raw_port_status & PORT_POWER))
|
||||
status |= USB_PORT_STAT_SUSPEND;
|
||||
}
|
||||
if ((raw_port_status & PORT_PLS_MASK) == XDEV_RESUME &&
|
||||
!DEV_SUPERSPEED(raw_port_status)) {
|
||||
if ((raw_port_status & PORT_RESET) ||
|
||||
!(raw_port_status & PORT_PE))
|
||||
return 0xffffffff;
|
||||
if (time_after_eq(jiffies,
|
||||
bus_state->resume_done[wIndex])) {
|
||||
xhci_dbg(xhci, "Resume USB2 port %d\n",
|
||||
wIndex + 1);
|
||||
bus_state->resume_done[wIndex] = 0;
|
||||
clear_bit(wIndex, &bus_state->resuming_ports);
|
||||
xhci_set_link_state(xhci, port_array, wIndex,
|
||||
XDEV_U0);
|
||||
xhci_dbg(xhci, "set port %d resume\n",
|
||||
wIndex + 1);
|
||||
slot_id = xhci_find_slot_id_by_port(hcd, xhci,
|
||||
wIndex + 1);
|
||||
if (!slot_id) {
|
||||
xhci_dbg(xhci, "slot_id is zero\n");
|
||||
return 0xffffffff;
|
||||
}
|
||||
xhci_ring_device(xhci, slot_id);
|
||||
bus_state->port_c_suspend |= 1 << wIndex;
|
||||
bus_state->suspended_ports &= ~(1 << wIndex);
|
||||
} else {
|
||||
/*
|
||||
* The resume has been signaling for less than
|
||||
* 20ms. Report the port status as SUSPEND,
|
||||
* let the usbcore check port status again
|
||||
* and clear resume signaling later.
|
||||
*/
|
||||
status |= USB_PORT_STAT_SUSPEND;
|
||||
}
|
||||
}
|
||||
if ((raw_port_status & PORT_PLS_MASK) == XDEV_U0
|
||||
&& (raw_port_status & PORT_POWER)
|
||||
&& (bus_state->suspended_ports & (1 << wIndex))) {
|
||||
bus_state->suspended_ports &= ~(1 << wIndex);
|
||||
if (hcd->speed != HCD_USB3)
|
||||
bus_state->port_c_suspend |= 1 << wIndex;
|
||||
}
|
||||
if (raw_port_status & PORT_CONNECT) {
|
||||
status |= USB_PORT_STAT_CONNECTION;
|
||||
status |= xhci_port_speed(raw_port_status);
|
||||
}
|
||||
if (raw_port_status & PORT_PE)
|
||||
status |= USB_PORT_STAT_ENABLE;
|
||||
if (raw_port_status & PORT_OC)
|
||||
status |= USB_PORT_STAT_OVERCURRENT;
|
||||
if (raw_port_status & PORT_RESET)
|
||||
status |= USB_PORT_STAT_RESET;
|
||||
if (raw_port_status & PORT_POWER) {
|
||||
if (hcd->speed == HCD_USB3)
|
||||
status |= USB_SS_PORT_STAT_POWER;
|
||||
else
|
||||
status |= USB_PORT_STAT_POWER;
|
||||
}
|
||||
/* Update Port Link State */
|
||||
if (hcd->speed == HCD_USB3) {
|
||||
xhci_hub_report_usb3_link_state(&status, raw_port_status);
|
||||
/*
|
||||
* Verify if all USB3 Ports Have entered U0 already.
|
||||
* Delete Compliance Mode Timer if so.
|
||||
*/
|
||||
xhci_del_comp_mod_timer(xhci, raw_port_status, wIndex);
|
||||
} else {
|
||||
xhci_hub_report_usb2_link_state(&status, raw_port_status);
|
||||
}
|
||||
if (bus_state->port_c_suspend & (1 << wIndex))
|
||||
status |= 1 << USB_PORT_FEAT_C_SUSPEND;
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
int xhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue,
|
||||
u16 wIndex, char *buf, u16 wLength)
|
||||
{
|
||||
|
@ -598,104 +719,20 @@ int xhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue,
|
|||
if (!wIndex || wIndex > max_ports)
|
||||
goto error;
|
||||
wIndex--;
|
||||
status = 0;
|
||||
temp = xhci_readl(xhci, port_array[wIndex]);
|
||||
if (temp == 0xffffffff) {
|
||||
retval = -ENODEV;
|
||||
break;
|
||||
}
|
||||
xhci_dbg(xhci, "get port status, actual port %d status = 0x%x\n", wIndex, temp);
|
||||
status = xhci_get_port_status(hcd, bus_state, port_array,
|
||||
wIndex, temp);
|
||||
if (status == 0xffffffff)
|
||||
goto error;
|
||||
|
||||
/* wPortChange bits */
|
||||
if (temp & PORT_CSC)
|
||||
status |= USB_PORT_STAT_C_CONNECTION << 16;
|
||||
if (temp & PORT_PEC)
|
||||
status |= USB_PORT_STAT_C_ENABLE << 16;
|
||||
if ((temp & PORT_OCC))
|
||||
status |= USB_PORT_STAT_C_OVERCURRENT << 16;
|
||||
if ((temp & PORT_RC))
|
||||
status |= USB_PORT_STAT_C_RESET << 16;
|
||||
/* USB3.0 only */
|
||||
if (hcd->speed == HCD_USB3) {
|
||||
if ((temp & PORT_PLC))
|
||||
status |= USB_PORT_STAT_C_LINK_STATE << 16;
|
||||
if ((temp & PORT_WRC))
|
||||
status |= USB_PORT_STAT_C_BH_RESET << 16;
|
||||
}
|
||||
|
||||
if (hcd->speed != HCD_USB3) {
|
||||
if ((temp & PORT_PLS_MASK) == XDEV_U3
|
||||
&& (temp & PORT_POWER))
|
||||
status |= USB_PORT_STAT_SUSPEND;
|
||||
}
|
||||
if ((temp & PORT_PLS_MASK) == XDEV_RESUME &&
|
||||
!DEV_SUPERSPEED(temp)) {
|
||||
if ((temp & PORT_RESET) || !(temp & PORT_PE))
|
||||
goto error;
|
||||
if (time_after_eq(jiffies,
|
||||
bus_state->resume_done[wIndex])) {
|
||||
xhci_dbg(xhci, "Resume USB2 port %d\n",
|
||||
wIndex + 1);
|
||||
bus_state->resume_done[wIndex] = 0;
|
||||
clear_bit(wIndex, &bus_state->resuming_ports);
|
||||
xhci_set_link_state(xhci, port_array, wIndex,
|
||||
XDEV_U0);
|
||||
xhci_dbg(xhci, "set port %d resume\n",
|
||||
wIndex + 1);
|
||||
slot_id = xhci_find_slot_id_by_port(hcd, xhci,
|
||||
wIndex + 1);
|
||||
if (!slot_id) {
|
||||
xhci_dbg(xhci, "slot_id is zero\n");
|
||||
goto error;
|
||||
}
|
||||
xhci_ring_device(xhci, slot_id);
|
||||
bus_state->port_c_suspend |= 1 << wIndex;
|
||||
bus_state->suspended_ports &= ~(1 << wIndex);
|
||||
} else {
|
||||
/*
|
||||
* The resume has been signaling for less than
|
||||
* 20ms. Report the port status as SUSPEND,
|
||||
* let the usbcore check port status again
|
||||
* and clear resume signaling later.
|
||||
*/
|
||||
status |= USB_PORT_STAT_SUSPEND;
|
||||
}
|
||||
}
|
||||
if ((temp & PORT_PLS_MASK) == XDEV_U0
|
||||
&& (temp & PORT_POWER)
|
||||
&& (bus_state->suspended_ports & (1 << wIndex))) {
|
||||
bus_state->suspended_ports &= ~(1 << wIndex);
|
||||
if (hcd->speed != HCD_USB3)
|
||||
bus_state->port_c_suspend |= 1 << wIndex;
|
||||
}
|
||||
if (temp & PORT_CONNECT) {
|
||||
status |= USB_PORT_STAT_CONNECTION;
|
||||
status |= xhci_port_speed(temp);
|
||||
}
|
||||
if (temp & PORT_PE)
|
||||
status |= USB_PORT_STAT_ENABLE;
|
||||
if (temp & PORT_OC)
|
||||
status |= USB_PORT_STAT_OVERCURRENT;
|
||||
if (temp & PORT_RESET)
|
||||
status |= USB_PORT_STAT_RESET;
|
||||
if (temp & PORT_POWER) {
|
||||
if (hcd->speed == HCD_USB3)
|
||||
status |= USB_SS_PORT_STAT_POWER;
|
||||
else
|
||||
status |= USB_PORT_STAT_POWER;
|
||||
}
|
||||
/* Update Port Link State for super speed ports*/
|
||||
if (hcd->speed == HCD_USB3) {
|
||||
xhci_hub_report_link_state(&status, temp);
|
||||
/*
|
||||
* Verify if all USB3 Ports Have entered U0 already.
|
||||
* Delete Compliance Mode Timer if so.
|
||||
*/
|
||||
xhci_del_comp_mod_timer(xhci, temp, wIndex);
|
||||
}
|
||||
if (bus_state->port_c_suspend & (1 << wIndex))
|
||||
status |= 1 << USB_PORT_FEAT_C_SUSPEND;
|
||||
xhci_dbg(xhci, "get port status, actual port %d status = 0x%x\n",
|
||||
wIndex, temp);
|
||||
xhci_dbg(xhci, "Get port status returned 0x%x\n", status);
|
||||
|
||||
put_unaligned(cpu_to_le32(status), (__le32 *) buf);
|
||||
break;
|
||||
case SetPortFeature:
|
||||
|
|
|
@ -250,13 +250,15 @@ static int xhci_pci_resume(struct usb_hcd *hcd, bool hibernated)
|
|||
* writers.
|
||||
*
|
||||
* Unconditionally switch the ports back to xHCI after a system resume.
|
||||
* We can't tell whether the EHCI or xHCI controller will be resumed
|
||||
* first, so we have to do the port switchover in both drivers. Writing
|
||||
* a '1' to the port switchover registers should have no effect if the
|
||||
* port was already switched over.
|
||||
* It should not matter whether the EHCI or xHCI controller is
|
||||
* resumed first. It's enough to do the switchover in xHCI because
|
||||
* USB core won't notice anything as the hub driver doesn't start
|
||||
* running again until after all the devices (including both EHCI and
|
||||
* xHCI host controllers) have been resumed.
|
||||
*/
|
||||
if (usb_is_intel_switchable_xhci(pdev))
|
||||
usb_enable_xhci_ports(pdev);
|
||||
|
||||
if (pdev->vendor == PCI_VENDOR_ID_INTEL)
|
||||
usb_enable_intel_xhci_ports(pdev);
|
||||
|
||||
retval = xhci_resume(xhci, hibernated);
|
||||
return retval;
|
||||
|
|
|
@ -186,11 +186,37 @@ static int xhci_plat_remove(struct platform_device *dev)
|
|||
return 0;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_PM
|
||||
static int xhci_plat_suspend(struct device *dev)
|
||||
{
|
||||
struct usb_hcd *hcd = dev_get_drvdata(dev);
|
||||
struct xhci_hcd *xhci = hcd_to_xhci(hcd);
|
||||
|
||||
return xhci_suspend(xhci);
|
||||
}
|
||||
|
||||
static int xhci_plat_resume(struct device *dev)
|
||||
{
|
||||
struct usb_hcd *hcd = dev_get_drvdata(dev);
|
||||
struct xhci_hcd *xhci = hcd_to_xhci(hcd);
|
||||
|
||||
return xhci_resume(xhci, 0);
|
||||
}
|
||||
|
||||
static const struct dev_pm_ops xhci_plat_pm_ops = {
|
||||
SET_SYSTEM_SLEEP_PM_OPS(xhci_plat_suspend, xhci_plat_resume)
|
||||
};
|
||||
#define DEV_PM_OPS (&xhci_plat_pm_ops)
|
||||
#else
|
||||
#define DEV_PM_OPS NULL
|
||||
#endif /* CONFIG_PM */
|
||||
|
||||
static struct platform_driver usb_xhci_driver = {
|
||||
.probe = xhci_plat_probe,
|
||||
.remove = xhci_plat_remove,
|
||||
.driver = {
|
||||
.name = "xhci-hcd",
|
||||
.pm = DEV_PM_OPS,
|
||||
},
|
||||
};
|
||||
MODULE_ALIAS("platform:xhci-hcd");
|
||||
|
|
|
@ -3075,8 +3075,8 @@ static u32 xhci_calculate_no_streams_bitmask(struct xhci_hcd *xhci,
|
|||
/* Are streams already being freed for the endpoint? */
|
||||
if (ep_state & EP_GETTING_NO_STREAMS) {
|
||||
xhci_warn(xhci, "WARN Can't disable streams for "
|
||||
"endpoint 0x%x\n, "
|
||||
"streams are being disabled already.",
|
||||
"endpoint 0x%x, "
|
||||
"streams are being disabled already\n",
|
||||
eps[i]->desc.bEndpointAddress);
|
||||
return 0;
|
||||
}
|
||||
|
@ -3084,8 +3084,8 @@ static u32 xhci_calculate_no_streams_bitmask(struct xhci_hcd *xhci,
|
|||
if (!(ep_state & EP_HAS_STREAMS) &&
|
||||
!(ep_state & EP_GETTING_STREAMS)) {
|
||||
xhci_warn(xhci, "WARN Can't disable streams for "
|
||||
"endpoint 0x%x\n, "
|
||||
"streams are already disabled!",
|
||||
"endpoint 0x%x, "
|
||||
"streams are already disabled!\n",
|
||||
eps[i]->desc.bEndpointAddress);
|
||||
xhci_warn(xhci, "WARN xhci_free_streams() called "
|
||||
"with non-streams endpoint\n");
|
||||
|
@ -4353,7 +4353,7 @@ static u16 xhci_get_timeout_no_hub_lpm(struct usb_device *udev,
|
|||
state_name, sel);
|
||||
else
|
||||
dev_dbg(&udev->dev, "Device-initiated %s disabled "
|
||||
"due to long PEL %llu\n ms",
|
||||
"due to long PEL %llu ms\n",
|
||||
state_name, pel);
|
||||
return USB3_LPM_DISABLED;
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue