diff options
author | Sarah Sharp <sarah.a.sharp@linux.intel.com> | 2009-12-09 15:59:11 -0800 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@suse.de> | 2010-03-02 14:53:12 -0800 |
commit | 6219c047d3fe18dee4916d6898fc94f5a7ffd156 (patch) | |
tree | 31657ba6dd7268ec53a06652bc0b4e104d586ce2 /drivers/usb | |
parent | 34fb562a436ca50e13c05e7584c9d62f151052bf (diff) | |
download | linux-3.10-6219c047d3fe18dee4916d6898fc94f5a7ffd156.tar.gz linux-3.10-6219c047d3fe18dee4916d6898fc94f5a7ffd156.tar.bz2 linux-3.10-6219c047d3fe18dee4916d6898fc94f5a7ffd156.zip |
USB: xhci: Allow roothub ports to be disabled.
Add the hub emulation code to allow ports on an xHCI root hub to be
disabled. Add the code to clear the port enabled/disabled bit, and clear
the port enabled/disabled change bit. Like EHCI, the port cannot be
enabled by setting the port enabled/disabled bit. Instead, a port is
enabled by the host controller after a reset.
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')
-rw-r--r-- | drivers/usb/host/xhci-hub.c | 18 |
1 files changed, 18 insertions, 0 deletions
diff --git a/drivers/usb/host/xhci-hub.c b/drivers/usb/host/xhci-hub.c index 5850e8bc30d..208b805b80e 100644 --- a/drivers/usb/host/xhci-hub.c +++ b/drivers/usb/host/xhci-hub.c @@ -129,6 +129,16 @@ static u32 xhci_port_state_to_neutral(u32 state) return (state & XHCI_PORT_RO) | (state & XHCI_PORT_RWS); } +static void xhci_disable_port(struct xhci_hcd *xhci, u16 wIndex, + u32 __iomem *addr, u32 port_status) +{ + /* Write 1 to disable the port */ + xhci_writel(xhci, port_status | PORT_PE, addr); + port_status = xhci_readl(xhci, addr); + xhci_dbg(xhci, "disable port, actual port %d status = 0x%x\n", + wIndex, port_status); +} + static void xhci_clear_port_change_bit(struct xhci_hcd *xhci, u16 wValue, u16 wIndex, u32 __iomem *addr, u32 port_status) { @@ -148,6 +158,10 @@ static void xhci_clear_port_change_bit(struct xhci_hcd *xhci, u16 wValue, status = PORT_OCC; port_change_bit = "over-current"; break; + case USB_PORT_FEAT_C_ENABLE: + status = PORT_PEC; + port_change_bit = "enable/disable"; + break; default: /* Should never happen */ return; @@ -260,9 +274,13 @@ int xhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue, case USB_PORT_FEAT_C_RESET: case USB_PORT_FEAT_C_CONNECTION: case USB_PORT_FEAT_C_OVER_CURRENT: + case USB_PORT_FEAT_C_ENABLE: xhci_clear_port_change_bit(xhci, wValue, wIndex, addr, temp); break; + case USB_PORT_FEAT_ENABLE: + xhci_disable_port(xhci, wIndex, addr, temp); + break; default: goto error; } |