diff options
Diffstat (limited to 'drivers/usb/host/xhci-hub.c')
-rw-r--r-- | drivers/usb/host/xhci-hub.c | 756 |
1 files changed, 698 insertions, 58 deletions
diff --git a/drivers/usb/host/xhci-hub.c b/drivers/usb/host/xhci-hub.c index a1a7a9795536..0be788cc2fdb 100644 --- a/drivers/usb/host/xhci-hub.c +++ b/drivers/usb/host/xhci-hub.c | |||
@@ -24,27 +24,19 @@ | |||
24 | 24 | ||
25 | #include "xhci.h" | 25 | #include "xhci.h" |
26 | 26 | ||
27 | static void xhci_hub_descriptor(struct xhci_hcd *xhci, | 27 | #define PORT_WAKE_BITS (PORT_WKOC_E | PORT_WKDISC_E | PORT_WKCONN_E) |
28 | struct usb_hub_descriptor *desc) | 28 | #define PORT_RWC_BITS (PORT_CSC | PORT_PEC | PORT_WRC | PORT_OCC | \ |
29 | PORT_RC | PORT_PLC | PORT_PE) | ||
30 | |||
31 | static void xhci_common_hub_descriptor(struct xhci_hcd *xhci, | ||
32 | struct usb_hub_descriptor *desc, int ports) | ||
29 | { | 33 | { |
30 | int ports; | ||
31 | u16 temp; | 34 | u16 temp; |
32 | 35 | ||
33 | ports = HCS_MAX_PORTS(xhci->hcs_params1); | ||
34 | |||
35 | /* USB 3.0 hubs have a different descriptor, but we fake this for now */ | ||
36 | desc->bDescriptorType = 0x29; | ||
37 | desc->bPwrOn2PwrGood = 10; /* xhci section 5.4.9 says 20ms max */ | 36 | desc->bPwrOn2PwrGood = 10; /* xhci section 5.4.9 says 20ms max */ |
38 | desc->bHubContrCurrent = 0; | 37 | desc->bHubContrCurrent = 0; |
39 | 38 | ||
40 | desc->bNbrPorts = ports; | 39 | desc->bNbrPorts = ports; |
41 | temp = 1 + (ports / 8); | ||
42 | desc->bDescLength = 7 + 2 * temp; | ||
43 | |||
44 | /* Why does core/hcd.h define bitmap? It's just confusing. */ | ||
45 | memset(&desc->DeviceRemovable[0], 0, temp); | ||
46 | memset(&desc->DeviceRemovable[temp], 0xff, temp); | ||
47 | |||
48 | /* Ugh, these should be #defines, FIXME */ | 40 | /* Ugh, these should be #defines, FIXME */ |
49 | /* Using table 11-13 in USB 2.0 spec. */ | 41 | /* Using table 11-13 in USB 2.0 spec. */ |
50 | temp = 0; | 42 | temp = 0; |
@@ -58,7 +50,103 @@ static void xhci_hub_descriptor(struct xhci_hcd *xhci, | |||
58 | temp |= 0x0008; | 50 | temp |= 0x0008; |
59 | /* Bits 6:5 - no TTs in root ports */ | 51 | /* Bits 6:5 - no TTs in root ports */ |
60 | /* Bit 7 - no port indicators */ | 52 | /* Bit 7 - no port indicators */ |
61 | desc->wHubCharacteristics = (__force __u16) cpu_to_le16(temp); | 53 | desc->wHubCharacteristics = cpu_to_le16(temp); |
54 | } | ||
55 | |||
56 | /* Fill in the USB 2.0 roothub descriptor */ | ||
57 | static void xhci_usb2_hub_descriptor(struct usb_hcd *hcd, struct xhci_hcd *xhci, | ||
58 | struct usb_hub_descriptor *desc) | ||
59 | { | ||
60 | int ports; | ||
61 | u16 temp; | ||
62 | __u8 port_removable[(USB_MAXCHILDREN + 1 + 7) / 8]; | ||
63 | u32 portsc; | ||
64 | unsigned int i; | ||
65 | |||
66 | ports = xhci->num_usb2_ports; | ||
67 | |||
68 | xhci_common_hub_descriptor(xhci, desc, ports); | ||
69 | desc->bDescriptorType = 0x29; | ||
70 | temp = 1 + (ports / 8); | ||
71 | desc->bDescLength = 7 + 2 * temp; | ||
72 | |||
73 | /* The Device Removable bits are reported on a byte granularity. | ||
74 | * If the port doesn't exist within that byte, the bit is set to 0. | ||
75 | */ | ||
76 | memset(port_removable, 0, sizeof(port_removable)); | ||
77 | for (i = 0; i < ports; i++) { | ||
78 | portsc = xhci_readl(xhci, xhci->usb3_ports[i]); | ||
79 | /* If a device is removable, PORTSC reports a 0, same as in the | ||
80 | * hub descriptor DeviceRemovable bits. | ||
81 | */ | ||
82 | if (portsc & PORT_DEV_REMOVE) | ||
83 | /* This math is hairy because bit 0 of DeviceRemovable | ||
84 | * is reserved, and bit 1 is for port 1, etc. | ||
85 | */ | ||
86 | port_removable[(i + 1) / 8] |= 1 << ((i + 1) % 8); | ||
87 | } | ||
88 | |||
89 | /* ch11.h defines a hub descriptor that has room for USB_MAXCHILDREN | ||
90 | * ports on it. The USB 2.0 specification says that there are two | ||
91 | * variable length fields at the end of the hub descriptor: | ||
92 | * DeviceRemovable and PortPwrCtrlMask. But since we can have less than | ||
93 | * USB_MAXCHILDREN ports, we may need to use the DeviceRemovable array | ||
94 | * to set PortPwrCtrlMask bits. PortPwrCtrlMask must always be set to | ||
95 | * 0xFF, so we initialize the both arrays (DeviceRemovable and | ||
96 | * PortPwrCtrlMask) to 0xFF. Then we set the DeviceRemovable for each | ||
97 | * set of ports that actually exist. | ||
98 | */ | ||
99 | memset(desc->u.hs.DeviceRemovable, 0xff, | ||
100 | sizeof(desc->u.hs.DeviceRemovable)); | ||
101 | memset(desc->u.hs.PortPwrCtrlMask, 0xff, | ||
102 | sizeof(desc->u.hs.PortPwrCtrlMask)); | ||
103 | |||
104 | for (i = 0; i < (ports + 1 + 7) / 8; i++) | ||
105 | memset(&desc->u.hs.DeviceRemovable[i], port_removable[i], | ||
106 | sizeof(__u8)); | ||
107 | } | ||
108 | |||
109 | /* Fill in the USB 3.0 roothub descriptor */ | ||
110 | static void xhci_usb3_hub_descriptor(struct usb_hcd *hcd, struct xhci_hcd *xhci, | ||
111 | struct usb_hub_descriptor *desc) | ||
112 | { | ||
113 | int ports; | ||
114 | u16 port_removable; | ||
115 | u32 portsc; | ||
116 | unsigned int i; | ||
117 | |||
118 | ports = xhci->num_usb3_ports; | ||
119 | xhci_common_hub_descriptor(xhci, desc, ports); | ||
120 | desc->bDescriptorType = 0x2a; | ||
121 | desc->bDescLength = 12; | ||
122 | |||
123 | /* header decode latency should be zero for roothubs, | ||
124 | * see section 4.23.5.2. | ||
125 | */ | ||
126 | desc->u.ss.bHubHdrDecLat = 0; | ||
127 | desc->u.ss.wHubDelay = 0; | ||
128 | |||
129 | port_removable = 0; | ||
130 | /* bit 0 is reserved, bit 1 is for port 1, etc. */ | ||
131 | for (i = 0; i < ports; i++) { | ||
132 | portsc = xhci_readl(xhci, xhci->usb3_ports[i]); | ||
133 | if (portsc & PORT_DEV_REMOVE) | ||
134 | port_removable |= 1 << (i + 1); | ||
135 | } | ||
136 | memset(&desc->u.ss.DeviceRemovable, | ||
137 | (__force __u16) cpu_to_le16(port_removable), | ||
138 | sizeof(__u16)); | ||
139 | } | ||
140 | |||
141 | static void xhci_hub_descriptor(struct usb_hcd *hcd, struct xhci_hcd *xhci, | ||
142 | struct usb_hub_descriptor *desc) | ||
143 | { | ||
144 | |||
145 | if (hcd->speed == HCD_USB3) | ||
146 | xhci_usb3_hub_descriptor(hcd, xhci, desc); | ||
147 | else | ||
148 | xhci_usb2_hub_descriptor(hcd, xhci, desc); | ||
149 | |||
62 | } | 150 | } |
63 | 151 | ||
64 | static unsigned int xhci_port_speed(unsigned int port_status) | 152 | static unsigned int xhci_port_speed(unsigned int port_status) |
@@ -67,8 +155,6 @@ static unsigned int xhci_port_speed(unsigned int port_status) | |||
67 | return USB_PORT_STAT_LOW_SPEED; | 155 | return USB_PORT_STAT_LOW_SPEED; |
68 | if (DEV_HIGHSPEED(port_status)) | 156 | if (DEV_HIGHSPEED(port_status)) |
69 | return USB_PORT_STAT_HIGH_SPEED; | 157 | return USB_PORT_STAT_HIGH_SPEED; |
70 | if (DEV_SUPERSPEED(port_status)) | ||
71 | return USB_PORT_STAT_SUPER_SPEED; | ||
72 | /* | 158 | /* |
73 | * FIXME: Yes, we should check for full speed, but the core uses that as | 159 | * FIXME: Yes, we should check for full speed, but the core uses that as |
74 | * a default in portspeed() in usb/core/hub.c (which is the only place | 160 | * a default in portspeed() in usb/core/hub.c (which is the only place |
@@ -123,15 +209,120 @@ static unsigned int xhci_port_speed(unsigned int port_status) | |||
123 | * writing a 0 clears the bit and writing a 1 sets the bit (RWS). | 209 | * writing a 0 clears the bit and writing a 1 sets the bit (RWS). |
124 | * For all other types (RW1S, RW1CS, RW, and RZ), writing a '0' has no effect. | 210 | * For all other types (RW1S, RW1CS, RW, and RZ), writing a '0' has no effect. |
125 | */ | 211 | */ |
126 | static u32 xhci_port_state_to_neutral(u32 state) | 212 | u32 xhci_port_state_to_neutral(u32 state) |
127 | { | 213 | { |
128 | /* Save read-only status and port state */ | 214 | /* Save read-only status and port state */ |
129 | return (state & XHCI_PORT_RO) | (state & XHCI_PORT_RWS); | 215 | return (state & XHCI_PORT_RO) | (state & XHCI_PORT_RWS); |
130 | } | 216 | } |
131 | 217 | ||
132 | static void xhci_disable_port(struct xhci_hcd *xhci, u16 wIndex, | 218 | /* |
133 | u32 __iomem *addr, u32 port_status) | 219 | * find slot id based on port number. |
220 | * @port: The one-based port number from one of the two split roothubs. | ||
221 | */ | ||
222 | int xhci_find_slot_id_by_port(struct usb_hcd *hcd, struct xhci_hcd *xhci, | ||
223 | u16 port) | ||
224 | { | ||
225 | int slot_id; | ||
226 | int i; | ||
227 | enum usb_device_speed speed; | ||
228 | |||
229 | slot_id = 0; | ||
230 | for (i = 0; i < MAX_HC_SLOTS; i++) { | ||
231 | if (!xhci->devs[i]) | ||
232 | continue; | ||
233 | speed = xhci->devs[i]->udev->speed; | ||
234 | if (((speed == USB_SPEED_SUPER) == (hcd->speed == HCD_USB3)) | ||
235 | && xhci->devs[i]->port == port) { | ||
236 | slot_id = i; | ||
237 | break; | ||
238 | } | ||
239 | } | ||
240 | |||
241 | return slot_id; | ||
242 | } | ||
243 | |||
244 | /* | ||
245 | * Stop device | ||
246 | * It issues stop endpoint command for EP 0 to 30. And wait the last command | ||
247 | * to complete. | ||
248 | * suspend will set to 1, if suspend bit need to set in command. | ||
249 | */ | ||
250 | static int xhci_stop_device(struct xhci_hcd *xhci, int slot_id, int suspend) | ||
251 | { | ||
252 | struct xhci_virt_device *virt_dev; | ||
253 | struct xhci_command *cmd; | ||
254 | unsigned long flags; | ||
255 | int timeleft; | ||
256 | int ret; | ||
257 | int i; | ||
258 | |||
259 | ret = 0; | ||
260 | virt_dev = xhci->devs[slot_id]; | ||
261 | cmd = xhci_alloc_command(xhci, false, true, GFP_NOIO); | ||
262 | if (!cmd) { | ||
263 | xhci_dbg(xhci, "Couldn't allocate command structure.\n"); | ||
264 | return -ENOMEM; | ||
265 | } | ||
266 | |||
267 | spin_lock_irqsave(&xhci->lock, flags); | ||
268 | for (i = LAST_EP_INDEX; i > 0; i--) { | ||
269 | if (virt_dev->eps[i].ring && virt_dev->eps[i].ring->dequeue) | ||
270 | xhci_queue_stop_endpoint(xhci, slot_id, i, suspend); | ||
271 | } | ||
272 | cmd->command_trb = xhci->cmd_ring->enqueue; | ||
273 | list_add_tail(&cmd->cmd_list, &virt_dev->cmd_list); | ||
274 | xhci_queue_stop_endpoint(xhci, slot_id, 0, suspend); | ||
275 | xhci_ring_cmd_db(xhci); | ||
276 | spin_unlock_irqrestore(&xhci->lock, flags); | ||
277 | |||
278 | /* Wait for last stop endpoint command to finish */ | ||
279 | timeleft = wait_for_completion_interruptible_timeout( | ||
280 | cmd->completion, | ||
281 | USB_CTRL_SET_TIMEOUT); | ||
282 | if (timeleft <= 0) { | ||
283 | xhci_warn(xhci, "%s while waiting for stop endpoint command\n", | ||
284 | timeleft == 0 ? "Timeout" : "Signal"); | ||
285 | spin_lock_irqsave(&xhci->lock, flags); | ||
286 | /* The timeout might have raced with the event ring handler, so | ||
287 | * only delete from the list if the item isn't poisoned. | ||
288 | */ | ||
289 | if (cmd->cmd_list.next != LIST_POISON1) | ||
290 | list_del(&cmd->cmd_list); | ||
291 | spin_unlock_irqrestore(&xhci->lock, flags); | ||
292 | ret = -ETIME; | ||
293 | goto command_cleanup; | ||
294 | } | ||
295 | |||
296 | command_cleanup: | ||
297 | xhci_free_command(xhci, cmd); | ||
298 | return ret; | ||
299 | } | ||
300 | |||
301 | /* | ||
302 | * Ring device, it rings the all doorbells unconditionally. | ||
303 | */ | ||
304 | void xhci_ring_device(struct xhci_hcd *xhci, int slot_id) | ||
305 | { | ||
306 | int i; | ||
307 | |||
308 | for (i = 0; i < LAST_EP_INDEX + 1; i++) | ||
309 | if (xhci->devs[slot_id]->eps[i].ring && | ||
310 | xhci->devs[slot_id]->eps[i].ring->dequeue) | ||
311 | xhci_ring_ep_doorbell(xhci, slot_id, i, 0); | ||
312 | |||
313 | return; | ||
314 | } | ||
315 | |||
316 | static void xhci_disable_port(struct usb_hcd *hcd, struct xhci_hcd *xhci, | ||
317 | u16 wIndex, __le32 __iomem *addr, u32 port_status) | ||
134 | { | 318 | { |
319 | /* Don't allow the USB core to disable SuperSpeed ports. */ | ||
320 | if (hcd->speed == HCD_USB3) { | ||
321 | xhci_dbg(xhci, "Ignoring request to disable " | ||
322 | "SuperSpeed port.\n"); | ||
323 | return; | ||
324 | } | ||
325 | |||
135 | /* Write 1 to disable the port */ | 326 | /* Write 1 to disable the port */ |
136 | xhci_writel(xhci, port_status | PORT_PE, addr); | 327 | xhci_writel(xhci, port_status | PORT_PE, addr); |
137 | port_status = xhci_readl(xhci, addr); | 328 | port_status = xhci_readl(xhci, addr); |
@@ -140,7 +331,7 @@ static void xhci_disable_port(struct xhci_hcd *xhci, u16 wIndex, | |||
140 | } | 331 | } |
141 | 332 | ||
142 | static void xhci_clear_port_change_bit(struct xhci_hcd *xhci, u16 wValue, | 333 | static void xhci_clear_port_change_bit(struct xhci_hcd *xhci, u16 wValue, |
143 | u16 wIndex, u32 __iomem *addr, u32 port_status) | 334 | u16 wIndex, __le32 __iomem *addr, u32 port_status) |
144 | { | 335 | { |
145 | char *port_change_bit; | 336 | char *port_change_bit; |
146 | u32 status; | 337 | u32 status; |
@@ -150,6 +341,10 @@ static void xhci_clear_port_change_bit(struct xhci_hcd *xhci, u16 wValue, | |||
150 | status = PORT_RC; | 341 | status = PORT_RC; |
151 | port_change_bit = "reset"; | 342 | port_change_bit = "reset"; |
152 | break; | 343 | break; |
344 | case USB_PORT_FEAT_C_BH_PORT_RESET: | ||
345 | status = PORT_WRC; | ||
346 | port_change_bit = "warm(BH) reset"; | ||
347 | break; | ||
153 | case USB_PORT_FEAT_C_CONNECTION: | 348 | case USB_PORT_FEAT_C_CONNECTION: |
154 | status = PORT_CSC; | 349 | status = PORT_CSC; |
155 | port_change_bit = "connect"; | 350 | port_change_bit = "connect"; |
@@ -162,6 +357,14 @@ static void xhci_clear_port_change_bit(struct xhci_hcd *xhci, u16 wValue, | |||
162 | status = PORT_PEC; | 357 | status = PORT_PEC; |
163 | port_change_bit = "enable/disable"; | 358 | port_change_bit = "enable/disable"; |
164 | break; | 359 | break; |
360 | case USB_PORT_FEAT_C_SUSPEND: | ||
361 | status = PORT_PLC; | ||
362 | port_change_bit = "suspend/resume"; | ||
363 | break; | ||
364 | case USB_PORT_FEAT_C_PORT_LINK_STATE: | ||
365 | status = PORT_PLC; | ||
366 | port_change_bit = "link state"; | ||
367 | break; | ||
165 | default: | 368 | default: |
166 | /* Should never happen */ | 369 | /* Should never happen */ |
167 | return; | 370 | return; |
@@ -173,17 +376,37 @@ static void xhci_clear_port_change_bit(struct xhci_hcd *xhci, u16 wValue, | |||
173 | port_change_bit, wIndex, port_status); | 376 | port_change_bit, wIndex, port_status); |
174 | } | 377 | } |
175 | 378 | ||
379 | static int xhci_get_ports(struct usb_hcd *hcd, __le32 __iomem ***port_array) | ||
380 | { | ||
381 | int max_ports; | ||
382 | struct xhci_hcd *xhci = hcd_to_xhci(hcd); | ||
383 | |||
384 | if (hcd->speed == HCD_USB3) { | ||
385 | max_ports = xhci->num_usb3_ports; | ||
386 | *port_array = xhci->usb3_ports; | ||
387 | } else { | ||
388 | max_ports = xhci->num_usb2_ports; | ||
389 | *port_array = xhci->usb2_ports; | ||
390 | } | ||
391 | |||
392 | return max_ports; | ||
393 | } | ||
394 | |||
176 | int xhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue, | 395 | int xhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue, |
177 | u16 wIndex, char *buf, u16 wLength) | 396 | u16 wIndex, char *buf, u16 wLength) |
178 | { | 397 | { |
179 | struct xhci_hcd *xhci = hcd_to_xhci(hcd); | 398 | struct xhci_hcd *xhci = hcd_to_xhci(hcd); |
180 | int ports; | 399 | int max_ports; |
181 | unsigned long flags; | 400 | unsigned long flags; |
182 | u32 temp, status; | 401 | u32 temp, temp1, status; |
183 | int retval = 0; | 402 | int retval = 0; |
184 | u32 __iomem *addr; | 403 | __le32 __iomem **port_array; |
404 | int slot_id; | ||
405 | struct xhci_bus_state *bus_state; | ||
406 | u16 link_state = 0; | ||
185 | 407 | ||
186 | ports = HCS_MAX_PORTS(xhci->hcs_params1); | 408 | max_ports = xhci_get_ports(hcd, &port_array); |
409 | bus_state = &xhci->bus_state[hcd_index(hcd)]; | ||
187 | 410 | ||
188 | spin_lock_irqsave(&xhci->lock, flags); | 411 | spin_lock_irqsave(&xhci->lock, flags); |
189 | switch (typeReq) { | 412 | switch (typeReq) { |
@@ -192,15 +415,30 @@ int xhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue, | |||
192 | memset(buf, 0, 4); | 415 | memset(buf, 0, 4); |
193 | break; | 416 | break; |
194 | case GetHubDescriptor: | 417 | case GetHubDescriptor: |
195 | xhci_hub_descriptor(xhci, (struct usb_hub_descriptor *) buf); | 418 | /* Check to make sure userspace is asking for the USB 3.0 hub |
419 | * descriptor for the USB 3.0 roothub. If not, we stall the | ||
420 | * endpoint, like external hubs do. | ||
421 | */ | ||
422 | if (hcd->speed == HCD_USB3 && | ||
423 | (wLength < USB_DT_SS_HUB_SIZE || | ||
424 | wValue != (USB_DT_SS_HUB << 8))) { | ||
425 | xhci_dbg(xhci, "Wrong hub descriptor type for " | ||
426 | "USB 3.0 roothub.\n"); | ||
427 | goto error; | ||
428 | } | ||
429 | xhci_hub_descriptor(hcd, xhci, | ||
430 | (struct usb_hub_descriptor *) buf); | ||
196 | break; | 431 | break; |
197 | case GetPortStatus: | 432 | case GetPortStatus: |
198 | if (!wIndex || wIndex > ports) | 433 | if (!wIndex || wIndex > max_ports) |
199 | goto error; | 434 | goto error; |
200 | wIndex--; | 435 | wIndex--; |
201 | status = 0; | 436 | status = 0; |
202 | addr = &xhci->op_regs->port_status_base + NUM_PORT_REGS*(wIndex & 0xff); | 437 | temp = xhci_readl(xhci, port_array[wIndex]); |
203 | temp = xhci_readl(xhci, addr); | 438 | if (temp == 0xffffffff) { |
439 | retval = -ENODEV; | ||
440 | break; | ||
441 | } | ||
204 | xhci_dbg(xhci, "get port status, actual port %d status = 0x%x\n", wIndex, temp); | 442 | xhci_dbg(xhci, "get port status, actual port %d status = 0x%x\n", wIndex, temp); |
205 | 443 | ||
206 | /* wPortChange bits */ | 444 | /* wPortChange bits */ |
@@ -210,10 +448,54 @@ int xhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue, | |||
210 | status |= USB_PORT_STAT_C_ENABLE << 16; | 448 | status |= USB_PORT_STAT_C_ENABLE << 16; |
211 | if ((temp & PORT_OCC)) | 449 | if ((temp & PORT_OCC)) |
212 | status |= USB_PORT_STAT_C_OVERCURRENT << 16; | 450 | status |= USB_PORT_STAT_C_OVERCURRENT << 16; |
213 | /* | 451 | if ((temp & PORT_RC)) |
214 | * FIXME ignoring suspend, reset, and USB 2.1/3.0 specific | 452 | status |= USB_PORT_STAT_C_RESET << 16; |
215 | * changes | 453 | /* USB3.0 only */ |
216 | */ | 454 | if (hcd->speed == HCD_USB3) { |
455 | if ((temp & PORT_PLC)) | ||
456 | status |= USB_PORT_STAT_C_LINK_STATE << 16; | ||
457 | if ((temp & PORT_WRC)) | ||
458 | status |= USB_PORT_STAT_C_BH_RESET << 16; | ||
459 | } | ||
460 | |||
461 | if (hcd->speed != HCD_USB3) { | ||
462 | if ((temp & PORT_PLS_MASK) == XDEV_U3 | ||
463 | && (temp & PORT_POWER)) | ||
464 | status |= USB_PORT_STAT_SUSPEND; | ||
465 | } | ||
466 | if ((temp & PORT_PLS_MASK) == XDEV_RESUME) { | ||
467 | if ((temp & PORT_RESET) || !(temp & PORT_PE)) | ||
468 | goto error; | ||
469 | if (!DEV_SUPERSPEED(temp) && time_after_eq(jiffies, | ||
470 | bus_state->resume_done[wIndex])) { | ||
471 | xhci_dbg(xhci, "Resume USB2 port %d\n", | ||
472 | wIndex + 1); | ||
473 | bus_state->resume_done[wIndex] = 0; | ||
474 | temp1 = xhci_port_state_to_neutral(temp); | ||
475 | temp1 &= ~PORT_PLS_MASK; | ||
476 | temp1 |= PORT_LINK_STROBE | XDEV_U0; | ||
477 | xhci_writel(xhci, temp1, port_array[wIndex]); | ||
478 | |||
479 | xhci_dbg(xhci, "set port %d resume\n", | ||
480 | wIndex + 1); | ||
481 | slot_id = xhci_find_slot_id_by_port(hcd, xhci, | ||
482 | wIndex + 1); | ||
483 | if (!slot_id) { | ||
484 | xhci_dbg(xhci, "slot_id is zero\n"); | ||
485 | goto error; | ||
486 | } | ||
487 | xhci_ring_device(xhci, slot_id); | ||
488 | bus_state->port_c_suspend |= 1 << wIndex; | ||
489 | bus_state->suspended_ports &= ~(1 << wIndex); | ||
490 | } | ||
491 | } | ||
492 | if ((temp & PORT_PLS_MASK) == XDEV_U0 | ||
493 | && (temp & PORT_POWER) | ||
494 | && (bus_state->suspended_ports & (1 << wIndex))) { | ||
495 | bus_state->suspended_ports &= ~(1 << wIndex); | ||
496 | if (hcd->speed != HCD_USB3) | ||
497 | bus_state->port_c_suspend |= 1 << wIndex; | ||
498 | } | ||
217 | if (temp & PORT_CONNECT) { | 499 | if (temp & PORT_CONNECT) { |
218 | status |= USB_PORT_STAT_CONNECTION; | 500 | status |= USB_PORT_STAT_CONNECTION; |
219 | status |= xhci_port_speed(temp); | 501 | status |= xhci_port_speed(temp); |
@@ -224,20 +506,114 @@ int xhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue, | |||
224 | status |= USB_PORT_STAT_OVERCURRENT; | 506 | status |= USB_PORT_STAT_OVERCURRENT; |
225 | if (temp & PORT_RESET) | 507 | if (temp & PORT_RESET) |
226 | status |= USB_PORT_STAT_RESET; | 508 | status |= USB_PORT_STAT_RESET; |
227 | if (temp & PORT_POWER) | 509 | if (temp & PORT_POWER) { |
228 | status |= USB_PORT_STAT_POWER; | 510 | if (hcd->speed == HCD_USB3) |
511 | status |= USB_SS_PORT_STAT_POWER; | ||
512 | else | ||
513 | status |= USB_PORT_STAT_POWER; | ||
514 | } | ||
515 | /* Port Link State */ | ||
516 | if (hcd->speed == HCD_USB3) { | ||
517 | /* resume state is a xHCI internal state. | ||
518 | * Do not report it to usb core. | ||
519 | */ | ||
520 | if ((temp & PORT_PLS_MASK) != XDEV_RESUME) | ||
521 | status |= (temp & PORT_PLS_MASK); | ||
522 | } | ||
523 | if (bus_state->port_c_suspend & (1 << wIndex)) | ||
524 | status |= 1 << USB_PORT_FEAT_C_SUSPEND; | ||
229 | xhci_dbg(xhci, "Get port status returned 0x%x\n", status); | 525 | xhci_dbg(xhci, "Get port status returned 0x%x\n", status); |
230 | put_unaligned(cpu_to_le32(status), (__le32 *) buf); | 526 | put_unaligned(cpu_to_le32(status), (__le32 *) buf); |
231 | break; | 527 | break; |
232 | case SetPortFeature: | 528 | case SetPortFeature: |
529 | if (wValue == USB_PORT_FEAT_LINK_STATE) | ||
530 | link_state = (wIndex & 0xff00) >> 3; | ||
233 | wIndex &= 0xff; | 531 | wIndex &= 0xff; |
234 | if (!wIndex || wIndex > ports) | 532 | if (!wIndex || wIndex > max_ports) |
235 | goto error; | 533 | goto error; |
236 | wIndex--; | 534 | wIndex--; |
237 | addr = &xhci->op_regs->port_status_base + NUM_PORT_REGS*(wIndex & 0xff); | 535 | temp = xhci_readl(xhci, port_array[wIndex]); |
238 | temp = xhci_readl(xhci, addr); | 536 | if (temp == 0xffffffff) { |
537 | retval = -ENODEV; | ||
538 | break; | ||
539 | } | ||
239 | temp = xhci_port_state_to_neutral(temp); | 540 | temp = xhci_port_state_to_neutral(temp); |
541 | /* FIXME: What new port features do we need to support? */ | ||
240 | switch (wValue) { | 542 | switch (wValue) { |
543 | case USB_PORT_FEAT_SUSPEND: | ||
544 | temp = xhci_readl(xhci, port_array[wIndex]); | ||
545 | /* In spec software should not attempt to suspend | ||
546 | * a port unless the port reports that it is in the | ||
547 | * enabled (PED = ‘1’,PLS < ‘3’) state. | ||
548 | */ | ||
549 | if ((temp & PORT_PE) == 0 || (temp & PORT_RESET) | ||
550 | || (temp & PORT_PLS_MASK) >= XDEV_U3) { | ||
551 | xhci_warn(xhci, "USB core suspending device " | ||
552 | "not in U0/U1/U2.\n"); | ||
553 | goto error; | ||
554 | } | ||
555 | |||
556 | slot_id = xhci_find_slot_id_by_port(hcd, xhci, | ||
557 | wIndex + 1); | ||
558 | if (!slot_id) { | ||
559 | xhci_warn(xhci, "slot_id is zero\n"); | ||
560 | goto error; | ||
561 | } | ||
562 | /* unlock to execute stop endpoint commands */ | ||
563 | spin_unlock_irqrestore(&xhci->lock, flags); | ||
564 | xhci_stop_device(xhci, slot_id, 1); | ||
565 | spin_lock_irqsave(&xhci->lock, flags); | ||
566 | |||
567 | temp = xhci_port_state_to_neutral(temp); | ||
568 | temp &= ~PORT_PLS_MASK; | ||
569 | temp |= PORT_LINK_STROBE | XDEV_U3; | ||
570 | xhci_writel(xhci, temp, port_array[wIndex]); | ||
571 | |||
572 | spin_unlock_irqrestore(&xhci->lock, flags); | ||
573 | msleep(10); /* wait device to enter */ | ||
574 | spin_lock_irqsave(&xhci->lock, flags); | ||
575 | |||
576 | temp = xhci_readl(xhci, port_array[wIndex]); | ||
577 | bus_state->suspended_ports |= 1 << wIndex; | ||
578 | break; | ||
579 | case USB_PORT_FEAT_LINK_STATE: | ||
580 | temp = xhci_readl(xhci, port_array[wIndex]); | ||
581 | /* Software should not attempt to set | ||
582 | * port link state above '5' (Rx.Detect) and the port | ||
583 | * must be enabled. | ||
584 | */ | ||
585 | if ((temp & PORT_PE) == 0 || | ||
586 | (link_state > USB_SS_PORT_LS_RX_DETECT)) { | ||
587 | xhci_warn(xhci, "Cannot set link state.\n"); | ||
588 | goto error; | ||
589 | } | ||
590 | |||
591 | if (link_state == USB_SS_PORT_LS_U3) { | ||
592 | slot_id = xhci_find_slot_id_by_port(hcd, xhci, | ||
593 | wIndex + 1); | ||
594 | if (slot_id) { | ||
595 | /* unlock to execute stop endpoint | ||
596 | * commands */ | ||
597 | spin_unlock_irqrestore(&xhci->lock, | ||
598 | flags); | ||
599 | xhci_stop_device(xhci, slot_id, 1); | ||
600 | spin_lock_irqsave(&xhci->lock, flags); | ||
601 | } | ||
602 | } | ||
603 | |||
604 | temp = xhci_port_state_to_neutral(temp); | ||
605 | temp &= ~PORT_PLS_MASK; | ||
606 | temp |= PORT_LINK_STROBE | link_state; | ||
607 | xhci_writel(xhci, temp, port_array[wIndex]); | ||
608 | |||
609 | spin_unlock_irqrestore(&xhci->lock, flags); | ||
610 | msleep(20); /* wait device to enter */ | ||
611 | spin_lock_irqsave(&xhci->lock, flags); | ||
612 | |||
613 | temp = xhci_readl(xhci, port_array[wIndex]); | ||
614 | if (link_state == USB_SS_PORT_LS_U3) | ||
615 | bus_state->suspended_ports |= 1 << wIndex; | ||
616 | break; | ||
241 | case USB_PORT_FEAT_POWER: | 617 | case USB_PORT_FEAT_POWER: |
242 | /* | 618 | /* |
243 | * Turn on ports, even if there isn't per-port switching. | 619 | * Turn on ports, even if there isn't per-port switching. |
@@ -245,41 +621,96 @@ int xhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue, | |||
245 | * However, khubd will ignore the roothub events until | 621 | * However, khubd will ignore the roothub events until |
246 | * the roothub is registered. | 622 | * the roothub is registered. |
247 | */ | 623 | */ |
248 | xhci_writel(xhci, temp | PORT_POWER, addr); | 624 | xhci_writel(xhci, temp | PORT_POWER, |
625 | port_array[wIndex]); | ||
249 | 626 | ||
250 | temp = xhci_readl(xhci, addr); | 627 | temp = xhci_readl(xhci, port_array[wIndex]); |
251 | xhci_dbg(xhci, "set port power, actual port %d status = 0x%x\n", wIndex, temp); | 628 | xhci_dbg(xhci, "set port power, actual port %d status = 0x%x\n", wIndex, temp); |
252 | break; | 629 | break; |
253 | case USB_PORT_FEAT_RESET: | 630 | case USB_PORT_FEAT_RESET: |
254 | temp = (temp | PORT_RESET); | 631 | temp = (temp | PORT_RESET); |
255 | xhci_writel(xhci, temp, addr); | 632 | xhci_writel(xhci, temp, port_array[wIndex]); |
256 | 633 | ||
257 | temp = xhci_readl(xhci, addr); | 634 | temp = xhci_readl(xhci, port_array[wIndex]); |
258 | xhci_dbg(xhci, "set port reset, actual port %d status = 0x%x\n", wIndex, temp); | 635 | xhci_dbg(xhci, "set port reset, actual port %d status = 0x%x\n", wIndex, temp); |
259 | break; | 636 | break; |
637 | case USB_PORT_FEAT_BH_PORT_RESET: | ||
638 | temp |= PORT_WR; | ||
639 | xhci_writel(xhci, temp, port_array[wIndex]); | ||
640 | |||
641 | temp = xhci_readl(xhci, port_array[wIndex]); | ||
642 | break; | ||
260 | default: | 643 | default: |
261 | goto error; | 644 | goto error; |
262 | } | 645 | } |
263 | temp = xhci_readl(xhci, addr); /* unblock any posted writes */ | 646 | /* unblock any posted writes */ |
647 | temp = xhci_readl(xhci, port_array[wIndex]); | ||
264 | break; | 648 | break; |
265 | case ClearPortFeature: | 649 | case ClearPortFeature: |
266 | if (!wIndex || wIndex > ports) | 650 | if (!wIndex || wIndex > max_ports) |
267 | goto error; | 651 | goto error; |
268 | wIndex--; | 652 | wIndex--; |
269 | addr = &xhci->op_regs->port_status_base + | 653 | temp = xhci_readl(xhci, port_array[wIndex]); |
270 | NUM_PORT_REGS*(wIndex & 0xff); | 654 | if (temp == 0xffffffff) { |
271 | temp = xhci_readl(xhci, addr); | 655 | retval = -ENODEV; |
656 | break; | ||
657 | } | ||
658 | /* FIXME: What new port features do we need to support? */ | ||
272 | temp = xhci_port_state_to_neutral(temp); | 659 | temp = xhci_port_state_to_neutral(temp); |
273 | switch (wValue) { | 660 | switch (wValue) { |
661 | case USB_PORT_FEAT_SUSPEND: | ||
662 | temp = xhci_readl(xhci, port_array[wIndex]); | ||
663 | xhci_dbg(xhci, "clear USB_PORT_FEAT_SUSPEND\n"); | ||
664 | xhci_dbg(xhci, "PORTSC %04x\n", temp); | ||
665 | if (temp & PORT_RESET) | ||
666 | goto error; | ||
667 | if (temp & XDEV_U3) { | ||
668 | if ((temp & PORT_PE) == 0) | ||
669 | goto error; | ||
670 | |||
671 | temp = xhci_port_state_to_neutral(temp); | ||
672 | temp &= ~PORT_PLS_MASK; | ||
673 | temp |= PORT_LINK_STROBE | XDEV_RESUME; | ||
674 | xhci_writel(xhci, temp, | ||
675 | port_array[wIndex]); | ||
676 | |||
677 | spin_unlock_irqrestore(&xhci->lock, | ||
678 | flags); | ||
679 | msleep(20); | ||
680 | spin_lock_irqsave(&xhci->lock, flags); | ||
681 | |||
682 | temp = xhci_readl(xhci, | ||
683 | port_array[wIndex]); | ||
684 | temp = xhci_port_state_to_neutral(temp); | ||
685 | temp &= ~PORT_PLS_MASK; | ||
686 | temp |= PORT_LINK_STROBE | XDEV_U0; | ||
687 | xhci_writel(xhci, temp, | ||
688 | port_array[wIndex]); | ||
689 | } | ||
690 | bus_state->port_c_suspend |= 1 << wIndex; | ||
691 | |||
692 | slot_id = xhci_find_slot_id_by_port(hcd, xhci, | ||
693 | wIndex + 1); | ||
694 | if (!slot_id) { | ||
695 | xhci_dbg(xhci, "slot_id is zero\n"); | ||
696 | goto error; | ||
697 | } | ||
698 | xhci_ring_device(xhci, slot_id); | ||
699 | break; | ||
700 | case USB_PORT_FEAT_C_SUSPEND: | ||
701 | bus_state->port_c_suspend &= ~(1 << wIndex); | ||
274 | case USB_PORT_FEAT_C_RESET: | 702 | case USB_PORT_FEAT_C_RESET: |
703 | case USB_PORT_FEAT_C_BH_PORT_RESET: | ||
275 | case USB_PORT_FEAT_C_CONNECTION: | 704 | case USB_PORT_FEAT_C_CONNECTION: |
276 | case USB_PORT_FEAT_C_OVER_CURRENT: | 705 | case USB_PORT_FEAT_C_OVER_CURRENT: |
277 | case USB_PORT_FEAT_C_ENABLE: | 706 | case USB_PORT_FEAT_C_ENABLE: |
707 | case USB_PORT_FEAT_C_PORT_LINK_STATE: | ||
278 | xhci_clear_port_change_bit(xhci, wValue, wIndex, | 708 | xhci_clear_port_change_bit(xhci, wValue, wIndex, |
279 | addr, temp); | 709 | port_array[wIndex], temp); |
280 | break; | 710 | break; |
281 | case USB_PORT_FEAT_ENABLE: | 711 | case USB_PORT_FEAT_ENABLE: |
282 | xhci_disable_port(xhci, wIndex, addr, temp); | 712 | xhci_disable_port(hcd, xhci, wIndex, |
713 | port_array[wIndex], temp); | ||
283 | break; | 714 | break; |
284 | default: | 715 | default: |
285 | goto error; | 716 | goto error; |
@@ -306,25 +737,35 @@ int xhci_hub_status_data(struct usb_hcd *hcd, char *buf) | |||
306 | { | 737 | { |
307 | unsigned long flags; | 738 | unsigned long flags; |
308 | u32 temp, status; | 739 | u32 temp, status; |
740 | u32 mask; | ||
309 | int i, retval; | 741 | int i, retval; |
310 | struct xhci_hcd *xhci = hcd_to_xhci(hcd); | 742 | struct xhci_hcd *xhci = hcd_to_xhci(hcd); |
311 | int ports; | 743 | int max_ports; |
312 | u32 __iomem *addr; | 744 | __le32 __iomem **port_array; |
745 | struct xhci_bus_state *bus_state; | ||
313 | 746 | ||
314 | ports = HCS_MAX_PORTS(xhci->hcs_params1); | 747 | max_ports = xhci_get_ports(hcd, &port_array); |
748 | bus_state = &xhci->bus_state[hcd_index(hcd)]; | ||
315 | 749 | ||
316 | /* Initial status is no changes */ | 750 | /* Initial status is no changes */ |
317 | retval = (ports + 8) / 8; | 751 | retval = (max_ports + 8) / 8; |
318 | memset(buf, 0, retval); | 752 | memset(buf, 0, retval); |
319 | status = 0; | 753 | status = 0; |
320 | 754 | ||
755 | mask = PORT_CSC | PORT_PEC | PORT_OCC | PORT_PLC; | ||
756 | |||
321 | spin_lock_irqsave(&xhci->lock, flags); | 757 | spin_lock_irqsave(&xhci->lock, flags); |
322 | /* For each port, did anything change? If so, set that bit in buf. */ | 758 | /* For each port, did anything change? If so, set that bit in buf. */ |
323 | for (i = 0; i < ports; i++) { | 759 | for (i = 0; i < max_ports; i++) { |
324 | addr = &xhci->op_regs->port_status_base + | 760 | temp = xhci_readl(xhci, port_array[i]); |
325 | NUM_PORT_REGS*i; | 761 | if (temp == 0xffffffff) { |
326 | temp = xhci_readl(xhci, addr); | 762 | retval = -ENODEV; |
327 | if (temp & (PORT_CSC | PORT_PEC | PORT_OCC)) { | 763 | break; |
764 | } | ||
765 | if ((temp & mask) != 0 || | ||
766 | (bus_state->port_c_suspend & 1 << i) || | ||
767 | (bus_state->resume_done[i] && time_after_eq( | ||
768 | jiffies, bus_state->resume_done[i]))) { | ||
328 | buf[(i + 1) / 8] |= 1 << (i + 1) % 8; | 769 | buf[(i + 1) / 8] |= 1 << (i + 1) % 8; |
329 | status = 1; | 770 | status = 1; |
330 | } | 771 | } |
@@ -332,3 +773,202 @@ int xhci_hub_status_data(struct usb_hcd *hcd, char *buf) | |||
332 | spin_unlock_irqrestore(&xhci->lock, flags); | 773 | spin_unlock_irqrestore(&xhci->lock, flags); |
333 | return status ? retval : 0; | 774 | return status ? retval : 0; |
334 | } | 775 | } |
776 | |||
777 | #ifdef CONFIG_PM | ||
778 | |||
779 | int xhci_bus_suspend(struct usb_hcd *hcd) | ||
780 | { | ||
781 | struct xhci_hcd *xhci = hcd_to_xhci(hcd); | ||
782 | int max_ports, port_index; | ||
783 | __le32 __iomem **port_array; | ||
784 | struct xhci_bus_state *bus_state; | ||
785 | unsigned long flags; | ||
786 | |||
787 | max_ports = xhci_get_ports(hcd, &port_array); | ||
788 | bus_state = &xhci->bus_state[hcd_index(hcd)]; | ||
789 | |||
790 | spin_lock_irqsave(&xhci->lock, flags); | ||
791 | |||
792 | if (hcd->self.root_hub->do_remote_wakeup) { | ||
793 | port_index = max_ports; | ||
794 | while (port_index--) { | ||
795 | if (bus_state->resume_done[port_index] != 0) { | ||
796 | spin_unlock_irqrestore(&xhci->lock, flags); | ||
797 | xhci_dbg(xhci, "suspend failed because " | ||
798 | "port %d is resuming\n", | ||
799 | port_index + 1); | ||
800 | return -EBUSY; | ||
801 | } | ||
802 | } | ||
803 | } | ||
804 | |||
805 | port_index = max_ports; | ||
806 | bus_state->bus_suspended = 0; | ||
807 | while (port_index--) { | ||
808 | /* suspend the port if the port is not suspended */ | ||
809 | u32 t1, t2; | ||
810 | int slot_id; | ||
811 | |||
812 | t1 = xhci_readl(xhci, port_array[port_index]); | ||
813 | t2 = xhci_port_state_to_neutral(t1); | ||
814 | |||
815 | if ((t1 & PORT_PE) && !(t1 & PORT_PLS_MASK)) { | ||
816 | xhci_dbg(xhci, "port %d not suspended\n", port_index); | ||
817 | slot_id = xhci_find_slot_id_by_port(hcd, xhci, | ||
818 | port_index + 1); | ||
819 | if (slot_id) { | ||
820 | spin_unlock_irqrestore(&xhci->lock, flags); | ||
821 | xhci_stop_device(xhci, slot_id, 1); | ||
822 | spin_lock_irqsave(&xhci->lock, flags); | ||
823 | } | ||
824 | t2 &= ~PORT_PLS_MASK; | ||
825 | t2 |= PORT_LINK_STROBE | XDEV_U3; | ||
826 | set_bit(port_index, &bus_state->bus_suspended); | ||
827 | } | ||
828 | if (hcd->self.root_hub->do_remote_wakeup) { | ||
829 | if (t1 & PORT_CONNECT) { | ||
830 | t2 |= PORT_WKOC_E | PORT_WKDISC_E; | ||
831 | t2 &= ~PORT_WKCONN_E; | ||
832 | } else { | ||
833 | t2 |= PORT_WKOC_E | PORT_WKCONN_E; | ||
834 | t2 &= ~PORT_WKDISC_E; | ||
835 | } | ||
836 | } else | ||
837 | t2 &= ~PORT_WAKE_BITS; | ||
838 | |||
839 | t1 = xhci_port_state_to_neutral(t1); | ||
840 | if (t1 != t2) | ||
841 | xhci_writel(xhci, t2, port_array[port_index]); | ||
842 | |||
843 | if (hcd->speed != HCD_USB3) { | ||
844 | /* enable remote wake up for USB 2.0 */ | ||
845 | __le32 __iomem *addr; | ||
846 | u32 tmp; | ||
847 | |||
848 | /* Add one to the port status register address to get | ||
849 | * the port power control register address. | ||
850 | */ | ||
851 | addr = port_array[port_index] + 1; | ||
852 | tmp = xhci_readl(xhci, addr); | ||
853 | tmp |= PORT_RWE; | ||
854 | xhci_writel(xhci, tmp, addr); | ||
855 | } | ||
856 | } | ||
857 | hcd->state = HC_STATE_SUSPENDED; | ||
858 | bus_state->next_statechange = jiffies + msecs_to_jiffies(10); | ||
859 | spin_unlock_irqrestore(&xhci->lock, flags); | ||
860 | return 0; | ||
861 | } | ||
862 | |||
863 | int xhci_bus_resume(struct usb_hcd *hcd) | ||
864 | { | ||
865 | struct xhci_hcd *xhci = hcd_to_xhci(hcd); | ||
866 | int max_ports, port_index; | ||
867 | __le32 __iomem **port_array; | ||
868 | struct xhci_bus_state *bus_state; | ||
869 | u32 temp; | ||
870 | unsigned long flags; | ||
871 | |||
872 | max_ports = xhci_get_ports(hcd, &port_array); | ||
873 | bus_state = &xhci->bus_state[hcd_index(hcd)]; | ||
874 | |||
875 | if (time_before(jiffies, bus_state->next_statechange)) | ||
876 | msleep(5); | ||
877 | |||
878 | spin_lock_irqsave(&xhci->lock, flags); | ||
879 | if (!HCD_HW_ACCESSIBLE(hcd)) { | ||
880 | spin_unlock_irqrestore(&xhci->lock, flags); | ||
881 | return -ESHUTDOWN; | ||
882 | } | ||
883 | |||
884 | /* delay the irqs */ | ||
885 | temp = xhci_readl(xhci, &xhci->op_regs->command); | ||
886 | temp &= ~CMD_EIE; | ||
887 | xhci_writel(xhci, temp, &xhci->op_regs->command); | ||
888 | |||
889 | port_index = max_ports; | ||
890 | while (port_index--) { | ||
891 | /* Check whether need resume ports. If needed | ||
892 | resume port and disable remote wakeup */ | ||
893 | u32 temp; | ||
894 | int slot_id; | ||
895 | |||
896 | temp = xhci_readl(xhci, port_array[port_index]); | ||
897 | if (DEV_SUPERSPEED(temp)) | ||
898 | temp &= ~(PORT_RWC_BITS | PORT_CEC | PORT_WAKE_BITS); | ||
899 | else | ||
900 | temp &= ~(PORT_RWC_BITS | PORT_WAKE_BITS); | ||
901 | if (test_bit(port_index, &bus_state->bus_suspended) && | ||
902 | (temp & PORT_PLS_MASK)) { | ||
903 | if (DEV_SUPERSPEED(temp)) { | ||
904 | temp = xhci_port_state_to_neutral(temp); | ||
905 | temp &= ~PORT_PLS_MASK; | ||
906 | temp |= PORT_LINK_STROBE | XDEV_U0; | ||
907 | xhci_writel(xhci, temp, port_array[port_index]); | ||
908 | } else { | ||
909 | temp = xhci_port_state_to_neutral(temp); | ||
910 | temp &= ~PORT_PLS_MASK; | ||
911 | temp |= PORT_LINK_STROBE | XDEV_RESUME; | ||
912 | xhci_writel(xhci, temp, port_array[port_index]); | ||
913 | |||
914 | spin_unlock_irqrestore(&xhci->lock, flags); | ||
915 | msleep(20); | ||
916 | spin_lock_irqsave(&xhci->lock, flags); | ||
917 | |||
918 | temp = xhci_readl(xhci, port_array[port_index]); | ||
919 | temp = xhci_port_state_to_neutral(temp); | ||
920 | temp &= ~PORT_PLS_MASK; | ||
921 | temp |= PORT_LINK_STROBE | XDEV_U0; | ||
922 | xhci_writel(xhci, temp, port_array[port_index]); | ||
923 | } | ||
924 | /* wait for the port to enter U0 and report port link | ||
925 | * state change. | ||
926 | */ | ||
927 | spin_unlock_irqrestore(&xhci->lock, flags); | ||
928 | msleep(20); | ||
929 | spin_lock_irqsave(&xhci->lock, flags); | ||
930 | |||
931 | /* Clear PLC */ | ||
932 | temp = xhci_readl(xhci, port_array[port_index]); | ||
933 | if (temp & PORT_PLC) { | ||
934 | temp = xhci_port_state_to_neutral(temp); | ||
935 | temp |= PORT_PLC; | ||
936 | xhci_writel(xhci, temp, port_array[port_index]); | ||
937 | } | ||
938 | |||
939 | slot_id = xhci_find_slot_id_by_port(hcd, | ||
940 | xhci, port_index + 1); | ||
941 | if (slot_id) | ||
942 | xhci_ring_device(xhci, slot_id); | ||
943 | } else | ||
944 | xhci_writel(xhci, temp, port_array[port_index]); | ||
945 | |||
946 | if (hcd->speed != HCD_USB3) { | ||
947 | /* disable remote wake up for USB 2.0 */ | ||
948 | __le32 __iomem *addr; | ||
949 | u32 tmp; | ||
950 | |||
951 | /* Add one to the port status register address to get | ||
952 | * the port power control register address. | ||
953 | */ | ||
954 | addr = port_array[port_index] + 1; | ||
955 | tmp = xhci_readl(xhci, addr); | ||
956 | tmp &= ~PORT_RWE; | ||
957 | xhci_writel(xhci, tmp, addr); | ||
958 | } | ||
959 | } | ||
960 | |||
961 | (void) xhci_readl(xhci, &xhci->op_regs->command); | ||
962 | |||
963 | bus_state->next_statechange = jiffies + msecs_to_jiffies(5); | ||
964 | /* re-enable irqs */ | ||
965 | temp = xhci_readl(xhci, &xhci->op_regs->command); | ||
966 | temp |= CMD_EIE; | ||
967 | xhci_writel(xhci, temp, &xhci->op_regs->command); | ||
968 | temp = xhci_readl(xhci, &xhci->op_regs->command); | ||
969 | |||
970 | spin_unlock_irqrestore(&xhci->lock, flags); | ||
971 | return 0; | ||
972 | } | ||
973 | |||
974 | #endif /* CONFIG_PM */ | ||