aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb/host/xhci-hcd.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/usb/host/xhci-hcd.c')
-rw-r--r--drivers/usb/host/xhci-hcd.c51
1 files changed, 17 insertions, 34 deletions
diff --git a/drivers/usb/host/xhci-hcd.c b/drivers/usb/host/xhci-hcd.c
index 3a30db6d6abe..5839453d342b 100644
--- a/drivers/usb/host/xhci-hcd.c
+++ b/drivers/usb/host/xhci-hcd.c
@@ -67,22 +67,14 @@ static int handshake(struct xhci_hcd *xhci, void __iomem *ptr,
67} 67}
68 68
69/* 69/*
70 * Force HC into halt state. 70 * Disable interrupts and begin the xHCI halting process.
71 *
72 * Disable any IRQs and clear the run/stop bit.
73 * HC will complete any current and actively pipelined transactions, and
74 * should halt within 16 microframes of the run/stop bit being cleared.
75 * Read HC Halted bit in the status register to see when the HC is finished.
76 * XXX: shouldn't we set HC_STATE_HALT here somewhere?
77 */ 71 */
78int xhci_halt(struct xhci_hcd *xhci) 72void xhci_quiesce(struct xhci_hcd *xhci)
79{ 73{
80 u32 halted; 74 u32 halted;
81 u32 cmd; 75 u32 cmd;
82 u32 mask; 76 u32 mask;
83 77
84 xhci_dbg(xhci, "// Halt the HC\n");
85 /* Disable all interrupts from the host controller */
86 mask = ~(XHCI_IRQS); 78 mask = ~(XHCI_IRQS);
87 halted = xhci_readl(xhci, &xhci->op_regs->status) & STS_HALT; 79 halted = xhci_readl(xhci, &xhci->op_regs->status) & STS_HALT;
88 if (!halted) 80 if (!halted)
@@ -91,6 +83,21 @@ int xhci_halt(struct xhci_hcd *xhci)
91 cmd = xhci_readl(xhci, &xhci->op_regs->command); 83 cmd = xhci_readl(xhci, &xhci->op_regs->command);
92 cmd &= mask; 84 cmd &= mask;
93 xhci_writel(xhci, cmd, &xhci->op_regs->command); 85 xhci_writel(xhci, cmd, &xhci->op_regs->command);
86}
87
88/*
89 * Force HC into halt state.
90 *
91 * Disable any IRQs and clear the run/stop bit.
92 * HC will complete any current and actively pipelined transactions, and
93 * should halt within 16 microframes of the run/stop bit being cleared.
94 * Read HC Halted bit in the status register to see when the HC is finished.
95 * XXX: shouldn't we set HC_STATE_HALT here somewhere?
96 */
97int xhci_halt(struct xhci_hcd *xhci)
98{
99 xhci_dbg(xhci, "// Halt the HC\n");
100 xhci_quiesce(xhci);
94 101
95 return handshake(xhci, &xhci->op_regs->status, 102 return handshake(xhci, &xhci->op_regs->status,
96 STS_HALT, STS_HALT, XHCI_MAX_HALT_USEC); 103 STS_HALT, STS_HALT, XHCI_MAX_HALT_USEC);
@@ -124,28 +131,6 @@ int xhci_reset(struct xhci_hcd *xhci)
124 return handshake(xhci, &xhci->op_regs->command, CMD_RESET, 0, 250 * 1000); 131 return handshake(xhci, &xhci->op_regs->command, CMD_RESET, 0, 250 * 1000);
125} 132}
126 133
127/*
128 * Stop the HC from processing the endpoint queues.
129 */
130static void xhci_quiesce(struct xhci_hcd *xhci)
131{
132 /*
133 * Queues are per endpoint, so we need to disable an endpoint or slot.
134 *
135 * To disable a slot, we need to insert a disable slot command on the
136 * command ring and ring the doorbell. This will also free any internal
137 * resources associated with the slot (which might not be what we want).
138 *
139 * A Release Endpoint command sounds better - doesn't free internal HC
140 * memory, but removes the endpoints from the schedule and releases the
141 * bandwidth, disables the doorbells, and clears the endpoint enable
142 * flag. Usually used prior to a set interface command.
143 *
144 * TODO: Implement after command ring code is done.
145 */
146 BUG_ON(!HC_IS_RUNNING(xhci_to_hcd(xhci)->state));
147 xhci_dbg(xhci, "Finished quiescing -- code not written yet\n");
148}
149 134
150#if 0 135#if 0
151/* Set up MSI-X table for entry 0 (may claim other entries later) */ 136/* Set up MSI-X table for entry 0 (may claim other entries later) */
@@ -490,8 +475,6 @@ void xhci_stop(struct usb_hcd *hcd)
490 struct xhci_hcd *xhci = hcd_to_xhci(hcd); 475 struct xhci_hcd *xhci = hcd_to_xhci(hcd);
491 476
492 spin_lock_irq(&xhci->lock); 477 spin_lock_irq(&xhci->lock);
493 if (HC_IS_RUNNING(hcd->state))
494 xhci_quiesce(xhci);
495 xhci_halt(xhci); 478 xhci_halt(xhci);
496 xhci_reset(xhci); 479 xhci_reset(xhci);
497 spin_unlock_irq(&xhci->lock); 480 spin_unlock_irq(&xhci->lock);