diff options
Diffstat (limited to 'drivers/usb/host/xhci.c')
-rw-r--r-- | drivers/usb/host/xhci.c | 39 |
1 files changed, 18 insertions, 21 deletions
diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c index 49b6edb84a79..6e0d886bcce5 100644 --- a/drivers/usb/host/xhci.c +++ b/drivers/usb/host/xhci.c | |||
@@ -730,6 +730,9 @@ void xhci_shutdown(struct usb_hcd *hcd) | |||
730 | 730 | ||
731 | spin_lock_irq(&xhci->lock); | 731 | spin_lock_irq(&xhci->lock); |
732 | xhci_halt(xhci); | 732 | xhci_halt(xhci); |
733 | /* Workaround for spurious wakeups at shutdown with HSW */ | ||
734 | if (xhci->quirks & XHCI_SPURIOUS_WAKEUP) | ||
735 | xhci_reset(xhci); | ||
733 | spin_unlock_irq(&xhci->lock); | 736 | spin_unlock_irq(&xhci->lock); |
734 | 737 | ||
735 | xhci_cleanup_msix(xhci); | 738 | xhci_cleanup_msix(xhci); |
@@ -737,6 +740,10 @@ void xhci_shutdown(struct usb_hcd *hcd) | |||
737 | xhci_dbg_trace(xhci, trace_xhci_dbg_init, | 740 | xhci_dbg_trace(xhci, trace_xhci_dbg_init, |
738 | "xhci_shutdown completed - status = %x", | 741 | "xhci_shutdown completed - status = %x", |
739 | xhci_readl(xhci, &xhci->op_regs->status)); | 742 | xhci_readl(xhci, &xhci->op_regs->status)); |
743 | |||
744 | /* Yet another workaround for spurious wakeups at shutdown with HSW */ | ||
745 | if (xhci->quirks & XHCI_SPURIOUS_WAKEUP) | ||
746 | pci_set_power_state(to_pci_dev(hcd->self.controller), PCI_D3hot); | ||
740 | } | 747 | } |
741 | 748 | ||
742 | #ifdef CONFIG_PM | 749 | #ifdef CONFIG_PM |
@@ -839,6 +846,7 @@ static void xhci_clear_command_ring(struct xhci_hcd *xhci) | |||
839 | int xhci_suspend(struct xhci_hcd *xhci) | 846 | int xhci_suspend(struct xhci_hcd *xhci) |
840 | { | 847 | { |
841 | int rc = 0; | 848 | int rc = 0; |
849 | unsigned int delay = XHCI_MAX_HALT_USEC; | ||
842 | struct usb_hcd *hcd = xhci_to_hcd(xhci); | 850 | struct usb_hcd *hcd = xhci_to_hcd(xhci); |
843 | u32 command; | 851 | u32 command; |
844 | 852 | ||
@@ -861,8 +869,12 @@ int xhci_suspend(struct xhci_hcd *xhci) | |||
861 | command = xhci_readl(xhci, &xhci->op_regs->command); | 869 | command = xhci_readl(xhci, &xhci->op_regs->command); |
862 | command &= ~CMD_RUN; | 870 | command &= ~CMD_RUN; |
863 | xhci_writel(xhci, command, &xhci->op_regs->command); | 871 | xhci_writel(xhci, command, &xhci->op_regs->command); |
872 | |||
873 | /* Some chips from Fresco Logic need an extraordinary delay */ | ||
874 | delay *= (xhci->quirks & XHCI_SLOW_SUSPEND) ? 10 : 1; | ||
875 | |||
864 | if (xhci_handshake(xhci, &xhci->op_regs->status, | 876 | if (xhci_handshake(xhci, &xhci->op_regs->status, |
865 | STS_HALT, STS_HALT, XHCI_MAX_HALT_USEC)) { | 877 | STS_HALT, STS_HALT, delay)) { |
866 | xhci_warn(xhci, "WARN: xHC CMD_RUN timeout\n"); | 878 | xhci_warn(xhci, "WARN: xHC CMD_RUN timeout\n"); |
867 | spin_unlock_irq(&xhci->lock); | 879 | spin_unlock_irq(&xhci->lock); |
868 | return -ETIMEDOUT; | 880 | return -ETIMEDOUT; |
@@ -2598,15 +2610,7 @@ static int xhci_configure_endpoint(struct xhci_hcd *xhci, | |||
2598 | if (command) { | 2610 | if (command) { |
2599 | cmd_completion = command->completion; | 2611 | cmd_completion = command->completion; |
2600 | cmd_status = &command->status; | 2612 | cmd_status = &command->status; |
2601 | command->command_trb = xhci->cmd_ring->enqueue; | 2613 | command->command_trb = xhci_find_next_enqueue(xhci->cmd_ring); |
2602 | |||
2603 | /* Enqueue pointer can be left pointing to the link TRB, | ||
2604 | * we must handle that | ||
2605 | */ | ||
2606 | if (TRB_TYPE_LINK_LE32(command->command_trb->link.control)) | ||
2607 | command->command_trb = | ||
2608 | xhci->cmd_ring->enq_seg->next->trbs; | ||
2609 | |||
2610 | list_add_tail(&command->cmd_list, &virt_dev->cmd_list); | 2614 | list_add_tail(&command->cmd_list, &virt_dev->cmd_list); |
2611 | } else { | 2615 | } else { |
2612 | cmd_completion = &virt_dev->cmd_completion; | 2616 | cmd_completion = &virt_dev->cmd_completion; |
@@ -2614,7 +2618,7 @@ static int xhci_configure_endpoint(struct xhci_hcd *xhci, | |||
2614 | } | 2618 | } |
2615 | init_completion(cmd_completion); | 2619 | init_completion(cmd_completion); |
2616 | 2620 | ||
2617 | cmd_trb = xhci->cmd_ring->dequeue; | 2621 | cmd_trb = xhci_find_next_enqueue(xhci->cmd_ring); |
2618 | if (!ctx_change) | 2622 | if (!ctx_change) |
2619 | ret = xhci_queue_configure_endpoint(xhci, in_ctx->dma, | 2623 | ret = xhci_queue_configure_endpoint(xhci, in_ctx->dma, |
2620 | udev->slot_id, must_succeed); | 2624 | udev->slot_id, must_succeed); |
@@ -3439,14 +3443,7 @@ int xhci_discover_or_reset_device(struct usb_hcd *hcd, struct usb_device *udev) | |||
3439 | 3443 | ||
3440 | /* Attempt to submit the Reset Device command to the command ring */ | 3444 | /* Attempt to submit the Reset Device command to the command ring */ |
3441 | spin_lock_irqsave(&xhci->lock, flags); | 3445 | spin_lock_irqsave(&xhci->lock, flags); |
3442 | reset_device_cmd->command_trb = xhci->cmd_ring->enqueue; | 3446 | reset_device_cmd->command_trb = xhci_find_next_enqueue(xhci->cmd_ring); |
3443 | |||
3444 | /* Enqueue pointer can be left pointing to the link TRB, | ||
3445 | * we must handle that | ||
3446 | */ | ||
3447 | if (TRB_TYPE_LINK_LE32(reset_device_cmd->command_trb->link.control)) | ||
3448 | reset_device_cmd->command_trb = | ||
3449 | xhci->cmd_ring->enq_seg->next->trbs; | ||
3450 | 3447 | ||
3451 | list_add_tail(&reset_device_cmd->cmd_list, &virt_dev->cmd_list); | 3448 | list_add_tail(&reset_device_cmd->cmd_list, &virt_dev->cmd_list); |
3452 | ret = xhci_queue_reset_device(xhci, slot_id); | 3449 | ret = xhci_queue_reset_device(xhci, slot_id); |
@@ -3650,7 +3647,7 @@ int xhci_alloc_dev(struct usb_hcd *hcd, struct usb_device *udev) | |||
3650 | union xhci_trb *cmd_trb; | 3647 | union xhci_trb *cmd_trb; |
3651 | 3648 | ||
3652 | spin_lock_irqsave(&xhci->lock, flags); | 3649 | spin_lock_irqsave(&xhci->lock, flags); |
3653 | cmd_trb = xhci->cmd_ring->dequeue; | 3650 | cmd_trb = xhci_find_next_enqueue(xhci->cmd_ring); |
3654 | ret = xhci_queue_slot_control(xhci, TRB_ENABLE_SLOT, 0); | 3651 | ret = xhci_queue_slot_control(xhci, TRB_ENABLE_SLOT, 0); |
3655 | if (ret) { | 3652 | if (ret) { |
3656 | spin_unlock_irqrestore(&xhci->lock, flags); | 3653 | spin_unlock_irqrestore(&xhci->lock, flags); |
@@ -3785,7 +3782,7 @@ int xhci_address_device(struct usb_hcd *hcd, struct usb_device *udev) | |||
3785 | slot_ctx->dev_info >> 27); | 3782 | slot_ctx->dev_info >> 27); |
3786 | 3783 | ||
3787 | spin_lock_irqsave(&xhci->lock, flags); | 3784 | spin_lock_irqsave(&xhci->lock, flags); |
3788 | cmd_trb = xhci->cmd_ring->dequeue; | 3785 | cmd_trb = xhci_find_next_enqueue(xhci->cmd_ring); |
3789 | ret = xhci_queue_address_device(xhci, virt_dev->in_ctx->dma, | 3786 | ret = xhci_queue_address_device(xhci, virt_dev->in_ctx->dma, |
3790 | udev->slot_id); | 3787 | udev->slot_id); |
3791 | if (ret) { | 3788 | if (ret) { |