diff options
author | Sarah Sharp <sarah.a.sharp@linux.intel.com> | 2009-10-27 13:56:33 -0400 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@suse.de> | 2009-12-11 14:55:17 -0500 |
commit | 4f0f0baef017dfd5d62b749716ab980a825e1071 (patch) | |
tree | 74f84a4ddd6ea41c5d359a4ecf1f25fa0a2c7d4d /drivers/usb/host/xhci-hcd.c | |
parent | 678539cfaa090093a9aef185f545f6b17acc445c (diff) |
USB: xhci: Re-purpose xhci_quiesce().
xhci_quiesce() is basically a no-op right now. It's only called if
HC_IS_RUNNING() is true, and the body of the function consists of a
BUG_ON if HC_IS_RUNNING() is false. For the new xHCI watchdog timer, we
need a new function that clears the xHCI running bit in the command
register, but doesn't wait for the halt status to show up in the status
register. Re-purpose xhci_quiesce() to do that.
Signed-off-by: Sarah Sharp <sarah.a.sharp@linux.intel.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
Diffstat (limited to 'drivers/usb/host/xhci-hcd.c')
-rw-r--r-- | drivers/usb/host/xhci-hcd.c | 51 |
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 | */ |
78 | int xhci_halt(struct xhci_hcd *xhci) | 72 | void 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 | */ | ||
97 | int 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 | */ | ||
130 | static 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); |