Commit 4f0f0bae authored by Sarah Sharp's avatar Sarah Sharp Committed by Greg Kroah-Hartman

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: default avatarSarah Sharp <sarah.a.sharp@linux.intel.com>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@suse.de>
parent 678539cf
...@@ -67,22 +67,14 @@ static int handshake(struct xhci_hcd *xhci, void __iomem *ptr, ...@@ -67,22 +67,14 @@ static int handshake(struct xhci_hcd *xhci, void __iomem *ptr,
} }
/* /*
* Force HC into halt state. * Disable interrupts and begin the xHCI halting process.
*
* Disable any IRQs and clear the run/stop bit.
* HC will complete any current and actively pipelined transactions, and
* should halt within 16 microframes of the run/stop bit being cleared.
* Read HC Halted bit in the status register to see when the HC is finished.
* XXX: shouldn't we set HC_STATE_HALT here somewhere?
*/ */
int xhci_halt(struct xhci_hcd *xhci) void xhci_quiesce(struct xhci_hcd *xhci)
{ {
u32 halted; u32 halted;
u32 cmd; u32 cmd;
u32 mask; u32 mask;
xhci_dbg(xhci, "// Halt the HC\n");
/* Disable all interrupts from the host controller */
mask = ~(XHCI_IRQS); mask = ~(XHCI_IRQS);
halted = xhci_readl(xhci, &xhci->op_regs->status) & STS_HALT; halted = xhci_readl(xhci, &xhci->op_regs->status) & STS_HALT;
if (!halted) if (!halted)
...@@ -91,6 +83,21 @@ int xhci_halt(struct xhci_hcd *xhci) ...@@ -91,6 +83,21 @@ int xhci_halt(struct xhci_hcd *xhci)
cmd = xhci_readl(xhci, &xhci->op_regs->command); cmd = xhci_readl(xhci, &xhci->op_regs->command);
cmd &= mask; cmd &= mask;
xhci_writel(xhci, cmd, &xhci->op_regs->command); xhci_writel(xhci, cmd, &xhci->op_regs->command);
}
/*
* Force HC into halt state.
*
* Disable any IRQs and clear the run/stop bit.
* HC will complete any current and actively pipelined transactions, and
* should halt within 16 microframes of the run/stop bit being cleared.
* Read HC Halted bit in the status register to see when the HC is finished.
* XXX: shouldn't we set HC_STATE_HALT here somewhere?
*/
int xhci_halt(struct xhci_hcd *xhci)
{
xhci_dbg(xhci, "// Halt the HC\n");
xhci_quiesce(xhci);
return handshake(xhci, &xhci->op_regs->status, return handshake(xhci, &xhci->op_regs->status,
STS_HALT, STS_HALT, XHCI_MAX_HALT_USEC); STS_HALT, STS_HALT, XHCI_MAX_HALT_USEC);
...@@ -124,28 +131,6 @@ int xhci_reset(struct xhci_hcd *xhci) ...@@ -124,28 +131,6 @@ int xhci_reset(struct xhci_hcd *xhci)
return handshake(xhci, &xhci->op_regs->command, CMD_RESET, 0, 250 * 1000); return handshake(xhci, &xhci->op_regs->command, CMD_RESET, 0, 250 * 1000);
} }
/*
* Stop the HC from processing the endpoint queues.
*/
static void xhci_quiesce(struct xhci_hcd *xhci)
{
/*
* Queues are per endpoint, so we need to disable an endpoint or slot.
*
* To disable a slot, we need to insert a disable slot command on the
* command ring and ring the doorbell. This will also free any internal
* resources associated with the slot (which might not be what we want).
*
* A Release Endpoint command sounds better - doesn't free internal HC
* memory, but removes the endpoints from the schedule and releases the
* bandwidth, disables the doorbells, and clears the endpoint enable
* flag. Usually used prior to a set interface command.
*
* TODO: Implement after command ring code is done.
*/
BUG_ON(!HC_IS_RUNNING(xhci_to_hcd(xhci)->state));
xhci_dbg(xhci, "Finished quiescing -- code not written yet\n");
}
#if 0 #if 0
/* Set up MSI-X table for entry 0 (may claim other entries later) */ /* 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,8 +475,6 @@ void xhci_stop(struct usb_hcd *hcd)
struct xhci_hcd *xhci = hcd_to_xhci(hcd); struct xhci_hcd *xhci = hcd_to_xhci(hcd);
spin_lock_irq(&xhci->lock); spin_lock_irq(&xhci->lock);
if (HC_IS_RUNNING(hcd->state))
xhci_quiesce(xhci);
xhci_halt(xhci); xhci_halt(xhci);
xhci_reset(xhci); xhci_reset(xhci);
spin_unlock_irq(&xhci->lock); spin_unlock_irq(&xhci->lock);
......
...@@ -1223,6 +1223,7 @@ void xhci_unregister_pci(void); ...@@ -1223,6 +1223,7 @@ void xhci_unregister_pci(void);
#endif #endif
/* xHCI host controller glue */ /* xHCI host controller glue */
void xhci_quiesce(struct xhci_hcd *xhci);
int xhci_halt(struct xhci_hcd *xhci); int xhci_halt(struct xhci_hcd *xhci);
int xhci_reset(struct xhci_hcd *xhci); int xhci_reset(struct xhci_hcd *xhci);
int xhci_init(struct usb_hcd *hcd); int xhci_init(struct usb_hcd *hcd);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment