aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb
diff options
context:
space:
mode:
authorSarah Sharp <sarah.a.sharp@linux.intel.com>2010-12-01 14:34:59 -0500
committerSarah Sharp <sarah.a.sharp@linux.intel.com>2011-03-13 21:23:35 -0400
commit5308a91b9fc1a8f94b860c2589b06908a97cba7e (patch)
tree4f97e7ea4c3280b367b951ea3b1d3f07c22c1b46 /drivers/usb
parentff9d78b36f76687c91c67b9f4c5c33bc888ed2f9 (diff)
xhci: Index with a port array instead of PORTSC addresses.
In the upcoming patches, the roothub emulation code will need to return port status and port change buffers based on whether they are called with the xHCI USB 2.0 or USB 3.0 roothub. To facilitate that, make the roothub code index into an array of port addresses with wIndex, rather than calculating the address using the offset and the address of the PORTSC registers. Later we can set the port array to be the array of USB 3.0 port addresses, or the USB 2.0 port addresses, depending on the roothub passed in. Create a temporary (statically sized) port array and fill it in with both USB 3.0 and USB 2.0 port addresses. This is inefficient to do for every roothub call, but this is needed for git bisect compatibility. The temporary port array will be deleted in a subsequent patch. Signed-off-by: Sarah Sharp <sarah.a.sharp@linux.intel.com>
Diffstat (limited to 'drivers/usb')
-rw-r--r--drivers/usb/host/xhci-hub.c126
-rw-r--r--drivers/usb/host/xhci-ring.c22
2 files changed, 95 insertions, 53 deletions
diff --git a/drivers/usb/host/xhci-hub.c b/drivers/usb/host/xhci-hub.c
index 847b071b6fc9..89ff025b41be 100644
--- a/drivers/usb/host/xhci-hub.c
+++ b/drivers/usb/host/xhci-hub.c
@@ -288,10 +288,18 @@ int xhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue,
288 unsigned long flags; 288 unsigned long flags;
289 u32 temp, temp1, status; 289 u32 temp, temp1, status;
290 int retval = 0; 290 int retval = 0;
291 u32 __iomem *addr; 291 u32 __iomem *port_array[15 + USB_MAXCHILDREN];
292 int i;
292 int slot_id; 293 int slot_id;
293 294
294 ports = HCS_MAX_PORTS(xhci->hcs_params1); 295 ports = HCS_MAX_PORTS(xhci->hcs_params1);
296 for (i = 0; i < ports; i++) {
297 if (i < xhci->num_usb3_ports)
298 port_array[i] = xhci->usb3_ports[i];
299 else
300 port_array[i] =
301 xhci->usb2_ports[i - xhci->num_usb3_ports];
302 }
295 303
296 spin_lock_irqsave(&xhci->lock, flags); 304 spin_lock_irqsave(&xhci->lock, flags);
297 switch (typeReq) { 305 switch (typeReq) {
@@ -307,8 +315,7 @@ int xhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue,
307 goto error; 315 goto error;
308 wIndex--; 316 wIndex--;
309 status = 0; 317 status = 0;
310 addr = &xhci->op_regs->port_status_base + NUM_PORT_REGS*(wIndex & 0xff); 318 temp = xhci_readl(xhci, port_array[wIndex]);
311 temp = xhci_readl(xhci, addr);
312 xhci_dbg(xhci, "get port status, actual port %d status = 0x%x\n", wIndex, temp); 319 xhci_dbg(xhci, "get port status, actual port %d status = 0x%x\n", wIndex, temp);
313 320
314 /* wPortChange bits */ 321 /* wPortChange bits */
@@ -336,7 +343,7 @@ int xhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue,
336 temp1 = xhci_port_state_to_neutral(temp); 343 temp1 = xhci_port_state_to_neutral(temp);
337 temp1 &= ~PORT_PLS_MASK; 344 temp1 &= ~PORT_PLS_MASK;
338 temp1 |= PORT_LINK_STROBE | XDEV_U0; 345 temp1 |= PORT_LINK_STROBE | XDEV_U0;
339 xhci_writel(xhci, temp1, addr); 346 xhci_writel(xhci, temp1, port_array[wIndex]);
340 347
341 xhci_dbg(xhci, "set port %d resume\n", 348 xhci_dbg(xhci, "set port %d resume\n",
342 wIndex + 1); 349 wIndex + 1);
@@ -379,12 +386,11 @@ int xhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue,
379 if (!wIndex || wIndex > ports) 386 if (!wIndex || wIndex > ports)
380 goto error; 387 goto error;
381 wIndex--; 388 wIndex--;
382 addr = &xhci->op_regs->port_status_base + NUM_PORT_REGS*(wIndex & 0xff); 389 temp = xhci_readl(xhci, port_array[wIndex]);
383 temp = xhci_readl(xhci, addr);
384 temp = xhci_port_state_to_neutral(temp); 390 temp = xhci_port_state_to_neutral(temp);
385 switch (wValue) { 391 switch (wValue) {
386 case USB_PORT_FEAT_SUSPEND: 392 case USB_PORT_FEAT_SUSPEND:
387 temp = xhci_readl(xhci, addr); 393 temp = xhci_readl(xhci, port_array[wIndex]);
388 /* In spec software should not attempt to suspend 394 /* In spec software should not attempt to suspend
389 * a port unless the port reports that it is in the 395 * a port unless the port reports that it is in the
390 * enabled (PED = ‘1’,PLS < ‘3’) state. 396 * enabled (PED = ‘1’,PLS < ‘3’) state.
@@ -409,13 +415,13 @@ int xhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue,
409 temp = xhci_port_state_to_neutral(temp); 415 temp = xhci_port_state_to_neutral(temp);
410 temp &= ~PORT_PLS_MASK; 416 temp &= ~PORT_PLS_MASK;
411 temp |= PORT_LINK_STROBE | XDEV_U3; 417 temp |= PORT_LINK_STROBE | XDEV_U3;
412 xhci_writel(xhci, temp, addr); 418 xhci_writel(xhci, temp, port_array[wIndex]);
413 419
414 spin_unlock_irqrestore(&xhci->lock, flags); 420 spin_unlock_irqrestore(&xhci->lock, flags);
415 msleep(10); /* wait device to enter */ 421 msleep(10); /* wait device to enter */
416 spin_lock_irqsave(&xhci->lock, flags); 422 spin_lock_irqsave(&xhci->lock, flags);
417 423
418 temp = xhci_readl(xhci, addr); 424 temp = xhci_readl(xhci, port_array[wIndex]);
419 xhci->suspended_ports |= 1 << wIndex; 425 xhci->suspended_ports |= 1 << wIndex;
420 break; 426 break;
421 case USB_PORT_FEAT_POWER: 427 case USB_PORT_FEAT_POWER:
@@ -425,34 +431,34 @@ int xhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue,
425 * However, khubd will ignore the roothub events until 431 * However, khubd will ignore the roothub events until
426 * the roothub is registered. 432 * the roothub is registered.
427 */ 433 */
428 xhci_writel(xhci, temp | PORT_POWER, addr); 434 xhci_writel(xhci, temp | PORT_POWER,
435 port_array[wIndex]);
429 436
430 temp = xhci_readl(xhci, addr); 437 temp = xhci_readl(xhci, port_array[wIndex]);
431 xhci_dbg(xhci, "set port power, actual port %d status = 0x%x\n", wIndex, temp); 438 xhci_dbg(xhci, "set port power, actual port %d status = 0x%x\n", wIndex, temp);
432 break; 439 break;
433 case USB_PORT_FEAT_RESET: 440 case USB_PORT_FEAT_RESET:
434 temp = (temp | PORT_RESET); 441 temp = (temp | PORT_RESET);
435 xhci_writel(xhci, temp, addr); 442 xhci_writel(xhci, temp, port_array[wIndex]);
436 443
437 temp = xhci_readl(xhci, addr); 444 temp = xhci_readl(xhci, port_array[wIndex]);
438 xhci_dbg(xhci, "set port reset, actual port %d status = 0x%x\n", wIndex, temp); 445 xhci_dbg(xhci, "set port reset, actual port %d status = 0x%x\n", wIndex, temp);
439 break; 446 break;
440 default: 447 default:
441 goto error; 448 goto error;
442 } 449 }
443 temp = xhci_readl(xhci, addr); /* unblock any posted writes */ 450 /* unblock any posted writes */
451 temp = xhci_readl(xhci, port_array[wIndex]);
444 break; 452 break;
445 case ClearPortFeature: 453 case ClearPortFeature:
446 if (!wIndex || wIndex > ports) 454 if (!wIndex || wIndex > ports)
447 goto error; 455 goto error;
448 wIndex--; 456 wIndex--;
449 addr = &xhci->op_regs->port_status_base + 457 temp = xhci_readl(xhci, port_array[wIndex]);
450 NUM_PORT_REGS*(wIndex & 0xff);
451 temp = xhci_readl(xhci, addr);
452 temp = xhci_port_state_to_neutral(temp); 458 temp = xhci_port_state_to_neutral(temp);
453 switch (wValue) { 459 switch (wValue) {
454 case USB_PORT_FEAT_SUSPEND: 460 case USB_PORT_FEAT_SUSPEND:
455 temp = xhci_readl(xhci, addr); 461 temp = xhci_readl(xhci, port_array[wIndex]);
456 xhci_dbg(xhci, "clear USB_PORT_FEAT_SUSPEND\n"); 462 xhci_dbg(xhci, "clear USB_PORT_FEAT_SUSPEND\n");
457 xhci_dbg(xhci, "PORTSC %04x\n", temp); 463 xhci_dbg(xhci, "PORTSC %04x\n", temp);
458 if (temp & PORT_RESET) 464 if (temp & PORT_RESET)
@@ -464,24 +470,28 @@ int xhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue,
464 temp = xhci_port_state_to_neutral(temp); 470 temp = xhci_port_state_to_neutral(temp);
465 temp &= ~PORT_PLS_MASK; 471 temp &= ~PORT_PLS_MASK;
466 temp |= PORT_LINK_STROBE | XDEV_U0; 472 temp |= PORT_LINK_STROBE | XDEV_U0;
467 xhci_writel(xhci, temp, addr); 473 xhci_writel(xhci, temp,
468 xhci_readl(xhci, addr); 474 port_array[wIndex]);
475 xhci_readl(xhci, port_array[wIndex]);
469 } else { 476 } else {
470 temp = xhci_port_state_to_neutral(temp); 477 temp = xhci_port_state_to_neutral(temp);
471 temp &= ~PORT_PLS_MASK; 478 temp &= ~PORT_PLS_MASK;
472 temp |= PORT_LINK_STROBE | XDEV_RESUME; 479 temp |= PORT_LINK_STROBE | XDEV_RESUME;
473 xhci_writel(xhci, temp, addr); 480 xhci_writel(xhci, temp,
481 port_array[wIndex]);
474 482
475 spin_unlock_irqrestore(&xhci->lock, 483 spin_unlock_irqrestore(&xhci->lock,
476 flags); 484 flags);
477 msleep(20); 485 msleep(20);
478 spin_lock_irqsave(&xhci->lock, flags); 486 spin_lock_irqsave(&xhci->lock, flags);
479 487
480 temp = xhci_readl(xhci, addr); 488 temp = xhci_readl(xhci,
489 port_array[wIndex]);
481 temp = xhci_port_state_to_neutral(temp); 490 temp = xhci_port_state_to_neutral(temp);
482 temp &= ~PORT_PLS_MASK; 491 temp &= ~PORT_PLS_MASK;
483 temp |= PORT_LINK_STROBE | XDEV_U0; 492 temp |= PORT_LINK_STROBE | XDEV_U0;
484 xhci_writel(xhci, temp, addr); 493 xhci_writel(xhci, temp,
494 port_array[wIndex]);
485 } 495 }
486 xhci->port_c_suspend |= 1 << wIndex; 496 xhci->port_c_suspend |= 1 << wIndex;
487 } 497 }
@@ -500,10 +510,11 @@ int xhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue,
500 case USB_PORT_FEAT_C_OVER_CURRENT: 510 case USB_PORT_FEAT_C_OVER_CURRENT:
501 case USB_PORT_FEAT_C_ENABLE: 511 case USB_PORT_FEAT_C_ENABLE:
502 xhci_clear_port_change_bit(xhci, wValue, wIndex, 512 xhci_clear_port_change_bit(xhci, wValue, wIndex,
503 addr, temp); 513 port_array[wIndex], temp);
504 break; 514 break;
505 case USB_PORT_FEAT_ENABLE: 515 case USB_PORT_FEAT_ENABLE:
506 xhci_disable_port(xhci, wIndex, addr, temp); 516 xhci_disable_port(xhci, wIndex,
517 port_array[wIndex], temp);
507 break; 518 break;
508 default: 519 default:
509 goto error; 520 goto error;
@@ -534,9 +545,16 @@ int xhci_hub_status_data(struct usb_hcd *hcd, char *buf)
534 int i, retval; 545 int i, retval;
535 struct xhci_hcd *xhci = hcd_to_xhci(hcd); 546 struct xhci_hcd *xhci = hcd_to_xhci(hcd);
536 int ports; 547 int ports;
537 u32 __iomem *addr; 548 u32 __iomem *port_array[15 + USB_MAXCHILDREN];
538 549
539 ports = HCS_MAX_PORTS(xhci->hcs_params1); 550 ports = HCS_MAX_PORTS(xhci->hcs_params1);
551 for (i = 0; i < ports; i++) {
552 if (i < xhci->num_usb3_ports)
553 port_array[i] = xhci->usb3_ports[i];
554 else
555 port_array[i] =
556 xhci->usb2_ports[i - xhci->num_usb3_ports];
557 }
540 558
541 /* Initial status is no changes */ 559 /* Initial status is no changes */
542 retval = (ports + 8) / 8; 560 retval = (ports + 8) / 8;
@@ -548,9 +566,7 @@ int xhci_hub_status_data(struct usb_hcd *hcd, char *buf)
548 spin_lock_irqsave(&xhci->lock, flags); 566 spin_lock_irqsave(&xhci->lock, flags);
549 /* For each port, did anything change? If so, set that bit in buf. */ 567 /* For each port, did anything change? If so, set that bit in buf. */
550 for (i = 0; i < ports; i++) { 568 for (i = 0; i < ports; i++) {
551 addr = &xhci->op_regs->port_status_base + 569 temp = xhci_readl(xhci, port_array[i]);
552 NUM_PORT_REGS*i;
553 temp = xhci_readl(xhci, addr);
554 if ((temp & mask) != 0 || 570 if ((temp & mask) != 0 ||
555 (xhci->port_c_suspend & 1 << i) || 571 (xhci->port_c_suspend & 1 << i) ||
556 (xhci->resume_done[i] && time_after_eq( 572 (xhci->resume_done[i] && time_after_eq(
@@ -569,10 +585,19 @@ int xhci_bus_suspend(struct usb_hcd *hcd)
569{ 585{
570 struct xhci_hcd *xhci = hcd_to_xhci(hcd); 586 struct xhci_hcd *xhci = hcd_to_xhci(hcd);
571 int max_ports, port_index; 587 int max_ports, port_index;
588 u32 __iomem *port_array[15 + USB_MAXCHILDREN];
589 int i;
572 unsigned long flags; 590 unsigned long flags;
573 591
574 xhci_dbg(xhci, "suspend root hub\n"); 592 xhci_dbg(xhci, "suspend root hub\n");
575 max_ports = HCS_MAX_PORTS(xhci->hcs_params1); 593 max_ports = HCS_MAX_PORTS(xhci->hcs_params1);
594 for (i = 0; i < max_ports; i++) {
595 if (i < xhci->num_usb3_ports)
596 port_array[i] = xhci->usb3_ports[i];
597 else
598 port_array[i] =
599 xhci->usb2_ports[i - xhci->num_usb3_ports];
600 }
576 601
577 spin_lock_irqsave(&xhci->lock, flags); 602 spin_lock_irqsave(&xhci->lock, flags);
578 603
@@ -593,13 +618,10 @@ int xhci_bus_suspend(struct usb_hcd *hcd)
593 xhci->bus_suspended = 0; 618 xhci->bus_suspended = 0;
594 while (port_index--) { 619 while (port_index--) {
595 /* suspend the port if the port is not suspended */ 620 /* suspend the port if the port is not suspended */
596 u32 __iomem *addr;
597 u32 t1, t2; 621 u32 t1, t2;
598 int slot_id; 622 int slot_id;
599 623
600 addr = &xhci->op_regs->port_status_base + 624 t1 = xhci_readl(xhci, port_array[port_index]);
601 NUM_PORT_REGS * (port_index & 0xff);
602 t1 = xhci_readl(xhci, addr);
603 t2 = xhci_port_state_to_neutral(t1); 625 t2 = xhci_port_state_to_neutral(t1);
604 626
605 if ((t1 & PORT_PE) && !(t1 & PORT_PLS_MASK)) { 627 if ((t1 & PORT_PE) && !(t1 & PORT_PLS_MASK)) {
@@ -628,15 +650,17 @@ int xhci_bus_suspend(struct usb_hcd *hcd)
628 650
629 t1 = xhci_port_state_to_neutral(t1); 651 t1 = xhci_port_state_to_neutral(t1);
630 if (t1 != t2) 652 if (t1 != t2)
631 xhci_writel(xhci, t2, addr); 653 xhci_writel(xhci, t2, port_array[port_index]);
632 654
633 if (DEV_HIGHSPEED(t1)) { 655 if (DEV_HIGHSPEED(t1)) {
634 /* enable remote wake up for USB 2.0 */ 656 /* enable remote wake up for USB 2.0 */
635 u32 __iomem *addr; 657 u32 __iomem *addr;
636 u32 tmp; 658 u32 tmp;
637 659
638 addr = &xhci->op_regs->port_power_base + 660 /* Add one to the port status register address to get
639 NUM_PORT_REGS * (port_index & 0xff); 661 * the port power control register address.
662 */
663 addr = port_array[port_index] + 1;
640 tmp = xhci_readl(xhci, addr); 664 tmp = xhci_readl(xhci, addr);
641 tmp |= PORT_RWE; 665 tmp |= PORT_RWE;
642 xhci_writel(xhci, tmp, addr); 666 xhci_writel(xhci, tmp, addr);
@@ -652,11 +676,20 @@ int xhci_bus_resume(struct usb_hcd *hcd)
652{ 676{
653 struct xhci_hcd *xhci = hcd_to_xhci(hcd); 677 struct xhci_hcd *xhci = hcd_to_xhci(hcd);
654 int max_ports, port_index; 678 int max_ports, port_index;
679 u32 __iomem *port_array[15 + USB_MAXCHILDREN];
680 int i;
655 u32 temp; 681 u32 temp;
656 unsigned long flags; 682 unsigned long flags;
657 683
658 xhci_dbg(xhci, "resume root hub\n"); 684 xhci_dbg(xhci, "resume root hub\n");
659 max_ports = HCS_MAX_PORTS(xhci->hcs_params1); 685 max_ports = HCS_MAX_PORTS(xhci->hcs_params1);
686 for (i = 0; i < max_ports; i++) {
687 if (i < xhci->num_usb3_ports)
688 port_array[i] = xhci->usb3_ports[i];
689 else
690 port_array[i] =
691 xhci->usb2_ports[i - xhci->num_usb3_ports];
692 }
660 693
661 if (time_before(jiffies, xhci->next_statechange)) 694 if (time_before(jiffies, xhci->next_statechange))
662 msleep(5); 695 msleep(5);
@@ -676,13 +709,10 @@ int xhci_bus_resume(struct usb_hcd *hcd)
676 while (port_index--) { 709 while (port_index--) {
677 /* Check whether need resume ports. If needed 710 /* Check whether need resume ports. If needed
678 resume port and disable remote wakeup */ 711 resume port and disable remote wakeup */
679 u32 __iomem *addr;
680 u32 temp; 712 u32 temp;
681 int slot_id; 713 int slot_id;
682 714
683 addr = &xhci->op_regs->port_status_base + 715 temp = xhci_readl(xhci, port_array[port_index]);
684 NUM_PORT_REGS * (port_index & 0xff);
685 temp = xhci_readl(xhci, addr);
686 if (DEV_SUPERSPEED(temp)) 716 if (DEV_SUPERSPEED(temp))
687 temp &= ~(PORT_RWC_BITS | PORT_CEC | PORT_WAKE_BITS); 717 temp &= ~(PORT_RWC_BITS | PORT_CEC | PORT_WAKE_BITS);
688 else 718 else
@@ -693,36 +723,38 @@ int xhci_bus_resume(struct usb_hcd *hcd)
693 temp = xhci_port_state_to_neutral(temp); 723 temp = xhci_port_state_to_neutral(temp);
694 temp &= ~PORT_PLS_MASK; 724 temp &= ~PORT_PLS_MASK;
695 temp |= PORT_LINK_STROBE | XDEV_U0; 725 temp |= PORT_LINK_STROBE | XDEV_U0;
696 xhci_writel(xhci, temp, addr); 726 xhci_writel(xhci, temp, port_array[port_index]);
697 } else { 727 } else {
698 temp = xhci_port_state_to_neutral(temp); 728 temp = xhci_port_state_to_neutral(temp);
699 temp &= ~PORT_PLS_MASK; 729 temp &= ~PORT_PLS_MASK;
700 temp |= PORT_LINK_STROBE | XDEV_RESUME; 730 temp |= PORT_LINK_STROBE | XDEV_RESUME;
701 xhci_writel(xhci, temp, addr); 731 xhci_writel(xhci, temp, port_array[port_index]);
702 732
703 spin_unlock_irqrestore(&xhci->lock, flags); 733 spin_unlock_irqrestore(&xhci->lock, flags);
704 msleep(20); 734 msleep(20);
705 spin_lock_irqsave(&xhci->lock, flags); 735 spin_lock_irqsave(&xhci->lock, flags);
706 736
707 temp = xhci_readl(xhci, addr); 737 temp = xhci_readl(xhci, port_array[port_index]);
708 temp = xhci_port_state_to_neutral(temp); 738 temp = xhci_port_state_to_neutral(temp);
709 temp &= ~PORT_PLS_MASK; 739 temp &= ~PORT_PLS_MASK;
710 temp |= PORT_LINK_STROBE | XDEV_U0; 740 temp |= PORT_LINK_STROBE | XDEV_U0;
711 xhci_writel(xhci, temp, addr); 741 xhci_writel(xhci, temp, port_array[port_index]);
712 } 742 }
713 slot_id = xhci_find_slot_id_by_port(xhci, port_index + 1); 743 slot_id = xhci_find_slot_id_by_port(xhci, port_index + 1);
714 if (slot_id) 744 if (slot_id)
715 xhci_ring_device(xhci, slot_id); 745 xhci_ring_device(xhci, slot_id);
716 } else 746 } else
717 xhci_writel(xhci, temp, addr); 747 xhci_writel(xhci, temp, port_array[port_index]);
718 748
719 if (DEV_HIGHSPEED(temp)) { 749 if (DEV_HIGHSPEED(temp)) {
720 /* disable remote wake up for USB 2.0 */ 750 /* disable remote wake up for USB 2.0 */
721 u32 __iomem *addr; 751 u32 __iomem *addr;
722 u32 tmp; 752 u32 tmp;
723 753
724 addr = &xhci->op_regs->port_power_base + 754 /* Add one to the port status register address to get
725 NUM_PORT_REGS * (port_index & 0xff); 755 * the port power control register address.
756 */
757 addr = port_array[port_index] + 1;
726 tmp = xhci_readl(xhci, addr); 758 tmp = xhci_readl(xhci, addr);
727 tmp &= ~PORT_RWE; 759 tmp &= ~PORT_RWE;
728 xhci_writel(xhci, tmp, addr); 760 xhci_writel(xhci, tmp, addr);
diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c
index 47763bed378a..582537689ebc 100644
--- a/drivers/usb/host/xhci-ring.c
+++ b/drivers/usb/host/xhci-ring.c
@@ -1161,9 +1161,11 @@ static void handle_port_status(struct xhci_hcd *xhci,
1161 struct usb_hcd *hcd = xhci_to_hcd(xhci); 1161 struct usb_hcd *hcd = xhci_to_hcd(xhci);
1162 u32 port_id; 1162 u32 port_id;
1163 u32 temp, temp1; 1163 u32 temp, temp1;
1164 u32 __iomem *addr;
1165 int max_ports; 1164 int max_ports;
1166 int slot_id; 1165 int slot_id;
1166 unsigned int faked_port_index;
1167 u32 __iomem *port_array[15 + USB_MAXCHILDREN];
1168 int i;
1167 1169
1168 /* Port status change events always have a successful completion code */ 1170 /* Port status change events always have a successful completion code */
1169 if (GET_COMP_CODE(event->generic.field[2]) != COMP_SUCCESS) { 1171 if (GET_COMP_CODE(event->generic.field[2]) != COMP_SUCCESS) {
@@ -1179,8 +1181,16 @@ static void handle_port_status(struct xhci_hcd *xhci,
1179 goto cleanup; 1181 goto cleanup;
1180 } 1182 }
1181 1183
1182 addr = &xhci->op_regs->port_status_base + NUM_PORT_REGS * (port_id - 1); 1184 for (i = 0; i < max_ports; i++) {
1183 temp = xhci_readl(xhci, addr); 1185 if (i < xhci->num_usb3_ports)
1186 port_array[i] = xhci->usb3_ports[i];
1187 else
1188 port_array[i] =
1189 xhci->usb2_ports[i - xhci->num_usb3_ports];
1190 }
1191
1192 faked_port_index = port_id;
1193 temp = xhci_readl(xhci, port_array[faked_port_index]);
1184 if (hcd->state == HC_STATE_SUSPENDED) { 1194 if (hcd->state == HC_STATE_SUSPENDED) {
1185 xhci_dbg(xhci, "resume root hub\n"); 1195 xhci_dbg(xhci, "resume root hub\n");
1186 usb_hcd_resume_root_hub(hcd); 1196 usb_hcd_resume_root_hub(hcd);
@@ -1200,7 +1210,7 @@ static void handle_port_status(struct xhci_hcd *xhci,
1200 temp = xhci_port_state_to_neutral(temp); 1210 temp = xhci_port_state_to_neutral(temp);
1201 temp &= ~PORT_PLS_MASK; 1211 temp &= ~PORT_PLS_MASK;
1202 temp |= PORT_LINK_STROBE | XDEV_U0; 1212 temp |= PORT_LINK_STROBE | XDEV_U0;
1203 xhci_writel(xhci, temp, addr); 1213 xhci_writel(xhci, temp, port_array[faked_port_index]);
1204 slot_id = xhci_find_slot_id_by_port(xhci, port_id); 1214 slot_id = xhci_find_slot_id_by_port(xhci, port_id);
1205 if (!slot_id) { 1215 if (!slot_id) {
1206 xhci_dbg(xhci, "slot_id is zero\n"); 1216 xhci_dbg(xhci, "slot_id is zero\n");
@@ -1209,10 +1219,10 @@ static void handle_port_status(struct xhci_hcd *xhci,
1209 xhci_ring_device(xhci, slot_id); 1219 xhci_ring_device(xhci, slot_id);
1210 xhci_dbg(xhci, "resume SS port %d finished\n", port_id); 1220 xhci_dbg(xhci, "resume SS port %d finished\n", port_id);
1211 /* Clear PORT_PLC */ 1221 /* Clear PORT_PLC */
1212 temp = xhci_readl(xhci, addr); 1222 temp = xhci_readl(xhci, port_array[faked_port_index]);
1213 temp = xhci_port_state_to_neutral(temp); 1223 temp = xhci_port_state_to_neutral(temp);
1214 temp |= PORT_PLC; 1224 temp |= PORT_PLC;
1215 xhci_writel(xhci, temp, addr); 1225 xhci_writel(xhci, temp, port_array[faked_port_index]);
1216 } else { 1226 } else {
1217 xhci_dbg(xhci, "resume HS port %d\n", port_id); 1227 xhci_dbg(xhci, "resume HS port %d\n", port_id);
1218 xhci->resume_done[port_id - 1] = jiffies + 1228 xhci->resume_done[port_id - 1] = jiffies +