diff options
-rw-r--r-- | drivers/usb/host/xhci-pci.c | 8 | ||||
-rw-r--r-- | drivers/usb/host/xhci.c | 7 | ||||
-rw-r--r-- | drivers/usb/host/xhci.h | 1 |
3 files changed, 15 insertions, 1 deletions
diff --git a/drivers/usb/host/xhci-pci.c b/drivers/usb/host/xhci-pci.c index 236c3aabe940..5444ecdbfb92 100644 --- a/drivers/usb/host/xhci-pci.c +++ b/drivers/usb/host/xhci-pci.c | |||
@@ -69,6 +69,14 @@ static void xhci_pci_quirks(struct device *dev, struct xhci_hcd *xhci) | |||
69 | "QUIRK: Fresco Logic xHC needs configure" | 69 | "QUIRK: Fresco Logic xHC needs configure" |
70 | " endpoint cmd after reset endpoint"); | 70 | " endpoint cmd after reset endpoint"); |
71 | } | 71 | } |
72 | if (pdev->device == PCI_DEVICE_ID_FRESCO_LOGIC_PDK && | ||
73 | pdev->revision == 0x4) { | ||
74 | xhci->quirks |= XHCI_SLOW_SUSPEND; | ||
75 | xhci_dbg_trace(xhci, trace_xhci_dbg_quirks, | ||
76 | "QUIRK: Fresco Logic xHC revision %u" | ||
77 | "must be suspended extra slowly", | ||
78 | pdev->revision); | ||
79 | } | ||
72 | /* Fresco Logic confirms: all revisions of this chip do not | 80 | /* Fresco Logic confirms: all revisions of this chip do not |
73 | * support MSI, even though some of them claim to in their PCI | 81 | * support MSI, even though some of them claim to in their PCI |
74 | * capabilities. | 82 | * capabilities. |
diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c index 1e36dbb48366..6d3e298a8174 100644 --- a/drivers/usb/host/xhci.c +++ b/drivers/usb/host/xhci.c | |||
@@ -839,6 +839,7 @@ static void xhci_clear_command_ring(struct xhci_hcd *xhci) | |||
839 | int xhci_suspend(struct xhci_hcd *xhci) | 839 | int xhci_suspend(struct xhci_hcd *xhci) |
840 | { | 840 | { |
841 | int rc = 0; | 841 | int rc = 0; |
842 | unsigned int delay = XHCI_MAX_HALT_USEC; | ||
842 | struct usb_hcd *hcd = xhci_to_hcd(xhci); | 843 | struct usb_hcd *hcd = xhci_to_hcd(xhci); |
843 | u32 command; | 844 | u32 command; |
844 | 845 | ||
@@ -861,8 +862,12 @@ int xhci_suspend(struct xhci_hcd *xhci) | |||
861 | command = xhci_readl(xhci, &xhci->op_regs->command); | 862 | command = xhci_readl(xhci, &xhci->op_regs->command); |
862 | command &= ~CMD_RUN; | 863 | command &= ~CMD_RUN; |
863 | xhci_writel(xhci, command, &xhci->op_regs->command); | 864 | xhci_writel(xhci, command, &xhci->op_regs->command); |
865 | |||
866 | /* Some chips from Fresco Logic need an extraordinary delay */ | ||
867 | delay *= (xhci->quirks & XHCI_SLOW_SUSPEND) ? 10 : 1; | ||
868 | |||
864 | if (xhci_handshake(xhci, &xhci->op_regs->status, | 869 | if (xhci_handshake(xhci, &xhci->op_regs->status, |
865 | STS_HALT, STS_HALT, XHCI_MAX_HALT_USEC)) { | 870 | STS_HALT, STS_HALT, delay)) { |
866 | xhci_warn(xhci, "WARN: xHC CMD_RUN timeout\n"); | 871 | xhci_warn(xhci, "WARN: xHC CMD_RUN timeout\n"); |
867 | spin_unlock_irq(&xhci->lock); | 872 | spin_unlock_irq(&xhci->lock); |
868 | return -ETIMEDOUT; | 873 | return -ETIMEDOUT; |
diff --git a/drivers/usb/host/xhci.h b/drivers/usb/host/xhci.h index 289fbfbae746..4f82d2172afa 100644 --- a/drivers/usb/host/xhci.h +++ b/drivers/usb/host/xhci.h | |||
@@ -1548,6 +1548,7 @@ struct xhci_hcd { | |||
1548 | #define XHCI_COMP_MODE_QUIRK (1 << 14) | 1548 | #define XHCI_COMP_MODE_QUIRK (1 << 14) |
1549 | #define XHCI_AVOID_BEI (1 << 15) | 1549 | #define XHCI_AVOID_BEI (1 << 15) |
1550 | #define XHCI_PLAT (1 << 16) | 1550 | #define XHCI_PLAT (1 << 16) |
1551 | #define XHCI_SLOW_SUSPEND (1 << 17) | ||
1551 | unsigned int num_active_eps; | 1552 | unsigned int num_active_eps; |
1552 | unsigned int limit_active_eps; | 1553 | unsigned int limit_active_eps; |
1553 | /* There are two roothubs to keep track of bus suspend info for */ | 1554 | /* There are two roothubs to keep track of bus suspend info for */ |