diff options
Diffstat (limited to 'drivers/usb/host/xhci.c')
-rw-r--r-- | drivers/usb/host/xhci.c | 32 |
1 files changed, 19 insertions, 13 deletions
diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c index c9e419f29b74..5c72c431bab1 100644 --- a/drivers/usb/host/xhci.c +++ b/drivers/usb/host/xhci.c | |||
@@ -40,7 +40,7 @@ MODULE_PARM_DESC(link_quirk, "Don't clear the chain bit on a link TRB"); | |||
40 | 40 | ||
41 | /* TODO: copied from ehci-hcd.c - can this be refactored? */ | 41 | /* TODO: copied from ehci-hcd.c - can this be refactored? */ |
42 | /* | 42 | /* |
43 | * handshake - spin reading hc until handshake completes or fails | 43 | * xhci_handshake - spin reading hc until handshake completes or fails |
44 | * @ptr: address of hc register to be read | 44 | * @ptr: address of hc register to be read |
45 | * @mask: bits to look at in result of read | 45 | * @mask: bits to look at in result of read |
46 | * @done: value of those bits when handshake succeeds | 46 | * @done: value of those bits when handshake succeeds |
@@ -52,7 +52,7 @@ MODULE_PARM_DESC(link_quirk, "Don't clear the chain bit on a link TRB"); | |||
52 | * handshake done). There are two failure modes: "usec" have passed (major | 52 | * handshake done). There are two failure modes: "usec" have passed (major |
53 | * hardware flakeout), or the register reads as all-ones (hardware removed). | 53 | * hardware flakeout), or the register reads as all-ones (hardware removed). |
54 | */ | 54 | */ |
55 | int handshake(struct xhci_hcd *xhci, void __iomem *ptr, | 55 | int xhci_handshake(struct xhci_hcd *xhci, void __iomem *ptr, |
56 | u32 mask, u32 done, int usec) | 56 | u32 mask, u32 done, int usec) |
57 | { | 57 | { |
58 | u32 result; | 58 | u32 result; |
@@ -103,7 +103,7 @@ int xhci_halt(struct xhci_hcd *xhci) | |||
103 | xhci_dbg(xhci, "// Halt the HC\n"); | 103 | xhci_dbg(xhci, "// Halt the HC\n"); |
104 | xhci_quiesce(xhci); | 104 | xhci_quiesce(xhci); |
105 | 105 | ||
106 | ret = handshake(xhci, &xhci->op_regs->status, | 106 | ret = xhci_handshake(xhci, &xhci->op_regs->status, |
107 | STS_HALT, STS_HALT, XHCI_MAX_HALT_USEC); | 107 | STS_HALT, STS_HALT, XHCI_MAX_HALT_USEC); |
108 | if (!ret) { | 108 | if (!ret) { |
109 | xhci->xhc_state |= XHCI_STATE_HALTED; | 109 | xhci->xhc_state |= XHCI_STATE_HALTED; |
@@ -132,7 +132,7 @@ static int xhci_start(struct xhci_hcd *xhci) | |||
132 | * Wait for the HCHalted Status bit to be 0 to indicate the host is | 132 | * Wait for the HCHalted Status bit to be 0 to indicate the host is |
133 | * running. | 133 | * running. |
134 | */ | 134 | */ |
135 | ret = handshake(xhci, &xhci->op_regs->status, | 135 | ret = xhci_handshake(xhci, &xhci->op_regs->status, |
136 | STS_HALT, 0, XHCI_MAX_HALT_USEC); | 136 | STS_HALT, 0, XHCI_MAX_HALT_USEC); |
137 | if (ret == -ETIMEDOUT) | 137 | if (ret == -ETIMEDOUT) |
138 | xhci_err(xhci, "Host took too long to start, " | 138 | xhci_err(xhci, "Host took too long to start, " |
@@ -167,7 +167,7 @@ int xhci_reset(struct xhci_hcd *xhci) | |||
167 | command |= CMD_RESET; | 167 | command |= CMD_RESET; |
168 | xhci_writel(xhci, command, &xhci->op_regs->command); | 168 | xhci_writel(xhci, command, &xhci->op_regs->command); |
169 | 169 | ||
170 | ret = handshake(xhci, &xhci->op_regs->command, | 170 | ret = xhci_handshake(xhci, &xhci->op_regs->command, |
171 | CMD_RESET, 0, 10 * 1000 * 1000); | 171 | CMD_RESET, 0, 10 * 1000 * 1000); |
172 | if (ret) | 172 | if (ret) |
173 | return ret; | 173 | return ret; |
@@ -177,7 +177,7 @@ int xhci_reset(struct xhci_hcd *xhci) | |||
177 | * xHCI cannot write to any doorbells or operational registers other | 177 | * xHCI cannot write to any doorbells or operational registers other |
178 | * than status until the "Controller Not Ready" flag is cleared. | 178 | * than status until the "Controller Not Ready" flag is cleared. |
179 | */ | 179 | */ |
180 | ret = handshake(xhci, &xhci->op_regs->status, | 180 | ret = xhci_handshake(xhci, &xhci->op_regs->status, |
181 | STS_CNR, 0, 10 * 1000 * 1000); | 181 | STS_CNR, 0, 10 * 1000 * 1000); |
182 | 182 | ||
183 | for (i = 0; i < 2; ++i) { | 183 | for (i = 0; i < 2; ++i) { |
@@ -480,7 +480,7 @@ static bool compliance_mode_recovery_timer_quirk_check(void) | |||
480 | if (strstr(dmi_product_name, "Z420") || | 480 | if (strstr(dmi_product_name, "Z420") || |
481 | strstr(dmi_product_name, "Z620") || | 481 | strstr(dmi_product_name, "Z620") || |
482 | strstr(dmi_product_name, "Z820") || | 482 | strstr(dmi_product_name, "Z820") || |
483 | strstr(dmi_product_name, "Z1")) | 483 | strstr(dmi_product_name, "Z1 Workstation")) |
484 | return true; | 484 | return true; |
485 | 485 | ||
486 | return false; | 486 | return false; |
@@ -880,6 +880,10 @@ int xhci_suspend(struct xhci_hcd *xhci) | |||
880 | struct usb_hcd *hcd = xhci_to_hcd(xhci); | 880 | struct usb_hcd *hcd = xhci_to_hcd(xhci); |
881 | u32 command; | 881 | u32 command; |
882 | 882 | ||
883 | if (hcd->state != HC_STATE_SUSPENDED || | ||
884 | xhci->shared_hcd->state != HC_STATE_SUSPENDED) | ||
885 | return -EINVAL; | ||
886 | |||
883 | spin_lock_irq(&xhci->lock); | 887 | spin_lock_irq(&xhci->lock); |
884 | clear_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags); | 888 | clear_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags); |
885 | clear_bit(HCD_FLAG_HW_ACCESSIBLE, &xhci->shared_hcd->flags); | 889 | clear_bit(HCD_FLAG_HW_ACCESSIBLE, &xhci->shared_hcd->flags); |
@@ -890,7 +894,7 @@ int xhci_suspend(struct xhci_hcd *xhci) | |||
890 | command = xhci_readl(xhci, &xhci->op_regs->command); | 894 | command = xhci_readl(xhci, &xhci->op_regs->command); |
891 | command &= ~CMD_RUN; | 895 | command &= ~CMD_RUN; |
892 | xhci_writel(xhci, command, &xhci->op_regs->command); | 896 | xhci_writel(xhci, command, &xhci->op_regs->command); |
893 | if (handshake(xhci, &xhci->op_regs->status, | 897 | if (xhci_handshake(xhci, &xhci->op_regs->status, |
894 | STS_HALT, STS_HALT, XHCI_MAX_HALT_USEC)) { | 898 | STS_HALT, STS_HALT, XHCI_MAX_HALT_USEC)) { |
895 | xhci_warn(xhci, "WARN: xHC CMD_RUN timeout\n"); | 899 | xhci_warn(xhci, "WARN: xHC CMD_RUN timeout\n"); |
896 | spin_unlock_irq(&xhci->lock); | 900 | spin_unlock_irq(&xhci->lock); |
@@ -905,7 +909,8 @@ int xhci_suspend(struct xhci_hcd *xhci) | |||
905 | command = xhci_readl(xhci, &xhci->op_regs->command); | 909 | command = xhci_readl(xhci, &xhci->op_regs->command); |
906 | command |= CMD_CSS; | 910 | command |= CMD_CSS; |
907 | xhci_writel(xhci, command, &xhci->op_regs->command); | 911 | xhci_writel(xhci, command, &xhci->op_regs->command); |
908 | if (handshake(xhci, &xhci->op_regs->status, STS_SAVE, 0, 10 * 1000)) { | 912 | if (xhci_handshake(xhci, &xhci->op_regs->status, |
913 | STS_SAVE, 0, 10 * 1000)) { | ||
909 | xhci_warn(xhci, "WARN: xHC save state timeout\n"); | 914 | xhci_warn(xhci, "WARN: xHC save state timeout\n"); |
910 | spin_unlock_irq(&xhci->lock); | 915 | spin_unlock_irq(&xhci->lock); |
911 | return -ETIMEDOUT; | 916 | return -ETIMEDOUT; |
@@ -967,7 +972,7 @@ int xhci_resume(struct xhci_hcd *xhci, bool hibernated) | |||
967 | command = xhci_readl(xhci, &xhci->op_regs->command); | 972 | command = xhci_readl(xhci, &xhci->op_regs->command); |
968 | command |= CMD_CRS; | 973 | command |= CMD_CRS; |
969 | xhci_writel(xhci, command, &xhci->op_regs->command); | 974 | xhci_writel(xhci, command, &xhci->op_regs->command); |
970 | if (handshake(xhci, &xhci->op_regs->status, | 975 | if (xhci_handshake(xhci, &xhci->op_regs->status, |
971 | STS_RESTORE, 0, 10 * 1000)) { | 976 | STS_RESTORE, 0, 10 * 1000)) { |
972 | xhci_warn(xhci, "WARN: xHC restore state timeout\n"); | 977 | xhci_warn(xhci, "WARN: xHC restore state timeout\n"); |
973 | spin_unlock_irq(&xhci->lock); | 978 | spin_unlock_irq(&xhci->lock); |
@@ -1035,7 +1040,7 @@ int xhci_resume(struct xhci_hcd *xhci, bool hibernated) | |||
1035 | command = xhci_readl(xhci, &xhci->op_regs->command); | 1040 | command = xhci_readl(xhci, &xhci->op_regs->command); |
1036 | command |= CMD_RUN; | 1041 | command |= CMD_RUN; |
1037 | xhci_writel(xhci, command, &xhci->op_regs->command); | 1042 | xhci_writel(xhci, command, &xhci->op_regs->command); |
1038 | handshake(xhci, &xhci->op_regs->status, STS_HALT, | 1043 | xhci_handshake(xhci, &xhci->op_regs->status, STS_HALT, |
1039 | 0, 250 * 1000); | 1044 | 0, 250 * 1000); |
1040 | 1045 | ||
1041 | /* step 5: walk topology and initialize portsc, | 1046 | /* step 5: walk topology and initialize portsc, |
@@ -2254,7 +2259,7 @@ static bool xhci_is_async_ep(unsigned int ep_type) | |||
2254 | 2259 | ||
2255 | static bool xhci_is_sync_in_ep(unsigned int ep_type) | 2260 | static bool xhci_is_sync_in_ep(unsigned int ep_type) |
2256 | { | 2261 | { |
2257 | return (ep_type == ISOC_IN_EP || ep_type != INT_IN_EP); | 2262 | return (ep_type == ISOC_IN_EP || ep_type == INT_IN_EP); |
2258 | } | 2263 | } |
2259 | 2264 | ||
2260 | static unsigned int xhci_get_ss_bw_consumed(struct xhci_bw_info *ep_bw) | 2265 | static unsigned int xhci_get_ss_bw_consumed(struct xhci_bw_info *ep_bw) |
@@ -3874,7 +3879,8 @@ static int xhci_usb2_software_lpm_test(struct usb_hcd *hcd, | |||
3874 | spin_lock_irqsave(&xhci->lock, flags); | 3879 | spin_lock_irqsave(&xhci->lock, flags); |
3875 | 3880 | ||
3876 | /* Check L1 Status */ | 3881 | /* Check L1 Status */ |
3877 | ret = handshake(xhci, pm_addr, PORT_L1S_MASK, PORT_L1S_SUCCESS, 125); | 3882 | ret = xhci_handshake(xhci, pm_addr, |
3883 | PORT_L1S_MASK, PORT_L1S_SUCCESS, 125); | ||
3878 | if (ret != -ETIMEDOUT) { | 3884 | if (ret != -ETIMEDOUT) { |
3879 | /* enter L1 successfully */ | 3885 | /* enter L1 successfully */ |
3880 | temp = xhci_readl(xhci, addr); | 3886 | temp = xhci_readl(xhci, addr); |