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>
This commit is contained in:
parent
678539cfaa
commit
4f0f0baef0
@ -66,6 +66,25 @@ static int handshake(struct xhci_hcd *xhci, void __iomem *ptr,
|
|||||||
return -ETIMEDOUT;
|
return -ETIMEDOUT;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Disable interrupts and begin the xHCI halting process.
|
||||||
|
*/
|
||||||
|
void xhci_quiesce(struct xhci_hcd *xhci)
|
||||||
|
{
|
||||||
|
u32 halted;
|
||||||
|
u32 cmd;
|
||||||
|
u32 mask;
|
||||||
|
|
||||||
|
mask = ~(XHCI_IRQS);
|
||||||
|
halted = xhci_readl(xhci, &xhci->op_regs->status) & STS_HALT;
|
||||||
|
if (!halted)
|
||||||
|
mask &= ~CMD_RUN;
|
||||||
|
|
||||||
|
cmd = xhci_readl(xhci, &xhci->op_regs->command);
|
||||||
|
cmd &= mask;
|
||||||
|
xhci_writel(xhci, cmd, &xhci->op_regs->command);
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Force HC into halt state.
|
* Force HC into halt state.
|
||||||
*
|
*
|
||||||
@ -77,20 +96,8 @@ static int handshake(struct xhci_hcd *xhci, void __iomem *ptr,
|
|||||||
*/
|
*/
|
||||||
int xhci_halt(struct xhci_hcd *xhci)
|
int xhci_halt(struct xhci_hcd *xhci)
|
||||||
{
|
{
|
||||||
u32 halted;
|
|
||||||
u32 cmd;
|
|
||||||
u32 mask;
|
|
||||||
|
|
||||||
xhci_dbg(xhci, "// Halt the HC\n");
|
xhci_dbg(xhci, "// Halt the HC\n");
|
||||||
/* Disable all interrupts from the host controller */
|
xhci_quiesce(xhci);
|
||||||
mask = ~(XHCI_IRQS);
|
|
||||||
halted = xhci_readl(xhci, &xhci->op_regs->status) & STS_HALT;
|
|
||||||
if (!halted)
|
|
||||||
mask &= ~CMD_RUN;
|
|
||||||
|
|
||||||
cmd = xhci_readl(xhci, &xhci->op_regs->command);
|
|
||||||
cmd &= mask;
|
|
||||||
xhci_writel(xhci, cmd, &xhci->op_regs->command);
|
|
||||||
|
|
||||||
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)
|
|||||||
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)
|
|||||||
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);
|
|||||||
#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);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user